Friday 14 March 2014

BirdBoxPiCam2014: updating Time on the RaspberryPi

Ok, so it turned out that using NTP to reset the clock on the Raspberry Pi was not one of my greatest ideas for this project.


NTP is for real computing, where high accuracy is required and small errors need to be slowly tuned out.


My requirements for this bird box project are for a step-change correction each time the system boots up, which may be several times per day. Accuracy is just not important.

So after a re-think, I've come up with a better solution.

What's the plan?


The idea is very simple:-
  • A server writes the current time & date to a file
  • The Raspberry Pi reads the file and resets the clock
There is no need for any setting delays, fancy trending, or protection from possible errors. I just need the Raspberry Pi to know what day it is, and know that this video clip or log entry occurred about this time.

Server details


My garage server is the time source or reference. It is not connected to the internet, so I expect it will drift during the next few months.

To be honest, the accuracy required for the Raspberry Pi could be +/- 10 minutes and I'd still be happy. So I've decided to simply write the current time to a text file at one minute intervals.

I can get the current date & time using the Linux command: date
And writing to a file just involves redirection, like this:-

date +%D_%T > /home/garage/clock/TheTime

...which puts a single line of text into the file "TheTime" with the format:-

mm/dd/yy_hh:mm:ss

e.g. 03/15/14_10:59:01

Each time this command runs, the "TheTime" file is re-written, so it only contains the latest time/date entry.

By putting this command string into a script which I then run from a cron job, I can execute this every minute.

I've called the script UpdateTime.sh and it just contains:-

#!/bin/bash
date +%D_%T > /home/garage/clock/TheTime


Using file manager Properties > Permissions, set this file to be executable.

To add this to a cron job, just type in a terminal:-

crontab -e

...then add the line:-


* * * * * /home/garage/UpdateTime.sh

...note that each * is separated by a space.

Access to TheTime file


We need to make TheTime file accessible to the Raspberry Pi over the network. The Network File System (NFS) basically allows a client to mount folders on a remote server.

In this case my Lubuntu garage computer will serve up the TheTime file to my RaspberryPi client. NFS is already installed on Lubuntu 13.10, but if the packages are missing you just need to install nfs-kernel-server which should automatically add the dependent package nfs-common.

A folder structure is required to hold the file "TheTime", so in a terminal type:-

mkdir /export
mkdir /export/clock

We need to mount this, which we can do manually for testing by typing:-

sudo mount --bind /home/garage/clock

...or to make this persistent (each time the system boots) put this in /etc/fstab:-

/home/garage/clock    /export/clock   none    bind  0  0

I have no security concerns, so in /etc/default/nfs-kernel-server I set:-

NEED_SVCGSSD=no #no security

One more edit; add these two lines to /etc/exports:-

/export       192.168.0.0/24(rw,fsid=0,no_subtree_check,sync)
/export/clock 192.168.0.0/24(rw,nohide,insecure,no_subtree_check,sync)


Its probably a jolly good idea to re-boot now (if you are following along with this).

NFS on the Raspberry Pi


NFS seems to be installed on my RaspberryPi, but if its missing on yours, you just need to add a package via Synaptic or from the terminal by typing:-

sudo apt-get install nfs-common

I've modified my /etc/fstab file by adding the line:-


server-IP:/    /mnt   nfs4    noauto  0  0

...using "noauto" because I suspect I'll get problems if I try to mount the server folders at boot time. So "mount" is performed by my Gambas application some time later.

In my case, "server-IP" is replaced with 192.168.0.10 (or you could use your servers name, if your system can resolve names).

The Gambas bit


Now, in my Gambas bird box application I can rip out the NTP routine and replace it with a function like this:-

Public Function UpdateRTC()As Boolean
'Dim variables here
 
  Exec ["sudo", "mount", "/mnt"]
  Wait 1
 
  strFilePath = "/mnt/clock/TheTime"


  If Exist(strFilePath) Then
    hFile = Open strFilePath For Read
    Read #hFile, strTime, -256
    Close #hFile
    strTime = Replace(strTime, Chr(10), "")
    strTime = Replace(strTime, "_", " ")
    Exec ["sudo", "date", "-s", strTime]
    Return True
  Else
    modLog.Event(APP_ERROR, "Time file not found")
  Endif
 
Catch
  modLog.Event(APP_ERROR, Error.Where & ": " & Error.Text)
End


This needs to be tidied up and possibly tuned (e.g. the Wait time) but its basically working reliably each time the bird box system is triggered and the Raspberry Pi boots.

Daylight Saving Edit!


...all was well until the clocks went forward 1 hour for daylight saving. During the winter months here in England, UTC is Greenwich Mean Time (GMT), so all references to time on my Raspberry Pi were correct.

But now we are on British Summer Time (GMT + 1hr) I find the file manager shows that file date/times (Modified) are 1 hour ahead i.e. BST + 1hr (or CET).
Could this be part of an EU conspiracy, that my Pi is using Central European Time?  (...better tell Nigel).
Anyway, this seems to be the only problem, and its not really an issue for me, as all the date/times I create, display and add to file names seem to be correct.
I had a quick look for a solution, but I can't see a way of turning  daylight saving off in Debian/Raspbian.


Refs:-
Ubuntu NFS HowTo
Command Scheduling with Cron
Keeping time without the internet



No comments:

Post a Comment