ちょっとながいですが、以下、記します。(バグがあったらお許しを、Pythonは不慣れなので突っ込んでくださいね。)
あと、これはPySerialが必要ですので、"easy_install pyserial"とか、PySerialとかからダウンロード願います。
---- ここから ----
#!/usr/bin/env python
from serial import Serial
class Gainer:
def __init_(self):
self.ser = None
self.continuous_mode = 0
def open(self, port, config=None):
self.continuous_mode = 0
try:
self.ser = Serial(port)
except:
print "Can't open port!"
return -1
if config:
if config.has_key('baudrate'):
self.ser.baudrate = config['baudrate']
if config.has_key('bytesize'):
self.ser.bytesize = config['bytesize']
if config.has_key('parity'):
self.ser.parity = config['parity']
if config.has_key('stopbits'):
self.ser.stipbits = config['stopbits']
if config.has_key('timeout'):
self.ser.timeout = config['timeout']
if config.has_key('xonxoff'):
self.ser.xonxoff = config['xonxoff']
if config.has_key('rtscts'):
self.ser.rtscts = config['rtscts']
else:
self.ser.baudrate = 38400
self.ser.timeout = 5
return 0
def close(self):
if self.ser.isOpen() == False:
return -1
else:
self.continuous_mode = 0
self.ser.close()
return 0
def send_command(self, cmd):
if self.ser.isOpen() == False:
print "port is not opened."
return -1
self.ser.write(cmd)
return 0
def receive_result(self):
if self.ser.isOpen() == False:
print "port is not opened."
return ""
result = ""
while True:
char = self.ser.read()
#print char
result += char
if char == "*":
return result
def set_to_gainer(self, cmd):
print cmd
self.send_command(cmd)
result = self.receive_result()
print result
if cmd == result:
return True
else:
return False
def get_from_gainer_str(self, cmd):
print cmd
self.send_command(cmd)
result = self.receive_result()
length = len(result)
if (result[0:1] == cmd[0:1]
and result[length-1:length] == "*"):
print result
return result[1:length-1]
else:
return ""
def get_from_gainer_value(self, cmd):
print cmd
self.send_command(cmd)
result = self.receive_result()
length = len(result)
print result
if (result[0:1] == cmd[0:1]
and result[length-1:length] == "*"):
return int("0x"+result[1:length-1], 16)
else:
return 0
def get_from_gainer_value_continuous_mode(self, cmd):
if self.continuous_mode == 0:
self.continuous_mode = 1
print cmd
self.send_command(cmd)
result = self.receive_result()
length = len(result)
print result
if (result[0:1] == cmd[0:1]
and result[length-1:length] == "*"):
return int("0x"+result[1:length-1], 16)
else:
return 0
def reset(self):
return self.set_to_gainer("Q*")
def version(self):
return self.get_from_gainer_str("?*")
def configuration(self, mode):
if mode >= 1 and mode <= 8:
return self.set_to_gainer("KONFIGURATION_%1d*" % mode)
return False
def set_all_digital_output(self, output):
return self.set_to_gainer("D%04X*" % output)
def set_specified_digital_output_high(self, port):
return self.set_to_gainer("H%1d*" % port)
def set_specified_digital_output_low(self, port):
return self.set_to_gainer("L%1d*" % port)
def get_all_digital_inputs(self):
return self.get_from_gainer_value("R*")
def get_all_digital_inputs_continuous_mode(self):
return self.get_from_gainer_value_continuous_mode("r*")
def exit_continuous_mode(self):
cmd = "E*"
print cmd
self.send_command(cmd)
count = 0
while True:
result = self.receive_result()
print result
if cmd == result:
break
else:
count += 1
if count > 10:
return False
self.continuous_mode = 0
return True
def set_sensitivity_for_capacitive_sensing_inputs(self, setting):
return self.set_to_gainer("T%1d*" % setting)
def set_all_analog_outputs(self, value):
return self.set_to_gainer("A%08X*" % value)
def set_specified_analog_output_port(self, port, value):
return self.set_to_gainer("a%1d%02X*" % (port, value))
def set_specified_analog_output_row(self, row, value):
return self.set_to_gainer("a%1d%04X*" % (row, value))
def get_all_analog_inputs(self):
return self.get_from_gainer_value("I*")
def get_all_analog_inputs_continuous_mode(self):
return self.get_from_gainer_value_continuous_mode("i*")
def get_specified_analog_input(self, value):
return self.get_from_gainer_value("S%1d*" % value)
def set_ain_sampling_mode(self, value):
return self.set_to_gainer("M%1d*" % value)
def get_button_state(self):
result = self.receive_result()
print result
if result == "N*":
return 1
else:
return 0
def set_onboard_led(self, value):
if value == 1:
return self.set_to_gainer("h*")
else:
return self.set_to_gainer("l*")
def set_pga_gain_reference(self, gain, referense):
return self.set_to_gainer("G%1d%1d*" % (gain, referense))
---- ここまで ----
ちなみに、非同期受信は出来ていませんので、悪しからず。もう少し待ってくださいね。
以下は、デバッグに使ったテストツールです。
ご参考までに。
---- ここから ----
#!/usr/bin/env python
import Gainer
from time import sleep
g = Gainer.Gainer()
config = { 'baudrate' : 38400, 'timeout' : 5 }
if g.open("/dev/tty.usbserial-A2002mmD", config) == 0:
if g.reset() == True:
print "RESET"
else:
print "ERROR"
sleep(0.1)
g.version()
g.configuration(1)
sleep(0.1)
g.set_onboard_led(1)
sleep(2)
g.get_all_digital_inputs_continuous_mode()
g.exit_continuous_mode()
g.set_all_digital_output(0xffff)
sleep(2)
if False:
#for i in range(16):
g.set_specified_digital_output_high(i)
sleep(1)
g.set_specified_digital_output_low(i)
sleep(1)
print "0x%04X" % g.get_all_digital_inputs()
# for i in range(0x00, 0x100, 0x10):
# g.set_all_analog_outputs(i)
# sleep(0.1)
# for i in range(0x100, 0x00, -0x10):
# g.set_all_analog_outputs(i-1)
# sleep(0.1)
# g.set_all_analog_outputs(0)
for i in range(0x00, 0x100, 0x10):
g.set_specified_analog_output_port(3, i)
sleep(0.1)
g.set_specified_analog_output_port(3, 0)
# for i in range(0x00, 0x10):
# g.set_specified_analog_output_row(9, i)
# sleep(0.1)
# g.set_specified_analog_output_row(9, 0)
for i in range(1000):
#while True:
print "0x%08X" % g.get_all_analog_inputs_continuous_mode()
g.exit_continuous_mode()
g.set_onboard_led(0)
g.close()
---- ここまで ----
以上です。

7 コメント:
preタグでソースは表示すればいいのだそうです。これだから素人は困るよ。。。
ありがとうございました、kinofumiさん!
campでお世話になりましたkameiこと亀鶴です。
gainer.pyで早速遊んでおります。
バグ報告なのですが
set_pga_gain_referenceで呼ばれている、set_to_gainerの引数の数が違うようです。
既にお気づきかも知れませんが、念のため。
鶴亀さん、早速のコメントありがとうございます。
ある程度動いているんですかねー?
ご指摘いただいたバグは、
def set_pga_gain_reference(self, gain, referense):
return self.set_to_gainer("G%1d%1d*" % gain, referense)
のreturn文の中の引数に括弧がついていない話ですか?
def set_pga_gain_reference(self, gain, referense):
return self.set_to_gainer("G%1d%1d*" % (gain, referense))
でいいでしょうか?
この関数はノーデバッグでした。
ちょっとこれから確かめてみますが、動作がちゃんと確認できるかどうか・・・。
それでOKだと思います。
実はそのメソッドを使ったわけではなく、pycheckerを使ったら発見しただけで、特に今すぐ使いたい!というわけではなかったりします。
それなのに動作確認に時間を取らせてしまっているようで、すみません。
こちらでも確認してみます。
綴り間違いや、括弧の対応ミスなどの発見にはpycheckerやpylintが便利です。
#私はほぼ無意識に使うようになっています
とりあえず、鶴亀さんご指摘のバグを修正しておきました。
亀鶴さんによると、
get_all_analog_inputs_continuous_mode関数でset_to_gainer()をコールしていてうまく動かない、というお話でしたが、ちゃんとget_from_gainer_value_continuous_mode関数を呼んでいるようです。
なんか、このブログでpreタグ処理にバグがあるのか、結構改行処理がうまく行っていないことがあるので、そのせいかなぁ。。。
再度、亀鶴さんから不具合ご指摘をいただいたので修正しました。
変更内容:
get_specified_analog_value_continuous_modeの関数名をget_specified_analog_valueに変更し、内部でコールしているset_to_gainer関数をget_from_gainer_value関数に修正。
ちなみに、仕様書には上記関数のSコマンドはcontinuous modeと書いてあるが、実際は単発応答である。
コメントを投稿