3本ローラーのスマートトレーナー化(その9)
一応、動くと思われるプログラムができた。
やはりマルチスレッドの処理を行わなくてはならない。EPS32の場合(多分、Arduinoと違って)、マルチスレッドをOSレベルで動かす仕組みがあるようだ。
解説は以下のサイトを参考とさせていただいた。
ESP32でマルチコアを試す12行 - Qiita
別記事のArduinoのマルチスレッド的なものの解説記事では、スレッド間で変数をどうやって受け渡すのかわからなかったのだが、この記事でグローバル変数を使えばいいことがわかった。この方の一連の記事には、他にキューを使った方法、セマフォ(初耳だった)を使う方法も紹介されている。後に行くほど変数の扱いが厳密になる感じ。大変に勉強になるし、本当はグローバル変数を使わない方が良いという知識は持っているのだが、簡単なので安直にグローバル変数を使うやり方を採用。採用してみて、まずいことがありそうなら他のやり方を試すことにする。
/********************************************************************** Filename : Smart_Trainer Description : Control training level of the cycle roller by bluetooth with ESP32 Auther : Ribble CrMo Modification: 2023/01/03 **********************************************************************/ #include "BluetoothSerial.h" #include "string.h" #define PIN_LED1 0 #define PIN_LED2 2 #define CHN1 0 //define the pwm channel #define CHN2 1 //define the pwm channel #define FRQ 1000 //define the pwm frequency #define PWM_BIT 6 //define the pwm precision #define PIN_ANALOG_IN 4 TaskHandle_t thp[1]; //Task handle for multi-task BluetoothSerial SerialBT; int training_level; void setup() { Serial.begin(115200); ledcSetup(CHN1, FRQ, PWM_BIT); //setup pwm channel ledcSetup(CHN2, FRQ, PWM_BIT); //setup pwm channe2 ledcAttachPin(PIN_LED1, CHN1); //attach the led pin to pwm channel ledcAttachPin(PIN_LED2, CHN2); //attach the led pin to pwm channe2 SerialBT.begin("SmartTrainer"); //Bluetooth device name xTaskCreatePinnedToCore(Core0a, "Core0a", 4096, NULL, 3, &thp[0], 0); } void loop() { int adcVal = analogRead(PIN_ANALOG_IN); //if (Serial.available()) { //Serial.println(training_level); //} if (training_level >= 0) { if (adcVal > 2036) { ledcWrite(CHN1, 7 * training_level); ledcWrite(CHN2, 0); } else if (adcVal < 1836) { ledcWrite(CHN1, 0); ledcWrite(CHN2, 7 * training_level); } else { ledcWrite(CHN1, 0); ledcWrite(CHN2, 0); } } if (training_level < 0) { if (adcVal > 2036) { ledcWrite(CHN1, 0); ledcWrite(CHN2, -7 * training_level); } else if (adcVal < 1836) { ledcWrite(CHN1, -7 * training_level); ledcWrite(CHN2, 0); } else { ledcWrite(CHN1, 0); ledcWrite(CHN2, 0); } } } void Core0a(void *args) { String buffer; while (1) { delay(1); if (SerialBT.available()) { buffer = SerialBT.readString(); training_level = buffer.toInt(); } delay(20); } }
このプログラムでブルートゥースからの通信を受けてLEDの明るさや切り替えを行いつつ、ADコンバータを使用することもできた。ただし実装はまだこれから。
実は実装用にEPS32開発キットを購入したのだが、ADコンバータが不調で色々やっている内にショートさせてしまい、USBインターフェース部分が壊れた模様(直接5V電源を入れるとまだ動くようだ?)。
トレーニングキットを実装用に転用するのは避けたいので新しいものを入手中。