Category Archives: Project diary

Blog about small electronic or digital projects that I am undertaking

Astronomical clocks

On Monday 15th July, I went ringing at Ottery St Mary in Devon. They are a lovely 18½ cwt eight cast by Taylor’s in 1949.  Glancing around the tower (a ground floor ring with a long draught) I saw what looked like a birdcage clock mechanism in a gallery some height above the floor.

Fifteenth century clock mechanism
Fifteenth century clock mechanism

The ringers pointed out that I had missed the most important part – a fantastic astronomical clock dial, which is visible from the crossing. (Shown at the top of this post)

I was told by the ringers that the clock mechanism was found in parts by a horologist in 1907 who put it all back together ‘with the bits he could find’. You can see from the photo that much of the gearing is very badly worn, although this is hardly unexpected in a 600-year-old mechanism that has been running 24 hours a day.  The clock has ticked  about 19 billion seconds! The ‘anchor’-style escapement looks newish to me and is probably part of the 1907 renovation. The angel on top of the dial case is not an original part of the clock – it was taken from the pulpit canopy when that was removed some long time in the past.

Sadly, only the ‘going’ train is working and that is now electrically-wound, since the church could not find anyone who was prepared to wind it daily. The clock is thought to date from about 1400, but it has a pendulum escapement, which would have been added later, since these were not invented until the mid-1600’s.  Although called an astronomical clock, this one shows the time on a 24-hour dial, and the ‘age’ of the moon in days.  The moon is indicated by a sphere which is set into the dial plate, and is painted half white and half black. It turns on a radial shaft to show the phase of the moon.   However, to me the most interesting thing is that the gearing for the dials is all within the dial case – the clock mechanism simply turns a drive shaft at some steady rate – I didn’t have time to study it closely.

The dial mechanism
The dial mechanism

The ringer who showed it to me explained that unfortunately the moon-age pointer and the sun-time pointer are simply on opposite ends of the same rod, so in fact the moon-age pointer is incorrect – it only shows the clock time.  He doesn’t know why it’s like that, but I suspect the gearing for the 29.5 day moon rotation has been lost. Or perhaps it was disconnected because it added too much friction for the going-train to cope. I wasn’t able to look at this closely owing to it being quite dark and the fact that I needed to return to base.  Sadly, the clock was not fully working, showing neither the correct time nor the correct moon phase (just past new moon) as some component had been removed for overhaul by the current horologist.

This clock is quite simple by the standards of other astronomical clocks, but it is undoubtedly one of the oldest surviving examples of a clock with a dial.  The clock at Salisbury Cathedral, for example, does not have a dial, but sounds the hours on a bell – the word ‘clock’ being, of course, derived from the French ‘cloche’, meaning a bell.

Nevertheless, it involves some very intricate precision work.  It is made entirely from wrought iron, but how did those early blacksmiths form the circular wheels and cut the teeth?

Of course, the original verge-and-foliot escapements were not very accurate, as the swing of the verge depended on the amount of force applied, which would vary due to changes of stiffness in the gear trains – often gaining or losing half an hour a day.  But better than relying on the sun in such a cloudy country as England.

By this token, I can call my moon clock an astronomical clock, but I think I’d need to design a fancy dial first!

 

 

Azimuth

Another good word – it means the compass direction of the object.  The moon is not always easy to see especially in daytime.  Since I have a spare shaft on the phase dial, I thought it might be nice to show this. Speaking approximately, the azimuth goes through 360 degrees each ‘day’ as the moon orbits: this needs 60 pulses a day. However the phase dial needs one pulse every two minutes, which is 720 pulses a day.  How to deal with this?  It seems that the best idea will be to track the azimuth when the moon is ‘up’ and to track the phase when it is down.  This will mean that the phase will get somewhat behind whilst the moon is up, but will catch up again as soon as it sets.  The rate of change is so slow that I don’t think this will be evident. (The current phase is ‘first quarter’ tonight, so this is shown correctly.) Of course, the azimuth indication will only be correct when the moon is up, but that will be when the moon lamp is lit.

How do you calculate the azimuth? PyEphem has a series of functions that do this and I have put these into a simple function:

# calculate the moon azimuth in degrees
def getAzimuth():
      moon=ephem.Moon()
      london.date=ephem.now()
      moon.compute(london)
      # convert azimuth from radians to degrees
      azimuth=57.2958*moon.az
      return azimuth

How does this function work?

moon defines the Moon object in terms of the ephem library
london defines the location of the observer – which has to be told the time of the observation using the method ephem.now().  (The position of London has been defined in the main program.)
We then ask ephem to compute the parameters of the moon for the stated observer.  This is all described in the PyEphem documents which need a bit of puzzling out.

Then moon.az extracts the azimuth from the object’s properties.  This is in radians, although confusingly, if you print(moon.az), it shows degrees, minutes and seconds. To get the result in degrees, multiply radians by 57.2958 (≅360/2π).  We could have worked in radians, but given that we are showing the results on a clock dial, degrees seem more intuitive. [There are, of course, good mathematical reasons for doing angular computations in radians.]

An extra consideration is the need to be able to pulse the azimuth hand manually. I have bodged in a way to do this. The image shows the  azimuth hand, but it has got a little bit behind as it should be showing about ESE. The movements occasionally miss a ‘tick’ – maybe only one in a thousand – and I think that I might see whether the 5v drive rail would give it a bit more of a kick [see below]. I could maybe reduce the pulse length a little, which would ensure only a modest increase in energy input to the motor.

I will let this run for a few days and if it seems to work, then maybe I will start explaining the algorithms I’ve used. Some of the maths might be of interest.  The coding isn’t a model of good practice but it does use many features of the Raspberry Pi and will hopefully provide some examples of how to use it.  I’ve never believed that it is good to use arcane coding tricks, because when working in a team it is important for the intention to be clear, otherwise it becomes impossible to maintain, extend and re-use code.

Driving from 5v rail

I decided to try this – all I had to do was to move the jumper from PI GPIO Pin1 to Pin2.  The moon LED was brighter, but it did nothing to increase the reliability of stepping the Time motor.  Looking at the circuit diagram (below) you see two pairs of diodes in series, across the motor coil.  These are essential to act as snubbers to the back emf generated at the end of each pulse.  I have replaced each of the diode pairs with a single LED.  These LEDs have a forward voltage of about 2V, but I calculated that the voltage across the coil would be 1.5 v when energised.  This is about the same as would be supplied in a quartz clock circuit, but below the 2v needed to light the LED, so the energy will go to the coil.  But once the forward voltage reaches about 2V, this will light the LEDs rather than increase the drive voltage to the motor.

A 5 v supply would increase the voltage across the coil to 2.3 v, which might be enough to give the motor more of a kick, but instead it will cause the LEDs to conduct.

The clock loses about 8 pulses in 3600 pulses (needed when the set time advances by two hours).  So it is losing about one pulse in 450.  It is possible that this occurs at a particular point on the dial.  Probably, I will just have to increase the pulse length a little more. Since it does not often need to advance more than two hours, a slight increase in setting time will not be important. (In fact, it tends to advance at unsocial times, so I hardly ever see it happen.)

Full Moon

The first Full Moon for the clock!

And we have had wonderful clear skies (and incredibly hot weather) for the past few days, so it has been easy to observe. Sunset was at 21:21 on 27th June, the evening of the full moon, and moonrise was at 20:37 with moon set at 5:07.  Full moon actually occurred at 05:53 on 28th June, so it occurred after it had set in London, although would have been visible from areas further west. Sunrise was at 04:45 on that day.   But I’m glad to say that I was sound asleep at that time!

The earlier information that I’d read – that on the day of the full moon, moonrise is at sunset and moonset is at sunrise is only approximately correct, although the discrepancy depends on your location on the planet.  I was able to see the (almost) full moon rise after the sun had set. I’m in a built-up area, so I can’t see the moon rise until some time later, which is very late at this time of year.

Moon clock at 10 am on 28th June, 5 hours after full moon
Moon clock at 10 am on 28th June, 5 hours after full moon

I’m glad to say that PyEphem correctly predicts these events, however, and the clock is showing both the time and the phase correctly, within the accuracy that can be achieved. Note that in the above photo of the clock, since the current time is 5 hours after moonset, it has already updated to the next times, namely moonrise at 21:28 and moonset at 05:56.  The phase is just a tiny bit past the central ‘full’ position.

The next job: I have bought the ‘seconds’ hand to fit the phase dial and I have worked out how to make it show the azimuth (horizontal compass direction) of the moon.  It is necessary to make some approximations in order for the dial to show phase and azimuth and I will discuss these in my next post.

Raspberry Pi Enclosures

A change of subject today.  Raspberry Pi enclosures.  There are an awful lot of them about.  This is not a scientific review but describes my experience with a few that I have tried out.

Raspberry Pi B
Raspberry Pi B

The first one was the Pimoroni, made of  multi-layered, multi-coloured Perspex sections, held together with long nylon bolts at the four corners.  It was fine and I used it in my Barometer.  The only trouble is that you have to undo the bolts to gain access, which can be inconvenient, but they give you a groovy little ‘spanner’ to assist, and if you connect a ribbon cable, you’ll rarely need to do this.  So it’s great fun.  I fixed it to the Barometer casing by replacing the nylon bolts with brass ones, taking care to insulate the circuit board where the bolts passed through. It has plenty of ventilation.  Perhaps not the most convenient project enclosure and not the cheapest at around £11 +VAT.

Pink and white enclosure
Pink and white enclosure

The second one was the ‘Official Raspberry Pi’ raspberry pink and white groovy-shaped box. Around £5.50 +VAT from RS Components. It is easy to clip and unclip the lid, the sides and the inner cover, and to get access to the GPIO pins. It has soft plastic pads on the base, but with the Pi being so small and light, it won’t stay on your desk if there is any tension on any of the connecting leads.  There are no fixing holes. You’d need to take the lid off if ventilation was an issue.  A very pretty box but very much at the mercy of your connecting leads.

Raspberry box with covers removed
Raspberry box with covers removed
Clear plastic box
Clear plastic box

The third one was the DesignSpark  clear transparent case (available in other colours) also around £5.50+VAT from RS.  This has ventilation holes in the base and slot all round the sides of the case.  However, the lid is only held on by the friction fit of four small lugs.  Once you have taken the lid off a few times, you will need sticky tape or some other way to keep it on.  It is very easy to assemble and has fixing holes in the base. Also, you can easily see the indicator LEDs and the GPIO connections.  This has become my favourite for project work.

Clear box with Pi board fitted
Clear box with Pi board fitted

The fourth is an entirely different proposition. It is the DesignSpark ‘Quattro’ case which holds the Pi and a thin 2.5-inch HDD (or SDD) in a very presentable square black box. (Other colours are available.) This is intended for use as a media server and is a very neat solution, for only £8.99 +VAT from RS Components, which is inexpensive when you look at the cost of ordinary project boxes.

Prior to this, I’d intended to put the Pi in a sandwich box along with a USB hard disk, but I was put off by the work involved in making access holes for the HDMI and power leads and fixing everything firmly.  My other half complained that it looked too complicated and untidy to have on the TV stand, and I’d gone back to saving home videos onto USB flash drives.  They supply it with a ‘VESA’ mount which would allow you to fix it onto the back of a monitor to provide a nice all-in-one display unit.

DesignSpark Quattro Case
DesignSpark Quattro Case

This box makes it all much neater. You put the Pi circuit board in first, and then a bare-bones 2.5 inch HDD. The base then clips on firmly.  You can access the Pi’s GPIO pins and the camera and display connectors from above.  There are no apertures in the box specifically for these connectors, but they supply spacers which will create a slot between the lid and the sides if you need access or to add a circuit board or HAT.  Also, there is a small round aperture at the ‘front’ of the box and a slot behind it to hold the Pi’s camera, so you could use this as a webcam or even a ‘hidden’ camera.  However, next to the camera aperture there are two light guides for the Pi’s activity LEDs, so the Pi’s presence may not be secret.

The Quattro case with Pi board and Seagate Hard disk
The Quattro case with Pi board and Seagate Hard disk

The camera aperture is in a slot-in cover which can be removed to reach the SD card. The whole unit can be secured by screws from underneath (not supplied) to deter prying fingers or accidental disintegration.

Seagate Barracuda 1 TB disk
Seagate Barracuda 1 TB disk with USB connecting cable

I bought a Seagate Barracuda 1 TB 2.5 inch SATA HDD for storing the media. This disk requires a power supply of 1A at 5V which is supplied over the USB connector. I could have gone for a larger capacity, but this will be fine for my purposes.

The box does not have any means of connecting the HDD to the Pi.  I have bought a StarTech USB3S2AT3CB USB to SATA connecting cable for this.  Although this cable is very short, you have to coil it rather annoyingly round the outside of the box.

Logitech keyboard
Logitech keyboard

Of course, a media server needs some sort of user interface.  I bought a Logitec K400+ TV keyboard for this purpose.  It uses ordinary wireless communication, not Bluetooth.  I’ve had trouble with Bluetooth keyboards.  They seem to go to sleep after a period of inactivity, and when you press a key to pause the film, etc, there is no response.  If and when the keyboard and Pi start talking again, you have tapped so many keys so many times that either the program has crashed or done something equally annoying. I’ve also had trouble with pairing Bluetooth devices – some won’t pair at all. The wireless keyboard doesn’t seem to suffer from this, and it includes a trackpad for scrolling and selecting.

Installing the HDD
The ‘barebones’ Seagate HDD [type ST1000LM048] is not formatted when you get it and the Pi just did not find it. Rather than struggle with sorting it out on the Pi,  I plugged it into a USB3 port on my PC which simply showed a device called ASMT 2115 SCSI Disk Device.  The Seagate disk manager software refused to do anything because it could not detect a Seagate disk.

So I went to the Windows Run command and started the disk manager using the command run diskmgmt.msc.  This showed the Seagate drive but said it was uninitialized. Being careful not to select the wrong drive by mistake, I selected that drive and clicked initialize.  I assigned an arbitrary drive letter and gave it a volume name, SeagPiMedia.  Then I formatted it with NTFS.  This file system is readable on both the PC and the Pi, which means I can put files onto the disk using either machine.

After putting some video files on it, I plugged it back into the Pi.  It was then visible in /media/pi/SeagPiMedia. Brilliant!  I put some video files on it and they play beautifully using OMXPlayer and Kodi.  The keyboard works very well too.  Maybe we can view our my old videos again.

A new moon

I’ve taken photos at intervals to see how well the clock is working.  Right at the beginning, I mentioned that the moon rise and set times coincide with sunrise and sunset at new moon, and with sunset and sunrise at full moon.  It is interesting to see that happening on the moon clock.

On 3rd June 2018, moonrise was at 00:11 and moonset at 08.59.
The rise time is accurate, but the set time is an hour fast, for the reasons discussed here many times.

The clock at 05:41 on 2018/06/03
The clock at 05:41 on 2018/06/03

On 4th June 2018, moonrise was at 00:45 and moonset was at 10:00. The rise time is slightly slow and the present time is very slow, suggesting we are losing pulses.

The clock at 12:47 on 2018/06/04
The clock at 12:47 on 2018/06/04

On 5th June, moonrise was at 1:15 and moonset was at 11:04.
The rise time is shown correctly, but the set time is an hour early.

11.54 on 5th June 2018
11.54 on 5th June 2018

On 6th June, moonrise was at 1:40 and moonset was at 12:09
The clock shows all the times quite closely.

12.51 on 6th June 2018
12.51 on 6th June 2018

On 7th June, moonrise was at 02:03 and moonset was at 13:17
The clock shows the rise time quite closely, but is early on the set time.

11.43 on 7th June 2018
11.43 on 7th June 2018

On 8th June, moonrise was at 2:25 and moonset was at 14.26
(no photo of this)

On 9th June, moonrise was at 02:47 and moonset at 15:39
The clock shows this well.

20:55 on 9th June 2018
20:55 on 9th June 2018

On 10th June, moonrise was at 3:10 and moonset at 16:54
The clock is slow on the rise and fast on the set, but within an hour. Note that the moon is up for about 13 hours.

17.55 on 10th June 2018
17.55 on 10th June 2018

On 11th June, moonrise was at 03:36 and moonset at 18:11.
The photo was taken at 18:33 on 10th, just after the clock has set the new rise and set time, which will be on 11th. Note that the rise time has gone rather too far ahead. However, I had been making adjustments to the algorithm.  So after taking this photo, I reversed the m hand to show the correct rise time.

18.33 on 10th June 2018
18.33 on 10th June 2018

On 12 June, moonrise was at 04:07 and moonset at 19:30
This photo was taken at 10:46 on 12 June, when the moon is still up – it is up for 15 h and 23 minutes.  Note that the moon is illuminated. The rise time is shown correctly but the set time is actually shown an hour early – as discussed previously, it could only show a set time after 19:00 if the rise time is after noon.

10.46 on 12th June 2018
10.46 on 12th June 2018

The new moon
On 13 June, moonrise was at 4:46 and moonset at 21:56.
The moon will be up for 17h and 10 minutes. The new moon occurs at 20:47, an hour before moonset. Sunrise was at 04:43 and sunset at 21:18.

13th June 2018 at 12:09
13th June 2018 at 12:09

Below is the last photo in the present series. I reset the hands and phase dial to the correct positions at about 18:30 last night, just before new moon occurred. The actual rise and set times today are 5:33 and 21:57.

11.45 on 14th June 2018
11.45 on 14th June 2018

The clock is showing the ‘closest’ times of 5:23 and 20:26 and current time 11:36.  It should pulse on to 12:00 in 15 minutes.

Verdict
Overall, I think the algorithms are working correctly.  The clock readings, including the moonphase setting, sometimes got rather adrift,  but I have updated the algorithms so many times without resetting the hands that I can’t attribute this to any specific problem.  I will wait until the set time is after 00:00 and then play around with various pulse durations, as this will not need the clock to pulse right round each time.   Without a ‘scope, I can’t test the pulses and they happen so infrequently that I can rarely observe the hands moving.  It is possible that there is extra inertia with the hands fitted and the clock hanging vertically, so I might need to lengthen the pulses some more. It is even possible that they sometimes touch the glass dome. Of course I could increase the drive voltage, but this would involve changes to the circuits that I’d rather not make.

Ironically, I don’t think I’ve seen the moon during this testing! In the early part of the month, it was not rising until after midnight, and in the middle of the month, it has been setting before dark.  Whilst the moon is visible in daylight on clear days, the weather has been generally cloudy – today it is heavily overcast.

Detailing the algorithm
The turn-over points (when the dials go past zero and start again) are always a potential problem and it’s not easy to test these in a real-time situation. The phase turnover at new moon worked as intended and now I need to see if the set-time turnover will work, when the set-time goes from before to after midnight.  If that works, then it will be time for me to start describing the algorithms. They’re not particularly complex, but some people might be interested in the techniques I’ve used.  There are about 400 lines, including comments, and about 10 subroutines [functions in Python terminology].  I make a lot of use of function libraries.  I make use of signal alarm and interrupt programming, and drive the input and output GPIO pins.  The program runs ‘headless’ and without any user input.  So I think there are some useful examples and applied experience which others may like. [I’m aware that yet others will NOT like the way I’ve done things, but even they will get some pleasure by feeling superior!]

Reading the clock

I described in an earlier post Setting the hands how I get each hand on the moon clock to show a different time.  But I need to be able to do the reverse – if I know how many pulses the clock has been given, what time does each hand show?  This is not as difficult as you’d think.

The s hand goes round once every 60 pulses, so its position doesn’t depend on the whole number of 60 pulses, since each whole number of 60 pulses always gets it back to the top position (00:00).  Its position depends on the number of pulses between 0 and 60.  This is simply:
frac(tcount/60) where frac() is a function that you need to create, to give the fractional part of the division. Oddly, Python doesn’t have that as a built-in function*, so I wrote my own:

def frac(a):
    c=a-int(a) # int is a built-in function giving the integer part
    return c

It seems a bit inelegant, but does work for positive and negative numbers.*

Since the s hand goes round once every 24 hours, the time shown is given by frac(tcount/60)*24, where tcount is the total number of pulses given to the clock motor, assuming that it originally started at 00:00.  This will give the time in hours and fractions of an hour, which can be converted to minutes if necessary.

The same logic applies to the m hand, which needs 3600 pulses to go round once:
frac(tcount/3600)*24

For the h hand, it is:
frac(tcount/43200)*24

Note that tcount is the same number in each case, but by dividing by the different number of pulses we can get the position of each hand!

The phase motor can be measured in the same way.  The phase dial is on the h hand, but it only rotates by half a turn to go from one new moon to the next, so the phase shown after pcount pulses is given by:
fract(pcount/21600)
This does not need to be multiplied by any factor, as ephem gives the phase as a number from 0 to 1, with 0.5 being full moon.

Example

Currently my clock is reading 32911 pulses. What time should it be showing?

The s hand (current time) = frac(32911/60)*24 = 12.4 hours (12:24 h:m)

The m hand (rise time) = frac(32911/3600)*24= 3.4 hours (3:24 h:m)

The h hand (set time) =frac(32911/42300)*24 = 18.28 hours (18:07 h:m)

The actual rise and set times are 3:36 and 18:24. The present time was right but is now running a little slow as the clock has not yet pulsed again.  However, I think the clock motor is sometimes missing pulses, so I will increase the pulse length a little more.

*If your number are always positive, then %1 will give you the fractional part, eg:

print(3.141592653%1) yields:
0.141592653  (the fractional part of pi, what else?)

However, print(-3.141592653%1) yields:
0.858407347 which is probably unexpected unless you’re a mathematician; whilst

print(-3.141592653%-1) yields:
-0.141592653

The moral here is: be very careful with the % operator if you are dealing with negative numbers.

On a final note, Python does have a decent math library which includes several varieties of modulus, trig, hyperbolic, and stats functions and a few natural constants. There is also a separate complex number library. These are said to be ‘thin wrappers of the C libraries’. The justification is that most users don’t want to have to learn the mathematics of complex numbers, but us electrical engineers couldn’t avoid that pleasure.

Daylight saving but lots of work making

There is one area that that has given me much difficulty, namely the subject of British Summer Time, or more broadly, Daylight Saving Time, DST.  PyEphem sensibly uses UTC (universal time) for all its computations, because this is based on a fixed reference point, namely the Greenwich Meridian (an imaginary line running from the north pole to the south pole, through the old Royal Observatory at Greenwich in London). Although this is rather convenient if you live in Epsom, just a few minutes west of Greenwich, or indeed anywhere in the UK, people have complicated matters by adding an hour in the summer, called in the UK ‘British Summer Time’ and more universally, ‘Daylight Saving Time’.  Other countries are in ‘Time Zones’ which are a fixed number of hours ahead of, or behind, ‘Universal Time’

The PyEphem authors realise that most people other than astronomers or mariners want things in their local clock time, and they provide a function to make the conversion.  Unfortunately this changes the representation of time from  PyEphem’s  mathematically convenient ‘fraction of a day’ to Python’s time ‘tuple’, whilst making the adjustments for local Time Zone and DST.  But the moon clock needs the fractions of an hour and I don’t want the hassle of converting the tuple back to fractions of an hour.

So I have spent many hours finding out how to convert the rise and set times to local time then testing these to see if they fall into DST.  Then I can simply add the DST offset to PyEphem as needed.  It’s probably quite inefficient but there is a very low overall demand on resources, so this is unimportant.

One reason I need to be careful it that because DST kicks in at 2 or 3 am (depending on whether DST is starting or ending) it is likely that, say, the rise time could be in DST and the set time could be in non-DST or the other way round. There isn’t much of a problem when you add an hour – the clock can move forward. But if you subtract an hour, the clock can’t go backward.    There could be a problem if the new set time was before the present set time.  The new set time can be as little as 50 minutes ahead of the previous set time, so losing DST would make the set time earlier than on the previous day.  At present, my algorithm would wind the clock right round until it got back to just before its previous position, around 43200 pulses! It may be better not to advance the clock on the day that DST goes back, if this results in a negative clock movement. The ‘current time’ will automatically stop advancing for an hour anyway.

How to find out if a time has DST added to it.
Python has many functions for manipulating time, but I found the explanations were baffling.  Firstly, Python uses a set of functions called ‘datetime’ – to specify a time clearly, you need the date as well as the hour. Very often, that’s enough, but when operating around the globe, it won’t be, say, 8 a.m. at all places at the same time.  If you arrange to phone someone in the United States at 5 p.m. you need to say ‘your time ‘, or ‘my time’,  remembering that the States have different times zones across the country.  Python deals with this by allowing datetimes to be ‘aware’.  This means that they include the day, the time and the time zone. But datetimes do not have to be ‘aware’, they can be ‘naïve’ – they don’t know which time zone they are in – and indeed this seems to be the usual position. Certainly, although PyEphem knows where the observer is located (you have to tell it, of course) when it converts a datetime to localtime, it leaves it ‘naïve’.

This is a bit silly, but with some jiggery-pokery you can fix the problem.  Firstly, you need a module called pytz, which adds and manipulates time zone attributes.  On the Pi you have to install it using the command-line command:

sudo pip3 install pytz

Having got your datetime as an ephem floating point number – the number of days and fractions since noon * on the last day of 1899 – the following function will convert it  to a Python ‘tuple’. (Assigned to the variable LeventTime in this example.)

LeventTime=ephem. localtime(EventTime)

Unfortunately, this is ‘naïve’ – it does not know its time zone, so you have to add it, using the statement:

LeventTime=pytz.timezone(‘Europe/London’).localize(LeventTime)

As far as I understand it, this uses a function localize in the pytz module to add the timezone property ‘Europe/London’ to the datetime tuple, which now becomes something like:

datetime.datetime(2018, 6, 10, 3, 10, 13, 6, tzinfo=<DstTzInfo ‘Europe/London’ BST+1:00:00 DST>)

You can see that LeventTime now contains the name of the timezone, its DST property and its offset from UTC (which is one hour).

So far, so good, but I want to extract these properties from the datetime.  The simplest is just to find out if DST is operative.  The dst method does this:

DSTincluded= LeventTime.dst()

DSTincluded now has the value: datetime.timedelta(0, 3600)

I assume this shows both the UTC offset (0) and the DST offset (3600 seconds), but isn’t user-friendly.  If you convert it to a Boolean value, eg

isDST=bool(DSTincluded)

isDST has the value True
which is just what we need.

If you need the total offset from UTC (which might be useful in some time zones) this is also obtainable, as follows:

OffSet=LeventTime.utcoffset().total_seconds()

This gives OffSet = 3600

I tested this further by speculatively setting the timezone to ‘Australia/Sydney’, and got the result that DST was false.  This isn’t absolute proof, I know.

*Measuring time
Astronomers and mariners used the highest point of the sun as their time reference point – i.e. noon.  For astronomers, the day started at noon.  Stars can be used as a time reference, called sidereal time, but the orbiting of the earth creates differences between that and solar time.    For mariners, the time at which the sun reached its highest point, measured on their chronometers set to the time at Greenwich,  told them their longitude.

There are many complexities which would take pages to describe. Not least is the fact that the tilt of the earth’s axis of rotation relative to the plane of its orbit around the sun, and the eccentricity of the earth’s orbit, means that through the year the length of a day (the time between noon on successive days) varies by about 15 minutes and is only 24 hours on average – hence the term ‘mean time’.

Keeping time

How well is the clock keeping and portraying the present, rise and set times?  The photo below shows the reading at 5:41 on 3rd June.  The moon rise and set times were 0:11 and 8:59.  You will see that the rise time on the red (m – i.e. minute) hand is shown accurately, but the set time on the black h hand is shown as 8 am rather than 9 am.

Why does this happen?
The problem is that  the h hand can’t point to 9 am unless the m hand (the red one) is at the bottom. But then the m hand would be showing a rise time of 12 noon, which is twelve hours out.  So decided to show the rise time accurately, and compromise on showing the set time to the nearest hour.

The current time shown on the thin blue ‘s’ hand is ‘fast’ by about 30 minutes. This hand can only move in steps of 24 minutes, but I manually stepped the clock on too far when I reset the clock.  You can’t step it backwards. Notice that the moon is illuminated.

The clock at 05:41 on 2018/06/03
The clock at 05:41 on 2018/06/03

At 8:59 on 3rd June, the photo below shows that the set time of 08:00 has passed, but the moon is still illuminated.  In fact the moon set time was 8:59 and the illumination was about to go off.

The clock at 8:59 on 2018/6/03
The clock at 8:59 on 2018/6/03

On 4th June, the rise time was 00:45 and the set time was 10:00.  The rise time was shown correctly earlier in the day, but the red hand has moved on since then. the h hand correctly shows the set time as 10.00.

The clock at 12:47 on 2018/06/04
The clock at 12:47 on 2018/06/04

Notice that the moon is not illuminated – the s hand should not be between the rise and set time, but the present time shown on this hand is way too slow, showing 8:45 instead of 12:47.  I have now identified a problem when stepping the clock, which I discuss next.

Is the clock stepping on to the new rise and set times correctly? The rise and set of the moon is caused by the daily rotation of the earth, but because the moon moves round the earth in the same direction as the rotation, the rise and set times are around an hour later each day.  [The earth has to rotate just a bit further to catch up with the moon.] The exact amount varies from day to day because the orbit of the moon is slightly tilted relative to the axis of the earth’s spin. Investigation shows that the clock correctly calculates the number of pulses required  to move the clock to the new times.

The rise and set times are provided by the ephem library, so I don’t have to do anything clever there.  Now, the h hand, which shows the set, can only show the set time to within about an hour.  At present, with the rise time being around midnight, the h hand can only be at 8 am or 10 am.  It can’t be at 7 am, because the m hand would have to be at the bottom, around 12 noon.  When moving to the new rise and set times, the clock either needs to move on about 120 pulses or about 3600 pulses of the s hand, depending on whether the h hand needs to move to the next nearest 2-hour time, or the m hand needs to move on about one hour, whilst leaving the s hand back at its original position (since current time hasn’t changed).

3600 pulses can take several minutes, but since the alarm ‘rings’ every minute, the pulsation will be interrupted by the alarm.  I have programmed the interrupt handler to register but otherwise ignore the alarm when the clock is pulsing. However, the interrupt is still disrupting the pulsing algorithm.  Sometimes this is seen as a momentary hesitation in the rotation.  But then I noticed that the clock momentarily reversed its rotation for maybe five pulses on two occasions!!  I don’t really know what happens to the output pins if they are interrupted whilst pulsing, but I’m guessing that the pulse length is incorrect.  If very short, the clock motor could effectively get two pulses of the same polarity, which could cause the reversal. Whatever happens, it’s clearly a bad thing. Losing 20 pulses will put the clock slow by 8 hours!

Preventing interruptions
After thinking about how I could prevent the alarm from being triggered during pulsing, I realised that my whole approach was unnecessarily complicated. I was trying to count interrupts generated once a minute by the alarm and when enough had been gathered (24 in the case of the ‘current time’ hand), I stepped the clock.  The problem is that this needs you to keep an accurate count of the interrupts, whatever else is going, such as the clock stepping to new times, the clock resetting, manual adjustment being pressed, and so on.  And this was being done for both the main clock and the phase dial. This got ever more complex and could easily get out of sync.   And totally unnecessary.

The new approach
All I need to do is to compare the time shown on the clock with the current time, and to pulse the clock when necessary.  The time shown on the clock is given by a counter, tcount, which just shows the number of pulses that have been made.  The same is done for the phase dial.  When the difference between the current time and the clock time reaches the trigger value (24 minutes in the case of the clock, and about 2 minutes in the case of the phase dial) then pulse the appropriate motor.

All I need to do is to trigger the alarm to wake the clock once a minute in order to test whether either of the motors needed to be pulsed.  Another alarm call will not be set until the work has been complete, included advancing the clock to new rise and set times when needed, so an interrupt cannot occur during pulsing.  I suppose someone could push the manual pulse button during that time, but they deserve any havoc that may cause.

A good pulse

There is an important consideration in getting the hands to point as closely as possible to the correct present, rise and set times.

Because the hands are geared together, you can’t get each hand to point independently to any desired time independently of what the others are showing, so all hands can’t show the exact time of each event. I decided that the present time should be shown as exactly as possible, within the constraints that 60 pulses of the ‘seconds’ hand have to cover 24 hours, so each pulse covers 24 minutes.

Calculating the number of steps/pulses required

For brevity, and to avoid confusion with actual units of time, I will refer to the hands as follows:

s = ‘seconds hand’ – shows present time
m = ‘minute hand’ – shows moon rise time
h = ‘hour hand’ – shows moon set time.

So the s hand needs 60 pulses to go right round the clock. 2.5 pulses cover 1 hour (bearing in mind that it is a 24-hour dial).

Some arithmetic shows the m hand needs 60×60 = 3600 pulses to go right round the clock, so 150 pulses cover 1 hour.

Likewise,  it takes  12×3600 = 43200 pulses to rotate the h hand right round the clock. This means that it takes 1800 pulses for the h hand  to move by 1 hour on the dial.

In order to show the present, rise and set times, I need to get these times in hours and decimal fraction, then multiply by the above numbers.

Rounding
The hands move in a series of finite steps. Considering the s hand, we are trying to show a 24-hour time on a dial that only has 60 steps for a complete day.  This means each step is 24 minutes.  If the clock is exact at the beginning of 24 minute period, it is actually 24 minutes slow just before the next step.  This is noticeable. We can make the clock precision of the clock better if we step it half-way through the 24-minute period.  Then it will be 12 minutes fast just after it has stepped and 12 minutes slow just before it steps again.  This isn’t too bad and gives the clock a better semblance of precision (the dial has markers at 15 minute intervals).  How can this be done?  You just add half the stepping interval to the time you are aiming for.  In the case of the spos calculation, add 0.5 to the number of steps. Thus, if we are half way through a stepping interval, spos would be, say, 20.5.  Adding 0.5 increases this to 21.0, and thus an extra step is added.  Otherwise, the result would have been truncated and that extra step would not be added until spos reached 21.0, but which time the clock is 24 minutes slow.

This means that the spos calculation becomes:
spos= curhour*2.5+0.5 

An equivalent amount is added to the calculation of mpos and hpos, 30 pulses and 1800 pulses respectively, and will not be detailed further at this point.

Combining into a single train of pulses

We can only pulse the motor by a single train of pulses, which moves all the hands at the same time. Yet we need each hand to be pointing as closely as possible to the correct time. How can this be done?  If you added all the pulses for all the hands, that would be far too many – the h and m hands would overshoot, although you could get the exact time on the s hand.

For example, suppose the
present time = 8:42 ; rise time =23:30; set time= 8:03 (hh:mm)
In decimal hours these become:
present time = 8.70; rise time= 23.50; set time= 8.05 (hrs)
multiplying by the hour-to-pulses factors, we have
(1)  s = 8.7*2.5=21.75
(2)  m=23.50*150=3525
(3)  h=8.05*1800 =14490

Each of the calculations is correct if it takes place on its own, and assumes that each hand starts from 00:00. However,  once we start to pulse the clock, all the hands move away from 00:00, so how do we deal with this?

My approach is to first to calculate spos, the pulses needed to position the s hand in accordance with equation (1). Next, calculate mpos, the pulses needed to position the m hand, in accordance with equation (2). Since the m hand has already had spos pulses, subtract this from mpos so that the m hand does not get too many pulses and thus overshoot.  However, we must ensure that when applying the mpos number of pulses, we don’t cause the s hand to end up in the wrong place.  The way to do this is to ensure that the number of pulses given by mpos is equal to an exact number of rotations of the s hand.

The term
mpos=int(mpos/60)*60
will do this – mpos/60 is the number of rotations of the s hand when mpos pulses are applied. int() removes the fractional part and multiplying by 60 leaves the  number of pulses need for a whole number of rotations of the s hand.*

This will mean that the m hand won’t be in quite the right place, because it has lost some pulses in the rounding process.  As a result, it will always show an earlier rise time than the correct one. It could be out by 60 pulses (one rotation of the s hand) or  24 minutes .   We can improve on this by adding 30 pulses (half a rotation of the s hand) before doing the rounding, so it will round towards the nearest multiple of 24 minutes.

The same logic is applied to the calculation of the hpos pulses needed for the h hand.

However, there is an additional consideration: when hpos is just after midnight, it value will be close to zero, whilst mpos and spos will be substantial positive numbers.  This opens the possibility for hpos to become negative (although the nature of lunar orbits probably means this can never occur in reality). The expression hpos=max(0,hpos) prevents hpos from going negative and is just a safety precaution.

This procedure seems to work well in tests.

Footnote

*In an earlier iteration of calcpulse, I used the  // operator here.  this acts as integer division for positive results as required.   However, for negative values, it rounds down (‘floor’ division) which is contrary to what we want.  For example, if mpos became a small value negative value close to zero, the // operator would give a value of -1, whereas we want 0 in that situation.

 

 

Mounting up

I found a place  in the hallway for the clock.  It is near to a power socket, which is important owing to the short power lead that I’m using.  It connects fine to my Wi-Fi and I can connect from my PC via its Remote Desktop and the xrdp interface I’ve installed on the Pi. (I have described how to do this in an earlier post Running Headless.)  You can see that I’m going to have to tidy up the power lead – but I will need to make it longer.

I’m running the clock from the IDLE interface as this means that I get the debug messages on the PC.  If you run a self-booting version, you can send the messages to a file, but they are buffered, so even if the Pi doesn’t crash, the messages might not yet have been output to file.

Infinite Recursion
So having pressed Run, did it work? Astonishingly, for about ten hours it worked as expected – the rise, set and present times were correctly shown and the moon lit up when it had risen.  But then it crashed with a repeated amusing – but bemusing – message that the maximum recursion depth had been reach whilst pickling an object!

A mysterious Gherkin there.  There were references to various lines within the program that seemed to relate to calls to pause signals within the Alarm Handler.  (You can read about signals by searching this blog.)  The Alarm Handler pulses the clock at set time intervals, usually once per minute.  My mistake was to call a pause within the Alarm Handler.  This essentially means that the Alarm Handler doesn’t exit, but calls itself again every time the Alarm is triggered.  Ah! Recursion! With no end.  So after a few hundred calls, the maximum recursion depth was reached.  In fact, there was no need to pause within the Handler.  You must let the Handler terminate and you must set the pause in the main routine – which in fact I had already programmed.  I had strangled myself with an extra belt and braces!

Getting new rise and set times
With that sorted, the clock ran for another night.  But when I looked next morning, it was constantly trying to reset the clock. I saw that the moon set time was remaining earlier than the present time, which is what triggers the clock to get new rise and set times.  After much puzzlement, I realised that although I was initialising the observer’s time at the start, I had wrongly assumed that it would be automatically updated. It isn’t. So that was an easy fix.

Stepping
My other concern has been the working of the stepping/reset button.  I found that I inadvertently triggered a reset when I was just trying to get the second hand positioned.  This is a real nuisance as the hands need to step to the right place, which can need over 15,000 pulses.  I’ve decided that I will allow the clock to idle until the alarm triggers, as this will automatically call a reset, since the rise and set times are zeroed at initialisation.  In fact, it seems to have dropped about 20 pulses during this initialisation, which is very few in 15,000, so I’m not going to bother with that, but I have used the stepping button to get to the exact time.  Actually, to the nearest 24 minutes – the second hand (showing the current time) moves in steps of 24 minutes on the 24-hour dial!

The other point to note is that the desired settings were:
Rise at 20.48, set at 06.26 and present time 19:00

You can see that the clock is showing rise at 21:15 set at 7:45 with present time 19:00.

For the clock to show an exact set time (on the black hour hand) of 6.26, the minute hand has to be at about 6.00h on the dial (this would be showing 3:15 on a 12-hour clock).  But the minute hand needs to be at 20:48 (about 53 minutes on a 12-hour clock). This is about halfway round the clock from the required position, which is about 1 hour later on the 24-hour clock.  So the time on the hour hand goes from 6.26 as wanted to 7.26.,

But the minute hand has to go from the 2400 position to the 1900 position, which is nearly three-quarters around the clock, and moves the minute hand by just less than half an hour on the 24-hour clock.

So the required time of 20.48 moves on to the displayed time of 21:15. This will need a bit more tweaking, as it should be possible to get the within one hour of the real times, but the moon will light and extinguish at the correct time (within one minute).

The Reset
The next challenge will be to see if the clock resets correctly when the set time has been passed. I have to say that I have not double-double-checked the logic so there are bound to be some issue.