I need to communicate with some device using serial port. I know this device parameters (boudrate etc.). I also know that this device waits untill it receives a new line character (I don't know unix or windows type) and then sends back something in ASCII.
The problem is that when i want to write anything the script hangs. No error occurs, just nothing happens later. It's impossible to print anything or even to close the port.
How can I fix that?
It doesn't work for really basic script. Of course this is no a whole code, just an example to present what is not working.
Sadly, I didn't find any explanation or an answer which works.
I'm working on Ubuntu 16.04
Thanks for your help!
import serial
ser = serial.Serial(
port="/dev/NameOfDevice",
baudrate=115200,
bytesize=8,
parity='N',
stopbits=1,
timeout = 0)
ser.open()
print('Port was opened')
ser.write(b'\r\n') #this is a line where it stops working. Different inputs were tried, nothing works.
print('Does it works?')
edit: I was a fool before, but now I am certain I am correct.
I ran into the same problem and solved it by adding a "write_timeout":
ser = serial.Serial(
port="/dev/NameOfDevice",
baudrate=115200,
bytesize=8,
parity='N',
stopbits=1,
write_timeout = 1,
timeout = 0)
Note that this will raise a timeout exception. In my case this is the expected behavior, because I'm checking to see if I can properly connect on the user specified port.
So I suspect you are connecting to something, but it isn't acknowledging your write, and since the default behavior for 'write' is to block until acknowledgement, this is what you see.
See also the api description for the write function:
https://pyserial.readthedocs.io/en/latest/pyserial_api.html
Related
I'm writing something like an SMS gate on Ubuntu. The device is a Huawei E173 Modem.
I use pyserial to write/read to and from the device. Here is my code:
import serial
import time
port = '/dev/ttyUSB0'
ser = serial.Serial(port,
stopbits=serial.STOPBITS_ONE,
parity=serial.PARITY_NONE,
bytesize=serial.EIGHTBITS
)
ser.write(b'AT\r\n')
time.sleep(0.1)
print(ser.read(ser.in_waiting))
This code works. But sometimes when I reconnect the device, I find that it cannot read anything. (ser.in_waiting=0 and nothing changes even if I set n larger).
But I can still use minicom to work with that port.
My Question: Why doesn't pyserial work but minicom can? Is there any difference between them?
What I guess it's happening is that the delay you are using together with the timeout you set when you open the port is conspiring with the time it takes for the modem to process the command.
To avoid that try reading data repeatedly for a certain time with a loop:
...
ser.write(b'AT\r\n')
timeout=time.time()+3.0
while ser.inWaiting() or time.time()-timeout<0.0:
if ser.inWaiting()>0:
data+=ser.read(ser.inWaiting())
timeout=time.time()+3.0 print(data)
With minicom or any other terminal you are always listening on the port so you always get the answer no matter how long the modem takes to process the command. In your code you send the command, wait 100 ms and then listen on the port for a time period defined by the timeout setting. Since you are not defining a timeout you have the default wait forever but that behavior is overridden by the use of the bytes in the buffer as an argument. If you happen to check the buffer before data arrives in it (because the command took longer than the 100 ms you gave it) the timeout becomes zero.
Considering the previous paragraph, and assuming you know the number of bytes it might be better to define a finite timeout and read with a ser.read(n) with n the expected bytes.
In my case, (on the BeagleBone Black), the above answer helped me get some bytes but not all. I realized, due to some reasons, minicom was reading the port and (maybe) flushing it. So, PySerial got nothing to read.
I simply closed minicom terminal and everything is good now :)
Having a small problem with opening a serial/console port via pySerial.
My program is meant to get the active com port, open a console connection and then send data. When the program is running and I plug in my RS232 USB I receive a SerialException error. (More specifically, "Could not open port: FileNotFoundError")
In the event where the program is run, it will keep printing "No RS232 Connected", but when the RS232 USB is connected the program breaks and runs into the SerialException error.
If I plug in the RS232 USB before running the program and then run it, it reads and performs normal operation without issue.
ports = serial.tools.list_ports.comports(include_links=False)
if not ports:
print("No RS232 Connected")
if ports:
for port in ports:
print('Found port ' + port.device)
ser = serial.Serial(port.device)
if ser.isOpen():
ser.close()
break
console = serial.Serial(port.device, baudrate=9600, parity="N", stopbits=1, bytesize=8, timeout=0.4)
I am quite new to Python and programming in general, but I feel that the problem may be around the 'ports' list already being populated twice due to the while True loop. Then when we go to create the console by opening the port we are expecting one entry in the list, but there are two.
Since we can't have 2 open console connections on the same COM port, we receive the error.
If I print the 'ports' list I get this.
"[<serial.tools.list_ports_common.ListPortInfo object at 0x000002B5D77F0D68>]
[<serial.tools.list_ports_common.ListPortInfo object at 0x000002B5D77F0D68>]"
Any help would be greatly appreciated! Please let me know if you require any more details.
Thanks,
After further research into it, I have realised that when a RS232 USB is plugged into the PC, we need to give it a bit of time to open a stream. It sounds like it is opened when the temp file is created for it.
Although it was identifying that a COM port was available almost immediately, it was not ready by the time I was trying to create the Serial instance, which was why I was getting the FileNotFound error.
A simple sleep function of half a second has solved the issue!
I'm working on some software, which involves communication between PC and embedded device over UART. I'm using STLink's USB/Serial adapter.
Most of the time communication works fine, but after some time (can be hours/minutes or even days) I got write timeout which I can't solve from software level - the only solution that works is to disconnect USB from Nucleo's st-link and then connect it again. I tried to reset or reprogramm embedded device, rerun serial script and nothing seems to work. I tried to implement exception handling which looks like this now (but doesnt work):
self.ser.reset_output_buffer()
try:
self.ser.write(bytes(response))
except Exception as e:
print(e)
print("write timeout occured")
while self.ser.inWaiting()>0:
self.ser.read(1)
self.ser.reset_output_buffer()
self.ser.flushOutput()
self.ser.flushInput()
self.ser.close()
self.ser.open()
serial port configuration is:
def createSerialConnection():
if os.name == "nt":
return serial.Serial('COM4', 38400, timeout=1, rtscts=0,
xonxoff=0,dsrdtr=0, write_timeout=1, parity=serial.PARITY_EVEN)
so... the two devices (PC and embedded) are exchanging 5 messages every second, package size is constant (196 bytes) and before last error I've got 500k packages exchanged without any issue (I've got both higher and lower numbers before). Communication protocol is pretty simple, master(embedded) sends data and waits for response. If response isn't send back in 5seconds it retransmits last package and that's it.
I'd kill for some information on where should I look for the issue. How can I avoid it? Is it pyserial issue (then what should I use, what would be stable enough)? Maybe stlink's (from Nucleo 144) uart/usb is broken?
Thanks for any help!
I have used pyserial for a couple of days. However, a problem occurs today. I met serial write timeout. Several days before, when I used a switch, everything is OK. But today I changed for another switch. Then serial write timeout appears. I did not change any code, but the problem is actually quite severe. More seriously, the timeout not always occurs, which means that sometimes I can write in the serial successfully.
ser = serial.Serial( #Serial COM configuration
port='COM5',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
rtscts=True,
timeout=2,
writeTimeout=5
)
strInput = "show ver"
ser.flushInput()
ser.flushOutput()
ser.write(strInput.encode('utf-8')+b'\n')
I have ensured that the port is COM5 and the baudrate of the switch is 9600. Thanks a lot for answering my question.
I ran into this problem recently. I found that setting write_timeout=0 solved the issue (also, not really sure why a write timeout even exists...)
Another answer here suggests the same thing :)
If you have flow control with request to send / clear to send structure and the device you are writing to isn't responding you need the timeout for the write in order to not hang
The problem may be that the interface tries to comply with RTS, CTS, DSR, or DTS signals. It is possible that if they are not properly connected, they can mysteriously affect communication through a timeout.
One solution may be to ignore their influence using rtscts=False and/or dsrdtr=False when opening the serial port in Python.
I got project to make on my University two weeks ago. I had to read temperature from METEX device connected on COM port. I decided to use Python's pyserial. I found on Internet a few examples and in accordance with them I made something like this:
import serial
ser = serial.Serial(
port='\\.\COM1',
baudrate=1200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.SEVENBITS,
timeout=5
)
if ser.isOpen():
ser.close()
ser.open()
ser.write('D')
s=ser.read(13)
print s
ser.close
and it doesn't work but it should do. Generally, this device send to your computer 13 bytes contain temperature when you send 'D' char to it. I couldn't fix this although I tried to change everything in code and in system configuration. My lecturer couldn't help me too beacuse he doesn't work in Python. He tried beacuse he show me his old program written in C but he has only exec file without code. Program worked on same computer which I executed my Python scripts, so I was sure that COM port, device and system work correctly.
Today, accidentally I add to code this:
import time
import serial
ser = serial.Serial(
port='\\.\COM1',
baudrate=1200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.SEVENBITS,
timeout=5
)
ser.setRTS(False)
time.sleep(0.5)
ser.setRTS(True)
time.sleep(0.5)
ser.setRTS(False)
if ser.isOpen():
ser.close()
ser.open()
ser.write('D')
s=ser.read(13)
print s
ser.close
and now it works perfectly. Why??!!
I must make report from this exercise and describe my code line by line. Please, help me.
Operating system: Windows XP.
I would imagine the Metex device you are using expects RTS to either be 'False' or be pulsed false-true-false.
There is some info about the Metex 14-byte protocol here: http://sigrok.org/wiki/Multimeter_ICs#Metex_14-byte_ASCII
One very simple way to investigate would be to use a terminal program (one which allows you to control RTS) on your PC to manually coimmunicate with the Metex meter, and see what level the RTS has to be to get the Metex device to respond to D.