pySerial/pyWin32でシリアル通信、でも受信が…
TracLightningに入っているpython(2.5)を使ってシリアル通信のプログラムを
試してみました。
その際、pySerial(pyserial-2.5-rc1.win32.exe)やpyWin32(pywin32-214.win32-py2.5.exe)を
インストールして使いました。
以下がそのプログラム。
# -*- coding: shift_jis -*-
from serial import Serial
from struct import unpack,pack
import time
from array import arraycmd1 = pack('8B',0x08,0x11,0x01,0x00,0x00,0x00,0x02,0xE4)
cmd2 = pack('8B',0x08,0x11,0x01,0x00,0x00,0x00,0x1B,0xCB)
cmd_done = pack('4B',0x04,0x12,0x02,0xE8)b_array = array('B')
"""
送信のフォーマット
1.コマンド
(パケット最後までの個数) 0x04または0x08 data0 … checksum
2番目のデータが0x08なら設定値書き換えコマンド、
0x04なら設定値にあわせた設定を実行するコマンド受信のフォーマット
1.メッセージ
(パケット最後までの個数) 0x0d data0 … checksum
最小パケットは(n,0x0d,0x00,checksum)で4byte
2.コマンドに対するack
0x03 0x0c 0xf1
"""
def checksum(num):
global b_array
csum = 0
for i in range(num):
csum += b_array[i]
csum = csum % 256
if csum==0:
return True
else:
return Falsedef mParser():
global b_array
#len(b_array)>=numが前提
num=b_array[0]
if num > 4 and b_array[1]==0x0d and b_array[2]!=0 and checksum(num)==True: #メッセージの時だけ取り出し
print b_array[:num]
elif num == 4 and b_array[1]==0x0d and b_array[2]==0 and b_array[3]==0xef: #
#なにもしない
num =num #dummy
elif b_array[0]==3 and b_array[1]==0x0c and b_array[2]==0xf1:#ack
num = num #dummy
#とりあえず何もやらない
else:
if num == 0 or checksum(num)==False:
#print b_array
#ここにくるものはほとんどごみ(なぜごみが出るか不明)…
b_array=b_array[1:] #1個削る
return
b_array=b_array[num:] #1パケット分を削るdef bParser():
global b_array
while True:
if len(b_array):
num = b_array[0]
if num == 0:
num = 1
if len(b_array)>=num:
num = b_array[0]
mParser()
else:
break
else:
breakcom = Serial(
port=0,
baudrate=115200,
bytesize=8,
parity='N',
stopbits=1,
timeout=0, #0ならread()はすぐ読み出し
xonxoff=0,
rtscts=0,
writeTimeout=None,
dsrdtr=None)com.flushInput()
com.flushOutput()print com.portstr
interval = 8 #[sec]
v=0
b_array = array('B') #arrayとして初期化print 'start'
nexttime = time.time()
while True:
if time.time() >= nexttime:
nexttime = nexttime + interval
#送信
if v==0:
#print 'CMD1' % n
com.write(cmd1)
v = 1
else:
#print 'CMD2' % n
com.write(cmd2)
v = 0
time.sleep(0.05)
com.write(cmd_done) #実際に実行させる
else:
#受信
dlen = com.inWaiting() #受信バッファにたまってる数を確認
if dlen > 0:
d = com.read(dlen)
b_array.extend(array('B',d)) #b_arrayの後ろから追加
bParser()
else:
b_array = array('B') #arrayをクリア#いるかな?これがないとしてもごみでるけど
time.sleep(0.05)
com.close() #結局ctrl+Cとかで止めるから意味がなくなってる
しかし、送信はいいのですが、受信に変なデータ(ごみ)が入ってきます。
必ずというわけでもないのですが。
とりあえず長さとチェックサムをチェックすることで
いまのところ何とかなってる(と思う)のですが、すっきりしません。
これがなければ、ackを確認してから次のコマンドが出るようにしたいのですけど。
コンソールだけでなく、修正してtkinterを使ったものにしてもごみが出てしまいます。
---
TracLightningのpythonでは
win用python関連(pySerialやpyWin32)のインストーラがpythonの場所を見つけられなくてインストールできないのを
TracLightningでpsycoを使うでの、1,2の内容、もしくは手作業でレジストリ書き替えが必要だと思います(私は以前やっていたので)。
| 固定リンク
「python」カテゴリの記事
- subversionのコミットログを検索して置換(2010.09.02)
- pySerial/pyWin32でシリアル通信、でも受信が…(2009.10.21)
- pythonでUTF8→S-JIS変換?結局UTF8のまま。(2009.04.02)
- SQLite DBの変更作業をしてみました(2009.02.19)
この記事へのコメントは終了しました。
コメント