2008年4月20日日曜日

Com ポートの制御、その2 マイコンとの通信

RS-232C ポートを pySerial で制御してマイコンと通信してみましょう。

ループバックと違い、いろいろなことを考えないといけません。
通信する相手に手元にある activecell さん の GP232 をターゲットにします。

もともと、GPIBの測定器を古いノートPCで制御するに買いました。とても気に入って使っています。
付属のCD-Rには、丁寧なマニュアルとVB(Excel)による制御ソフトがついていて非常にありがたいです。これを、ADコンバータ入力、PWM出力モードにして Python + pySerialから制御してみましょう。思い出しましたが、このGP232 をもっと使い込みたいというのも Python を勉強するきっかけでした。ありがとうございます。

取り扱い説明書、および Visual Basic のコードに細かく丁寧な説明があるので、詳細はそちらを参照してください。

おおまかに

  1.  COMポートの設定
  2.  DTR を マイナスに、GP232 アダプタにマイナス電源を供給する。
  3.  RTS を、0、1 リセットする
  4.  I コマンドで通信確認を兼ねてファームのバージョンを読み込む35文字あるけど10文字だけ読んで残りは受信バッファーから消す
  5.  アダプターを AD読み込みモードにする
  6.  ボーレートを 9600 から 115200に変更する
  7.  Iコマンドで再度通信確認
  8.  Gコマンドで A/D データを読み込む(3回)
  9.  PコマンドでPWM出力を設定する
  10.  ボーレートを115200 から 9600に変更する
  11.  PコマンドでPWM出力を設定する

デスクトップPCで確認したときは、かなり早い GP-232 でしたが、自宅のノート + USB シリアルで確認すると遅くなりました。これは GP-232のせいではなく USB Serial アダプタのせいだと思われます。 Activecell さんもそのあたり いろいろトラブルが在った様で、同サイトに USB-Serial に関する情報も豊富です。わたしの自宅の USB-Serial adapter は、不運なことに1秒に1回しか反応しない、だめなアダプタのようです。

デスクトップでもある程度スリープが必要な UART コントローラもありますので各自 sleep() を入れる場所と(値)のチューニングをしてください、

-


## $Id$
##
## Win32 (Win XP)
## Python 2.5
## Python2.5 (for win32)
## Pywin32 210 (for win32 Python2.5)
## pySerial 2.2 (for win32 Python2.5)


import serial
from time import sleep, time

ser = serial.Serial(
port = 0, ## COM1 = 0, COM2 = 1, ...
baudrate = 9600,
parity = serial.PARITY_NONE,
bytesize = serial.EIGHTBITS,
stopbits = serial.STOPBITS_ONE,
timeout = 2.0, ## Sec
)

ser.open()

## Initialize Adapter
ser.setDTR(0) # Minus : Supply minus volts
ser.setRTS(0) # Minus : Reset
sleep(0.1)
ser.setRTS(1) # Plus :
sleep(0.1)
ser.flushInput()
ser.flushOutput()

## check Firmware
ser.write('I')
Data = ser.read(10) # (35)
print Data
sleep(0.1)
ser.flushInput()

## set Adapter mode
ser.write('A')
Data = ser.read(2) #
print Data

## change BaudRate
ser.write('B5')
sleep(0.1)
ser.setBaudrate(115200)
print ' ... Change baudrate from 9600 to 115200 '

## check Firmware
ser.write('I')
Data = ser.read(10) # (35)
print Data
sleep(0.1)
ser.flushInput()

## read AD values
ser.write('G')
Data = ser.read(20)
print time(),Data

ser.write('G')
Data = ser.read(20)
print time(),Data

ser.write('G')
Data = ser.read(20)
print time(),Data

## wrire PWM values
ser.flushInput()
ser.write('P10FF') # ch1 = 25%
print ser.read(2)

ser.flushInput()
ser.write('P22FF') # ch2 = 75%
print ser.read(2)

raw_input(' Check duty cycle and press Enter > ' )

## change BaudRate
ser.write('B0')
sleep(0.1)
ser.setBaudrate(9600)
print ' ... Change baudrate from 115200 to 9600 '


## wrire PWM values
Ch = '1'
Duty = 70.0
ser.flushInput()
ser.write('P%(c)s%(d)03X' %{'c':Ch,'d':Duty/99 *0x3FF })
print ser.read(2)

Ch = '2'
Duty = 30.0
ser.flushInput()
ser.write('P%(c)s%(d)03X' %{'c':Ch,'d':Duty/99 *0x3FF })
print ser.read(2)


raw_input(' Check duty cycle and press Enter > ' )
ser.close()





0 件のコメント: