Advice on permissionless communication between two microcontrollers - Page 1
Forum section: electronics / projects

author: Red_Micro
author_rank: Regular Contributor
timestamp: January 13, 2024, 01:07:12 am
content: I want to have two devices that can transmit and receive at the same time, so full duplex communication. Both can initiate communication at any time. I’m not familiar with all communication physical layers and protocols and wondering if a simple approach could be UART over RS422 or RS485 with full duplex transceivers?

author: SuzyC
author_rank: Frequent Contributor
timestamp: January 13, 2024, 02:05:03 am
content: If two devices are communicating at the same time what you will create most likely is chaos.You aren't communicating if the information received is not coordinated in time by both devices.The resulting communication cannot be just a shouting match.That being said, your devices might also be spending so much time servicing transmitting or receiving to so as to not be able to make any sense or decisions about data transferred or even to find any time to do anything else but chatter.It might be easy enough to use two different serial ports on each device to accomplish receive and transmit at the same time.Simultaneous communication does not imply that each device has any understanding of the timeliness, meaning and acknowledgement of data being transmitted or received. Its all about both devices processing info before responding to be able for both devices to know what and when to do anything, as well as acknowledge what has been accomplished with info being transferred.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: January 13, 2024, 03:15:10 am
content: Quote from: Red_Micro on January 13, 2024, 01:07:12 amHow far apart ?If you wantBoth can initiate communication at any time, you will need fully duplex, so go tohttps://www.maxlinear.com/products/interface/serial-transceivers/rs485-422and pick full duplex, then select Baud or ESD/Fault levels that your system needsTheir XR33053 / XR33156 have impressive ESD and fault tolerance numbers.Addit: An option instead of one full duplex part, is to pick two smaller, cheaper half duplex parts.You can then add some loop-back diagnostics, if you have a second spare UART on your MCU

author: Psi
author_rank: Super Contributor
timestamp: January 13, 2024, 03:35:11 am
content: When you say permissionless what exactly do you mean? Obviously there has to be something to stop you overloading the other MCU with too much data it can't process before new data comes in.SPI can be used for bidirectional coms if you keep something being transmitter constantly so the clock is always running a bit stream between the MCUs.Since it's a bit loop, so if you transmit to the other MCU that is also transmitting bits back to you at the same time.Or, another options is to roll your own parallel bus, it can be any width, but 2 or 4 or 8 or 16 bits is nice. For bi-directional coms you could have two buses that are totally separate, one for each direction.Basically you have 2 bits for handshaking and 1,2,4,8,16 bits for data depending how much IO you want to allocate to it and the speed required. The 2 handshaking bits are one input and one output.They basically just mean, Transmitter has loaded something onto the bus y/n, and Receiver has read data on bus y/n.The transmitter and receiver respond to those bits changing and load or read the data then update their handshaking bits to reflect the new situation and that prompt the other MCU to read/load another block of data and the cycle continues.This process can be triggered form a pin change interrupt for the handshaking input bit for super fast speed. Or form a timer. Or even from main().The system clocks itself based on how quickly the receiving MCU reads the data and how fast the transmitter detects this and loads new data onto the bus.I've done this before for a 16bit bus and it worked great.If you're doing a 1,2,4 bit bus obviously you need some code to extract blocks of 1,2,4 bits out of your data buffer to be sent, but that is pretty simpleUsing 8 wires/pins between the MCUs you could have two totally separate 2 bit wide buses. So 1 byte per 4 clocks.(eg... 2 bits handshaking and 2 bits data for one direction bus and 2 bits handhsaking and 2 bits data for the other direction bus.)

author: Andy Chee
author_rank: Super Contributor
timestamp: January 13, 2024, 06:15:33 am
content: Just to clarify, are your two microcontrollers only talking to each other? Or are they both attempting to talk to a third "master" device?If it's just two devices like this, then no special hardware is required. Your software code however, must be capable of responding to interrupts.On the other hand, perhaps you are unable to implement multiple channels and only have a single-wire communication channel? In which case some sort of packet collision detection will be required in your software.Incidentally, I seem to recall a single-wire full-duplex setup which essentially worked like a full-duplex telephone current loop and used an opamp.

author: tooki
author_rank: Super Contributor
timestamp: January 13, 2024, 11:32:20 am
content: Quote from: Red_Micro on January 13, 2024, 01:07:12 amYou’re leaving out tons of key information by not telling us what you’re actually attempting to accomplish. For example:- distance- environment (Home, factory, car, outdoors, …)- speed- other constraints like power budgetAnd that’s before getting to issues of protocol and such like SuzyC alluded to.

author: David Hess
author_rank: Super Contributor
timestamp: January 13, 2024, 02:43:50 pm
content: Quote from: Red_Micro on January 13, 2024, 01:07:12 amA UART over RS422 or RS485 can do what you want assuming that two RS422 or RS485 channels are implemented, with one for transmit and one for receive. RS422 or RS485 are more suitable for long range, and over a single board or within a chassis, the UARTs can be connected directly together.SPI or I2C could also be used however UARTs have the advantage of not requiring extra signals for the clock.

author: hans
author_rank: Super Contributor
timestamp: January 13, 2024, 03:17:11 pm
content: Ditch all synchronous protocols. Use UART, as both sides can initiate a packet of communication at any time. You can limit the baudrate and/or use CTS/RTS signaling to prevent overloading of either MCU. SPI and such are nice for (really) high communication throughputs, but I don't see it as a requirement, so best to keep things simple. For point-to-point a back-to-back UART connection should work fine. If necessary, you can run UARTs nowadays on MBaud speeds as well, so that should give decent throughputs.RS422 if you want to use it over long cabling (differential pair), perhaps over 2 pairs (A->B and B->A).

author: zapta
author_rank: Super Contributor
timestamp: January 13, 2024, 09:46:51 pm
content: I needed once something similar and implemented a packet oriented communication protocol that worked very well. Each side can send a message any time they want. The message includes minimal metadata such as the end point (function) at the target node and wether it's one way or message or a request expecting a response (RPC like). It also had HDLC like like 'byte stuffing' such that the protocol resync on new messages in case of a like error. It works well with no. If you remove the requirements for RPC like request/response and can live simple messaging, the code should be straight forward.Python implementation:https://pypi.org/project/serial-packets/C++ implementation:https://github.com/zapta/daq/tree/main/controller/platformio/lib/serial_packets

author: Siwastaja
author_rank: Super Contributor
timestamp: January 14, 2024, 12:03:51 pm
content: More information needed to say anything definite, but first-order guess would be UART (higher level protocol is up to you); for short distances (within single assembly, no user-accessible connectors, maybe <2 meters) logic-level is fine; for anything longer or requiring ESD protection, simply add RS422 transceivers: so two pairs, one per direction.

author: IDEngineer
author_rank: Super Contributor
timestamp: January 14, 2024, 02:18:45 pm
content: Async + bidirectional... obvious answer is UART. Can be made long distance with suitable external hardware.Are you certain the two devices must be able to talk literally simultaneously? If not, a collision handling choice such as CAN might be a great option.

author: Psi
author_rank: Super Contributor
timestamp: January 14, 2024, 10:22:46 pm
content: We really need to know why OP needs the two devices to be able to transmit at the same time.Since they'll always be some sort of lag to read/understand/respond to a message, nothing really happens at exactly the same time anyway. Even if you build it on a full duplex link.eg,Does he need full duplex just because he believes it will be easier without having to wait for the other direction to finish.(A common misconception when starting out writing mcu code. You always have to wait for something to be ready in either software or hardware be it full or half duplex.)Or is there some timing requirement where he needs a specific or predicable latency between the communication directions and can't handle a device creating lag for the other directionAlso need to know if these two microcontrollers are right next to each other, maybe on the same PCB, or on the other side of the room or other side of thebuilding.

author: Red_Micro
author_rank: Regular Contributor
timestamp: January 15, 2024, 09:00:19 pm
content: Thanks all for the suggestions. A little bit of context: only these two MCUs need to talk to each other. There will not be a third one. MCU1 will typically handle data from sensors and send them to MCU2 which will handle a display. They are like 1.5 meters apart. MCU2 will need to communicate asynchronously some events back to MCU2. I don’t have all the details yet but this is the core idea. My worry with half duplex is that while MCU1 is communicating data to MCU2, let’s say MCU2 needs to send an asynchronous event to MCU1 which needs to react quick enough (how quick to be defined) then MCU2 would be unable to do so while MCU1 is transmitting taking the bus. I understand though that there’s need to be some lag as MCU1 is transmitting it can’t take care of the its reception immediately.

author: Andy Chee
author_rank: Super Contributor
timestamp: January 15, 2024, 09:51:38 pm
content: Quote from: Red_Micro on January 15, 2024, 09:00:19 pmI'm guessing MCU2 is a touchscreen LCD, and MCU1 is controlling a sensor whose parameter settings are adjusted by the touchscreen? Something along those lines?Provided you're not using something ridiculously under-powered (like a PIC12C508!), this should be an easily doable project even with a pair of original Arduino UNOs.You may need to learn about interrupts. The commonly used technique of sensor "polling" may not be up to the task, depending on your requirements.

author: David Hess
author_rank: Super Contributor
timestamp: January 15, 2024, 10:01:29 pm
content: An asynchronous UART will do everything you need, and would be my first choice. A pair of SPI or I2C ports could also do it but will require twice as many signals for the clocks.Over that distance level translators should not be required and logic level signals should be good enough, but signal routing should be clean and termination would be a good idea.

author: IDEngineer
author_rank: Super Contributor
timestamp: January 15, 2024, 11:05:45 pm
content: There's two votes for a UART based solution. Unless you need crazy speeds, anything else will be extra cost and extra work.

author: Siwastaja
author_rank: Super Contributor
timestamp: January 16, 2024, 07:09:35 am
content: Quote from: Red_Micro on January 15, 2024, 09:00:19 pmUART sounds good. The advantage is, the two directions, even when they are implemented using a single UART peripheral, are completely independent of each other, so you can handle input events right when they arrive, and generate output as you wish - generate output based on the input events with no timing requirements (i.e., immediately or later), or even generate output completely regardless of inputs if that suits better.For such small distance, logic level directly out of MCU pins would work, but it would be a very good idea to add ESD protection. RS422 transceivers cost less than $1, and if you don't have 5V available, 3.3V variants exist, so it's a simple and obvious solution to improve signal integrity and add ESD protection built-in to transceivers; your wire count goes from 3 to 5, though.