すこしふしぎ.

VR/HI系院生による技術ブログ.まったりいきましょ.(友人ズとブログリレー中.さぼったら焼肉おごらなきゃいけない)

蛇と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メソッドが楽だなあと思いました.