What time is it?I've been re-purposing old cell phones as clocks for several years.
Android 2.2.2 - Froyo. This one still going, its sibling has failed. And more recent phones have failed.Android 2.2.2 - Froyo. This one still going, its sibling has failed. And more recent phones have failed.
Two have just failed. That's the last one running...good hardware. Really old OS, but still gets the time off the network and still updates when we switch to daylight time and back.
So I need to replace them, and I started thinking about Arduinos and Raspberries and stumbled into ESP32.
Quarter inch squares, this is about 25cm x 50cmQuarter inch squares, this is about 25cm x 50cm
This is from espressif and I got this one on amazon, 3 for $17. So far I've played with blinking an LED and using the built-in WIFI hardware. Yes, WIFI, and blue tooth, and lots of I/O pins, 4M rom and 512K ram (I think. have not explored far enough to know for sure.) In the process, I ran the NTP (Network Time Protocol) example and started wondering how NTP works.
At the bottom, NTP is really simple. A computer that wants to know the time sends a short message to another computer that hosts an NTP server, and that computer sends a short message back that includes the GMT time. Done.
(It is much more complicated; apparently the NTP servers may answer the question 1000 times a second! And the mechanisms for synchronizing the servers use statistics. And David L Mills invented the NTP stuff around 1980.)
The internet mostly uses TCP (Transmission Control Protocol), a robust protocol built on top of IP. TCP retries, etc, to make sure data is delivered, in order, and intact. It is a heavy-weight protocol. NTP servers use a light weight protocol, UDP (also on top of IP) which guarantees nothing. Your messages might get lost, never arrive, arrive out of order. But the load on the server is minimal; the server doesn't need to do any extra hand-shaking to make sure you get an answer. The U in UDP (User Datagram Protocol) means the user is responsible for handling errors.
This JSL creates a socket to use port 123 (the NTP port) and the UDP protocol to send a message to a pool of NTP servers and get the response. It does some really simple statistics math that assumes the travel time to and from the server are equal so the server's time can be synced with the local computer better. The results are pretty good! Here's a slightly better than average example that found a server in the pool half-way around the world:
pool.ntp.org(rn5.quickhost.hk)
TotalTime = 0.143846988677979
FlightTime = 0.143799781799316
Difference = 0:00:00.01689
Assuming .hk is really in Hong Kong, that's 8,000 miles from North Carolina. 16,000 round trip. The Flight Time is the Total Time less the processing time in Hong Kong, which was negligible. If I did my math right, that's more than 100,000 miles/second, a significant fraction of the speed of light.
The last number, difference, is the difference between my CPU clock and the NTP server's clock. That's less than 1/50 second. And I get results from most servers within 1/10 second, unless the flight time is large, in which case it is asymmetrical and the correction technique breaks down.
pool.ntp.org(LAX.CALTICK.NET)
TotalTime = 0.101963043212891
FlightTime = 0.101903915405273
Difference = 0:00:00.08646
pool.ntp.org(ns2.nuso.cloud)
TotalTime = 0.103617668151855
FlightTime = 0.103596687316895
Difference = 0:00:00.04034
pool.ntp.org(50-205-57-38-static.hfc.comcastbusiness.net)
TotalTime = 0.0763883590698242
FlightTime = 0.0763206481933594
Difference = 0:00:00.00965
pool.ntp.org(13.86.101.172)
TotalTime = 0.077089786529541
FlightTime = 0.07708740234375
Difference = 0:00:00.00663
// this snippet demonstrates a UDP (User Datagram Protocol) exchange with an NTP
// (Network Time Protocol) server using a JSL socket. NTP sends enough information
// from an NTP server to correct for some network delays and make a really good guess
// at the local time, possibly within 1/100 second, usually within 1/10 second (depending
// on how similar send and receive times are.) Using the OS time setting to sync your
// clock first (which uses NTP as well) will make the deltas near zero. Otherwise the
// deltas should be similar across several runs. Your computer clock will drift between
// the syncs (once a day?) that your computer automatically performs with an NTP server.
//
// idea from https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html
timezone = -4; // (tz for my computer) Eastern Daylight Time is GMT-4.
// build the transmit packet to send to the NTP server
xPacket = Hex To Blob( "1b" || Repeat( "00", 47 ) );
// make the socket object
sock = Socket( DGRAM ); // not a normal STREAM socket, this is an unreliable UDP socket.
// choose a server (or server pool)
addr = "pool.ntp.org"; // a pool of servers. Don't ask too often, they have a heavy load.
// if nothing goes wrong, the bind and ioctl are optional, but
// if we never get a response (for various reasons) we'd rather not hang forever...
rc = sock << bind( addr, "123" ); // bind, maybe not required, but needed for NBIO...
If( rc[2] != "ok",
sock << close;
Throw( "bad bind" );
);
rc = sock << Ioctl( FIONBIO, 1 ); // NBIO: non blocking i/o. the unreliable UDP may never answer.
If( rc[2] != "ok",
sock << close;
Throw( "bad ioctl" );
);
// send our request to the server. <<SENDTO is="" for="" unreliable="" udp="" packets.=""></SENDTO>

Using UDP sockets to get time from an NTP server.
Re: What time is it?Before I order revision 2 of the PCB I'm building the other two boards from the first order. Like the first one, but in parallel, construct a bit and test. And I learned something I didn't expect.
Build phases look something like this:
- Put all the low-profile, small, inexpensive components on the board. They are hard to do later.
- Add the LED drivers, three 16-pin ICs.
- Add the power supply components and see if the power indicator LEDs light up.
- Add the CPU, make sure it will accept a downloaded program.
- Add the digits on the other side. The digits hide things, so they must be last.
Some of these prototypes are not working correctly.Some of these prototypes are not working correctly.The digits (four of them) are modestly expensive and somewhat delicate. I somewhat randomly placed one (hours-one position) and did a quick test. Only some of the segments worked. Back to the workbench, visual check, meter check, finally pull out the scope. At this point there are a half-dozen things that could be wrong; anything from the CPU to the driver ICs to the digits. It isn't the basic design; I've got two working prototypes (one on a breadboard, one on the first PCB.)
The clock is a multiplexed design; each driver chip has four outputs. One of the drivers selects a digit and the other two drivers select seven segments and a decimal point. A 4X8 matrix of 32 elements, addressed by 12 bits. Up to eight elements can be on at a time (one digit). Luckily, I'm looking at a digit that should have most of its segments on and I'm seeing all missing segments that belong to one driver chip. Using the scope on that chip, I see the inputs are requesting the segments be on, but the outputs are...dead.
Replacing an IC is a pain. I grabbed a fresh one from the tube, got it installed, and...Bummer! It is better, but one segment is still not showing! Did I misdiagnose? Something else crumbling?
Wait. I'm building two cards in parallel. Let's look at the other one. Nothing. No segments. After a bit of study...Hmm. This time the problem is not the driver for the segments, it is the driver for other axis in the matrix, the one that selects a digit. Do I have a whole tube of bad ICs?
This was an unused tube of ICs, purchased for another project about 10 years earlier. I need to build a tester. Here's the tester showing four green lights for a chip that I got recently from a different distributor.
All 10 in the newer tube checked out good.All 10 in the newer tube checked out good.
I currently believe at least 5/10 of the chips in the other tube were bad on one or more outputs:
Crush the pins in (to prevent re-use) and roll them on their backs so they look like dead bugs. Even 3/4 OK is not good enough when all four outputs are needed!Crush the pins in (to prevent re-use) and roll them on their backs so they look like dead bugs. Even 3/4 OK is not good enough when all four outputs are needed!
What I learned might be about testing the chips before install, but I don't think that is really needed. But what I will do is use the scope to do a test, probably reversing items 2 and 3 in the assembly, so I can test a little better before attaching a digit. Then, for placing the first digit, pick one that blocks the power supply, not a driver chip. Right now I've got to remove a digit so I can remove a driver IC.
Re: What time is it?Prototype built and working.
It's hard for me to call this the back; it was the front in KiCad.It's hard for me to call this the back; it was the front in KiCad.
The flash makes the white balance show the red digits as red.The flash makes the white balance show the red digits as red.
With no flash, the white balance messes up the colors, but this is closer to what it really looks like otherwise.With no flash, the white balance messes up the colors, but this is closer to what it really looks like otherwise.
The linear regulators run really hot; the 5V regulator delivers about 1/4 amp but that means the 16V input drops 11 volts * 1/4 amp = almost 3 watts into that tiny heat sink. Time to look at a drop-in replacement switch-mode regulator. Apparently the same package size, but 90% efficient.
Re: What time is it?Circuit boards are in! Designed with KiCad, manufactured by OSHPark, 20 days including 11 days of manufacturing and 8 days of free shipping (saving where I can!) Probably shouldn't show these until I know they work...prototypes...
This is my first board that will have components front and back.This is my first board that will have components front and back.
The rough points around the edges are where my boards were broken out of a larger panel; I'll clean them up soon, they are pointy! The boards are about 3x9 inches. I'm using through-hole technology; all the surface mount bits will be on pre-built cards (GPS, BME, and the ESP32). I went with the AfterDark boards even though the time was a bit longer. I'm liking the look! A preliminary test fit says the parts I designed footprints for are going to work. Yay!
Re: What time is it?update... the blue light at the far right is the esp32. It's 4:05 PM.
It's really hard to get the light right to take a picture of an LED display.It's really hard to get the light right to take a picture of an LED display.
The 2 1/4 inch tall digits require 8 volts, not the 2 volts the old data sheet suggested. That means I need the extra power supply in the top right, made from junk-box parts, and the 4 driver chips came from the same box. There is a $12 GPS at the bottom right too. The time can be set from the GPS if it can see some satellites, or from the wifi if the password has not been changed.
Not sure where JMP fits into this yet, but I've got a pressure/temperature/humidity sensor I want to add. Maybe it will do some data logging and run a webserver. Or maybe I'll add a small display for the weather. Once the details are worked out, I'll be making a PCB. Those wires won't work on the wall.