Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Martster

macrumors newbie
Original poster
Feb 9, 2008
28
1
Van Diemen's Land
Hi, I'm an artist who uses programming in multimedia work. I have limited experience with python and with java. At the moment i'm trying to get data from a weather meter to use as input for an animation. The device has two optical ports on the back, and when in 'download mode' sits in a cradle (with electronics inside) that has a serial output. I have a Keyspan USA-19HS attached to the serial port, and plugged into my Santa Rosa MBP via usb port.

I have been given authorised access to a copy of the protocol that the unit uses. It uses an ASCII protocol and comma separated output values. It operates at 9600 baud, 8 bit data, 1 stop bit and no parity. Full duplex. No hardware or software handshaking.

I'm wondering if pySerial is the right approach in order to set up a connection via the terminal and send the unit the right signal to download the logged data?

any comments and advice would be greatly appreciated,

cheers

Mart
 
While you will need the serial protocol, you'll also need a driver for the chip in the Keyspan USA-19HS. Many USB to serial converters are based on the FTDI series of chips (http://www.ftdichip.com/) and a generic driver from them can often be used.

Drivers for USB<->serial converters generally fall into two camps: either they provide a quasi-serialport interface to user-level apps, or they have a custom (but usually more efficient) interface. If the driver you find for the Keyspan USA-19HS falls into the first category, then using pySerial should be fine. Otherwise, you'll need to do some more hacking to access the API of the driver from within Python.
 
Thanks Bakerman. The Keyspan USA-19HS came with an OSX driver, and the installed 'Keyspan Serial Assistant' application shows the correct info for the device. I ran some quick tests with pySerial from the terminal and was able to open a port and seem to be able to write to the device, however when I use ser.readline() the device returns a blank line to the terminal. These are the commands i was using in the python interpreter;

>>> import serial
>>> ser = serial.Serial('/dev/cu.USA19H1d1P1.1', 9600, timeout=1)
#Open named port at "9600,8,N,1", 1s timeout::

>>> line = ser.readline() #read a '\n' terminated line

The instructions for the protocol say that the device should download the data log upon receiving the command 'B'. I am obviously missing something here, but am not sure what to do next.

thanks again for your help so far : )
 
Thanks Bakerman. The Keyspan USA-19HS came with an OSX driver, and the installed 'Keyspan Serial Assistant' application shows the correct info for the device. I ran some quick tests with pySerial from the terminal and was able to open a port and seem to be able to write to the device, however when I use ser.readline() the device returns a blank line to the terminal. These are the commands i was using in the python interpreter;

>>> import serial
>>> ser = serial.Serial('/dev/cu.USA19H1d1P1.1', 9600, timeout=1)
#Open named port at "9600,8,N,1", 1s timeout::

>>> line = ser.readline() #read a '\n' terminated line

The instructions for the protocol say that the device should download the data log upon receiving the command 'B'. I am obviously missing something here, but am not sure what to do next.

thanks again for your help so far : )

I'm just making this up, but perhaps:
Code:
ser.writeline('B')
would get you going? Then you can read the response? Is there some sequence that you can be looking for to let you know the device is done transmitting?

-Lee
 
Thanks Lee,

I have an open port and a connection to the device
(I have tested this by removing the device when the port is open
and it hangs until the device is replaced)

I seem to be able to write to the device using
Code:
ser.write('B')

the problem is all I get back is
Code:
>>> ' '
(an empty tuple perhaps?)
if i use either
Code:
ser.read()
ser.read(20)

or
Code:
>>> []
(i guess thats an empty array)
when I use
Code:
ser.readlines()

am not sure where to go from here,
python uses utf-8, so the 'B' should be valid ASCII
do you think I should add a CR and NL to my 'B' ?

any other suggestions greatly appreciated

thanks

Mart
 
am not sure where to go from here,
python uses utf-8, so the 'B' should be valid ASCII
do you think I should add a CR and NL to my 'B' ?

I would definetly try different variations of line termination. Send 0x0 or 0x13 or 0x10 or 0x13 0x10, there is unfortunately no single universal standard here. No termination at all is also possible, but you already tried that..
 
Thanks again for your input Bakerman.
Here is a sample of my terminal session.

Code:
>>> import serial
>>> ser = serial.Serial('/dev/cu.USA19H1d1P1.1', 9600, timeout=1)
>>> ser.inWaiting()
0
>>> ser.flushInput()
>>> ser.flushOutput()
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> ser.write('B0x0')
>>> ser.read(100)
''
>>> ser.write('B0x13')
>>> ser.read(100)
''
>>> ser.read()
''
>>> ser.readlines()
[]
>>> ser.write('B0x10')
>>> ser.read(100)
''
>>> ser.write('B0x130x10')
>>> ser.read(100)
''
>>> ser.readlines()
[]
>>> ser.write("B0x130x10")
>>> ser.read(100)
''
>>>



Do you think I'm on the right track? I'm not at all familiar with the way serial ports handle input and output, let alone that of the Kestrel 4500 weather meter I'm trying to talk to.

Am interested to know what format your line terminations are in. Should my 'B' be in that format too?

tnx

Mart
 
'B0x13' should be 'B\x13'? It is supposed to be a two-character string, not five characters. Same goes for all the others.
 
A one second timeout for a 9600 baud serial device is kinda low, try setting the timeout to 5 seconds and sending only a "B" and see if that works.
 
Tnx Sayer,

but still no success, results below:

Code:
>>> import serial
>>> ser = serial.Serial('/dev/cu.USA19H1d1P1.1', 9600, timeout=5)
>>> ser.write("B")
>>> ser.read(10)
''
>>> print ser
Serial<id=0x753590, open=True>(port='/dev/cu.USA19H1d1P1.1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=5, xonxoff=0, rtscts=0, dsrdtr=0)
>>> x = ser.readlines()
>>> print x
[]
>>> ser.timeout = 10
>>> ser.write("B")
>>> ser.read(100)
''
>>> ser.write('I?')
>>> x =  ser.readlines()
>>> print x
[]
>>> ser.timeout = 15
>>> ser
Serial<id=0x753590, open=True>(port='/dev/cu.USA19H1d1P1.1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=15, xonxoff=0, rtscts=0, dsrdtr=0)
>>> ser.write("I?")
>>> ser.read() 
''
>>> ser.flushInput()
>>> ser.flushOutput()
>>> ser.write("I?")
>>> ser.readline()
''
>>> x = ser.readline()
>>> print x

>>>

Ive been doing some research to try to figure what kind of microprocessor is in it, as I hope that might give me some more info. I think its a PIC16F87XAC made by Microchip, but will try to confirm that with the national tech support for the device.

thanks for your input :apple:

Marty
 
Tnx Sayer,

but still no success, results below:

Code:
>>> import serial
>>> ser = serial.Serial('/dev/cu.USA19H1d1P1.1', 9600, timeout=5)
>>> ser.write("B")
>>> ser.read(10)
''

Have you tried
Code:
>>> ser.write("B\x13")
>>> ser.write("B\x10")
>>> ser.write("B\x13\x10")
>>> ser.write("B\x00")
?
 
Success and many thanks

Hi Cromulent, Bakerman and Sayer;

thanks all of you for helping me out with my puzzle.
The last bit fell into place with Crom's suggestion re \r\n.
Tried a few combos and \r was the key. Awesome, now I can access the data in raw form without having to deal with a non-mac operating system or the gigabytes of guff that it would entail.

Also this approach will give me access to polled data in real time, which the standard "communicator" app does not allow. So thanks again for all the help :)

Mart







Here is the Python session for the protocol that works:

Code:
>>> ser = serial.Serial('/dev/cu.USA19H1d1P1.1', 9600, timeout=5)
>>> ser
Serial<id=0x753dd0, open=True>(port='/dev/cu.USA19H1d1P1.1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=5, xonxoff=0, rtscts=0, dsrdtr=0)
>>> ser.write('I?\r')
>>> ser.readlines()
['I?\r\n', 'Iss 4.29   All\r\n', 'Status=0\r\n', 'RH cal 1: 01/00/2008 05:02:33\r\n', 'RH cal 2: 01/00/2008 20:35:44\r\n', 'T2_correct: 83789846\r\n', 'K4500\r\n', '> ']
>>> ser.write('B\r')
>>> ser.readlines()
['B\r\n', '> DT,MG,TR,WS,CW,HW,TP,WC,RH,HI,DP,WB,BP,AL,DA\r\n', 's,Mag,True,km/h,km/h,km/h,\xb0C,\xb0C,%,\xb0C,\xb0C,\xb0C,hPa,m,m\r\n', '280683000,---,---,0.0,0.0,0.0,21.1,21.1,58.6,20.9,12.7,15.8,983.0,251,588\r\n', '280683600,125,125,0.0,0.0,0.0,19.9,19.9,54.9,19.0,10.5,14.2,983.3,249,534\r\n',  etc, etc
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.