Arduinoの類は比較的プログラミングの詳細には踏み込まない使い方をすることが多いでしょうけれど、それでもコピペ以上のことを自分の思い通りにやりたいと思ったら知らなきゃいけないことはいろいろあります。
- C/C++言語の基礎ぐらいは知っておかないとどうにもなりません。
Cには文字列という型はなく、文字の配列で終端が'\0'であるものを文字列として扱うということになっているだけです。で、Cでは配列はしばしば配列データの先頭の在り処を以て表すことになっています。
C
1char str1[6]="Hello";
2char str2[6]="Hello";
これは、
- srt1としてメモリ6バイト分の領域を確保し、そこにHello+\0をコピーします。
- str2としてメモリ6バイト分の領域を確保し、そこにHello+\0をコピーします。
このとき、str1とかstr2は確保した領域の場所を指しています。決して"Hello"というデータの中身を表してはいないのです。str1==str2
は確保した場所の比較ということになり、それぞれ別に確保した領域なのでこれは偽になります。文字列の比較は、それぞれの場所から順次データを比較していく、という手順を踏まなければいけません。それをやってくれるstrcmp()等の関数はあるのでそれを使うのが一つの手段。
あるいは、Arduinoでは文字列を(charの配列よりは)楽に扱うためにStringという型(クラス)が用意されています。その機能で文字列を比較するものがありますから、
Arduino
1void func(){
2 String str1="Hello";
3 String str2="Hello";
4 if(!str1.compareTo(str2)){//compareToはstrcmpと同様一致で0を返すので修正しました
5 Serial.println("same");
6 }
7}
などとするのも一つの手です(C++標準ライブラリのstringとはちょっと違うので注意が必要)
もう一つ。シリアル通信の基礎も。
(書いてるうちに話は進んじゃってるけど)
BluetoothSerial::read()関数は、送られた文字を「1文字だけ」受け取る関数です。送り側が"reboot"を送ったなら、read()では'r'だけが取得されます(他は溜め込まれています。あまり溜まっているのが多くなるといろいろ支障がでますが、数文字分は問題ないです)。なので、"reboot"と比較したいのなら、順次'r''e''b''o''o''t'と比較するか、あるいは受信文字を溜め込んで"reboot"と比較するか、そういうことが必要になります。
で。read()がそういう働きをする根源は、シリアル通信の通信単位が「バイト」であるということです。一文字分。通信のレベルでは、二文字以上のグループを形成する決まりはありません。送る側で"12345"というデータを送ったとして、受信する側ではバイト単位で受信するから"123"と"45"と受け取るか、"12345"と受け取るか、あるいは"1""2""3""4""5"と受け取るか、場合によってはその前後のデータとくっついてしまったり...なので、複数バイトで意味を持つデータをやりとりするときには、何らかの方法でその「塊」がわかるようにしてやる必要があります。そういう規則のことを「プロトコル」といいますが、送り手と受け手でなにかの規則を共有します。例えば「データは常にxバイトの固定長」とか、「さきにデータの大きさをxバイトで送って、以降そのデータサイズを受け取る」とか、「データ本体に出現しないはずのデータが出てくるまではひとかたまり」とか。
Arduinoでは、多分比較的簡単なのがテキストベースで通信し、改行を区切りにして改行までをひとかたまりのデータとみなす、という手法でしょう。readStringUntil()という関数を使います。
'Arduino readStringUntil'あたりで検索してみれば、Serialでの使用例が見つかると思いますので参考にしてみて下さい(いや、ちょっと力尽きてきたので手抜き:-)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/29 09:04
2019/12/29 09:15
2019/12/29 09:18