Close

Early proof of concept test

A project log for Raspberry Pi Zero W desk clock

An LED desk clock driven by NTP on a Pi Zero W

nick-sayerNick Sayer 03/03/2017 at 18:100 Comments

Just 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.

Discussions