Distributing a 50Hz clock signal on a 125 kbps CAN bus? - Page 1
Forum section: electronics / beginners

author: e100
author_rank: Frequent Contributor
timestamp: September 26, 2021, 09:32:15 am
content: As far as I'm aware CAN is unsuited to the distribution of clock signals because of the collision and retry mechanism that adds variable length delays to messages.Is there a general solution to this type of problem?

author: Doctorandus_P
author_rank: Super Contributor
timestamp: September 26, 2021, 10:55:17 am
content: First, CAN has a built in priority in the addressing. "Active" bits overrule "passive" bits.Also, a circuit used a "missing pulse detector" used to be common in the old days. This can for example be an osillator that runs a tiny bit slower then the actual clock should be, during normal operation each pulse of the "master clock" resets this missing pulse detector, but if the master clock fails, then this oscillator is not reset and takes over.CAN bus goes to a microcontroller and usually these a systems timer running anyway, and this can also be fairly accurate because most of the uC's run from their own crystal oscillator, but these oscillators do have a limited accuracy (typically 200ppm) and long term drift.It's quite easy to send "keep alive" messages over the CAN bus at a fixed interval and then the uC reads these messages and makes small adjustments to it's internal system timer to keep it in sync.Because it uses the time that these CAN messages arrive, a message that looses arbitration should not be sent again, but just deleted, so there are a few less syncs.Another possibility is to send CAN messages at irregular intervals, but with embedded timing information. The microcontroller can then use the arrival time and the time embedded in the message to make adjustments. Very similar to hearing a church bell (I hate those things) and then synchronizing your watch to it.I see no need to send CAN messages at 50Hz. a system tick timer of (almost?) any uC is perfectly capable of generating a 50Hz tick interrupt. A system tick timer that runs on 50Hz, and has an accuracy of 200ppm can be off by one tick in 50*24*60*60*200e-6 = 864.0 seconds. (Edit: Oops, I goofed up here. I should not have used 24*60*60, which is the number of seconds in a day here. See the remark of MIS42N below).Which means that if you send a synchronization value once a minute, then the accumulated error will never be bigger then 7% of a 50Hz clock cycle.

author: MIS42N
author_rank: Frequent Contributor
timestamp: September 26, 2021, 11:38:21 am
content: Quote from: Doctorandus_P on September 26, 2021, 10:55:17 amNot quite sure where 864 seconds comes from. 200ppm is 1:5000 so gaining or losing one tick in 5000. 5000 ticks take 100 seconds.I agree that sending a tick 50 times a second is unnecessary. I assume receivers would have much faster clocks than 50Hz, transmitters can know when they send a timing message so can time stamp it correctly. Up to the receiver to generate its own 50Hz by dividing the much faster clock, and correcting according to the messages from the transmitter. Once a second should be enough and unlikely to overload the bus with messages. Of course, assumptions are what they are - often wrong.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: September 26, 2021, 11:44:22 am
content: Looking at what can happen, either the signal will arrive immediately, or it will be delayed.So all you need to do is have a local clock which is stable enough to know when a message has been delayed, and ignore it.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 26, 2021, 11:46:54 am
content: I have successfully used highest priority ID (0) to send periodic sync packets, then write a PI loop to synchronize the phase of a local clock source (i.e., a timer) to said sync messages, generating kind of a software PLL.But do note that sending a higher priority message does not stop whatever is being currently sent on the bus, the current transfer is finished first, so even with highest priority, the delay is variable.If you have small number of delayed sync messages but most are "correct", you can either ignore the outliers like Mike suggests, or just use benign enough coeffs in the PI loop so that they do not significantly throw off the phase. This all then comes to using stable and fairly accurate (i.e., crystal oscillators, not RC) clock sources on each node. In my case, I could otherwise guarantee that there is no other bus traffic when the sync packet is being sent, because the sync packet itself initiated data generation which is finished before the next sync packet. To cover my ass, I also tested that the resulting clock jitter is within acceptable limits even when the bus is flooded with dummy packets creating variability to timing.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: September 26, 2021, 01:05:54 pm
content: The most important common factor of all answers is that you can not rely on all CAN messages arriving at all or arriving at the right time, and to make your system robust you have to build in some system to allow for these irregularities.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 26, 2021, 01:15:57 pm
content: Well the whole point in CAN is that youcanassume messages arriving definitely "at all", and even better, with all components in your control, at some worst case deterministic time; it's no UDP/IP. Otherwise is a clear error condition, and handled as such, no different from an unexpected lightning strike killing some part. Of course I'm not saying not to prepare for errors and try to handle them, but you can depend on CAN bus delivering messages within some time limits you can calculate.In other words, even a dedicated simple IO line could fail in numerous ways!

author: MIS42N
author_rank: Frequent Contributor
timestamp: September 26, 2021, 09:43:55 pm
content: Previous posts assume a message is prepared then thrown at the transmitter hoping it will be sent in a timely manner. Is it possible for a transmitter to wait until it gets a clear line then fill in the time just as it sends? I see no technical impediment, but if all the logic is buried in a hard coded device then it won't work. Maybe an opportunity for a manufacturer to make such a device. It would depend on the demand for timing on CAN bus.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 27, 2021, 07:22:24 am
content: Modern CAN interfaces on MCUs do implement timestamping for outgoing packets, exactly what you want.

author: MIS42N
author_rank: Frequent Contributor
timestamp: September 27, 2021, 07:35:15 am
content: Quote from: Siwastaja on September 27, 2021, 07:22:24 amThat answers OP question.

author: Siwastaja
author_rank: Super Contributor
timestamp: September 27, 2021, 07:43:14 am
content: Well not directly, but you can utilize this information. For example, after sending a sync packet, read the timestamp to find out the "wait for line" delay, then sendanotherpacket to tell others what the delay was, so they can subtract this value when synchronizing their "software PLL". Or just send sync packets regularly, with a field that describes the "wait for line" delay of the previous sync packet. I don't know if anybody does exactly that but it's surely one way to skin a cat. This synchronization thing is a commonly occurring requirement so it's been likely solved in gazillion of different ways.