Christmas fun for makers
Maker Christmas

© Lead Image © fabio bergamasco, 123RF.com
Make your own Christmas music box with a microcontroller, servomotor, NeoPixel LED ring, and mini-MP3 player.
Music boxes and Christmas pyramids are among the top sellers in Germany during the Advent season. Expensive, hand-carved items can fetch four-figure sums, whereas cheap imitations sell for EUR20 (~$17). Christmas pyramids are often powered by the heat of candles, and the cheaper ones in particular have such an unfavorable candle-to-propeller ratio that the pyramid will not turn without mechanical help. Music boxes are driven by fragile springs, but the constant need to rewind them spoils the fun.
My idea of building a music box of my own design was born from these frustrations. In terms of the electronics, you do not need many components. The following sections are intended to give you some ideas for your own projects; the parts used in this example can easily be replaced by whatever delving into the depths of your lumber box reveals. The only important elements in this project are light, motion, and music.
Controls
To control the project, I used a Trinket M0 microcontroller [1] by Adafruit (Figure 1), which runs CircuitPython, a minimalist Python that supports a wide range of peripherals with its many libraries. The price of the controller is in the same range as a Pi Zero, including an SD card, but it is easier to put into operation because you do not need to install and configure an operating system.

Another advantage of a microcontroller is that you do not have to boot it, and you can simply switch it off without damaging the installation. The biggest advantage, though, is the CircuitPython support. The examples offered here illustrate how little code is needed to implement your ideas. Independently, the project could also be implemented with a Pi Zero, but some tweaks would be necessary at various points, such as the power supply.
Let There Be Light
In this project I use LEDs – more precisely, NeoPixel LEDs [2] – to create the illumination effects. NeoPixel LEDs are available in all shapes and sizes, from long strips through rings and arrays to individual LEDs. The components already contain the driver chips, which make them a bit more expensive than normal LEDs, but make controlling the LEDs far simpler.
NeoPixels normally require 5V. Three connections are all you need: supply voltage, ground, and data. If the cables are short and the number of pixels is low, 3.3V might be sufficient for the power supply and control. The maximum brightness is reduced a little, but because the LEDs are very bright anyway, the low voltage doesn't matter in practical terms. Regardless of the selected voltage, it is important to check that the NeoPixels do not overload the voltage source. The Raspberry Pi's 3.3V pins are not designed to deliver high currents. The Trinket's 3.3V rail has fewer problems: The built-in converter outputs 500mA.
I chose to use a 24-pixel RGBW LED ring (Figure 2). This device could easily be supplied with 3.3V from the Trinket M0 and controlled directly. The power consumption with the LEDs turned down is about 60mA maximum. The LED ring is the most expensive single component in the project ($17/EUR21). When soldering the cables, avoid creating a solder bridge to the adjacent LEDs.

In the minimal application program (Listing 1), the neopixel library for CircuitPython (imported in line 3) expects the code in the lib/
subdirectory. However, the library has a bug: When initializing the object (lines 8-12), you have to specify the pixel_order=neopixel.GRBW
argument, even though the value you are passing in is the default.
Listing 1
NeoPixel Control
01 import time 02 import board 03 import neopixel 04 05 pixel_pin = board.D2 06 num_pixels = 24 07 08 pixels = neopixel.NeoPixel(pixel_pin, 09 num_pixels, 10 pixel_order=neopixel.GRBW, 11 brightness=0.05, 12 auto_write=False) 13 14 def colorwheel(pos): 15 if pos < 0 or pos > 255: 16 return (0,0,0,0) 17 if pos < 85: 18 return (255 -- pos * 3,pos * 3,0,0) 19 if pos < 170: 20 pos -= 85 21 return (0,255 -- pos * 3,pos * 3,0) 22 pos -= 170 23 return (pos * 3,0,255 -- pos * 3,0) 24 25 def rainbow(wait): 26 for j in range(255): 27 for i in range(num_pixels): 28 rc_index = (i * 256 // num_pixels) + j 29 pixels[i] = colorwheel(rc_index & 255) 30 pixels.show() 31 time.sleep(wait) 32 33 while True: 34 rainbow(0.1)
The program generates rainbow colors across all pixels and rotates more or less slowly, depending on the wait
parameter (lines 25 and 31). CircuitPython does not support interrupts, so if you want to connect an additional button to the Trinket M0 (e.g., for an on/off switch or to switch between effects), you have to query the switch at a suitable point. In the example, this would be either inside the while
loop (lines 33-34) or before line 31.
In Motion
A continuous rotation servomotor rotates the music box. In contrast to stepper motors, which support precise positional control, only speed and direction can be specified for rotating servos. In this project, I use a Fitec FS90R [3] ($5, EUR6; Figure 3), which is available from various vendors.

Again, a few lines of code are all you need for control (Listing 2). First, a pulse-width modulation (PWM) object is created in line 6, along with a control object for the motor in line 7. The throttle
parameter controls the direction (sign) as well as the speed and expects values between -1
and 1
. Depending on the model and power supply, the motor does not stop for a value of
. In my lab, it stopped for values between 0.05
and 0.10
.
Listing 2
Servomotor Control
01 import time 02 import board 03 import pulseio 04 from adafruit_motor import servo 05 06 pwm = pulseio.PWMOut(board.D0, frequency=50) 07 my_servo = servo.ContinuousServo(pwm) 08 my_servo.throttle = 0.01 09 10 while True: 11 time.sleep(1)
Without a while
loop, the program ends and the microcontroller resets the hardware – hence lines 10 and 11. You can start, stop, or change the speed of the motor within this loop, but for this project, no further support after startup would be practical, because you will be manipulating the LEDs in the while
loop of the main program (Listing 1).
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Direct Download
Read full article as PDF:
Price $2.95
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Find SysAdmin Jobs
News
-
MNT Seeks Financial Backing for New Seven-Inch Linux Laptop
MNT Pocket Reform is a tiny laptop that is modular, upgradable, recyclable, reusable, and ships with Debian Linux.
-
Ubuntu Flatpak Remix Adds Flatpak Support Preinstalled
If you're looking for a version of Ubuntu that includes Flatpak support out of the box, there's one clear option.
-
Gnome 44 Release Candidate Now Available
The Gnome 44 release candidate has officially arrived and adds a few changes into the mix.
-
Flathub Vying to Become the Standard Linux App Store
If the Flathub team has any say in the matter, their product will become the default tool for installing Linux apps in 2023.
-
Debian 12 to Ship with KDE Plasma 5.27
The Debian development team has shifted to the latest version of KDE for their testing branch.
-
Planet Computers Launches ARM-based Linux Desktop PCs
The firm that originally released a line of mobile keyboards has taken a different direction and has developed a new line of out-of-the-box mini Linux desktop computers.
-
Ubuntu No Longer Shipping with Flatpak
In a move that probably won’t come as a shock to many, Ubuntu and all of its official spins will no longer ship with Flatpak installed.
-
openSUSE Leap 15.5 Beta Now Available
The final version of the Leap 15 series of openSUSE is available for beta testing and offers only new software versions.
-
Linux Kernel 6.2 Released with New Hardware Support
Find out what's new in the most recent release from Linus Torvalds and the Linux kernel team.
-
Kubuntu Focus Team Releases New Mini Desktop
The team behind Kubuntu Focus has released a new NX GEN 2 mini desktop PC powered by Linux.