Longcase Clock Audio Simulator

by nightcustard in Circuits > Raspberry Pi

1451 Views, 7 Favorites, 0 Comments

Longcase Clock Audio Simulator

Grandfather clock.jpg
3pmchimes
Reboot
Shutdown
IMG_20220211_145041978_HDR.jpg
IMG_20220211_145052485.jpg
IMG_20220211_145102633.jpg

A friend has a longcase clock which hasn't worked for ages which unfortunately has had its mechanism removed and replaced with a quartz movement. I thought it would be a great idea to give his clock its voice back by building a Raspberry Pi based clock sound generator. 

I recorded the ticking sounds from my 19th century longcase clock and the quarter hour and hour chimes from a family 1930s era mantlepiece clock. The sound generator plays any combination of those recordings, and being synchronised to UTC, it'll always play them at the right time. It worked so well I made two - one for him and one for me.

This design uses a Raspberry Pi Zero W, an i2s stereo decode board, an amplifier, a couple of small speakers and a buck dc converter. 

My choice of a Pi Zero W was mainly on grounds of size and cheapness. If you want to use another model of Pi, go ahead. You could also modify the design to take the audio from the 3.5mm headphone socket and dispense with the UDA1334A. Using powered speaker(s) would also allow you to dispense with the audio amplifier.

Shorting links are used to enable/disable the ticks, the quarter chimes and the hour chimes. A momentary push switch is used to either reboot or halt the Pi, determined by a short or long press respectively.  A rather nice voice prompt tells you what's happening.

An internet connection (via WiFi or ethernet) is necessary to maintain good timekeeping and recommended for the odd maintenance action (such as changing the volume manually).

Volume is controlled manually via ssh & 'alsamixer' (a built-in audio mixer programme) and automatically via scripts run in 'crontab'. As set up, the clock sounds are muted at 22:59 and enabled again at 06:59. These times can be changed at will by simple edits ('crontab -e'). 

The construction method will hopefully also be of interest. I've utilised an open-frame stacking concept, making use of some thin wooden venetian blind slats I happened to have knocking around. This design is a nice compact solution and is easy to modify or add other layers as required.

Some soldering is necessary.

Supplies

Mount#6.jpg

Parts list

For the Pi Zero W mount:

  • 5cm long M2.5 machine screws (x4)
  • M2.5 nuts (x24)
  • Wooden slats 4-5mm thick, 70mm x 35mm (x3)

Please note the links below are for illustrative purposes only as I've not necessarily bought from the suppliers shown.

  • Raspberry Pi Zero W (available* from PiHut etc.)
  • A micro SD card (4GB and up)
  • UDA1334A i2S board (available eBay, Banggood etc. - Look for CJMCU-1334 UDA1334A I2S Audio Stereo Decoder Module Board 3.3V - 5V CJMCU for Arduino). Price at time of writing was £7.51
  • PAM8403 Power Amp (available eBay, Banggood etc. - Look for PAM8403 Miniature Digital USB Power Amplifier Board 2.5V - 5V) Price at time of writing was £4.73 for five
  • 5v buck converter (available eBay, Banggood etc. - Look for DC-DC 7-28V to 5V 3A Step Down Power Supply Module Buck Converter Replace LM2596)
  • (note - an LM2596 type will also do perfectly well - see eBay)
  • small 4 or 8ohm speakers (one or two, depending on what you have lying around)
  • 2 pin male headers (x3) (the UDA1334A above comes with a male pin header strip which you can use for this) eBay etc.
  • 2 pin single row female header (x3) (junk box or eBay etc.) 
  • 2.1mm dc socket (eBay, Banggood etc.)
  • Short jumper wires (to connect to GPIO pins) (x9) (eBay, Banggood etc.)
  • 2 core screened audio cable (5 - 6cm length) (junk box/ snip length of phono cable etc.)
  • micro USB plug (eBay, Banggood etc. or snip the end off a USB lead and use that)
  • AC - DC power supply. 7v to 30v 12W or more (junk box/eBay etc.)

* due to the current general shortage, should be: 'will be available'

Consumables

  • Solder
  • Heatshrink sleeve
  • Hot-melt glue
  • PVA glue (for the mount if needed)

If you want to use a 'full fat' Pi and use the headphone socket to drive powered speakers, the parts list is as follows:

  • 1 off Raspberry Pi model B, any version from 1 through to 3 plus (v4 doesn't have a headphone socket, so is not suitable) (Pi 3B+ £33.90 from PiHut; other older models from Ebay as they're out of production)
  • 1 off Pi case (eBay or similar, dependent on model of Pi used) (typically around £3.00 to £4.00)
  • 1 off USB WiFi adaptor (not needed if using a Pi 3B) (£6.00 PiHut)
  • 1 off 5v 2A micro USB PSU (typically £5.00ish eBay or similar)

Other combinations of Pi and speakers are perfectly feasible - just pick from the above list as needed.

Pi Mount Construction & Assembly

Mount#1.jpg
Mount#2.jpg
Mount#3.jpg
Mount#5.jpg
Mount#4.jpg
Mount#7.jpg
Mount#8.jpg
Mount#9.jpg
Mount#10.jpg
Mount#11.jpg

I made a mount for my Pi Zero W from some old wooden blind slats I had lying around. I like this design as it makes for a compact construction when you've got other circuit boards to interface to the Pi.

My early attempts used a single slat per layer but I soon found the corners tended to break when assembling onto the screw posts, so I now use PVA wood glue to stick a couple of slats together.

The dimensions of each layer are 70mm x 35mm, 5mm thickness (each slat is 2.5mm thick).

I used M3 screws as these are what I had in stock. Accordingly, I had to widen the mounting holes in the Pi with a 3.5mm drill bit. You could certainly use M2.5 screws and that's what's listed in the parts list.

I used nuts instead of stand-offs, only because I didn't have enough for the job. Using stand-offs makes the construction quicker and it's easier to take things apart if you need to.

I constructed the mount assuming the Pi is on the bottom layer. If it's on the top layer, you can avoid having to cut out a recess for the GPIO pins and thus weakening that layer.

Wiring

Block Diagram.jpg
Top view.jpg
Side view 1.jpg
Side view 2.jpg
End view 1.jpg
End view 2.jpg
Side view 3.jpg

I used hot-melt glue to fix the UDA1334A, Amplifier board and buck converter onto the mount layers. Only use a small amount as Murphy's law dictates you'll have to take it apart again!

As the board was a prototype, I didn't leave enough space to mount the dc socket on one of the slats, so it's been left on a flying lead.

Please consult the block diagram for a guide to the overall wiring design and the photos for a layout suggestion.

The screened audio cable is absolutely necessary as the Pi's WiFi signal would be picked up by unscreened wires and cause a lot of noise. Take note of the grounding arrangements below.

Wiring UDA1334A to the Pi:

'VIN' to Raspberry Pi pin 2 (5v)

'GND' leave open ((connecting this causes a 'ground loop' - the UDA1334A gets its ground connection via the audio amp board)

'DIN' to Raspberry Pi pin 40 (PCM_DOUT)

'BCLK' to Raspberry Pi pin 12 (PCM_CLK/PWM0)

'WSEL' to Raspberry Pi pin 35 (PCM_FS/PWM1)

Wiring UDA1334A to the audio amp:

(note - screened cable should be used for this, using the screen for the ground connection)

'LOUT' to 'L'

'AGND' to amp ground

'ROUT' to 'R'

Wiring audio amp to DC buck converter:

(note, before connecting adjust the converter's output to 5v)

'5V +' to '+'

'5V -' to '-'

Wiring audio amp to speakers:

NOTE - don't connect the L OUT and R OUT pins together as you'll destroy the amplifier board (it's a bridge output amplifier).

L OUT '+' to left speaker +

L OUT '-' to left speaker -

R OUT '+' to right speaker +

R OUT '-' to right speaker +

Momentary push button switch to Raspberry Pi:

[Shutdown/reboot button]

pole 1 to pin 22 (GPIO 6)

pole 2 to pin 30 (ground)

Header pins to Raspberry Pi:

[Tick & chime enable/disable - link made to enable]

Header 1 - Ticks

pin 1 - Raspberry Pi pin 14 (ground)

pin 2 - Raspberry Pi pin 16 (GPIO 4)

Header 2 - Quarter hour chimes

pin 1 - connect to pin 1 of header 1 above

pin 2 - Raspberry Pi pin 11 (GPIO 0)

Header 3 - Hour chimes

pin 1 - connect to pin 1 of header 1 above

pin 2 - Raspberry Pi pin 18 (GPIO 5)

Software Installation & Testing

The instructions below assume some familiarity with using a terminal session to talk to a Raspberry Pi. If you're unfamiliar with this, the information provided here is a good place to start.

The Raspberry Pi is operated 'headless' (ie) there's no monitor or keyboard/mouse and all communications are via SSH (eg) using PuTTY (on Windows) or ssh on Linux (open a terminal window and type 'ssh pi@192.168.xxx.yyy', where 192.168.xxx.yyy is your Pi's address on the local network).

I edit files on Windows using Notepad++ and transfer between PC and Pi using WinSCP drag & drop.

I'd recommend using a fixed IP address for the Pi outside the DHCP range assigned by the router (you'll have to figure that out as it's router-specific). 

Network communications are via 2.4GHz WiFi so a 'wpa_supplicant' file needs setting up with the appropriate SSID and password in the 'boot' partition of the SD card, otherwise on boot-up the pi won't have joined your network and you can't ssh to it.

Install Pi OS (lite):

Flash the latest Raspberry Pi OS image onto your SD card (4GB min) using 'Raspberry Pi Imager' available from https://www.raspberrypi.org/software/. When selecting the OS, choose 'Raspberry Pi OS (other)' and then select 'Raspberry Pi OS Lite (32 bit)'. Once the SD card has been flashed, Windows will display a message saying the drive needs formatting before you can use it. You can safely IGNORE this message, as it's referring to the Linux part of the SD card.

Remove the SD card from the PC when prompted and then reinsert it to get the operating system to remount the card.

Create an empty file in the SD card's boot partition called ssh:

If you're using Windows, 'boot' is the only partition on the SD card available to you. Open 'Explorer', navigate to the SD card (the folder called 'boot') and right click in the right hand pane. Select 'New' and 'Text document' to create a blank text file called ssh - delete the '.txt' extension and press 'Enter' to save. Ignore the warning message.

Likewise, create a file in the boot partition called wpa_supplicant.conf (replace the default '.txt' extension with '.conf') and edit it using 'Notepad' or similar as follows:

country=UK
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev 
update_config=1
network={
    ssid="yourwifiSSID"
    psk="yourwifipassword"
    key_mgmt=WPA-PSK
  }

Where "yourwifiSSID" is the name of your WiFi network & "yourwifipassword" is your WiFi password.

Save and close File Explorer. Safely remove the SD card, place in the Pi Zero W and boot.

Once booted, open up a terminal session using PuTTY or similar and log in using the default password 'raspberry'. You'll be prompted to change the default password, so enter:

$ passwd

and change the password.

Then enter

$ sudo raspi-config

to enable the i2s interface:

Select '3. Interface Options', followed by 'P5 I2C Enable/disable automatic loading of I2C kernel module'. Press '<Select>', followed by '<Yes>', '<OK>', and '<Finish>'.

Install the software to drive the i2s UDA1334A board: (skip if using the headphone output)

$ curl -sS https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2samp.sh | bash

After following the script prompts (selecting 'y' when asked), the Pi will reboot. Re-run the 'curl' script again to test the audio. The script then prompts you to reboot, which you should do.

To control the audio level using alsamixer, another reboot is required:

$ sudo reboot

I've found I can't adjust the volume levels using alsamixer without stopping 'aplay'. Whether this is a bug or not, I don't know but just run this command and you can then set the playback volume:

sudo killall -9 aplay

followed by:

$ alsamixer 

The Card should be shown as "snd_rpi_hifiberry_dac". If using the headphone output, the card is shown as "bcm2835 Headphones".

Use the up/down arrow keys to reduce PCM playback level to 45 or so. Press <Esc> to exit.

Please note you'll need to 'sudo killall -9 aplay' each time you want to use alsamixer. The other quirk I discovered is the volume levels set here appear to be forgotten on reboot, on my build defaulting to maximum. Running the 'setvol.sh' script every time the machine boots ensures the volume levels are always correct. This is detailed below.

The above is applicable whether you're using the i2s board or the headphone output.

Update the OS and install mpg123: 

$ sudo apt update && sudo apt -y upgrade
$ sudo apt install mpg123

mpg123 is used to play recordings of the grandfather clock ticks (as a service) and uses user crontab to play recordings of chimes on the hours and at the quarter hours.

Install pip, python-crontab, git & rpi.gpio:

$ sudo apt install python3-pip

python3-pip is a software installer for 'python-crontab'

$ pip3 install python-crontab

This is needed for the for chimes scheduler. Be patient - 'pip3' always takes longer to get going than 'apt'.

$ sudo apt install subversion python3-rpi.gpio 

This permits downloads from GitHub and GPIO operations.

Download code and audio files:

These can all be downloaded from my Github site:

$ svn checkout https://github.com/nightcustard/clock-audio-sim/trunk/audio /home/pi/audio/
$ svn checkout https://github.com/nightcustard/clock-audio-sim/trunk/main /home/pi/software/
$ chmod +x /home/pi/software/*

Python files:

clocksim_v3.py   This is run as a service 'clocksim.service'. It monitors the GPIO inputs and takes appropriate actions when their states change: It plays the tick sounds when GPIO 17 is grounded; It edits the user cron if the GPIO 23 or 24 inputs change state to either activate or disable the quarter hour and hour chimes by adding or removing the two Python scripts below; It monitors the state of the reboot/shutdown switch on GPIO 25 and either reboots or shuts down the Pi as appropriate.

hour_chimes_v1.py  Called from user crontab and plays recordings of hour chimes - uses datetime to select the appropriate hour chimes recording (1 to 12).

quarter_chimes_v1.py Likewise but uses datetime to select the appropriate 15, 30 or 45 minute chime.

bash script files:

setvol.sh Sets the playback volume to desired level (currently set to 50%)

mutevol.sh Mutes the playback volume

Audio files:

1.mp3 to 12.mp3 Hour chimes 1 o'clock to 12 o'clock

15.mp3, 30.mp3 & 45.mp3 Quarter hour chimes

GrandfatherClockTick_16mins.mp3 A 16 minute recording of longcase clock ticking (looped by the software).

Rebooting.mp3 & GoingForShutdown.mp3 Audio prompts when the reboot/shutdown switch is pressed.

Running clocksim_v3.py as a service (a service runs independently of terminal sessions):

Step 1– Create A Unit File

Open a new unit file using the command as shown below:

$ sudo nano /lib/systemd/system/clocksim.service

Add in the following text :

 [Unit]
 Description=clocksim service
 After=multi-user.target

 [Service]
 Type=idle
 User=pi
 ExecStart=/usr/bin/python3 /home/pi/software/clocksim_v3.py
 Restart=always
 RestartSec=0
 StandardOutput=file:/home/pi/software/clocksim_output.log
 StandardError=file:/home/pi/software/clocksim_error.log

 [Install]
 WantedBy=multi-user.target

Save and close.

This defines a new service called “clocksim service” which is launched once the multi-user environment is available. The “ExecStart” parameter is used to specify the command to run. The “Type” is set to “idle” to ensure that the ExecStart command is run only when everything else has loaded. Note that the paths are absolute and define the complete location of Python as well as the location of the Python script. 'User=pi' is necessary to prevent a 'module not found' error (python module 'sh').

The permissions on the unit file need to be set to 644 :

$ sudo chmod 644 /lib/systemd/system/clocksim.service


Step 2 – Configure systemd

Now the unit file has been defined we can tell systemd to start it during the boot sequence :

$ sudo systemctl daemon-reload
$ sudo systemctl enable clocksim.service

Set the nominal output audio level to 34% each channel (you can change the volume levels as required):

$ sudo /bin/bash /home/pi/software/setvol.sh 34 34

Finally, edit crontab to add the scheduled volume changes:

$ crontab -e

Select 'nano' as the editor if prompted. Add the following:

# last two digits are the left & right volume level in %. Change as required.
@reboot sudo /bin/bash /home/pi/software/setvol.sh 34 34 
59 6 * * * sudo /bin/bash /home/pi/software/setvol.sh 34 34
1 23 * * * sudo /bin/bash /home/pi/software/mutevol.sh

Save and exit.

The above entries quieten the audio at bedtime and makes it active again in the morning. These times can be changed at will or deleted entirely.

The first entry sets the volume on the left & right channels to 34%. This can be changed as wanted as can the time at which it becomes active (currently 06:59 am every day).

The second entry mutes the sound output at 23:01 every day.

Shut down the Pi in readiness for testing:

$ sudo halt

and remove power.

Testing:

Ensure all three header links are fitted. Apply power to the Pi. After a short delay, a ticking sound should be heard. Remove the Header 1 link. The ticking should cease shortly. Refit the link. Confirm the ticking resumes.

Press the Reboot/Shutdown switch for about 1 second and then release. After a short delay, a voice saying 'Rebooting' should be heard several times. Soon after, the Pi will restart. Wait until the ticking resumes.

Press and hold the Reboot/Shutdown switch. After a short delay, a voice saying 'Going for shutdown' should be heard, which repeats once or twice. Release the button. Wait for the green LED on the Pi to extinguish and you can then safely remove power.

In everyday use, it's expected that the links will be set to the desired configuration before power is applied.

Troubleshooting:

If no ticking sound is heard, check the volume setting by running 'alsamixer' as detailed above.

If the audio level is above zero (40% is a good nominal level to use), listen for a hiss and the odd crackle from the speakers. This will hopefully be pretty quiet but should be sufficient to confirm the audio amp is working. If there's no hiss, shut the Pi down as described above and carefully check the wiring.

If there's some hiss but no ticks, run:

$ sudo service clocksim status

Confirm the service status is shown as 'active (running)'. If not, try:

$ sudo service clocksim restart && sudo service clocksim status

to restart it.

If still no joy, you're into a bit of software troubleshooting. The system logs are a good place to start but outside the scope of this Instructable. I will try to help if I can.

The software has been pretty thoroughly tested over the last year so I'm pretty happy there aren't any bugs (...but you can never be certain...).

Note re. removing power etc.:

The pi's SD card can become corrupted if power is removed without shutting the Pi down first. This can be achieved either via ssh and entering:

$ sudo shutdown -h now

or more conveniently by pressing the push button. As described under 'Testing' above, a short (<1sec) push should reboot the the Pi, a longer press (>2secs) should shut it down...... You should hear a voice prompt telling you what it's going to do.

If it doesn't work, you'll have to use the ssh method (or just pull power and hope you're lucky). Except in the latter case, wait for the pi's green LED to stop flashing, wait another few seconds and then pull power.