Reading data from the serial port:
readline() in the below code return the null vector, the reading data from the serial port is hexadecimal number like AABB00EF the putty gives me the output means the communication is working but nothing works via python
here is the code:
#!/usr/bin/python
import serial, time
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 115200
#ser.bytesize = serial.EIGHTBITS
#ser.parity = serial.PARITY_NONE
#ser.stopbits = serial.STOPBITS_ONE
#ser.timeout = None
ser.timeout = 1
#ser.xonxoff = False
#ser.rtscts = False
#ser.dsrdtr = False
#ser.writeTimeout = 2
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
#ser.flushInput()
#ser.flushOutput()
#time.sleep(0.5)
# numOfLines = 0
# f=open('signature.txt','w+')
while True:
response = ser.readline()
print len(response)
#f=ser.write(response)
print response
# numOfLines = numOfLines + 1
f.close()
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
readline will try to read until the end of the line is reached, if there is no \r or \n then it will wait forever (if you have a timeout it might work...) instead try something like this
ser.setTimeout(1)
result = ser.read(1000) # read 1000 characters or until our timeout occures, whichever comes first
print repr(result)
just use this code
ser = serial.Serial("/dev/ttyUSB0",115200,timeout=1)
print "OK OPENED SERIAL:",ser
time.sleep(1)# if this is arduino ... wait longer time.sleep(5)
ser.write("\r") # send newline
time.sleep(0.1)
print "READ:",repr(ser.read(8))
you can create a readuntil method
def read_until(ser,terminator="\n"):
resp = ""
while not resp.endswith(terminator):
tmp = ser.read(1)
if not tmp: return resp # timeout occured
resp += tmp
return resp
then just use it like
read_until(ser,"\r")
Related
I am trying to send textual commands to a microcontroller through usb serial port (ttyUSB0), the controller should respond with 'Y' or 'N' and execute the command. Commands are given in the following form '#01a' where the # is beginning symbol 0 is position for A channel and 1 position for B channel and 'a' is checksum of A+B.
I'm stuck and a beginner in python so any help is welcome and appreciated.
p.s. when I connect using putty everything works as expected
also the OS is Ubuntu 16.04 LTS
This is my code:
import time
import serial
import binascii
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=19200,
)
print 'Enter your commands below.\r\nInsert "exit" to leave the application.'
AT = chr(int('1000000',2))
A = chr(int('100000',2))
B = chr(int('100000',2))
AB = chr(int('1000000',2))
input = AT + A + B + AB
print input
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
#and discard all that is in buffer
#write data
ser.write(input)
# print("write data: AT+CSQ")
time.sleep(0.5) #give the serial port sometime to receive the data
numOfLines = 0
while True:
response = ser.readline()
print("read data: " + response)
numOfLines = numOfLines + 1
if (numOfLines >= 5):
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
Hello I have trouble with read/write from or to device. I wanted to make a serial connection via rs 485 (half-duplex) . When I call read and write functions they didnt receive a data. Anyone know what I do wrong?
def Transmission(ser,data):
if ser.isOpen():
try:
print(data)
ser.flushInput()
ser.flushOutput()
ser.rtscts = True
ser.write(data)
time.sleep(0.1)
numOfLines = 0
print("write: " + data)
while True:
response = ser.readline()
print("read data: " + response)
ser.rtscts = False
numOfLines = numOfLines + 1
if(numOfLines >= 5):
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
return response
Terminal didnt show receiving data:
powah
write: powah
read data:
read data:
read data:
read data:
read data:
I tried to write with read in the loop (with changing ser.rtscts). How to fix that problem? Thank You
I'm attempting to read the values of some GPIO. Here's the code:
import serial
import codecs
import time
ser = serial.Serial(port = 'COM4', baudrate = 9600, \
parity = serial.PARITY_NONE, \
stopbits = serial.STOPBITS_ONE, \
bytesize = serial.EIGHTBITS, \
timeout = 0, \
)
print('connected to: ',ser.name)
ser.close()
def SSend(input):
ser.write(codecs.decode(input, "hex_codec")) #send as ASCII
print('sent: ', input)
def ReadIO():
#open the port
try:
ser.open()
except:
print('error opening serial port')
exit()
#flush the buffers
ser.flushInput()
ser.flushOutput()
#write data to read from GPIO
#causes SC18IM to return a byte containing each of the 8 I/O values
SSend(b'4950')
time.sleep(0.1) #allow time for the data to be received
#read the data
serialData = False
serialData = ser.readline()
ser.close()
return serialData
while 1:
print(ReadIO())
time.sleep(0.5)
This prints the following:
sent:
b'4950'
b''
(I am expecting back either 0x00 or 0x20 instead of an empty byte)
I know my hardware is good as is what I'm sending because it get back what I expect when using Realterm and have successful write commands in my script elsewhere.
I had some luck using this
#read the data
serialData = False
for c in ser.readline():
print('in loop')
print(c)
serialData = c
ser.close()
However, I don't really understand why it worked and it only appears to work intermittently.
Thanks for reading.
readline() assumes that there is some end-of-line symbol, like \n or \r. You should read data byte-wise:
serialData = ''
while ser.inWaiting() > 0:
c=ser.read(1)
# or c=ser.read(1).decode('latin1')
serialData += c
As discussed before in the forum reading problem is being solved but now getting write problem. I want to write some hexadecimal address to the serial port. the address looks like:
000062240
000062A4B
000062244
000062245
000062D50
00006225E
00006A25F
I want to write them byte by byte with the delay of 0.01 sec. To write I do:
Before writing I need to write N and that works perfectly. After C I need to write the address. I put the inner loop in the text file to read the address. But ser.write(line[line1-1]) give the string can not combine with int error. Any solution?
for line1 in range(1,8):
ser.write(line[line1-1])
time.sleep(0.01)
The writing code :
with open('lut.txt', 'r') as f:
for line in f:
#print line
ser.write('N')
time.sleep(0.01)
ser.write(' ')
time.sleep(0.01)
ser.write('C')
time.sleep(0.01)
for line1 in range(1,8):
ser.write(line[line1-1])
time.sleep(0.01)
line+=1
time.sleep(0.01)
For the reference complete code.
import serial, time
from addresstable import *
ser = serial.Serial()
ser.port = "/dev/ttyUSB0"
ser.baudrate = 38400
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.xonxoff = False
ser.rtscts = False
ser.dsrdtr = False
number_address = 10
number_char = 9
timeout=1
#f=open('lut.txt','r')
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
ser.flushInput()
ser.flushOutput()
# reading
max_packet = 20
lines = 0
while True:
byteData = ser.read_until('\r',max_packet)
newdata=str(byteData)
print newdata.strip()
ser.write('I')
time.sleep(0.01)
# writing
with open('lut.txt', 'r') as f:
for line in f:
#print line
ser.write('N')
time.sleep(0.01)
ser.write(' ')
time.sleep(0.01)
ser.write('C')
time.sleep(0.01)
for line1 in range(1,8):
ser.write(line[line1-1])
time.sleep(0.01)
line+=1
time.sleep(0.01)
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
This is what I am doing now:
for line in f:
ser.write('N')
time.sleep(0.01)
ser.write(' ')
time.sleep(0.01)
ser.write('C')
time.sleep(0.01)
#for line1 in range(1,8):
line="line"+"0"
print len(line)
requ = binascii.unhexlify(line)
for i in requ:
ser.write(i)
time.sleep(0.01)
line+=1
time.sleep(0.01)
Problem solved with much simpler way. For future reference.
for i in line:
newdata=i
ser.write(newdata)
time.sleep(0.01)
I have raspberry PI B+ with connected Telegesis ZigBee module(ETRX3 USB sticks) via USB. Using commands:
debian:~# stty -F /dev/ttyUSB0 -raw ispeed 19200 ospeed 19200
debian:~# cat < /dev/ttyUSB0 &
debian:~# echo "ATI" > /dev/ttyUSB0
the ZigBee module executed ATI command and I can see the correct output:
Telegesis ETRX357
R308C
OK
The same thing I want to do with python script. I was written python script with code:
#!/usr/bin/env python
# based on tutorials:
# http://www.roman10.net/serial-port-communication-in-python/
# http://www.brettdangerfield.com/post/raspberrypi_tempature_monitor_project/
import serial, time
SERIALPORT = "/dev/ttyUSB0"
BAUDRATE = 19200
ser = serial.Serial(SERIALPORT, BAUDRATE)
ser.bytesize = serial.EIGHTBITS #number of bits per bytes
ser.parity = serial.PARITY_NONE #set parity check: no parity
ser.stopbits = serial.STOPBITS_ONE #number of stop bits
#ser.timeout = None #block read
#ser.timeout = 0 #non-block read
ser.timeout = 2 #timeout block read
ser.xonxoff = False #disable software flow control
ser.rtscts = False #disable hardware (RTS/CTS) flow control
ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
ser.writeTimeout = 0 #timeout for write
print 'Starting Up Serial Monitor'
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
ser.write("ATI")
print("write data: ATI")
time.sleep(0.5)
numberOfLine = 0
while True:
response = ser.readline()
print("read data: " + response)
numberOfLine = numberOfLine + 1
if (numberOfLine >= 5):
break
ser.close()
except Exception, e:
print "error communicating...: " + str(e)
else:
print "cannot open serial port "
and get results as on the screen
ATI
but I want to command be execute by ZigBee module, as like in shell commands. What am I doing wrong?
you need to append an end-of-line to your write()
ser.write("ATI\r\n")
you should change the timeout to:
ser.timeout = None
Otherwise readline() will return after 2 seconds, even if nothing has been read.