Imagine we have a smallish collection of state-machines — perhaps running on the Arduino-based architecture I discussed previously — each of which is measuring and/or controlling some attached piece of hardware. Now imagine that it is a requirement that some or all of these state-machines do their work in a synchronised way. How should this best be done?
Types of synchronisation
First, it’s important to say that by “synchronisation”, I mean several different things.
- If you want to sample something at a certain frequency, then you would like that frequency to be accurate and constant.
- If you want to sample multiple things at the same frequency, then you would like those frequencies to be the same. That is, any offset in the time between the various samples should not drift, even if the devices under control are widely separated, and not connected to the same microcontroller.
- You may have several devices in your lab, each controlled by its own state-machine, that you would like to work together in such a way that their states are synchronised. In other words, you would like to change the “super-state” of the entire system, and you would like this to be done by coordinating the states of the individual systems.
- Lastly, you may like there to be a “heartbeat” that governs all the actions within your lab. That is, data cannot be taken at any arbitrary time, but only at pre-determined time delays after receiving a heartbeat pulse.
My proposal is to build an RS485 bus with a drop to each of the devices to be synced. These act as slaves to an additional master microcontroller that does the work of syncing everything.
Each of the devices has an address that can be represented as a single byte, and all communications from the master begin with an address byte in order to determine which slave is the target of the message. One special value of the address byte — perhaps 0xFF — means that the message is intended to be received by all slaves.
With the exception of broadcast messages, all messages require a response from the slave. It should respond with its own address byte, followed by the appropriate response for the command. A lack of a response results in the slave being marked as “bad”.
One of the messages to the slave should be “ENQ” (“enquire”), for which the appropriate response by the slave is “ACK”.
The communication protocol allows state to be shared, but doesn’t allow timing to be synced with any reasonable precision. An additional signal is needed.
On top of the three cables needed for the RS485 (“A”, “B”, and “GND”), an extra cable is added to the bus that carries a high frequency square wave generated by the master. Arduinos, or an attached Real-Time Clock, can easily generate square waves up to ~1 MHz without major intervention. All slaves on the line have access to this signal, and use them to trigger an interrupt that increments a counter. The main microcontroller code can then use this counter to properly time the execution of events.
Watch this space…
This is just a proposal at the moment, so watch for developments as I try to implement it in my home lab.