I have a Digi Transport WR41 cellular router that runs a it's own proprietary operating system and a Python 2.6 interpreter. The router has a serial port (RJ45) that I've connected to a serial port (DB9) on a Windows 7 PC. The cable wiring is a straight through configuration.
On the PC, I've installed RealTerm Serial Capture program and connected it to COM1.
I want to be able to read/write data through the serial connection using python (and pyserial).
My python script is very very basic:
import serial
ser = serial.Serial(port=0, baudrate=9600, parity=serial.PARITY_EVEN, timeout=1)
ser.write(‘hello world’)
#ser.read(1000)
When I send data from RealTerm, I can read it just fine in python via ser.read(1000). This works all day long.
However, when I try to send data from python via ser.write('hello world'), I am unable to see it in RealTerm.
Thinking it might be a RealTerm issue, I tried other emulator/capture programs on the PC: TeraTerm and Serial Port Monitor 6 (by Eltima), but I never saw the data show up.
Serial Port Monitor 6 was the only program to show some sort activity, but I still never saw my data. I don't know enough about serial communication to make any sense of the output, but here is an excerpt:
[19/02/2015 07:58:21]
435 IRP_MJ_DEVICE_CONTROL - Request operates a serial port (COM1)
STATUS_SUCCESS
IOCTL_SERIAL_WAIT_ON_MASK - Request is used to wait for the occurrence of any wait event specified by using an IOCTL_SERIAL_SET_WAIT_MASK request
Mask - 0x00000010 (EV_DSR)
----------------------------------------------------------------------------------
[19/02/2015 07:58:21]
437 IRP_MJ_DEVICE_CONTROL - Request operates a serial port (COM1)
STATUS_SUCCESS
IOCTL_SERIAL_GET_WAIT_MASK - Request returns the event wait mask that is currently set on a COM port
Mask - 0x00000119 (EV_CTS | EV_DSR | EV_RING | EV_RXCHAR)
----------------------------------------------------------------------------------
[19/02/2015 07:58:21]
439 IRP_MJ_DEVICE_CONTROL - Request operates a serial port (COM1)
STATUS_SUCCESS
IOCTL_SERIAL_GET_MODEMSTATUS - Request updates the modem status, and returns the value of the modem status register before the update
Modem Status - 0x00000080 (MS_RLSD_ON)
----------------------------------------------------------------------------------
The router has a counter for Bytes Sent. Every time I call ser.write('hello world'), I see it increment by the correct number of bytes.
I've looked at two similar issues on SO:
pySerial sends ASCII data but recieving device does not respond to it
PySerial can read but not write
I've verified that the device, RealTerm and the python code have consistent settings for the baudrate, parity, stopbits, control flow, etc.
Any other ideas why serial communication with pyserial would only work one way? Why would reads be allowed but not writes?
When I send data from RealTerm, I can read it just fine in python via ser.read(1000). This works all day long.
However, when I try to send data from python via ser.write('hello world'), I am unable to see it in RealTerm.
Are you sure that you can send 'hello world' maybe this is just filtered ?
Did you try with another command or at least another encoding format?
Related
I have a smart camera sending telemetry data every one minute through wMbus (wireless Meter-Bus) and I have a usb stick (wMbus receiver) plugged in a raspberry pi 3 Model B+. I am trying to read the data sent by the camera. I used this:
import serial
ser = serial.Serial(port='/dev/ttyUSB0', baudrate=2400, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=10)
while True:
data = ser.readline()
print(data)
the result is as follows:
b''
b''
b''
b''
b''
Do you know what is the problem and how I can fix it to be able to read the telemetry data sent by the camera?
This can be so many different things, almost every device has his own characteristics when it comes to serial communication, i recommend you to look for some library that's designed directly for your device, or maybe look the device documentation directly.
My opnion is based on my experience with IoT proofs of concept, i had to work with different modules and devices togheter with RPI and Arduino, and every single one of them had some peculiarity when it comes to serial pairing and data exchange.
Looking into google for "wMbus python3 lib" returned a few libraries on github that you may try out and check if it fits your needs.
Most likely it's because there is no data being received over the serial port, and the timeout (which is 10 seconds) has been hit. You can validate this with no device attached at all and see if you get the same behavior.
So I am working on a project that has a Raspberry Pi connected to a Serial Device via a USB to Serial Connector. I am trying to use PySerial to track the data being sent over the connected Serial device, however there is a problem.
Currently, I have my project set up so that every 5 seconds it calls a custom port.open() method I have created, which returns True if the port is actually open. This is so that I don't have to have the Serial Device plugged in when I initially go to start the program.
However I'd also like to set it up so that the program can also detect when my serial device is disconnected, and then reconnected. But I am not sure how to accomplish this.
If I attempt to use the PySerial method isOpen() to check if the device is there, I am always having it return true as long as the USB to Serial connector is plugged in, even if I have no Serial device hooked up to the connector itself.
You might be able to tell whether the device is physically plugged in by checking the status of one of the RS232 control lines - CTS, DSR, RI, or CD (all of which are exposed as properties in PySerial). Not all USB-serial adapters support any of these.
If the only connection to the device is the TX/RX lines, your choices are extremely limited:
Send a command to the device and see if it responds. Hopefully its protocol includes a do-nothing command for this purpose.
If the device sends data periodically without needing an explicit command, save a timestamp whenever data is received, and return False if it's been significantly longer than the period since the last reception.
I am relatively new to Python. I wrote a script and need to add triggers that need to be send via an usb serial port to another pc. The problem is that the triggers (in this code example the 2) never show up on the software on the other pc. When I check it with the print() command, it does print a value, but the printed value is the same number for two different triggers. I have read other posts, I searched the internet, and I tried various things, but I didn't manage to resolve this iusse. This is the code I use for interfacing with the serial port (COM3).
#this part of code is defined at the beginning:
import serial
ser = serial.Serial(port=2, baudrate=9600)
ser.close()
#this part of the code later on to interface with the serial port:
ser.open()
ser.write(chr(2))
ser.close()
Maybe anyone here has any suggestions on where the problem could be? Thanks!
If you haven't already, check that the port settings are correct, 9600,8,N,1 for example. These must match the settings of the remote serial port.
It might be useful to check that the serial connection does work with a terminal emulation program such as minicom (linux), or PuTTY (Windows). Once you have verified that a connection can be made and data transferred, you can be certain that you are connecting to the correct local port, that the port settings are correct, and that your serial cable is working properly.
I am trying to implement a python traceroute that sends UDP messages and receives the ICMP responses via raw sockets. I've run into an issue where the ICMP packets seem to avoid capture at all cost. The ICMP responses show up in wireshark as exactly what I'd expect, but the socket never receives any data to read. Another complication is that I am running the code on VirtualBox running Ubuntu, as the sendto() would not get the packets on the wire in Windows 7. (I'm running wireshark in windows to capture the packets). The strange thing is that wireshark will capture the ICMP messages when I run the python script from the virtual machine. However, when I try to run the script on windows, the ICMP messages don't show up in wireshark. (The UDP packets have magically started working on windows)
I've played around with all sorts of different versions of setting up the socket from online examples, and played around with using bind() and not using it, but no configuration seems to produce a socket that reads. It will just time out waiting to read the ICMP message.
It should also be noted that if I try to read my udp sending socket, it successfully reads the udp packets. As soon as I set IPPROTO_ICMP the read times out.
receive_response method:
def receive_response(rec_socket, packetid, tsend, timeout):
remain = timeout
print packetid
while remain > 0:
ready = select.select([rec_socket], [], [], remain)
if ready[0] == []:
return
print 'got something'
setting up the socket:
rec_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
rec_socket.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
rec_socket.bind(("",0)) #played with using this statement and skipping it
call to receive is simply:
reached = receive_response(rec_socket, packetid, time.time(), timeout)
It looks like the problem is VirtualBox will default to using NAT to connect to the network. This means that the virtual machine won't receive the ICMP messages by virtue of them being ICMP messages. It seems like the solution to this is to configure VirtualBox networking to use "Bridged networking" mode. Unfortunately I cannot confirm this as I can't set up the virtual machine on my university's network within bridged mode. As for the reason they didn't work in windows, it must be related to windows' lack of support for raw sockets.
I am working on a multi threaded server application for processing serial/USB ports.
The issue is that if a cable gets unplugged, pyserial keeps reporting that the port is open and available. When reading I only receive Empty exceptions (due to read timeout).
How do I find out that a port has been disconnected so that I can handle this case?
Edit: OS is Ubuntu 12.04
Edit 2: Clarification - I am connecting to serial port devices via Serial to USB connector, thus the device being disconnected is an USB device.
A Serial port has no real concept of "cable connected" or not connected.
Depending on the equipment you are using you could try to poll the DSR or CTS lines, and decide there is no device connected when those stay low over a certain time.
From wikipedia:
DTR and DSR are usually on all the time and, per the RS-232 standard
and its successors, are used to signal from each end that the other
equipment is actually present and powered-up
So if you've got a conforming device, the DSR line could be the thing you need.
Edit:
As you seem to use an USB2Serial converter, you can try to check whether the device node still exists - you don't need to try to open it.
so os.path.exists(devNode) could suffice.