Reputation: 2859
I need to communicate and pass values to a serial connected device using RS232 Protocol. I need to pass commands through the 8 bytes of data and then be able to receive the response afterwards.. Im not sure how to write this in PySerial so if anyone can help out it would be great (9600 Baud, 8 data bits, No parity, and 1 stop bit.)
import serial
ser = serial.Serial('/dev/ttyUSB0') # open serial port
print(ser.name) # check which port was really used
ser.write(b'hello') # write a string
ser.close() # close port
The Timer Manager Command structure consists of one start byte, one command byte, five bytes of data, and a one byte checksum. Each message packet is formatted as follows:
BYTE 0 BYTE 1 BYTE 2 BYTE 3 BYTE 4 BYTE 5 BYTE 6 BYTE 7
200 COMMAND DATA1 DATA2 DATA3 DATA4 DATA5 CK SUM
Im looking to receive the following back from the machine: If command was successfully received, the Timer Manager will respond with:
BYTE 0 BYTE 1 BYTE 2
6 0 6
The actual data that I want to send is this Data i need to pass to the timer is structured this way:
BYTE 0 BYTE 1 BYTE 2 BYTE 3 BYTE 4 BYTE 5 BYTE 6 BYTE 7
200 31 4 0 0 0 0 235
Is this passed via bytearray ?
ser.write( bytearray(200,31,4,0,0,0,0,235) );
Upvotes: 2
Views: 11877
Reputation: 996
First of all, due to the fact that you use RS232, you must set the ASCII characters you wanna send in variables. And then, when you got in a variable all the sentence you want to send, sent it decoding it into bytes. It would be something like this.
def sendserial(sendstring):
ser.port(yourport)
try:
ser.open()
except Exception as e:
flag=1
if ser.isOpen():
try:
ser.flushInput()
ser.flushOutput()
ser.write(bytes(sendstring,'iso-8859-1'))
#iso 8859-1 is the only encode that works for me
time.sleep(0.5)
numOfLines = 0
while True:
resp = bytes.decode(ser.readline())
result = ord(str(response))
if result == ord(ACK)
#I set previously the ACK var to the ASCII symbol that the machine returns
response = 'Y'
else:
response = 'N'
numOfLines = numOfLines +1
if (numOfLines>=1):
break
ser.close()
except Exception as e1:
print('Communication error...:' + str(e1))
else:
pass
return(response)
Upvotes: 2
Reputation: 9427
I generally have something like this to do binary IO over a serial port:
from timeit import default_timer as clk
from serial import Serial, SerialException
class TimeManager(object):
def __init__(self, port, baudrate=9600):
self.ser = Serial(port, baudrate=baudrate)
self.ser.open()
self.ser.flushInput()
self.ser.flushOutput()
def send(self, tx):
tx = bytearray(tx)
try:
self.ser.write(tx)
self.ser.flush()
except SerialException as e:
if e.args == (5, "WriteFile", "Access is denied."):
# This occurs on win32 when a USB serial port is
# unplugged and replugged. It should be fixed by
# closing and reopening the port, which should happen
# in the error handling of our caller.
raise IOError(errno.ENOENT, "Serial port disappeared.",
self.ser.portstr)
else:
raise
def receive(self):
rx = bytearray()
delay = 10e-3 # s
timeout = 1 # s
end_time = clk() + timeout
while True:
time_remaining = end_time - clk()
if time_remaining < 0:
break
rx += self.ser.read(self.ser.inWaiting())
if 0 in rx:
break
time.sleep(delay)
if time_remaining <= 0:
raise IOError(errno.ETIMEDOUT, "Communication timed out.")
return rx
tm = TimeManager("/dev/ttyS0")
My device sends null terminated messages (the if 0 in rx:
line). You'd have to figure out a similar condition for your messages.
Upvotes: 2