今回は電子工作の記事です。
雑記ブログ的にのんびり書いていきたいと思います。
Arduinoでシリアル通信で角度を入力してサーボモーターをその角度に動かしてみました。
簡単に思えるのですが、いろいろと学んだことがあるので備忘録的に書いておこうと思います。
やりたいこと
やりたいのは初期角度0°の状態からシリアル通信で角度を入力してその位置にサーボモーターを動かすことです。
動いたらその角度で静止していてほしいです。
コード
コードは以下です。
#include <Servo.h>
// サーボインスタンスを生成
Servo myServo;
// サーボピンと角度変数を宣言
const int servoPin=13;
int servoAngle;
void setup() {
// put your setup code here, to run once:
// サーボピンにサーボを割り当て
myServo.attach(servoPin);
// 初期角度を設定
servoAngle=0;
myServo.write(servoAngle);
// シリアル通信の通信速度を設定
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
// シリアル通信をしたときのみif文内を実行する
if(Serial.available()>0){
// シリアルモニターで入力した角度にサーボモーターを動かす
servoAngle=Serial.parseInt();
myServo.write(servoAngle);
// 入力した角度を表示する
Serial.print("servoAngle: ");
Serial.println(servoAngle,DEC);
}
}
シリアルモニターの設定を”No Line Ending”にしないと0°に戻る
ところが上記のコードでシリアルモニターで角度を入力して動かしても一定時間経過後にサーボの角度が0°に戻ってしまいました。
やりたいのは入力した角度にとどまることなのでこれでは困ってしまいます。
どうやらこれは、シリアルモニターの設定が”New Line”になっているのと、Serial.parseIntがbufferにあるデータが有効でない場合にタイムアウト時間経過後に0を出力するようになっているのが原因みたいです。
設定が”New Line”だとEnter(改行)もArduinoのbufferに送られます。
詳しく分解してみると
シリアルモニターで角度を入力してEnterを押す
↓
角度の情報がArduinoのbufferに送られる
↓
if文の条件であるSerial.available()>0がtrueになる
↓
if文内が実行されてサーボモーターが入力した角度に動く
↓
設定が”New Line”なのでEnterもArduinoのbufferに送られる
↓
if文の条件であるSerial.available()>0がtrueになる
↓
if文内が実行されるが、EnterはparseIntにとって有効なデータではないのでタイムアウト時間が経過してparseIntは0を出力する
↓
サーボモーターの位置が0°になる
ということのようです。
これを解決するにはシリアルモニターの入力ボックスのすぐ横にあるプルダウンで”No Line Ending”にすればいいだけです。こうするとEnter(改行)がArduinoに送られなくなります。
※上記はArduinoの英語版リファレンスに偶然たどり着いて知ったことです。やはりリファレンスを読むのは大事ですね。
コメント