openFrameworks, serial通信, arduino, 1 byte, 2 bytes, multi-data

初めに

oFのGPIOで色々制御したいなと思った時に, serial通信が1つの柔軟な方法のようなので勉強しました. あまり速度が速くないそうですが, 知っておくと色々便利そうなのでまぁよし. 皆さんが実際にどう制御しているのかを知りたくて調べたんですが, 思った以上に見つからず. serial通信自体は常套手段の1つだと思うので, 皆さんがどうされているのか是非知りたいところです.

前置きが長いですが, 全部スルーして

本題: codes

に行っても結構です.

本題の前に

一番最初は openFrameworks + Arduinoをserial通信してswitchのon/offをinputする http://qiita.com/shu223/items/a3754f8015875c1cc4f2 をそのまま実行するところからはじめました.

動画

references, その他

参考にさせていただいたページです. 他にもあったかもしれませんが...

公式のドキュメントはやはり強力でした. http://openframeworks.cc/documentation/communication/ofSerial/#show_writeByte https://www.arduino.cc/en/Serial/Available

serialの処理はこちらを参考にさせていただきました. 2byteのシフトの説明もこちらにかかれてあります. 基本的にはビットシフトした1byteの値に対して127(01111111)を論理積(&)をとることで後半7bitを活かす -> 128(10000000)を足すとヘッダー(>=128)になる. という寸法です http://ryoizu.com/blog/2016/06/08/arduino%E3%81%A8openframeworks%E3%81%AE%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E9%80%9A%E4%BF%A1%E3%80%82/ http://d.hatena.ne.jp/kougaku-navi/20141008/p1 当初, Serial.printlnや, readBytesを利用して苦しんでいたんですが, 単数形のwriteByte, readByteでやると一気にシンプルになりました. [0,255]を1byteで送れるし, writeByte, readByteは便利ですね. readBytesの方が高機能なのかもしれないのですが, まぁ勉強し始めなのでおいおいということで.

安定のyoppa.org http://yoppa.org/ma2_11/3383.html ただし, こちらの内容はfirmataを利用されていたもののようだったので断念. firmataも触ってみたいところですが, この記事以降の目的としてarduino megaの使用があり, firmataはmegaに対応していないようだったことが断念の利用です. 単にarduino unoを使うだけなら, firmataも便利な気がします. http://openframeworks.cc/documentation/communication/ofArduino/#show_getPwm

改行ってどう書くんだっけ, と思い参考に http://www9.plala.or.jp/sgwr-t/c/sec05.html

macでバックスラッシュてどう書くんだっけ, と思い参考に http://qiita.com/miyohide/items/6cb8967282d4b2db0f61

signed char: [-127,127] unsigned char: [0,255] なんですね. なるほど. http://stackoverflow.com/questions/75191/what-is-an-unsigned-char

Serial.printとbitを使った例. 今回は使用せず. http://stackoverflow.com/questions/3031413/bitwise-operators-and-converting-an-int-to-2-bytes-and-back-again

"本題の前に"の中身につながる内容. memset http://www9.plala.or.jp/sgwr-t/lib/memset.html memcpy http://www9.plala.or.jp/sgwr-t/lib/memchr.html

c++で配列ってどう書くんだっけ, と思い参考に http://vivi.dyndns.org/tech/cpp/array-algorithm.html

"本題の前に"の中身につながる内容 2. あと, Kyleが答えてる!!と勝手にテンション上がってました. https://forum.openframeworks.cc/t/reading-serial-data-from-arduino/8161

複数のデータを処理してる例 http://4009.jp/post/2016-08-16-74HC595/ 非常に面白そうだったのですが, 今回は0/1ではなく256以上の解像度の複数データの処理をしたかったので断念しました.

software serial. http://asukiaaa.blogspot.jp/2016/03/arduinosoftwareserial.html 面白そうでしたが今回はさわれず. 同時に複数のポートを使うとか, listenでスイッチするとかも後でやりたいところです.

シリアル通信速度(bps) http://www32.atpages.jp/rs232/

本題: 注意点

ようやく本題.

以下,

  • 1 byte [0,255]のデータのやり取り (+ PWMでLEDのグラデーション制御)
  • 2 bytes [0,1023]のデータのやり取り
  • 複数の2 bytes [0,1023]のデータのやり取り (+ PWMでLEDのグラデーション制御)

の順でcodesを書いていきます.

  • 複数の1 byte [0,256]のデータのやり取り

は, 書き方として2 bytesのときと同じ方法しか思いつかなかったので書いてないです. もっと良い処理の方法があると思うんですが, 現状では思いつかず, です.

基本的にはarduinoとmacをUSBケーブルでつないでるだけです. arduinoのPINには何も挿しておらず, 単にserial通信をしているだけです.

bpsは早いほうがいいんですかね?? とりあえずここでは9600にしてます. もっと早くしてる例も結構あるので, 実際に使うときは57600とか115200とかにしようかな.

ただ, oFのFrameRateは60とか120とかである程度制限したほうがいいかも? 1 byteなら

とかで無制限にしても大丈夫でした. ただ2 bytesの時?だと, 処理の途中でミスするのか, 区切りが上手く処理されないのかわからないですが変な値になることがありました(writeでも). 巨大数になったので連結しちゃってるのかなぁ.

1byteでもmac > arduinoでコケることがありました.  ofSetVerticalSync(false)はやらない方が良さそうです. 

bpsを早くしてもoFが遅かったら意味がない(こともある)ので, そこら辺は事情に応じて調整が必要な気がします. まぁread,write自体の処理が早く終わるからそれはそれでメリットはあるか. ふむぅ, 悩み中です.

通信状況は oF : コンソール arduino: シリアルモニタ に表示されます.

接続が上手くいかないときは, mac側のUSBを一旦抜いて挿し直すと, 通信できるようになったりします. USBポートの接触不良が直る? or arduinoのrebootで直る? のかはわかりませんが, とりあえず現状はこれで解決します. 一度つながってからは通信中に調子が悪くなることはまだ体験してないです.

oFのmySerial.setup内の "/dev/cu.usbmodem1421" は, 適宜自分の環境に合わせて変えてください.

oFでerror文の書く場所をdraw内にしてるのはupdateの中においても勿論おkです. printfなのでupdate内でもコンソールに書けます. drawに置いているのは, 実際に画面に出す時に使おうかなぁ...という時に場所がわかりやすいかな?と思っただけです. isValidがグローバル変数になっているのも同様の理由です.

arduino, oFで, valueがグローバル変数になっているのも同様です. writeの際にはグローバルにする必要はないと思いますが, 先頭に書いたほうが, "実際にどの値を送ろうとしているか"がわかりやすいかな?と言う意味も込めてます.

本題: codes

1 byte [0,255]のデータのやり取り

arduino > oF

oF > arduino

oF > arduino でLEDをグラデーションに制御

配線: IMG_3906.jpg

動画:

2 bytes [0,1023]のデータのやり取り

arduino > oF

oF > arduino

 

複数の2 bytes [0,1023]のデータのやり取り

arduino > oF

oF > arduino

oF > arduino でLEDをグラデーションに制御

配線: PWMが出力可能な3,5,6ピンを使用: 3: 赤LED 5: 青LED 6: 黃LED IMG_3921.JPG

動画:

注意

oF > arduino Megaの時

arduino MegaだとoFからのデータをreadするのに少しコツがいるようです. megaが複数ポートあるせいでしょうか...? keypressed等を使って, writeするタイミングを自分で決める様にすると動きました. 理由については調べているところです. 例:

終わりに

以上です. もっと良い書き方等あれば是非教えて頂ければ幸いです!!