DreamerDreamのブログ

夢想家の夢です。〜揚げたてのモヤっとしたものをラフレシアと共に〜

ESP32でカメラ搭載ラジコンを作る ③サーボモーターの追加

前回、ステッピングモーターを制御するためのコードを作りました。

dreamerdream.hateblo.jp

 

今回はそれに加えてサーボモーターの制御コードを加えます。

 

本来、ArduinoのGPIOピン制御はsetup関数内で行うことが通例ですが、motion.cpp内で行えるのか試してみました。

motion.cpp内のinitM()でセットアップを試みます。

 

motion.cppでモーター類一式設定します。

セットアップはここで行います。

これでコンパイル通りました。

なんだ、setup()以外でも出来るんじゃん!

 

 

ESP32のサーボモーターの制御には「ESP32Servo」というライブラリが使われる例が多いようでしたが、裏でなんやかんや動いているせいなのか、僕の環境ではうまく動きませんでしたのでデフォルトPWM制御に使われているLEDC機能で制御することにしました。

上のledcSetup関数の設定でSG90モーターはうまく動かせましたので備忘録として残します。

youtu.be

サーボは電力削減のため、角度指定後3秒経ったらサーボ機能停止するようにしました。(実際に運用すると1秒で充分でした)

サーボに制御出来ない値を与えるとサーボ機能は停止します。※下記コードの「ledcWrite(SERVO_c1, 0);」部分。

先のESP32Servoライブラリでも.detach()関数を用いると位置保持停止できましたが、再度動かすには.attach()関数を読み出さないといけないようで回りくどくなります。

 

サーボ停止用カウントを入れて、前回記事のステッピングモーター制御同様に別スレッドで動かすようにしたコード

void servoM(void *args){
  int cnt = 0;
  int old_dig = 0;
  while(1){
    
    if(0 < cnt){
      cnt++;
    }
    if( 30 < cnt){
      ledcWrite(SERVO_c1, 0);
      cnt = 0;    
    }
    
    if(old_dig != servo_dig_1){
      old_dig = servo_dig_1;
      // 角度からパルス幅を計算する
      int pulseWidth = map(servo_dig_1 , sv_MinSig, sv_MaxSig, servoPlsMin, servoPlsMax);
      // サーボを制御する
      ledcWrite(SERVO_c1, pulseWidth);
      cnt = 1;
      Serial.println(servo_dig_1);
    }
    delay(100);
  }
}

 

ステッピングモーターより楽に動かすことができました。

 

2つ配置していろいろ動作テスト

youtu.be

 

少し癖があるものの、ハードはいい感じで動いたのでいよいよ本体を作っていきます。

 

 

dreamerdream.hateblo.jp

 

 

 

kampa.me