Category Archives: Moon Clock Project

The stages of my Moon Clock Project

Moon Clock – declared final?

I’ve just reinstalled the moon clock, after storing it away for a year during my renovations.   And it wasn’t working well.  Basically, the hands would stutter and ‘fibrillate’, meaning it just wasn’t keeping time.  I concluded that they were sticking, so got some proper watch oil [having been told by a clockmaker that bicycle oil was ruination for a clock, because it turns treacly after some time] and took the quartz movements apart.  They seemed to be quite clean, but there was no oil, perhaps the plastic components have little friction, but having got that far, I thought I would try some oil.  I made an oiler out of a piece of fairly thin garden wire, flattened at the end, and used it to carefully apply tiny drops of oil on the pivots and gears.

Testing the motors on the bench, they worked like a charm.  But when I assembled the whole thing, they would rotate beautifully but then start fibrillating and even running backwards!

I slowed the pulsing rate down but this didn’t help.  Then I realised that in a certain place, the long seconds hand touched the glass!   This caused it to spring backwards and then forwards repeatedly.  The answer was straightforward – to bend the seconds hand very slightly away from the glass, but not so far that it tangled with the other hands.  The moon phase disc also seemed to touch the edges of its housing at one point due to being very slightly eccentric.  I was able to pare away a very fine sliver from the edge.

Now, touch wood, it is keeping time beautifully. It was satisfying to watch it at moonrise this morning – the time hand clicked past the rise-time hand, the moonlight came on and the azimuth hand spun to the correct position in a fabulous little routine.  But it needs a bit more ‘soak testing’ before I’m sure.

When I have the energy, I will write this up into a complete project.  In the meantime, I have a wind-up clock to get working again.

Formatting output in Python 3

I’ve had to work hard to get ‘pretty’ output from Python: it seems more complicated than with 50-year-old Fortran IV! Fortunately, Python’s formatting procedures have advanced, no doubt trying to resolve some of the issues.  Unfortunately, there are now many ways to do things, and if you search online, each website shows yet another method.

After considerable frustration, I found that Python has a full set of consistent, flexible and simple formatting codes – not a million miles away from those in Fortran!

An example

I want to show clock times in the conventional way such as 12:32 or as 05:09. Note the need for leading zeroes. The moon clock keeps the hours and minutes of the time in separate variables, which are already converted to integers.

To convert an integer value into a string formatted as above, the statement is:
hourString = ‘{0:02}’.format(hourInteger)
If hourInteger = 4, this would produce an output string  04

The format parameter ‘{0:02}’ says ‘convert the numerical value hourInteger into a string representation within a field length of 2 and pad the field with leading zeroes.

Converting a floating point value into a string, might use
clockphaseString = ‘{0:.3f}’.format(clockphase)
This could produce an output like 0.683.  The floating point value is correctly rounded to three decimal places.

clockazString = ‘{0:.0f}’.format(clockaz)
could produce an output like 306 (note that although clockaz is a floating-point value, it is displayed as a whole number).

You can format and insert any number of values from the format list: the ‘0’ at the beginning refers to the position in the value to be inserted.  Supposing the hour is 4 am stored as an integer in variable clockhour and the minute is 9 minutes past the hour, stored in variable clockmin, the following would create the character string 04:09

clocktime= ‘{1:02}:{0:02}’.format(clockmin, clockhour}

Note how the index value (the 1 in {1:02}) is used to correctly reposition the minutes and hours.

I don’t want to put all the detail into this blog, but the system is described well in this tutorial:
How to use string formatters in Python 3

I can recommend this method of formatting as being a powerful way of formatting numbers and inserting variable values into strings.

Problems with the clock

My software upgrade to include the graphical output window went smoothly enough, but I’ve started getting trouble with the clock mechanism. The first thing I noticed was that the manual advance button wasn’t working.  Obviously, stopping and starting the clock during numerous tests meant that it was slightly behind time and needed to be advanced manually.  I knew the GPIO was working because the moon lit up and the hands were advancing.  The most likely problem was a bad connection somewhere.

I checked all the connections and although some of the screws could be slightly tightened, this didn’t really seem to be enough to cause a problem.  Anyway, this got the button working again, but now both the clock motors are losing some pulses.  I have to wonder if the connectors on the Pi’s GPIO are not making proper contact.  It’s possible that in disturbing them, they have moved slightly as they are only connected by spring force.  Maybe there is the tiniest bit of corrosion causing the problem.  Otherwise, perhaps there is a problem with a component somewhere, although that doesn’t seem so likely.  Maybe I should buy a ribbon connector that would grip tightly.

The graphical interface

I have noticed that the graphical interface causes the Pi to run hotter – I am not sure to what extent this is caused when I RDP into the desktop, but it is running at over 50 % utilisation when updating, although it does drop to 0 % when idle.  When updating, the CPU temperature rises to 66 degrees, cooling to 56 degrees during idle periods.  This cycling range of 10 degrees each minute does seem rather undesirable.  Heat cycling can cause problems with connections and components. I could increase the interrupt timing to once every two minutes, but this might result in even larger temperature excursions.

Update on the temperature issue – 24th November 2018
Task Manager showed an increasing utilisation percentage, causing the temperature rise, and in fact there seemed to be two instances of Python3 running.  I started to suspect some sort of recursion, because it was taking ever longer for each update to complete, with long waits during the redraw process.  I wondered if this was due to multiple drawing to the same window, so I decided that instead of blanking the window with a coloured rectangle, which I thought would be quick and not cause a problem if I moved it, instead I would close the window and reopen it.  In trying this out, I realised that I was creating the window in the main program, but redrawing it in a subroutine, but I had not declared the instance of the window to be global.  It seemed that Graphics.py created another instance in the subroutine and perhaps it was creating a new instance each time I wrote to the window, although using some settings, perhaps that it was keeping local to itself, but this was clearly causing it extra work.  I’ve now made all the window and text object declarations global. Then I discovered the ‘undraw’ function to remove the old text before entering the updated text. (If you don’t remove the old text, it remains on screen, causing the text to ‘smear’.) The redraw now takes a fraction of a second, the utilisation has dropped to a typical value of 0 %, rising to 4 % momentarily during redraw. The temperature has stabilised at 47 degrees: result!

I should mention that if you open extra windows on the screen, Graphics.py tries to find somewhere to put the window: it tries to put it in the last place you moved it to, even though it is closed and redrawn. (I’ve realised that this must be handled by LXDE.)  Given the much reduced load on the processor, I was hoping that the power supply voltage would be higher and the clock movement would be more reliable, but this doesn’t seem to be the case, so more investigation is still needed.

Starting the moon-clock from the GUI

In the previous post, I explained how I was using a graphics window to display the current clock settings, and I showed how it was possible to generate a nice-looking output using a package called graphics.py by John Zelle.  I use xrdp (remote desktop protocol) to connect to the Pi from my PC, although I’m aware that there are other ways like using a terminal emulator.  However, I like to be able to use a familiar window-type interface with the file management, editing and web-browsing that it offers.

It turns out that this raises several issues.  Firstly, the graphical LXDE desktop on the Pi is only initiated after logon, not at bootup.  Therefore, you can’t write to it in during boot-up.  If you try, you get various weird errors like: Invalid MIT-MAGIC-COOKIE-1.  This is something to do with incorrect setting of the .Xauthority environment variable, which is apparently set for each user, and during bootup there isn’t a user, except root.  I have seen various suggestions for fixing this.  But if you get past that hurdle, you will then be told that it can’t find display :10 or something similar. Since LXDE hasn’t yet been started, that is to be expected.

Now, you can get programs to open automatically when the desktop loads by editing the file using
sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart

You simply add the file that you want to run, as follows:

@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi
@python3 /home/pi/Downloads/moon-clock-with-reporter18-11-09.py

In my case, I’ve added the last line starting @python3, which executes the moon–clock software.  Now experienced users will be aware that because the moonclock software uses the GPIO pins for both input and output, I should run it as super-user, using
sudo python3, otherwise I can’t access the GPIO.  But, if I run it as superuser, then I have the problem of lacking permissions to access the desktop (I get the can’t find display :10 error).   So, how do you fix this?  I thought that there has to be a way giving an ordinary user access to the GPIO.  It turn out that you can edit our old friend /etc/rc.local to do this by changing permissions as follows:

chgrp -R dialout /sys/class/gpio
chmod -R g+rw /sys/class/gpio

I admit that I’m not entirely sure what this does, but I understand that it gives any user who is a member of the dialout group (which includes all ordinary users) to read and write to GPIO, so you do not need to be a superuser.

And it works!  I boot the Pi into the desktop and then autostart the moonclock from the desktop, and it writes into a nice graphical window.  Now I always know that the clock should be showing.

GUIs

Well, I never thought I’d be blogging about GUIs (Graphical User Interfaces), at least not in the context of my moon clock.  After all, a clock is the original and best GUI of them all!

But I want to be able to check that the clock hands are showing the times that the software thinks they should be showing. The clock starts automatically in the background on power up and by default any output that it writes will disappear.  You can redirect it to stdout, which will display in a terminal window, or redirect it to a file, but this is a scrolling display that isn’t easy to read.

I would like the current settings to be displayed in a nice, clear, fixed window.

Python doesn’t have a ‘windows’ display built in but there is a big choice of GUI libraries that give a graphical interface.  The most popular seems to be tkinter, which is a Python wrapper for a GUI called Tcl.  Like most GUIs, tkinter is event-driven.  It runs in an infinite loop, and when the user does something, such as clicking a button, this creates an ‘event’. This causes tkinter to transfer control to the relevant function to deal with the button click, and when this has completed, it then returns to the infinite loop until another event occurs.  This makes sense for most apps, as it means that control always returns to the user via the GUI.

I knocked together a few lines of code using Tkinter, but found that it would not display unless I called the infinite loop or the update function, and once in the loop, execution of the code would not proceed further.  Basically, it wanted user input.  Since the clock is driven by timer events rather than an external user, this might not matter – as long as tkinter passed control to the timer event – but on the other hand it might not work.  (The documentation doesn’t seem to address this point.)   Even if it could work, it is quite involved and would need some changes to my own waiting loop.

I searched around for a GUI that is not event driven and came across easyGUI. This uses the Tk/Tcl drivers but is not event-driven.  Each GUI feature is a separate function. However, after displaying the window relevant to the function, again it waits for user input, which it will never get, so it’s no better than Tkinter.

Suddenly, the light dawned.   My question about getting a simple text output in a window has been asked on a lot of forums, and all the advice is to use a GUI.  But this is wrong!  You only need a graphics routine that can draw on the screen in a window.  I searched around for something very simple, and came across csc161graphics. This uses a library called graphics.py written by John Zelle.  It is said to be a wrapper for Tkinter!  But it is for creating things on-screen, not a GUI.   I downloaded and installed it using the following command.
sudo pip3 install –upgrade http://bit.ly/csc161graphics

csc161graphics is actually a computer course in the USA, so it has helpful tutorial material.  I only want to create a Text Box with some writing in it, that will stay on-screen, and can be updated.

This was very easy to do.  After importing the graphics library, you call a function to open the window as follows:

from graphics import *
# Create window with title and dimensions
win = GraphWin('Moon Clock', 600, 200) 
# Set the background colour fill of the window
win.setBackground('turquoise4')
# Compose the text to display
label = Text(Point(300,100),'The clock is now up and running')
# Set the text colour
label.setTextColor('yellow')
# Set the text size
label.setSize(12)
# Write the text into the window
label.draw(win)

I’m only showing some dummy text ‘The clock is now up and running’. The hardest bit was to format the real numerical information that I want to show in the window.  The spacing still isn’t perfect – it is difficult to get this right with a proportional-spaced font –  but you will notice that the numbers are displayed in the format you’d expect. I would have to cover that in another post.

Of course, now I have text display using a graphics interface, it is tempting to consider making a replica graphical clock display too!

The change from BST to GMT

How did the moon clock cope with this change – the first occurrence since we started?  I think the answer is 80 %.  Firstly, it did correctly recognise that BST had ended and this meant that npulse (the number of pulses needed at the end of each minute) was negative until the current time caught up with the displayed time.  So the s hand waited for one hour. (I did not get up to watch this).  In the morning, the moon was illuminated (it is near full moon with the moon up for 15 hours) and the s hand showed the right time. So far so good.

But the next test was whether the new rise and set times could be correctly displayed.  The problem is that on the 27/28th October, the rise time was 19:45 and the set time was 10:51, whereas on the 28/29th October, the rise time was 19:30 and the set time was 11:56. So the rise time was 15 minutes earlier on 28th than the previous day. This was caused by clocks going back an hour. Since the clock can’t go backwards, it would have to go forwards about 23 hours and 45 minutes, needing 43,000 pulses.  The algorithm decides that it is better to wait for 24 hours than to pulse this far, so it flashes the moon 500 times as an indicator.  Unfortunately, the counter in the flashmoon function  had somehow got deleted, so it was stuck in an infinite loop!  This seems like a silly error when the hard part was working, but it shows how easy it is to make a mistake when editing.  So I had to correct the error in the flashmoon function, adjust the rise and set times by hand and restart the clock.

Of course it will be a year until this situation arises again – when summer time comes into effect, times go forward and that’s not a problem.

Time Zones

Anyone following this blog will know that the time displayed on a clock depends on its time zone.  Time zones are intended to allow everyone in a region to have a common time reference.  The convenience of this overrides the slight inconvenience arising from midday (and thus sunrise and set) getting slightly later as you move to the west.  And of course, there is also a north-south variation in sunrise and set.  The length of the day gets shorter as you move north in the winter, but longer as you move north in the summer, due to the tilt of the earth.  This means that in the winter in Scotland, it doesn’t get light until about 9 am.

The EU imposed a common set of time zones accompanied by ‘Daylight Saving Time’ in 1996.  However, the moving of clocks forward and back in Spring and Autumn is unpopular and the EU is now proposing that Summer Time should apply all year round.  The change would mean lighter evenings but darker mornings. Apparently, this was most popular with Germans and Austrians, but Britons and Italians didn’t care.

Permanent summer time was tried in the UK, with one argument being that it would reduce road accidents and energy consumption, but there wasn’t much evidence for this especially as some parts of  Scotland and northern England wouldn’t get daylight until 10 am in the winter.

Speaking personally, I quite liked the permanent summer time because of the lighter evenings.  Being in the south of England, the dark mornings are less of a problem than the dark evenings, although I have to say that in the winter months, there just isn’t enough daylight and messing with the clocks won’t change that.

And speaking as someone who looks after a church clock, I would rather not have to turn the clock hands on an hour in spring and stop it for an hour in the autumn. (It is possible to advance a chiming clock, but not to wind it backwards, as this would damage the mechanism.) The clock is mechanism is shown at the top of this blog.  It is a typical English flat-bed design, made by JW Bennett of Ludgate Hill in 1871, so it is almost 150 years old.  Nevertheless it is very sturdily built and keeps accurate time with little adjustment.  The frame is of heavy cast iron about four feet wide and 2 feet deep.   I still wind it by hand, having resisted the blandishments of those who would ruin it by fitting electric winding motors.  The weights are extremely heavy (I calculate that the quarter chiming weight is almost one ton and must be wound about 40 feet every week) but two fit people can wind it in fifteen minutes.  Adjusting the clock is a bit of a fag as the time shown on the mechanism does not exactly correspond with what is shown by the external hands, so unless I’m very careful, I have to climb the tower several times to get it right! It has a long, heavy pendulum at the other side from the photo. This goes through the floor into the bell-ringing chamber underneath.

Improvements to the Moon Clock Software

The moon clock seems to be keeping the correct time and to advance to the new rise and set times correctly.  So what improvements needed?

The main issue is that when running headless, there is no text output to tell you what the clock should be showing. This is a nuisance if you need to set the clock hands.  It is of course possible to direct the standard output to the console, but I have not been able to determine what buffer size is allocated, or how to flush it.  It could fill up after months or years. The same issue could apply to a file.  Moreover, directing to a file isn’t good because the output is buffered and only written when the buffer is full. Given the small amount of output from the clock, you’d never know what the current readings are.

It would be better to output to a GUI box nicely formatted to show just the expected information.  It is possible to do this in Python and my next step will be to try this out.

There is another small change I’d like to make.  We know that we are limited on the accuaracy that the h hand can show the set time, but there shouldn’t be much of an issue with the rise time.  Except that the rise time can be 15 hours or more after the previous set time. The present algorithm calculates the rise time display to be accurate at the time it is evaluated, 1.5 hours after the previous set time.  So the s hand can have moved by 13 or 14 hours before the rise time is reached, during which the m hand has moved about 13 or 14 minutes.  By allowing for this, we can get a more accurate rise time.  It can’t be completely accurate, of course, because the hands are all geared together.

 

The Moon Clock Software Published at last

The Moon Clock  has been soak-tested for a month now and seems to be running as designed.  So you can download it from the link below.

moon-clock-with-azimuth positioner18-08-18

Note that it has been given a file type of .txt (text).  If it is stored as a .py file, which is an executable file type, spam filters will  prevent it from downloading, as a precaution in case it contains malicious code.

As it is, you can review the code NotePad, or better in any code editor, such as NotePad++, which will colour the code to help you to follow its structure.

You will need to change the file type to .py in order for NotePad ++ or the IDLE interface in the Raspberry Pi, to be able to recognise it as Python code.  You can’t run it until you change the file type.

The code is fully commented and is fully described in my blog and on the Moon Clock Software page.  I hope it will be of interest and look forward to any (positive) feedback.

Final testing

I’ve been tidying up the moon clock operating software, removing redundant bits and clarifying the comments.  In the process, I’ve found some minor bugs, but who knows if I’ve introduced some new ones?  So I have decided to let it run for a while longer before releasing it.

Overall it seems to be running as intended.  The new moon is in two days time.  The clock is showing very little of the moon is visible: I wonder if it will last out two more days?  It will be a crucial test of the maths when the set time passes midnight. This will not be for another 11 days.  If this works correctly, we should be good to release the software fully.

I have previously said the clock motor was still dropping the occasional ‘tick’.  I decided to lengthen the ‘off’ time of the pulse from 17 to 20 ms. It looks as thought this might be enough to allow the rotor to settle properly.   I’ll need a 2-hour shift to give it a really good test of 3600 or more pulses, but over the last few days, the set time has only changed by a few minutes, so I’ll need to wait a bit longer.