Need a method for synchronization of galvanically separated microcontrollers

Question 1: is there a method to do sampling correction/syncronization between the microcontrollers? Can you suggest a literature in this topic?

All STM32 ADC are capable of using an external trigger to initiate sampling.
You can distribute a 100 KHz clock and use that to trigger the conversions synchronously.
This is the easiest and most reliable method, often found in many data acquisition systems.
How to do this is described in the reference manual of your chip.

You may need to choose between starting a scan or a single conversion per edge.
See AN3116 STM32™’s ADC modes and their applications

Question 2: if hardware redesign is possible, currently I am thinking in software solution, how can I put syncronization between the seperated microcontrollers?

SPI is also a synchronous protocol, so that problem you have already tackled. You can get 100 Mbps isolators for cheap. You just have to keep an eye on the jitter they have.


You could also try to make some synchronization happen by calibrating against the SPI clock or intervals. By doing some software PLL like functionality.
But I'm afraid you'll be going down a rabbithole that way.


Both of these work on the idea that there is at least some delay in the sample loop of the slaves, which could be adjusted to make the slowest slave catch up with the fastest. That is, that there's a software timer which triggers an individual capture of the ADC.

Pure software You could read about the Network Time Protocol, and borrow/adapt as much of it as you thought necessary. At base, a master sends out time signals and the slaves calibrate themselves by a (software) phase-locked loop. With dedicated microprocessors and SPI communications, those mechanisms should get your your accuracy.

Explanation of NTP mechanisms Documentation, Presentation. NTP has quite a number of modes. The ones which might have mechanisms you can borrow are making the control host a fake reference clock (deemed to be correct) and having the slaves work like broadcast clients (even if they are receiving the messages one at a time). The main thing to read about is the clock discipline algorithm, which explains how the client gets its clock in sync with the master.

I'd consider using one of the STM32s as a clock master, and the host controller gets a nominal time from that, rather than using the host controller's clock. This is because we're not trying to sync the slaves to the real time, we're trying to remove time skew from the multiple samples. (As far as I've understood your goal.)

If you find you want to do it according to standards, NTP is defined as an internet RFC 5905, though you might want to also read the earlier versions which are a bit simpler. You might also want to look at PTP (precision time protocol), which is an IEEE standard IEEE Std 1588-2002. It's much more accurate, also much more complex, and much more expensive!

At the higher end of your resolution (0.1 ms), it should be entirely possible to simply get the host to tell each slave periodically "the time is X ns", and leave them to sample on X % 10000 = 0. All the jitter will be in the host controller. Assuming Linux kernel, you'll need to read clock_gettime(3) and pay attention to CLOCK_MONOTONIC or perhaps CLOCK_MONOTONIC_RAW settings.) The only thing to fret about is how to deal with a slave smooths the changing of its clock so it doesn't miss any sampling: I'd guess you can just sample "right now" if you have to jump. It depends on how much spare time the slaves have between samples.

Hardware If you can afford a wire and an input on the slaves (and the additional isolation), run an extra wire to tell all the slaves to sample. If that generates interrupts on the slaves, they will be about as synced as it's possible to get in software, and could be much better than your target. The optimal syncrhonisation (given in Jeroen3's answer), is to trigger the ADC capture directly from an IO pin.


is there a method to do sampling correction/syncronization between the microcontrollers? Can you suggest a literature in this topic?

So, you'll need to synchronize their sampling clocks. That requires

  1. keeping the core frequencies of the MCUs identical and
  2. marking a common start point in time.

The first one can be managed by distributing an oscillator to the MCUs, also in the same galvanically isolated manner. Your 16 MHz oscillators need to go! Instead, your central board gets one, and buffers it and distributes it to your boards.

The second is way harder: Maybe the ADCs can be triggered to an external pulse (I don't think so, but really, read their respective documentation). Then, well, just distribute the same pulse to all of them.

If that's not the case, you'd still need to distribute a common point in time when to start, and the only way I could see you doing that reliably would be through distributing a pulse to a pin on all these MCUs, and having an interrupt be executed on a positive edge of that pulse, which in turn starts the first ADC conversion.

Problem is that on Cortex-M, interrupt latencies aren't as strictly defined; but, honestly, 10 µs should be pretty doable – that's a lot of clock cycles.

If you need better coordination, external ADCs that take a separate conversion clock source would be better suited.

if hardware redesign is possible, currently I am thinking in software solution, how can I put syncronization between the seperated microcontrollers?

Hm, so, without addition of a distributed clock and trigger signal, it's going to be very hard. I don't see a viable method, as there's no clock recovery hardware in the STM32 that you could use to "discipline" the internal clock to run locked to eg. the clock of the communication bus with your main board.

And then each microcontroller would change the sampling frequency a bit (100.0001ksps or 99.99999ksps).

Can't do that with that level of precision, since the sampling times are essentially set by internal dividers of the core frequency.