use ft2232H on lattice machXO3 dev. board - python

first sorry if this is a simple question but I can't figure this out. I have this development board and on page 19 on the kits user guide the block diagram shows a RS232 line and on page 20 and 22 the schematic show the pins I need to connect to use RS232. My problem is that, despite being able to configure the fpga/cpld, I cannot find the com port on my computer (using pyserial and the following code(I tried changing COM%s in line 15 to FTUSB-%s)). So my questions are:
What interface does the FTDI, ft2232h USB to UART/FIFO, chip use (Serial, parallel... ) on the computer's end (like arduino's virtual COM port)?
On lattice's software there are 3 options to program the device. the program shows the following: HW-USBN-2b (FTDI) (with port as FTUSB-0), HW-USBN-2b (with port as ezUSB-0) and HW-DLN-3C. How can I use either of them to communicate with the device outside of Lattice's software?
thanks for you time.

1) RS232 is a combination of UART with certain voltage levels for the high and low (i.e. +3 to +15V and -3 to -15V afaik. Never ever connect a RS232 adapter to standard 3.3V or 5V devices e.g. UART, TTL-UART etc. The Lattice Semiconductor document just plainly missuses the term RS232 - try not to fall for it (IMHO the performance of their products strongly anticorrelates with the quality of their documentation and support).
2) page 19 of the linked doc shows the sections: Ordering Information, Technical Support Assistance, Revision History. Shifted by one page?
3) The FT2232H can be used in multiple modes. This depends on the way how it is addressed and of the settings flashed to the EEPROM connected to it (on the dev board is one placed but the FT2232H can be used without as well). The dev board is in the standard configuration designed to be programmed via the JTAG pins and the FT2232H is opened via the D2XX driver by lattice diamond. For that reason they flashed the EEPROM with settings which prohibits the use as virtual com port. The FTDI flash software can be used to change that behavior - for each bank seperately.
4) The solder bridges can be used to rearrange the connections (e.g. if one wants to change from the JTAG interface to the SPI or I2C programming interface). In your case you most likely want to place bridges on R14 and R15 to make the proper connection for an UART link to the port B of the FT2232H. EDIT: This way Port A can be used in JTAG mode to program the FT2232H and port B to communicate via e.g. UART or even other modes like the fast opto or the parallel bus/FIFO - if the correct bridges are soldered. Changing the EEPROM settings might be still required to make Port B visible as VCP if one want to avoid the usage of the D2XXX driver.

Most things were said in the previous reply, but here again in a slightly different way. This is what you need to prepare the use of an UART connection to the FPGA, but still needs any generic UART module configured into the FPGA after that:
This was tested on the Lattice MachXO3D development board, but I crosschecked that at least this part with the pins is the same with the MachXO3L board that you linked:
First, you need to bridge (solder) resistors R14 and R15 to connect UART RX and TX pins from the FTDI to the FPGA. You can use 0 Ohm resistors or just do it with solder tin, they are close enough for that. After that, FPGA pins/sites C11(=Tx) and A11(=Rx) can be used for your UART inside the FPGA, that you probably have as a Verilog/VHDL design. You find this information by looking at the "Appendix A. Schematics" of the user guide.
Additionally, something that was at least needed for the MachXO3D is to reconfigure the FTDI chip with FTDI's "ftprog" software. Not sure if it is needed for the MachXO3L, but it is easy to check and causes no harm:
Run "ftprog". Search/Parse for your FTDI chip and find the configuration for "Port B", and change "Hardware" from "245 FIFO" to "RS232 UART", and "Driver" from "D2XX" to "Virtual COM port". Then the second of the two ports you get from the FTDI chip (COM# in Windows, /dev/ttyUSB# in Linux; # being a number) should be usable through some virtual terminal software, use with python-serial, etc.
In Linux, the ftdi_sio kernel module has to be unloaded (sudo modprobe -r ftdi_sio) for Lattice Diamond to be able to program the FPGA, and after that loaded again (sudo modprobe ftdi_sio), to be able to use the respective /dev/ttyUSB# device. In Windows it doesn't need that and just works with python using COM#. Any suggestion to make this easier in Linux is also welcome!
In any case, as already said, you still need the respective UART module programmed in the FPGA and connected to the respective sites to be able to use it.
Update: I found that at a very obscure location, Lattice also documented a part of this, which is the User Guide to their Propel SDK. You can find the information starting Page 39 there: Lattice Propel SDK 2.0 User Guide

Related

Multi clients modbus to single modbus server

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.

Setting RS485 device address in python under linux

I am trying to connect to an existing network of devices communicating via RS485 (HMI + PLC, the communication protocol is Fatek's own protocol). I have no problem connecting directly to the PLC (I can read and write registers), but I have to leave the HMI<>PLC connection. When connecting directly to the line between HMI and PLC (via an FTDI USB<>RS485 adapter) I can't read or write registers from the PLC (I don't receive proper responses).
From I've gathered, it's possible to connect multiple devices on one RS485 line, provided they have their addresses set. And here's the problem: I can't see where to set this address. Is it included in every "frame" sent? Is it set somewhere in the driver of the USB<>RS485 adapter? Is it hardcoded in the adapter?
Thank you in advance,
MichaƂ
Usually in serial communications, either 1:1 or 1:N, there can only be one master (in your case the HMI is the master) and one or more slaves that respond to requests from the master, and the master must always wait to receive the response before submitting a new request.
If you connect a second master you are creating collisions on the network, RS-485 has no way to manage those collisions.
Only one master can exist on the serial network.
If you want to overcome these limitations think about replacing that network with Ethernet and TCP/IP
As the Wikipedia article below, RS485 is an electrical specification with no default software or protocol.
The mechanism for handling the device address must be created by yourself or by selecting a protocol having such a function and applying it.
RS-485 - Wikipedia
RS-485 only specifies electrical characteristics of the generator and the receiver: the physical layer. It does not specify or recommend any communications protocol; Other standards define the protocols for communication over an RS-485 link. The foreword to the standard references The Telecommunications Systems Bulletin TSB-89 which contains application guidelines, including data signaling rate vs. cable length, stub length, and configurations.
For example, isn't Modbus often used?
Modbus -Wikipedia
Modbus is a data communications protocol originally published by Modicon (now Schneider Electric) in 1979 for use with its programmable logic controllers (PLCs). Modbus has become a de facto standard communication protocol and is now a commonly available means of connecting industrial electronic devices. Modbus is popular in industrial environments because it is openly published and royalty-free.
There are also some python packages.
minimalmodbus 1.0.2
pymodbus 2.3.0
How to set the device address will need to be done according to the specifications of the package to be adopted.
In Addition:
By the way, if you are using a manufacturer's proprietary protocol for a PLC device, it is likely that you will be using such multi-drop for that device and protocol.
It seems that the first way to do this is to contact the manufacturer's support desk.
Or even if this site is a manufacturer support location, you will need to add information such as what equipment you are trying to connect and in what configuration.
HMI_Support & PLC_Support
HMI_Products & PLC_Products
It looks like your system is using "Fatek communication protocol" which is documented in Appendix 1 of the FB user manual. (Download here)
That protocol looks like many such protocols typical of industrial PLC controllers. However, it is a bit complicated by the number of message types. Without looking too deeply, it seems practical to implement the logic in a few days. Or there is likely an open source implementation somewhere (though I didn't search).

How to find out what instruments is behind a FTDI adapter on Windows?

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.

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.

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.

Categories

Resources