syncing time via VGA

menu

what?

The title is slightly misleading :-) What it really is, and this is a TL;DR too:
PPS via Arduino into the I2C pins of a VGA connector of a Linux-running-PC which then gets interfaced to NTPd.

how

As described above, there's an Arduino to which I connected a PPS source. This PPS source ("Pulse Per Second") gives a pulse every second. For my experiment I used a simple TCXO (temperature compensated crystal oscillator, a 10MHz TCXO with a PicDiv to make that into a PPS signal) but a GPS with a PPS pin is preferred.

On the Arduino runs a custom script. This script waits for an I2C request to which it should respond in a short time (else the requester times out). The Arduino then waits for 50us (50 microseconds) in a loop until the PPS signal comes in (e.g. the GPS pulls the pin high). If the signal is received, a '!' is sent back, else some other character.

The Linux PC tries to find a baseline for the PPS offset by frequently polling the Arduino. When the first signal was received, then that is used and a sleep of 990ms to minimize the polling. Every time a PPS comes in, the timestamp is send to NTP via a "shared memory segment".

On this website there's a picture of how to connect the Arduino to the VGA connector: .
Connect pin 15 ("SCL", lower left hole) to A5 and pin 12 ("SDA", next the pin on the right) to pin A4 and pin 5 ("GND") to one of the GND pins of the Arduino. You might need to add pull-up resistors between A4 and VCC, and A5 and VCC (4.7k Ohm) - with the videocard I used (Radeon HD 8370D) it also worked without.

Refer to the website I mentioned for how to determine how to find which I2C bus the Arduino is connected to. You can also probe them manually by first connecting the Arduino to the port (don't forget to upload the script first) and then run i2cdetect -y -a on each bus - if it detects something on address 8, then that may be the Arduino:

root@brain:~# i2cdetect -y -a 11
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- 08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

In this example, the Arduino sits on bus 11. You can now and retrieve the code from GitHub. Before "make"-ing, you might need to replace the "11" in i2cppsl.cpp to the bus you found:

if ((fd = open("/dev/i2c-11", O_RDWR)) < 0) {

Add the following line to /etc/ntp.conf:

server 127.127.28.0 minpoll 4 maxpoll 4 prefer
and run the 'il' program you build in the previous step (after restarting ntpd).

results

After 8 hours it looked like this on my system:

     remote            refid      st t when poll reach   delay   offset   jitter
================================================================================
*SHM(0)           .SHM.            0 l    4    8  377   0.0000   0.2660   0.2562
+192.168.65.211   .PPS.            1 u   43   64  377   0.7995 3491.294   3.4860
+192.168.64.79    .PPS.            1 u   36   64  377   0.3217 3493.653   1.9202
+192.168.64.1     192.168.64.79    2 u   24   64  377   0.2613 3496.491   3.3935
You're looking for the 'SHM(0)' line. A jitter of 0.2562 is not too bad I would say. The output of ntpq is explained on this website.

Allen deviation plot

picture

Raspberry pi

The Raspberry Pi (RPI) has an i2c bus of course, but it would be interesting to see if this trick works with other hardware as well.

The RPI has no VGA connector but an HDMI connector instead. The HDMI connector also has i2c pins!

I had no HDMI connector laying around, but I had a HDMI to VGA dongle and a converter-cable.

The dongle did not work: it shows all kind of i2c end-points, but not end-point 0x08 (the one I configured the Arduino for).

The converter cable on the other hand, worked perfectly!

(to enable i2c on the HDMI-port, add dtparam=i2c2_iknowwhatimdoing to /boot/config.txt)






Other projects: here and here.


The Lotter allows you to participate in lotteries from all over the world!