蛇とstrとシリアルと〜pantilt雲台の場合〜
前回に引き続きpython3からシリアルを叩いて遊びます.今回のターゲットはこちらの雲台.こちらの情報を参考にさせていただいています.
仕様確認
まずはシリアルでどのような形式のデータを送ればよいのか調べます.公式サイトのpbf参照.曰く
- オペレーションコードの文字列
- 動作量の数字
- キャリッジリターン
を送ればよさそう.
たとえば'PP2500\r'
と送ると,絶対位置で2500の位置に動かしてくれるそうな.
叩いてみる
とりあえず叩いてみるよ.
pythonコード
port = "/dev/tty.usbserial-" baudrate = 9600 ser = serial.Serial(port=port, baudrate=baudrate) pan_pos = 2500 ser.write('pp' + str(pan_pos) + '\n')
実行結果
TypeError: 'str' does not support the buffer interface
うむ.stringではシリアルにおくれないようです.str型はダメなんですね.てことで次,encodeを噛ませてみる.
ser.write('pp'+str(pan_pos).encode()+'\n')
TypeError: Can't convert 'bytes' object to str implicitly
bytesをstrに変換できません.そうですか.
'pp'
とstr(pan_pos).encode()
に+演算子は使えないということですね.
そういえばpython3では文字列とバイト型は別物でした.
てことでpan_pos前後のstrをバイト型にキャストしてみます.
ser.write(b'pp'+str(pan_pos).encode()+b'\n')
これでうごいたー!
ちゃんとbytes型にすることが大切ですね.
前回の知識のおかげで今回は割とすんなり動きました.よかったよかった.
..ここまで書いて気付いたけど,\rを\nで書いてたなぁこれ. まぁ動いてっからいいか.
ちなみに
前回つかったbytes()関数を使って,こんなんでも挑戦してみました.
ser.write(b'pp') ser.write(bytes([pan_pos])) ser.write(b'\n')
TypeError: 'float' object cannot be interpreted as an integer
ぐぬぬ..
ser.write(b'pp') ser.write(bytes([int(pan_pos)])) ser.write(b'\n')
ValueError: bytes must be in range(0, 256)
おう..
0~256でどやって2500を表現するんだろう.. 2bytesになってもいいのだろうか. たとえばこんなん?
# 2500 = 255 * 9 + 205 val = [9,255] ser.write(bytes(val)) # 0x09,0xFF?
..うごきません..
結局解決せず..
str化してencodeメソッドが楽だなあと思いました.