バージョン情報
Arduino IDE 1.0.6 ,windows 8.1
Arduinoスレーブの第2弾:サーボをシリアル通信のスレーブとして動くようにしてみてた。
第1弾はこちら<Arduino スレーブその1: 1桁7セグ>
PCや他のArduinoなどから”文字列”でコマンドを送信し、スレーブ側で受信した文字列を解析して動作するようにしてみた。
材料
・Arduino pro mini 328 5V
・タクトスイッチ(手動動作確認用)
・サーボモータ SG90
回路
ソースコード
アクションの種類と数値を文字列で結合したものを、コマンドとして処理しようと思ったら結構はまった。
【はまりポイント】
・switch case で文字列が使えない?
・splitが使えない?
・自作関数の引数、戻り値に文字列が使えない?
いろいろ手段はありそうだが、今回は強引に以下の手段で乗り切ることにした。(クラスを作ったほうがいいんだろうけど)
・Stringオブジェクトをグローバル変数で使う。
・if ~ else if ~ を羅列する。
・”100_action”のように数値の後ろにアクションの種類を書くことにして、アクションの種類の判定には、string.endsWidth()を使い、数値の取得にはatoi()を使う。
//スレーブ:サーボ #include <Servo.h> #define servo_1 9 #define button_1 11 #define button_2 12 String str_cmd = ""; Servo myservo_1; int angle = 90; void setup() { myservo_1.attach(servo_1); pinMode(button_1, INPUT_PULLUP); pinMode(button_2, INPUT_PULLUP); Serial.begin(115200); } void loop() { //マスターから受信したら if(myReadLine() > 0){ Serial.println(str_cmd); action_servo(); } //ボタンで手動操作 if (digitalRead(button_1) == 0){ angle = min(angle + 10,180); myservo_1.write(angle); } if (digitalRead(button_2) == 0){ angle = max(angle - 10,10); myservo_1.write(angle); } delay(20); } int myReadLine(void){ int cnt_buf = 0; str_cmd = ""; char ch; //受信したら if(Serial.available() > 0){ delay(100); cnt_buf = Serial.available(); for (int iii = 0; iii < cnt_buf; iii++){ ch = Serial.read(); str_cmd.concat(ch); } } return cnt_buf; } //サーボアクション void action_servo(void){ if(str_cmd.endsWith("action")){ char chA[5]; str_cmd.toCharArray(chA,4); myservo_1.write(constrain(atoi(chA),10,180)); }else if(str_cmd == "play"){ myservo_1.write(90); }else if(str_cmd == "back"){ myservo_1.write(10); }else if(str_cmd == "forward"){ myservo_1.write(180); } delay(20); }
動作確認
Arduino IDEのシリアルモニタからコマンドを送信して動作確認。
「Arduino スレーブその2:サーボ」への1件のフィードバック