実現したいこと
ESP32のFreeRTOS機能を使って「モーター制御」を行いながら「センシング+データ解析」を同時に行いたいと考えています(並列処理)
前提
モーター制御部分についてはスイッチを2つ用意し、スイッチが押されるたびに割り込み処理で速度や移動距離が変わることを想定しています。
マルチタスクの割り当て:
Task1: モーター制御+割り込み処理(速度または移動距離の切り替え)
Task2: センシング+データ解析
しかし現状では下記のプログラムにおいて、一方のスイッチを押すともう一方のスイッチも連動してしまう不具合が起こっています(速度スイッチを押すと速度も変わるが、同時に距離も変わってしまう)
該当のソースコード
C
1#include <freertos/FreeRTOS.h> 2#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" 3NAU7802 myScale; 4#include <SPI.h> 5 6volatile float Hz = 1000; //この変数は割り込み処理とモーター制御(osc_stdで共有) 7volatile float distance = 20; //この変数は割り込み処理とモーター制御(osc_stdで共有) 8int strain_level = 1; 9int Hz_level = 1; 10 11void distance_controll() { //移動距離を3段階で切替可能 12 if (strain_level == 0) { 13 distance = 10; 14 strain_level = 1; 15 delay(100); 16 } 17 else if (strain_level == 1) { 18 distance = 20; 19 strain_level = 2; 20 delay(100); 21 } 22 else if (strain_level == 2) { 23 distance = 30; 24 strain_level = 0; 25 delay(100); 26 } 27} 28 29void Hz_controll() { //速度を5段階で切替可能 30 if (Hz_level == 0) { 31 Hz = 1000; //速度1 32 Hz_level = 1; 33 delay(100); 34 } 35 else if (Hz_level == 1) { 36 Hz = 450; //速度2 37 Hz_level = 2; 38 delay(100); 39 } 40 else if (Hz_level == 2) { 41 Hz = 260; //速度3 42 Hz_level = 3; 43 delay(100); 44 } 45 else if (Hz_level == 3) { 46 Hz = 125; //速度4 47 Hz_level = 4; 48 delay(100); 49 } 50 else if (Hz_level == 4) { 51 Hz = 47; //速度5 52 Hz_level = 0; 53 delay(100); 54 } 55} 56 57// 割り込みハンドラ 58// IMPUT_PIN HIGH→LOW 59// 60void IRAM_ATTR switchON_dist() { 61 62 // 割り込みフラグ設定 63 interruptState_dist = 1; 64} 65 66void IRAM_ATTR switchON_hz() { 67 68 // 割り込みフラグ設定 69 interruptState_hz = 1; 70} 71 72void task1( void *param ) //モーター制御+割り込み処理 73{ 74 while ( 1 ) { 75 osc_std(); //モーター制御関数 76 if (interruptState_dist) { // 割り込み発生 77 if ((millis() - msTime_dist) > 50) { // 50ミリ秒以下の割り込みは無視する 78 distance_controll(); 79 osc_std(); 80 msTime_dist = millis(); // 割り込み時刻更新 81 } 82 interruptState_dist = 0; // 割り込みフラグOFF 83 } 84 85 if (interruptState_hz) { // 割り込み発生 86 if ((millis() - msTime_hz) > 50) { // 50ミリ秒以下の割り込みは無視する(チャタリング回避) 87 Hz_controll(); 88 osc_std(); 89 msTime_hz = millis(); // 割り込み時刻更新 90 91 } 92 interruptState_hz = 0; // 割り込みフラグOFF 93 } 94 delay(1); 95 } 96} 97 98void task2( void *param ) //センシング+データ解析 99{ 100 while ( 1 ) { 101//プログラム省略(センシング+データ解析部分) 102 delay(1); 103 } 104} 105 106void setup() 107{ 108 // ウォッチドッグタイマ無効 109 disableCore0WDT(); 110 111 Serial.begin(115200); 112 Wire.begin(); 113 delay(50); 114 115 pinMode(33, OUTPUT); //motor driver dir 116 pinMode(25, OUTPUT); //motor driver stp 117 pinMode(14, OUTPUT); //M0 118 pinMode(27, OUTPUT); //M1 119 pinMode(26, OUTPUT); //M2 120 pinMode(32, INPUT); // 121 pinMode(35, INPUT); // 122 pinMode(36, INPUT); //Hz 123 pinMode(39, INPUT); //distance 124 125 digitalWrite(14, LOW); 126 digitalWrite(27, HIGH); 127 digitalWrite(26, LOW); 128 129//荷重センサの初期化 130 if (myScale.begin() == false) 131 { 132 Serial.println("Scale not detected. Please check wiring. Freezing..."); 133 while (1); 134 } 135 Serial.println("Scale detected!"); 136 137 myScale.setGain(NAU7802_GAIN_128); //Gain can be set to 1, 2, 4, 8, 16, 32, 64, or 128. 138 myScale.setSampleRate(NAU7802_SPS_320); //Sample rate can be set to 10, 20, 40, 80, or 320Hz 139 140 myScale.calibrateAFE(); //Does an internal calibration. Recommended after power up, gain changes, sample rate changes, or channel changes. 141 142 /* create task */ 143 xTaskCreatePinnedToCore( task1, 144 "TASK1", /* タスクの入口となる関数名 */ 145 0x800, /* スタックサイズ */ 146 NULL, /* パラメータのポインタ */ 147 1, /* プライオリティ */ 148 NULL, /* ハンドル構造体のポインタ */ 149 1 ); /* 割り当てるコア (0/1) */ 150 151 xTaskCreatePinnedToCore( task2, 152 "TASK2", /* タスクの入口となる関数名 */ 153 0x800, /* スタックサイズ */ 154 NULL, /* パラメータのポインタ */ 155 0, /* プライオリティ */ 156 NULL, /* ハンドル構造体のポインタ */ 157 0 ); /* 割り当てるコア (0/1) */ 158 159 attachInterrupt(39, switchON_dist, FALLING); //移動距離スイッチを押したときに割り込み処理を実行 160 attachInterrupt(36, switchON_hz, FALLING); //速度スイッチを押したときに割り込み処理を実行 161 msTime_dist = millis(); 162 msTime_hz = millis(); 163} 164 165void loop() 166{ 167 delay(10); 168} 169 170void osc_std() { 171//省略(モーター駆動) 172} 173 174
試したこと(下記プログラム)
RTOSを使用せず、Task1の内容(モーター制御+割り込み)を単独で動作させることはできています(速度スイッチを押すと速度だけが変化し、距離スイッチを押すと移動距離だけが変化)
C
1//#include <freertos/FreeRTOS.h> 2//#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" 3//NAU7802 myScale; 4#include <SPI.h> 5 6volatile float Hz = 1000; //この変数は割り込み処理とモーター制御(osc_stdで共有) 7volatile float distance = 20; //この変数は割り込み処理とモーター制御(osc_stdで共有) 8int strain_level = 1; 9int Hz_level = 1; 10 11void distance_controll() { //移動距離を3段階で切替可能 12 if (strain_level == 0) { 13 distance = 10; 14 strain_level = 1; 15 delay(100); 16 } 17 else if (strain_level == 1) { 18 distance = 20; 19 strain_level = 2; 20 delay(100); 21 } 22 else if (strain_level == 2) { 23 distance = 30; 24 strain_level = 0; 25 delay(100); 26 } 27} 28 29void Hz_controll() { //速度を5段階で切替可能 30 if (Hz_level == 0) { 31 Hz = 1000; //速度1 32 Hz_level = 1; 33 delay(100); 34 } 35 else if (Hz_level == 1) { 36 Hz = 450; //速度2 37 Hz_level = 2; 38 delay(100); 39 } 40 else if (Hz_level == 2) { 41 Hz = 260; //速度3 42 Hz_level = 3; 43 delay(100); 44 } 45 else if (Hz_level == 3) { 46 Hz = 125; //速度4 47 Hz_level = 4; 48 delay(100); 49 } 50 else if (Hz_level == 4) { 51 Hz = 47; //速度5 52 Hz_level = 0; 53 delay(100); 54 } 55} 56 57// 割り込みハンドラ 58// IMPUT_PIN HIGH→LOW 59// 60void switchON_dist() { 61 62 // 割り込みフラグ設定 63 interruptState_dist = 1; 64} 65 66void switchON_hz() { 67 68 // 割り込みフラグ設定 69 interruptState_hz = 1; 70} 71 72 73void setup() 74{ 75 Serial.begin(115200); 76 Wire.begin(); 77 delay(50); 78 79 pinMode(33, OUTPUT); //motor driver dir 80 pinMode(25, OUTPUT); //motor driver stp 81 pinMode(14, OUTPUT); //M0 82 pinMode(27, OUTPUT); //M1 83 pinMode(26, OUTPUT); //M2 84 pinMode(32, INPUT); // 85 pinMode(35, INPUT); // 86 pinMode(36, INPUT); //Hz 87 pinMode(39, INPUT); //distance 88 89 digitalWrite(14, LOW); 90 digitalWrite(27, HIGH); 91 digitalWrite(26, LOW); 92 93 attachInterrupt(39, switchON_dist, FALLING); //移動距離スイッチを押したときに割り込み処理を実行 94 attachInterrupt(36, switchON_hz, FALLING); //速度スイッチを押したときに割り込み処理を実行 95 msTime_dist = millis(); 96 msTime_hz = millis(); 97} 98 99void loop() 100{ 101 osc_std(); //モーター制御関数 102 if (interruptState_dist) { // 割り込み発生 103 if ((millis() - msTime_dist) > 50) { // 50ミリ秒以下の割り込みは無視する 104 distance_controll(); 105 osc_std(); 106 msTime_dist = millis(); // 割り込み時刻更新 107 } 108 interruptState_dist = 0; // 割り込みフラグOFF 109 } 110 111 if (interruptState_hz) { // 割り込み発生 112 if ((millis() - msTime_hz) > 50) { // 50ミリ秒以下の割り込みは無視する(チャタリング回避) 113 Hz_controll(); 114 osc_std(); 115 msTime_hz = millis(); // 割り込み時刻更新 116 117 } 118 interruptState_hz = 0; // 割り込みフラグOFF 119 } 120} 121 122void osc_std() { 123//省略(モーター駆動) 124}
回路図を提示しよう
回答2件
あなたの回答
tips
プレビュー