5
\$\begingroup\$

I would like to find a good way to interface many UART devices (sensors) to a single PC for data collection and processing. For my use, there may be as many as 100 UART devices each operating at 115200 baud. Currently I am using FTDI UART-to-USB bridges - a separate FTDI for each UART device. This, combined with a USB hub works fine for small numbers of devices, but beyond about 5 or 6 devices, there are problems with data drops over the virtual serial coms. And there seems to be a number limit associated with the computer (12 for one of my computers, 17 for my laptop) beyond which the computer fails to recognize more. In general this does not seem like a workable solution and even if you could hook up 100 UARTs+FTDIs+USB hubs etc., this seems like it would be a very clunky solution.

BTW, I also thought about this netburner module that supports 8 UARTs and could send the data over ethernet for a network interface: http://www.netburner.com/products/core-modules/mod5441x . It's an option, but still only 8 channels.

So certainly I'm not the first person to want to hookup and record data from many UART sensors. What is the best way to do it?

\$\endgroup\$
17
  • 6
    \$\begingroup\$ Your 100+ UARTs on a single PC sound like a job for a larger FPGA, interfaced via PCIE to the PC for example. \$\endgroup\$
    – Turbo J
    Commented Apr 20, 2017 at 16:34
  • 2
    \$\begingroup\$ Why not make a RS485 communication? \$\endgroup\$ Commented Apr 20, 2017 at 16:37
  • 3
    \$\begingroup\$ It's a very broad question and one of the main issues is how much data you're actually wanting to collect. 100 devices at 115200bps means potentially 11Mbits per second and any PC is going to find processing and recording that a challenge regardless of how it's hooked up. \$\endgroup\$
    – Finbarr
    Commented Apr 20, 2017 at 16:46
  • 1
    \$\begingroup\$ What kind of devices (sensors) and what is the speed? If the devices are DIY (not builded yet), you can add a RS485 transceiver and implement a Modbus RTU protocol. \$\endgroup\$ Commented Apr 20, 2017 at 18:32
  • 1
    \$\begingroup\$ Meh. You should just come to the conclusion that the sensor interface you have is not suited for many nodes. Either change the sensor interface (and probably the sensor) to an appropriate one (like 485, or Ethernet); or change the number of sensors that you're willing to support. \$\endgroup\$ Commented Apr 20, 2017 at 18:36

5 Answers 5

3
\$\begingroup\$

First off, this has been stated before, but: UART is not an appropriate sensor interface here. Pick a different sensor, if possible. I'll assume it's not possible, otherwise you wouldn't be going through all this effort.

I personally think the most important question hasn't really been answered by you:

  • Is this some sensor that you query, and it responds, afterwards, or
  • Will the sensor continuously send data?

The first case might be the easier one, because it would allow you to take one UART, and multiplex it between multiple sensors, meaning that you connect TX to the first, talk to it, then reconnect to the second, and so on. RX would be shared between all the sensors on the bus, but because it's a query/answer system, you'd always know who's currently talking (the one you asked).

If it's the second case, well: You'll need something that manages each of these onto a more flexible bus.

Personally:

  • get a cheap microcontroller that can talk UART on one side, and I²C on the other, one for each of your sensors. Boards should be small, and the BOM would be < $3, ideally.
  • Write firmware that makes it possible to query the sensor via I²C. That means relaying things the "controller" sends via I²C to the device, and storing the data the device sends via UART long enough for it to be requested by the master. That's not a very complex firmware, but it's still a bit to write and debug. It's probable that if you do this on a popular platform (arduino, stm32), someone else has done it before.
  • Assign a separate I²C address to each one of your translators.

There's not infinitely many addresses, and not infinitely much bandwidth, so bundle a reasonable amount of sensors via I²C to one bus each. Use a Full-Speed (12 Mb/s) USB capable microcontroller to interface all your translators, and relay the data to your PC. You can have multiple of those.

Also, there might be ready-to-use UARTs that might be usable via I²C as bus extenders.

Another thought:

There's Microcontrollers that have built-in Ethernet controllers. You just need to an Ethernet Phy (there's a standardized interface for that, called MII). Ethernet

  • allows for practically arbitrary numbers of devices, and
  • ethernet cables can be long,
  • ethernet switches cost < 2€/port
  • ethernet switches can aggregate a lot of slow, easy to design 10 Mb/s links to one 100 Mb/s or gigabit ethernet link,
  • ethernet is actually meant for huge buses,
  • and is really easy to connect to – just write network software for you PC (no driver development in any way, just handle raw network packets),
  • depending on what the examples from your microcontroller manufacturers offer, you get a complete ethernet stack, including things like autodetection by just letting your firmware periodically send "hey, I'm here" broadcast packets.

I'd go with that solution. The ST STM32F107RC and similar microcontrollers come with said MII interface and up to 5 USARTs. Or go for the NXP LPC1830, which is significantly cheaper, but only has 4 UARTs.

That would be

  • one LPC1830 6.17€, connecting four UART sensors at once
  • one RMII fast ethernet PHY 0.80€
  • Ethernet connector with integrated magnetics 2.70€ (cheaper if you do separate magnetics and connector, but might not be worth the additional assembly effort)
  • Power supplies, discretes 2€
  • PCB manufactured in China 1.50€ (might be cheaper if you panelize properly)

Firmware: Ethernet example code from NXP, hand-written UART handling

Makes a total of about 13.50€ for 4 sensors, or about 3.50€ per sensor. You need 25 of these to connect 100 Sensors. You need a 24-Port gigabit ethernet Switch, plus another small switch for the rest which adds maybe 50€ to the bill (pre-VAT).

The benefit would be having a system that you can extend arbitrarily. If you're feeling adventurous, use an IP stack on your microcontroller (lwIP, µIP) and make it possible to deploy your devices within any LAN, even across network boundaries such as the internet and so on.

Edit: Turns out NXP ships examples that do the full TCP/IP dance on the MCU. Oh well, all the simpler then.

\$\endgroup\$
4
  • \$\begingroup\$ I'd personally have thought of CAN bus for that purpose. Much simpler than Ethernet, especially when micro-controllers are involved. \$\endgroup\$
    – user59864
    Commented Apr 20, 2017 at 22:13
  • \$\begingroup\$ @Nasha also a nice idea, but what I really like about my ethernet idea is the fact that the link isn't really shared between things I develop – if one of my sensor interface firmwares crashes, the Switch will happily continue to work with the other devices, and only one LAN port would be dead :) But: CAN would be a massive cost reduction, indeed! \$\endgroup\$ Commented Apr 20, 2017 at 22:18
  • \$\begingroup\$ Yup. Plus the fact that CAN also encompasses error detection, retransmission and robustness with very few components and relatively little programming efforts. \$\endgroup\$
    – user59864
    Commented Apr 21, 2017 at 8:58
  • \$\begingroup\$ @Nasha if you write an answer suggesting "hey, you can use CAN, it's thoroughly proven its worth as many-node bus e.g. in automotive application", and describe the bus architecture you propose, and ping me: I'd upvote, and I'd mention your answer in my answer as "desirable". \$\endgroup\$ Commented Apr 21, 2017 at 9:25
3
\$\begingroup\$

I would look into using a single UART of a microcontroller and multiplexing it.

If the devices only respond when data is requested, then you can logically OR all the receive lines into the UART. A multiplexer on the UART output selects which device receives data from the micro.

If the devices all constantly send their data, you may not need transmit lines to them at all. Have the receive line into the single UART multiplexed. A device is selected, the firmware waits to make sure it is synchronized with the byte stream, the data captured, the next device selected, etc.

Yet another possibility is to put a small micro at each device and chain them instead of the star topology you are assuming now. Each micro would handle its device privately. A token passing scheme can be used to let each micro send its data to the next one in the chain, otherwise passing data from the previous to the next. The PC is at the end of the chain and collects all the data over a single serial or USB port.

Yet another way is similar to above, but use CAN for each of the individual micros to blurt out their sensor's information periodically. The PC gets all the CAN messages via a USB to CAN adapter.

There are many ways, but trying to set up a PC with 100 COM ports isn't one of them.

\$\endgroup\$
3
\$\begingroup\$

You could implement a multidrop line similar to RS485. Perhaps you should read this.

RS485 is used in very long line industrial application and can be very useful. This EE-Times article lays it out quite well.

If you want simplicity, then you could implement separate send/receive lines, and use a very simple request/response protocol.
Operation at 115k baud should be possible, but it does depend on the quality of your twisted pair cable and the distances involved.

If the sensors are simply sending data at an asynchronous rate then you'd need some means of throttling and synchronizing them.
You could:

  1. Frontend the sensors with a small micro (say an Arduino Pro mini) that accumulates readings and either simply buffers the data or accumulates with time stamps if that is required. The micro responds to a software request/response protocol. Accumulating results and averaging could reduce the amount of data sent significantly.
  2. If your sensors support DTS/RTS, then an RS485 interface implemented via a small micro could simply stop readings. This time you use the software request/response protocol to halt sending at the sensor.
\$\endgroup\$
4
  • \$\begingroup\$ Looking at this closer, it seems that RS485 could offer a simple connection to the PC, but I'm still unsure of how to put all the UART devices onto a single RS485. How can I ensure that they are not all trying to transmit at the same time? \$\endgroup\$
    – py_man
    Commented Apr 20, 2017 at 17:25
  • \$\begingroup\$ That would be the simple request/response protocol. Send an Address command to the sensor ...get the reply back from a single sensor. If your sensors are just async blind Tx all the time, then you have a problem. \$\endgroup\$ Commented Apr 20, 2017 at 17:27
  • \$\begingroup\$ Looks like I might have a problem. Is there anything like a RS485 buffer that could store the incoming data in a FIFO and respond to the request/response protocol? \$\endgroup\$
    – py_man
    Commented Apr 20, 2017 at 17:31
  • \$\begingroup\$ @py_man - a microcontroller which directly interfaces with the sensor and also the RS-485 would be able to do that. \$\endgroup\$ Commented Apr 20, 2017 at 19:49
2
\$\begingroup\$

You could consider a daisy-chain system, something like this...

Each of your sensors contains an RS232 input and an RS232 output, called here rin and rout, and a cheap microcontroller with 256 bytes RAM or more for a serial buffer.

Each sensor send an n-byte message out, consisting of a message sensor address, a timestamp (if needed) and the sensor output. To make it easy to identify message positions, you could have a '1' in bit 7 of the first byte only, a '0' in bit 7 of all subsequent bytes. Spread the data bits across bit 6..0 of the message bytes and the start of a message is easy for a receiver to find.

Each sensor sends its own message on rout. Each sensor buffers all of any message it receives on rin, then transmits it on rout when free to do so.

The end of each daisy-chain of sensors goes into your PC. The PC now needs just one RS232C port per chain of sensors.

(The message addresses can be automatically assigned by a simple protocol but I'll leave detailing that for now. Let me know if you want more on this.)

A further idea is for each sensor can have two RS323C inputs, rin1 and rin2, and pass on messages from both on rout, along with its own message. This way, chains can easily be combined into a single input and your PC needs fewer or more RS232C ports as you see fit.

This assumes you can change your sensor design, you're reasonably capable with microcontrollers and that your system can tolerate the traffic and delays inherent in this. Timestamping your readings takes care of some of that but it depends if your host application can tolerate any slight ageing of the readings.

On the plus side, it's simple, very expandable, makes wiring easy and is fairly quick to implement and test.

\$\endgroup\$
1
  • \$\begingroup\$ @py_man, out of interest, what did you decide to make in the end? \$\endgroup\$
    – TonyM
    Commented Apr 27, 2017 at 12:38
1
\$\begingroup\$

Multi-node communication with multiple sensors is a good candidate application for a CAN bus system.

If you can't avoid sensors with a serial interface, there are a number of micro-controllers that embed both a CAN and UART/USART controllers. Search Digi-Key, Farnell, Mouser for one that fits your requirements. Otherwise see I²C (or TWI), SPI or other multi-node serial links (if you need that) since UART/USART is only a peer-to-peer communication, not well suited for such a number of peers, as already mentioned.

As a concrete example, a rough search on Digi-Key reports the cheapest micro controllers are from Microchip, i.e. the ATmega16M1. It's an automotive MCU with embedded CAN and UART controllers. It also has a factory-calibrated temperature sensor, ADC & DAC units. You get 100 units at about $1.5 each. CAN requires an external transceiver such as ATA6560 from Atmel (~¢30 each by 50 units), Microchip's MCP2544 (~¢60 each by 50 units) or Nxp's TJA1040 (~$1 each by 50 units). They're all 8-pin SMD packages and the good side is they're all pin-compatible (almost). If there are variations, it's mostly about pin 5, which some use for powering the logic interface, others to provide a split reference (2.5V) between CANH and CANL.

The CAN bus provides robustness and extreme reliability. Your sensors just have to broadcast their data periodically. There are CAN/USB adapters available for PC, such as Peak system PCAN USB analyzer — okay, the latter is far from cheap but you get the point: CAN is pretty pervasive and has tools available almost for every platform.

Be sure to use component providers (Digi-Key, Mouser, Farnell) parametric search tools to fine tune your micro-controller and sensor selection. If you need PCB manufacturing hints, check Marcus Müller response.

On the micro controller side, all you need is write when to send sensors data as the hardware takes care for the rest (protocol management, error detection, deterministic arbitration, collision, retransmission...). CAN 2.0a provides 2048 possible messages with 11-bit message identifiers, which should be enough to source data from about 100 sensors, I think. Otherwise you still have CAN2.0b extended frame format.

On the software side there are open source and/or free libraries like OpenCAN or CANfestival if you look for some industry-standard solution, such as CANopen. You could also write your own protocol if you like.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.