For her birthday my daughter received a cuckoo clock. It was unfortunate, she wanted it in her room but it had very limited programming for 'quiet hours' so I fiddled with it and ended up breaking it. I didn't want to disappoint her so I gutted it and proceeded to install a Pi Zero W and a headphone amplifier I had built. She now has a fully programmable, USB powered, linux based cuckoo clock where I can program it to whatever suites our needs and it syncs it's time with NTP severs. I even connected her night light to it which turns on at night and off to let her know when its time to get out of bed. This combination also allows us to have dance parties with flashing lights, a dancing bird and fun songs coming out of her cuckoo clock. It's ridiculous and eccentric but it makes us happy!

Build

  • The Pi Zero's dont come with a sound output so I built an audio output filter to convert the PWM output to an analog audio output
  • Connected the analog out to a OPA1642 based headphone amplifier I designed and built
  • Wired up the cuckoo bird's coil actuator to a simple MOSFET drive circuit to control it from the Pi's weak GPIO output
  • Wired up some 5V string lights (used to be battery powered) to a simple MOSFET driver circuit to control it from the Pi's 3.3V GPIO output
  • Wrote some bash code to make the bird dance, the light flash and the cuckoo bird sounds play
  • All the scheduling and execution of the code is done clean and simple in crontab
  • I also have a text to speech engine verbally state the hour after the cuckoo action so my daughter can better learn to tell time by herself

picture

picture

To re-map the audio to the PWM0 output of the Pi

add to /boot/config.txt to remap the audio to the PWM0 and PWM1 pins of the pi.

# Enable audio (loads snd_bcm2835)
dtparam=audio=on
#remaps the audio to the PWM0 and PWM1 pins (pins 18 and 13)
dtoverlay=audremap,pins_18_19

Code

Cron Scheduling

@reboot /home/pi/startup.sh

#cuckoo between 8am and 6pm, inclusive
0 8-18 * * * /home/pi/cuckoo.sh

#turn on the night light at 6:15 pm
15 18 * * * echo "1" > /sys/class/gpio/gpio26/value
#turn off the night light at 6:15 am
15 6 * * * echo "0" > /sys/class/gpio/gpio26/value

Startup Configuration for GPIO

#!/bin/bash

#setup the GPIO
#"In order to use a GPIO pin through sysfs, we first have to “export” each one to make the appropriate paths available."
echo "17" > /sys/class/gpio/export
echo "26" > /sys/class/gpio/export
#set direction
echo "out" > /sys/class/gpio/gpio17/direction #cuckoo movement
echo "out" > /sys/class/gpio/gpio26/direction #nightlight

Flashing Light Code

#!/bin/bash

i=1

while [ "$i" -le 3 ]; do
        #turning the GPIO on
        echo "1" > /sys/class/gpio/gpio26/value
        sleep 0.050
        echo "0" > /sys/class/gpio/gpio26/value
        sleep 0.050
        i=$((i + 1))
done

Cuckoo Code

#!/bin/bash
i=1
echo "Looping "$(date +%I)" times"

while [ "$i" -le "$(date +%I)" ]; do
        aplay /home/pi/cuckoo.wav &
        #flash the lights three times quickly
        /home/pi/flash.sh &
        #turn on the cuckoo bird coil to make it bob down and flaps its wings
        echo "1" > /sys/class/gpio/gpio17/value
        sleep 0.300
        #turn off the cuckoo bird coil so it sits back down
        echo "0" > /sys/class/gpio/gpio17/value
        sleep 0.700
        i=$((i + 1))
done
#Text to speech engine, speaks the current hour through the speaker
#date + sed command below returns the hour, in 12 format, and the sed command removes the leading zeros
espeak -v mb-en1 -s 120 "it is $(date +%I | sed 's/^0*//') oh clock"