Bluetoothラジコン
タイトルが長い。Bluetoothが使えることが分かったので、自動走行車に組み込んでいく。
basicMotion()
void basicMotion(char c) {
String s = String(c);
mySerial.println(s);
if (s == "8") {
forward();
} else if (s == "2") {
reverse();
} else if (s == "7") {
turnLeft();
} else if (s == "9") {
turnRight();
} else if (s == "4") {
rotateLeft();
} else if (s == "6") {
rotateRight();
} else if (s == "5") {
brake();
}
}
switch文からif文に変えた。switch文ではintとcharしか扱えないみたいで、比較演算子でどうやって比較すりゃいいのかよく分からんかった。で、if文なら文字列も扱えるだしこっちにしよーと思って書き換えてみたものの、charのままだと判定に引っかかってくれない。なんでやねんと思ったらString()使えってことだったので、そうしてみたら上手くいった。あと、前進・後退・右折・左折・右旋回・左旋回をそれぞれf, r, tr, tl, rr, rlとしてそれをスマホのターミナルで打ちbasicMotion内で判断して動きを決めるみたいにした。
こんな感じでマクロを登録した。でも送信文字列が2文字になると、後退しかしてくれなくなった。なんでだろーと一旦printlnで表示してみたら
こんな感じで、2文字一緒に送信してるつもりが1文字ずつになってた。そりゃ動き変わらんわ。分解されたrの文字で判定してるから後退しかしなかったんだなとわかった。ということで前進・後退・右折・左折・右旋回・左旋回を8, 9, 7, 6, 4にするとなんだか上手くいった。
なんで?
あやふやだが、シリアル通信のUARTの場合、データのやり取りは大体
データ : 8bit
パリティ : なし
ストップビット : 1bithttp://tri-s.world.coocan.jp/SfStS_N64/SfStS_Common/UART/Explain_UART.html#Data_Format
という形式でやり取りされる。Bluetoothモジュールとスマホの間のシリアル通信では、文字はASCIIコードの形式でやり取りしているみたい。ASCIIコードは10進や16進の形式に変換される。例えばfという1文字は10進だと102、16進だと66となる。これを2進数にすると1100110で7bit、で、ストップビットを1bitつけて8bitのデータとしてやり取りしてるってことになる。たぶん。なので1文字ずつしか送れないってことになるんかな。で、これを2文字以上として処理するには終了文字かなんかをつけるようにして、終了文字が来るまでデータを待つみたいな感じで動くようにプログラミングしなきゃならんと思われる。それはめんどくさい。なので数字にした。
でもさ、serial.println()とかでやり取りするときはそういうの意識しなくてもちゃんと複数文字が返ってくるんよね。最初、試しにdelay(1000); serial.println(“hello”);とかにしたらちゃんと送られてきたし。この違いは何なんだろう、謎は深まるばかりですね。wikipediaのASCIIも参照。
loop()
ということでloop()内もちょっと変えた。
void loop() {
if (mySerial.available() > 0) {
char c = mySerial.read();
basicMotion(c);
}
if (withinDistance()) {
avoid();
}
}
前にcollisionAvoid()を作ってみたはいいけども、そのままだと何や上手く動かない。collisionAvoid()内でdelayを使っていたので、その間は操作を受け付けないようになっていたわけだ。このメソッドは自動走行の時に必要だったわけなので、思い切って消した。で上記のようになった。意図としては、センサーを読みつつ、操作も受けつつ、ってのを擬似的にでも同時にやりたい!ていう感じ。全体図は次ページ。
配線
怒髪天を衝く感じになった。線いっぱいだー。
動画はとれんかった。ターミナルで動かすのと動画撮影を同時にやれない…残念。



