I've created a receiver design for a UART. Testing with stimuli on the testbench does indeed show correct functionality. What I am now to try is to test it on real hardware, but I am not sure how to be able to send data serially from the PC to the FPGA with a specific baud rate.
Desired output data_out_sim (shown as ASCII) for binary input data_in_sim
People have been mentioning using pySerial but I am not sure how to make the connection between code and hardware design.
This is not a particularly well formulated question.
A common way to do this is with an FTDI cable or similar USB to UART bridge
Related
I have two python scripts which need to get data from the same modbus server.
However they cannot be simultaneously connected to the same modbus server, so I am looking for a "proxy" software.
This proxy will then sequentially transfer the modbus queries to the modbus server.
Solution should run on debian 11 lite.
Thanks!
I have the same challenges before and ended up with Modbus-to-MQTT bridge solution, because each protocol has its limit, Modbus is designed for master-slave poll in nature and MQTT is good for multiple clients/subscribers.
Modbus + MQTT, such a combination is just nice and could be very powerful in modern IoT applications. You can try modpoll, which is a python-based Modbus tool and can run as a Modbus-to-MQTT bridge in your case.
Assuming you are dealing with Modbus TCP you can try modbus-proxy:
Many modbus devices support only one or very few clients. This proxy
acts as a bridge between the client and the modbus device. It can be
seen as a layer 7 reverse proxy. This allows multiple clients to
communicate with the same modbus device.
When multiple clients are connected, cross messages are avoided by
serializing communication on a first come first served REQ/REP basis.
EDIT: According to your comment below:
...it is RTU over a linux file descriptor /dev/ttyS1
That seems to me a not-so-straightforward way of saying that you are dealing with a serial link.
If that's the case I'm afraid you need to go back all the way to the physical layer.
If you have a point-to-point serial connection (no matter the voltage levels you have, they can be TTL 3.3VDC or RS-232) there is no way you can have more than one Modbus client connecting to the same server.
For a serial link to have more than two devices (two or multiple clients sending queries to a Modbus server, for instance) you need a way for the devices to take control of the bus when they communicate and let go of it when they are idle. An RS-485 multipoint serial link is the most frequent solution to this problem.
If you follow the link you will find many resources and documentation. That might be a bit overwhelming but it is actually very easy: instead of connecting RX to TX as you'd do for a normal serial port you will have two cables for each device (they are called A and B or D+ and D-) that you can put together. And you only need to add a TTL to RS-485 transceiver in between each device and the bus (or RS-232 to RS-485, depending on your devices).
There are a couple of nuances:
You might need terminating resistors, but that should only be the case if your devices are far away (more than several meters) from each other.
If you go for the cheapest transceivers you might end up being forced to toggle the bus in your software, which is not a good solution. See my answer here for more details. And better aim for something with automatic TX enable.
The most complete reference on all these topics I know of is Jan Axelson's book Serial Port Complete. It's a bit old (the last edition was released in 2007) but still very relevant. And you can find older editions secondhand for next to nothing. If you need to work with serial ports, this book will be a very valuable companion.
Final note: if you are not able or willing to mess with the phy layer, you might, of course, find other solutions that are more palatable. You might, for instance, implement a software forwarder to take queries from your clients and convert them to Modbus RTU to be sent to your server. Pymodbus includes an example, but since you did not elaborate much I'm not sure it will be useful for your situation.
I am currently developing a Python tool for Windows that is able to lookup all devices connected to a windows pc. It already supports ethernet devices and by now I'm trying to add support for USB and serial devices. For those devices I want to read out their vendor id, product id, serial number and of course the address/port which is needed to connect to the device.
Simple USB devices can be easily detected with PyUSB or PyWin32. Unfortunately, many devices say that its vendor is FTDI, which is not the case. As far as I know, FTDI just provides the USB adapter/converter.
So, how can I lookup the device behind the FTDI adapter? I already tried PyUSB, PyWin32 and PySerial, but all of them just say, that there is a FTDI-device connected; but I want to know the actual device behind the FTDI adapter... Is there a way to find that out?
I hope that you can help me... Thank you for that in advance.
Update
Since there seems to be no universal solution, is there at least a way to uniquely identify one of those FTDI devices? Some of them provide serial numbers, but unfortunately not all of them. For example there are devices, with a device id like "USB\VID_0403&PID_FAF0\7&5E2426C&0&2", where "7&5E2426C&0&2" should be the serial number. But these serial numbers with ampersands in it are not the real serial numbers (maybe it is something from Windows or so). PySerial even recognizes this serial number only as "7".
If I had at least the possibility to get the real serial number of that device, this would be very helpful. So I could uniquely identify that device, even if it got a new port or device id after disconnecting and reconnecting. Or are those ampersand-serials always the same for one device?
When a FTDI Serial to USB converter is used you usually get a virtual com port that is recognized as PlugAndPlay device by windows. A small internal electronic circuit board is placed in the USB-Plug of an FTDI cable which performs the conversion from serial UART interface to USB.
When you now request the information about the connected device you get the information of the connected PlugAndPlay device, the FTDI cable board, not the information of the device behind this cable. E.g. when a Card Reader is connected using such a cable you get the serial number of the FTDI Cable board not the serial number of the Card Reader.
But it is possible that usefull information can be retrieved. There is a program from FTDI, called FT_Prog, which allows to programm the EEPROM board in the cable. Using this tool it is possible to change some of the information you can retrieve from the FTDI cable as shown in the image below.
This is sometimes done but not mandatory for device manufacturers. And when it is done there is no standardized scheme of what to put into these fields. You would need your own dictionary of known device identifiers to handle that.
Another way is to get information directly from the device behind the cable. But in this case you need to know the communication protocol to be able to talk to the device. If proprietary protocols are used, your only chance is to use sniffer hardware to reverse engineer the protocol but that may be a bit to extreme^^
Af far as company using FTDI is not interested in buying own vendor ID you are out of luck.
There is no standard protocol behind FTDI so no universal way to detect device behind it.
USB specification allows (not requires) device to provide string descriptor containing serial number - or better it could be any string.
Fortunately FTDIs provides unique serial numbers. See this thread Get Serial Number of USB device with Python 3
FTDI is typically allow the use of an EEPROM (actually it is in most cases a simple flash memory) to store specific information about the product in it. E.g. one can assign a specific vendorID, ProductID, SerialNo, Manufacturer Desc., Product Desc. BUT it is only optional (For details search for FT_Prog). So every product designer has the freedom, but does not need to fill in whatever he/she wants.
If you have a set of devices you want to support you could check if the either support a SCPI compliant interface. In this case you can ask them using *IDN? about their identity. If not you can hope that the product has properly written ROM to supply further information. In any other case you can only guess.
This question is as much related to software as it is related to hardware and I posted the similar question to electronic stack exchange for hardware part.
I have an instrument which writes its output to the okidata printer. My goal is to write it directly to the computer in some text-ASCII file. The pinout from the device is shown in the image below:
It is DB-25 with only 8 pin in use so I assume it is transmitting data serially. So I bought a null modem (crossover) cable with DB-25 female to DB-9 female converter and attached it to my serial port of my computer. One thing about the device is, it used to recognize whether printer is ready or not when it was plugged in the printer, thus I assume the printer had set one of the pin high if it was ready so that the device(instrument) knew that the printer was ready. If this logic should be followed, then I had to set one pin among these 8 pins to high.
I am just experimenting with pyserial and could not figure out and the device is saying that printer is not ready which means that it is not seeing one pin it wants to see high as high.
I tried setting serial RTS and DTR to false and toggled true but does not help.
Am I not understanding something here? Can somebody point me in how to approach this and replace the printer. I can also use arduino if required but I am not seeing how to for now.
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.
I have a GPS module connected through serial port(USB->Virtual COM port). A measurement software is using this port, so with other software I can't access to the data. I would like to create two virtual COM port and share this data through that. Is it possible using Python? Is there any opensource example written in Python?
I don't think you can do that if you cannot modify the sources of the measurement software.
Serial port protocols are written as "point to point" protocols, so there's no general way to multiplex them. You can write a program that shares the access to the GPS module (handling it exclusively and exposing an API to multiple programs), but every program that wanted to use the GPS module should be written to talk to your API and not directly to the serial port - and in this case it can be done only if you can change the measurement software.
Notice that probably it's not impossible to implement your "virtual port" solution, but it would be an ad-hoc hack (it would work just with that specific protocol) and it may be quite complicated: you would need to emulate two GPS modules and multiplex the requests to the real GPS module; depending on how does it work (e.g. if it has a "complicated" persistent state) it may be simple or very complicated. But surely Python wouldn't be enough, to emulate serial ports you have to go in kernel mode.
Do you need two-way communication, or just reading? You could build or buy hardware to physically split the Rx data line so you could use two COM ports, each of which would read the same data. You could do this with Tx data as well, but you would have to be careful about trashing the data if both ports tried to write at the same time.