[Tutor] any serial gurus available?
Michael P. Reilly
arcege@speakeasy.net
Thu, 3 May 2001 11:26:28 -0400 (EDT)
Bill Tolbert wrote
> I need to read data from a small medical device over a serial port (it's a
> spirometer; measures lung function). I'm using Roger Burnham's Serial
> package, Python 2.0 on Win98.
>
> According to the documentation (yes, I have some!) the "transmission shall
> be initiated when the PB100 sends a start of header character (0xa5)." I
> can open the port and ask for the first byte (line 5 below). I indeed
> receive the header character, so I know something is happening (line 6
> prints '0xa5' to stdout). The docs say the device will wait on the PC for
> an acknowledgement. I believe this is working. Line 9 causes the device
> to beep.
>
> First question: From the docs, "Valid acknowledge signals shall be one
> byte values in the range of 0x01 to 0xFE." So, is line nine the way to
> send a valid 0x01? I assume yes (why else would it beep? <grin>)
Below you are sending the hex() of a number, which results in a multi-
byte(character) ASCII string, not a single byte binary string to be sent.
You might be getting the beep because the first byte written is 48, not 1.
The difference is that hex(1) gives a string of three bytes '0'(48),
'x'(120), '1'(49). But the single byte string is '\001'(1). The number
in parenthises is the ASCII (ISO-8859-1) value returned by ord().
Python provides a chr() function that creates the ASCII character for
a given value.
>>> chr(1) # the binary 1, ASCII SOA
'\001'
>>> chr(32) # space
' '
>>> chr(48) # the ASCII zero numeral, but not the integer 0
'0'
> The device waits 200 milliseconds to adjust the baud rate, then sends
> either a 1 or a 2. Here's where I get really confused. How do I get the
> next value? Line 10 begins a for loop. I read 1 byte from the port,
> looping 10 times. I would expect to see either a 1 or a 2, but instead I
> usually get a series of 0's.
You can sleep for a number of milliseconds by using a float with the
"sleep" function in the "time" module.
>>> import time
>>> sleep_howlong = 0.200 # seconds, or 200 milliseconds
>>> time.sleep(sleep_howlong)
> My read of the docs is that it will just dump bytes at this point, then
> wait on a checksum. I don't think I'm getting anything to calculate a
> checksum on!
>
> My COM1 buffers are set to the minimum, so I don't think I'm losing data
> in there. Is there something about my read method that isn't correct?
>
> Thanks a 0xf4240,
>
> Bill
> ==============================
>
> (port setup stuff above...)
> ...
> 1 #read some data
> 2 try:
> 3 # read the first byte; should be 0xa5 in hex
> 4 # delivered as an octal
> 5 header = port.read(1, timed=1)
> 6 print hex(ord(header[0]))
> 7 if '0xa5' == hex(ord(header[0])):
#Just test with (use the hex character ('\xa5' with Python 2.1):
if '\245' == header[0]: # the octal value of 0xa5
> 8 # send an achnowlegement. now what?
> 9 port.write(hex(1))
#Use the binary character instead:
port.write(chr(1))
> 10 for i in range(1,11):
> 11 byte = port.read(1, timed=1)
> 12 blocks.append(byte)
#Sleep here, then read ten bytes:
time.sleep(0.2) # sleep for 200 milliseconds
bytes = port.read(10, timed=1)
blocks = list(bytes)
> 13 print blocks
> 14 port.close()
> 15 except:
> 16 port.close()
> 17 traceback.print_exc()
> 18 return None
Good luck - I can't test any of this of course, I don't have a device
to test it on or the "serial" module you speak of (or the OS). But if
it doesn't work, I'm sure someone will correct me. :)
-Arcege
--
+----------------------------------+-----------------------------------+
| Michael P. Reilly | arcege@speakeasy.net |