PySerial, check if Serial is Connected - python

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.

Related

Is there a way to view what is being written on serial from a Python script without connecting a device?

In short, I have written a Python program to write a series of commands to a serial device I'm working with, and I want to make sure they're working in the way I want them to.
For sure, no device connected means no response/nothing to read...
Did you consider trying a serial port sniffer, if you google for serial port sniffer, you'll find more than you need.
Connect any serial device and sniff what you send.

Sniffing data of serial port without removing data from buffer

I am using the bgapi library to manage bluetooth communication using a USB dongle. The library will take a command from my program and will handle all serial communications through the COM port in its own thread. I want to echo back all data coming out of the COM port, but the library only gives me access to what it chooses to parse out itself.
I could go into the bgapi library and change the functionality of the code, setting up a variable or function to return what data is currently being read, but other people are also working on this project and changing the library could cause larger problems or invalidate updates.
Is there any way for me to access the data coming into the COM port without interfering with the library, like sniffing the data going through the COM port without taking it out of the buffer for the library? The library holds the port open for itself and discards the extra data that I want to see.
I'm not sure I understood completely how your library works so I'm not sure this will work for you but you can give it a try anyway.
What you can do (on Windows) is use Termite as a man-in-the-middle with port forwarding.
Since you probably want to keep everything inside one computer you can use com0com to create a couple of virtual ports.
To activate port forwarding on Termite you have to go to settings and then forward on the bottom-left side of the screen. You'll see a menu where you can choose the port you want to forward to. On the following screenshot I can forward from COM1 to COM2:
After selecting the right settings for COM1 you accept and connect by clicking on the big button marked COM1 57000 bps... and you'll see everything incoming on COM1 forwarded to COM2 and displayed on the console.

Understanding why missing serial port I'm receiving data from usb

I've a device which is supposed to send data via a usb connection. When I connect my laptop via usb to this device and open a terminal I get sone weird characters and are printed as a command line. However I haven't configured anything.
If I try to connect to the device via serial port initializing it I cannot know which port is? Plugging ang unplugging the device shows no difference in the result of:
>ls /dev/*
Which seems the device is not detected, but as I said in the command promp or even if I use any other application, it is as if I was writing, but random characters
Does anyone k ow why does it happen?
How can I set communication characteristics to be able to connect to the device at a certain baud-rate?
The idea is to get data via Python.
Lots of thanks ;)

Serial Communication one to one

If this is a stupid question, please don't mind me. But I spent some time trying to find the answer but I couldn't get anything solid. Maybe this is a hardware question, but I figured I'd try here first.
Does Serial Communication only work one to one? The reason this came up is because I had an arduino board listening for communication on its serial port. I had a python script feed bytes to the port as well. However, whenever I opened up the arduino's serial monitor, the connection with the python script failed. The serial monitor also connects to the serial port for communication for its little text input field.
So what's the deal? Does serial communication only work between a single client and a single server? Is there a way to get multiple clients writing to the server? I appreciate your suggestions.
Multiple clients (e.g. Arduinos) communicating with one server (e.g. a desktop computer) is commonly done with the serial variant:
RS-485
This is a simple method widely used in industrial settings where you want to have many devices connected to one computer via one serial port. This type of arrangement is also called multi-drop, because one cable strings around a building with Tees that tap in and drop lines to each device.
The hardware for this is widely available. You can buy USB serial adapters that provide the hardware interface for a computer. Programmatically the port looks just like an RS232 port. For the Arduino you would just add a transceiver chip. A sea of serial transceivers exists, e.g.
Example computer USB adapter with 485 interface
Sample RS485 transceiver chip from Element14
All the devices hang on the same bus listening at the same time. A simple communication protocol used is just add a device address before every command. For example:
001SETLIGHT1 <- tells Arduino "001" to turn on the light
013SETLIGHT0 <- tells "013" to turn off the light
Any device hanging on the cable ignores commands that do not start with their address. When a device responds, it prepends its address.
001SETLIGHT1DONE <- response from device "001" that the command has been received and executed
The address in the response lets the receiving party know which device was talking.
Well, your question can be quite wide, so I'm going to layer my answer:
On the hardware side, the same pair of wires can work be shared with many devices. It is mostly a question of electronics (maintaining the signal in the good voltage range), and not having all devices writing to the serial port at the same time (or you'll get wreckage).
On the software side, on the host, yes you can share the same serial connection to a device with multiple processes. But that's not straight forward. I'll assume you're using an unix (macos or linux):
in unix, everything is a file, your serial connection is one too: /dev/ttyACM0 on linux, for example.
When you have a process opening that file, it will block it (using ioctl, iirc) so no other process can mess with that file too.
Then, you can input and output to that file using the process that opened it, that's all.
But hopefully, it is still possible to share the connection between processes. One of them would simply be to use the tee command, that will be able to get input from one process, and give it back output, and copy the output to another process. You can also do it from within python, by duplicating the file descriptor.
To easily output stuff that can be redirected the unix way (using pipes), you can use socat: http://www.dest-unreach.org/socat/
here's an usage example:
socat -,raw,echo=0,escape=0x0f /dev/ttyACM0,raw,echo=0,crnl
you may want to tweak it for your needs.
Edit:
I forgot about RS-485, which 'jdr5ca' was smart enough to recommend. My explanation below is restricted to RS-232, the more "garden variety" serial port. As 'jdr5ca' points out, RS-485 is a much better alternative for the described problem.
Original:
To expand on zmo's answer a bit, it is possible to share serial at the hardware level, and it has been done before, but it is rarely done in practice.
Likewise, at the software driver level, it is again theoretically possible to share, but you run into similar problems as the hardware level, i.e. how to "share" the link to prevent collisions, etc.
A "typical" setup would be two serial (hardware) devices attached to each other 1:1. Each would run a single software process that would manage sending/receiving data on the link.
If it is desired to share the serial link amongst multiple processes (on either side), the software process that manages the link would also need to manage passing the received data to each reading process (keeping track of which data each process had read) and also arbitrate which sending process gets access to the link during "writes".
If there are multiple read/write processes on each end of the link, the handshaking/coordination of all this gets deep as some sort of meta-signaling arrangement may be needed to coordinate the comms between the process on each end.
Either a real mess or a fun challenge, depending on your needs and how you view such things.

How to find out if serial port is closed?

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.

Categories

Resources