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電源を入れるとまだ動くようだ?)。
 トレーニングキットを実装用に転用するのは避けたいので新しいものを入手中。