-
A better power supply
03/09/2017 at 03:34 • 0 commentsI've decided to add a buck converter to the board to make the 5 volt power supply from anything from 7-15 volts input. This makes the clock a lot easier to power. It's a little like building a "pi power" directly in, though the circuit will be slightly different (it'll be a copy of the 5 volt supply from my FE-5680A GPS board) because it's not going to support as much power. The supply will be rated for around 500 mA, which should be more than enough for the Pi Zero and clock display running flat out. Pretty much any power source that supplies 5W of 7-15 volt power on a 2.1mm center positive barrel connector will do.
EDIT: I've changed my mind. I'm going to just go with a 5V input jack like the GPS clock and my GPSDOs. I've got a bunch of those and adding a 5V buck converter to the board just raises the cost/price.
It wouldn't take much to *also* make a Pi Zero clock into a GPS stratum 1 server at the same time. To get it to work, you'd need to disable the serial console once you got it working on the network. Next, you'd connect a GPS receiver breakout board up to pins 4, 6, 8, 10 and 12 of the GPIO header (+5, gnd, TX, RX and PPS respectively). The easiest way to do this would be to use a "double male" stacking header (like this one) for your GPIO so that you could connect up to the top as well.
-
More operational suggestions
03/07/2017 at 05:10 • 0 commentsFor those who want to alter the timezone for the display, I've tested this and it works: you can set the TZ environment variable as is traditional on *nix. For example, if you want a UTC display, you can
export TZ=UTC
and then run the clock executable and the display will show UTC.
When you add the clock executable to /etc/rc.local (or take other steps to run it automatically on startup), you may notice that it starts by showing the wrong time (usually some time in the past) for a little bit, and then snaps to the correct time. This is because (normally) the Raspberry Pi has no RTC hardware to keep the time when the power is off. If you allow the pi to shut down gracefully, it will write the current time to a file and use that during boot. The clock will be wrong by however much time it was off, but the benefit to this method is that the clock will never go backwards (as it would if it started at time zero every boot).
If this isn't good enough for you, you can add an i2c RTC clock (the easy way is with a breakout board) and that will allow it to preserve time across power loss.
-
Boot config
03/05/2017 at 21:12 • 0 commentsTurns out that you don't have to add the dtoverlay line for hardware CS. I'm not sure why it wasn't working before, but I removed that line from config.txt on a whim, and the clock continues to function. Go figure.
-
Prototype happened
03/04/2017 at 08:10 • 0 commentsI spent this evening building a prototype. I used a board for my GPSDO clock accessory, left off the microcontroller and tacked wires on to bring +5 from the Pi along with MOSI, CLK and !CS from the GPIO header.
The result took some horsing around to get working.
I found I had to not only enable SPI, but I had to add
dtoverlay=spi0-hw-cs
or else the CS line wouldn't work properly. I'm not entirely sure I understand why, but the hardware CS system works and the software one doesn't. Go figure.
But that done, when I take a slow-mo video to compare the result with one of my GPS clocks, it's (at the moment) about one frame slow, which easily puts it under 10 ms. With this prototype, I'm cheating a little - it happens to be one of my stratum 1 public servers, so it actually has a GPS module connected up to NTP, so I know that the actual Unix clock is well under a few dozen microseconds accurate. In short, the clock is performing well up to the desired specification.
Now it's just a matter of waiting for boards to arrive from OSHPark and a Pi Zero W from whichever vendor happens to ship first. :)
-
Early proof of concept test
03/03/2017 at 18:10 • 0 commentsJust to insure that the clock display daemon is a thing that has even a shot of working properly, I wrote this:
#include <stdlib.h> #include <stdio.h> #include <time.h> #include <sched.h> #include <sys/mman.h> // 10 milliseconds #define SLEEP_NSEC (10L * 1000L * 1000L) int main(int argc, char **argv) { if (mlockall(MCL_FUTURE)) { perror("mlockall"); } struct sched_param sp; sp.sched_priority = (sched_get_priority_max(SCHED_RR) - sched_get_priority_min(SCHED_RR))/2; if (sched_setscheduler(0, SCHED_RR, &sp)) { perror("sched_setscheduler"); } while(1) { static unsigned int last_tenth = 12; struct timespec now; if (clock_gettime(CLOCK_REALTIME, &now)) { perror("clock_gettime"); } unsigned int tenth = (unsigned int)(now.tv_nsec / (100L * 1000L * 1000L)); if (tenth != last_tenth) { last_tenth = tenth; printf("%d\n", tenth); } struct timespec sleepspec; sleepspec.tv_sec = 0; sleepspec.tv_nsec = SLEEP_NSEC; nanosleep(&sleepspec, NULL); } }
This code locks itself into memory and sets a real-time scheduling priority, then attempts to print out the current tenth of a second to within around 10 ms or so.On a Pi Zero, this consumes less than 1% of the CPU, and if I run it over ssh on two PIs and look at a slow motion video, the two changes happen 4 frames apart. Since my phone does 240 fps, that's inside of 20 ms, which is certainly in the ballpark. And there are a huge catalog of error sources in that test - the refresh rate of the terminal window on my laptop, the wifi connection from my laptop (the two Pis are on Ethernet), SSH and TCP packet batching, etc. None of those would be a factor for the final clock. Even taking into account the time the SPI updates would take is negligible. The MAX6951 has a maximum SPI clock of something like 26 MHz. The plan at the moment is to configure for maybe 1 MHz. Assuming something like 20 clock cycles per write (it's 16 bits plus some dead time), it's still less than a couple hundred microseconds to update the whole display.