I'm thinking about trying to use an esp8266 again. I switched to the esp32 because software serial at 9600 baud gave a lot of watchdog resets, not what you want in a time server. Software serial was needed because the esp8266 has only one usable UART and that is used for programming and debug messages. It has a second one but the receive pin is in use by on module flash making it unsuitable for receiving messages from a GPS module.
I've found that its possible to swap the pins used for UART0 to an alternate set of pins and I can connect the GPS there. You can also send debug messages to UART1 since its transmit pin is usable.
I'm interested to see if the GPIO interrupt latency is more consistent than I have found on the ESP32. There the latency varies between 4us and 38us. With wifi connected it tends to be on the higher side. With two cores, wifi using core0 and my app and GIPO interrupts using core1 I expected the ESP32 to be able to respond consistently.
I've moved to an ESP32, and renamed the project. I had too many issues with software serial on the ESP8266 failing to read properly at 9600 baud. Also I'm now using esp-idf instead of Arduino. I've added a small OLED display to show status and current UTC time.
Its running 3 "tasks":
I threw together a quick prototype using a NodeMCU, small oled display and a gps unit. Then spent some time working with the software.
I had seen a number random crashes and found that this was due to power demands from the GPS module so I added a large-ish capacitor nearby.
Since the ESP8266 only has one USART I’m using a software serial implementation. I've still seen some crashes and decoding the stack trace they are happening on the interrupt service routine for this module. A quick look at the modules code shows a WAIT macro that may not be safe in an interrupt service routine,
I'm also using a nice, small NMEA parsing library to parse the GPS messages.
Its responding to ntp requests and syncing with the PPS signal from the GPS unit. I am seeing a few times where the NMEA message from the GPS is parsed after the next second pulse from the GPS. Because I'm validating validating that the time I have is correct with each message I see it time warp back one second then timeworn forward one second a few times a day. I think that the ESP wifi housekeeping functions may sometimes delay the serial parsing. Or that rendering the display could be taking too long to render each second.
While I don't have a GPS module, I do have boards from SynchroClock that have the DS3231 real time clock 1hz routed to a GPIO pin on on the ESP8266. This lets me pretend I have a GPS (and I read the current time from the DS3231).
I used a strategy mentioned by @Nick Sayer, in the comments on one of his projects here, and used the ESP8266 builtin CPU cycle counter, 80Mhz, to interpolate the time between seconds. And it answers queries!
flugelberry$ ntpdate -q -u 192.168.0.29 server 192.168.0.29, stratum 1, offset 0.273729, delay 0.06538 3 Nov 19:39:51 ntpdate: adjust time server 192.168.0.29 offset 0.273729 sec
EDIT: It turns out that ESP.getCycleCount() is not very consistent. Using this I end up with up with well over 250us of jitter! Maybe something with idle sleep or some other power saving mode? In any case using micros() works much much better with jitter less than 20us!