アナログ信号からモータをPWM制御する
こんにちわ。今回は前回に使用した測距センサ(GP2Y0A21YK)にモーターをくっつけて回転数の制御をしてみました。この記事はメモ書きの意味が強くなります。というか前に購入したESP32が燃えてしまって買い直したら別のモジュールを買ってしまったみたいで仕様が若干違って手間取っていたり、回転数上げるとプログラムが謎に止まってわけわかめ状態に陥り、数日放置したら普通にうごくとかなんなんだ…ということで本題行きましょうね。
- 目標
- 使用部品
- 回路図及びプログラム
- 動作結果
- 今後
- 参考資料
1. 目標
測距センサに物体が近づいたときのみに、プロペラの回転数が上がるおもちゃを作ります 。今回、モーターの回転数を制御するためにモータードライバを使用します。
2. 使用部品
前回に引き続いてesp32(NodeMCU-32)と測距センサ(GP2Y0A21YK0F)さらにモーターとモータードライバーモジュール(TB6612FNG)を使用します。プロペラは部品屋さんにあったものを買いました。
3. 回路図及びプログラム
今回からKicadを使用して回路図を書きました。TB6612FNGモータードライバモジュール(以下モータードライバ)は初めての型を使用します。AI1とAI2、STBYはデジタル信号でそれぞれP17,P16、P32に接続します。PWM制御はP33に接続します。 AO1,AO2にモーターを接続します。VM,Vccにはesp32から3.3Vの給電を行います。
GP2Y0A21YK0F(以下測距センサ)の信号ピンである3ピンには10Kの抵抗を入れてプルダウンさせます。これをすることで低い値がしっかり出力されたので効果はあると実感しました。
プログラムは測距センサから出た値が1500以上だとPWM信号が250出力1500以下だと100を出力します。測距センサに障害物が近づけばプロペラの回転数が高くなり遠ざかれば回転数が低くなります。また、測距センサが取得した値をわかりやすくするために、シリアル通信で表示しました。
int LED =4; const int voutPin = 26; const int volt = 3.3; const int ANALOG_MAX = 4096; const int Threshold = 1500; const int Amotr1 = 17 ; const int Amotr2 = 16 ; const int stby = 32 ; void setup() { // put your setup code here, to run once: Serial.begin (115200); int reading =0; pinMode(LED,OUTPUT); ledcSetup (0,10000,8); ledcAttachPin(33,0); pinMode(Amotr1,OUTPUT); pinMode(Amotr2,OUTPUT); pinMode(stby,OUTPUT); digitalWrite (Amotr1,HIGH); digitalWrite (Amotr2,LOW); digitalWrite (stby,HIGH); ledcWrite (0,0) ; int voltage = 0 ; } void loop() { int reading = analogRead(voutPin) ; float voltage = ((long)reading*volt*1000)/ANALOG_MAX ; Serial.print(voltage); Serial.println("mV"); if(voltage>Threshold){ ledcWrite(0,250); delay (100); } else if(voltage<Threshold) { ledcWrite(0,100); delay (100); } }
4.動作結果
遊んでる pic.twitter.com/IYn0XmCxSf
— ヨ ロ ズ マ サ ム ネ (@munekunsan) 2020年3月10日
Twitterに乗せた動画では測距センサに手を近づけるとプロペラの回転数が上がりテッシュペーパーがなびいてる様子がわかります。(わかってくれ…)
写真1は測距センサから出力された値をシリアルモニタで表示しています。写真からだけだと低いところで325mmV高いところで2917mmVが出力されています。設定した1500mmVでプロペラの回転数が変化しているのが確認できました。
5.今後
今回1500mmVで回転数が変化するようにしましたが、センサー値に比例して回転数を制御してみたいとおもっています。
追記
比例制御?的なことができるコードを書きましたので追記します。
int LED =4; const int voutPin = 26; const int volt = 3.3; const int ANALOG_MAX = 4096; const int Threshold = 1500; const int Amotr1 = 17 ; const int Amotr2 = 16 ; const int stby = 32 ; void setup() { // put your setup code here, to run once: Serial.begin (115200); int reading =0; pinMode(LED,OUTPUT); ledcSetup (0,10000,8); ledcAttachPin(33,0); pinMode(Amotr1,OUTPUT); pinMode(Amotr2,OUTPUT); pinMode(stby,OUTPUT); digitalWrite (Amotr1,HIGH); digitalWrite (Amotr2,LOW); digitalWrite (stby,HIGH); ledcWrite (0,0) ; int voltage = 0 ; } void loop() { int reading = analogRead(voutPin) ; float voltage = ((long)reading*volt*1000)/ANALOG_MAX ; Serial.print(voltage); Serial.println("mV"); int x = ((255*voltage)/3000) ; Serial.println(x); ledcWrite(0,x); delay (100);
6.参考資料
測距センサ(GP2Y0A21YK0F)
https://docs.rs-online.com/91b2/0900766b80d1bdcb.pdf
モータードライバTB6612FNG
https://www.switch-science.com/catalog/385/
モーターRE-280RA
https://product.mabuchi-motor.co.jp/detail.html?id=66
プルダウン、プルアップ