# How to use 1PPS to Synchronize ESP32 Clocks and Peripherals

I've read a few posts (example) about what the 1PPS signal is and how it can be used at a high-level, but I'm still not sure how to actually implement it on a PCB schematic to sync up with my microcontroller (ESP32). Do I just connect the 1PPS to a GPIO on the ESP32 and configure the rest in software? What would that look like?

For reference, here's my schematic showing just the MCU, external flash, and my crystal (configured based on the ESP32 Hardware Design Guidelines). You'll notice there's four different clock frequencies. How can I calibrate all of them based on the 1PPS? What are the hardware steps and subsequent firmware steps?

• I would connect it to a hard interrupt line if you have any available, if you care about really precise synchronization. – Hearth Jan 24 at 2:04
• What are you trying to synchronize? – user253751 Jan 24 at 2:25
• @immibis I'm not really trying to synchronize anything, just figured I'd use the 1PPS to compensate for drift in the clocks on my other components. My circuit board is turning on every 4-6 hours to collect environmental data (gas concentrations, temp, pressure, humidity) and saves it to a microSD card before transmitting via WiFi/Bluetooth/LoRa. I just thought since I have the 1PPS signal I might as well use it to keep things sharp. – YNGVV Jan 24 at 2:35
• So you could count 14400-21600 PPS signals to know when it's been 4-6 hours very accurately. Otherwise what you have is a solution in search of a problem. – user253751 Jan 24 at 5:46
• – Dave Tweed Jan 25 at 13:33

I'm not sure what it is exactly that you want to "calibrate", but I worked on a very similar project several years ago, and came up with a scheme that worked fairly well for us.

In our case, we had a GPS receiver providing position fixes and a 1 PPS signal to our processor, and we needed to be able to precisely interpolate 5 ms intervals (200 Hz) from the 1 PPS so that we could accurately control the sampling of the IMU. (Additional background material here.) However, we had no direct control over the CPU clock, which also drove its hardware timers. Therefore, I invented a kind of "software PLL" to fill the gap.

The basic idea is that we set up a hardware timer (call it T1) to produce the 5 ms interrupts we needed. Suppose the processor clock is nominally 50 MHz. Therefore, the T1 period is nominally (but not exactly) 250000 CPU clocks. We keep track of the passage of time through a combination of reading the hardware timer and counting the number of T1 interrupts that have occurred.

The 1 PPS signal is connected to a second timer (T2) that simply "captures" its value in a register and also triggers an interrupt, at which time we also take a snapshot of T1's value. T2 gives us the exact number of CPU clocks between 1 PPS edges, which is an exact measure of its actual frequency. The period of T1 needs to be 1/200 of this value, which is not always going to be an integer.

Therefore, we dither the T1 period between two adjacent values, keeping track of the accumulated error and updating it on every interrupt. We can also control the "phase" of the T1 interrupts relative to the T2 interrupt in order to create an offset that accounts for any unavoidable latency in the processing.

This is a very general description of what we did. Let me know if anything is not clear.

However, from your comment about what you're doing, it sounds like you don't need anywhere close to this level of precision (i.e., a few µs). Just read the timestamps in the GPS messages.