A Raspberry Pi powered snapology origami sunrise lamp, night light and disco ball

It’s a fairly common problem for kids to wake up and not know what time it is and so the below sleep trainer clocks are also fairly common. Stars during the night then Mr Sunshine appears at a set time.

Gro clock
Gro clock
Gro Clock

We were passed down two of these GRO clocks, which sit next to star projectors in each room. I've never got on with them. I find them a bit ugly, they are forever being disconnected and often show the wrong time.

I'd been curious for while about Adafruit's vibrant NeoPixels LED, and had wondered if they could be combined with a more aesthetically pleasing approach to our endless pursuit for lie-ins beyond 5am!

It was comment on my Cardboard Planetarium video recommending Snapology Origami that sent me down a path to designing a lamp.

My cardboard planetarium

After Googling Snapology Origami I found myself happily down yet another Internet rabbit hole of discovery.

Most sources point to Heinz Stroble as the pioneer, and in his words Snapology Origami is…

A simple and cheap method to make convex polyhedra models.

Between his site, and that of Dave Honda, I discovered some pretty mesmerising designs and couldn’t help wondering what patterns of light would be thrown from a light source in the centre.

Essentially, strips of paper are folded into polygons then connected with further strips acting as connectors. No glue or other fixing methods required — just paper.

Two Snapology triangles joined with a connector

Before long, I was the proud creator of a multicoloured Icosahedron.

Oscar Cat with Snapology icosahedron
Oscar Cat with Snapology icosahedron
Oscar Cat with Snapology icosahedron

But it was with this model, apparently referred to as an icosidodecahedron, that I had a light bulb moment… of the literal kind.

icosidodecahedron on lamp
icosidodecahedron on lamp
Icosidodecahedron

With a little further Googling I came across this design by Ed Chew. He’d used recycled Tetrapak cartons to create a spherical lamp for which he won a design award. I was a little dubious about the authenticity of the light patterns shown, but thought it would be cool to create something along the same lines and find out if I could get similar results. And as you will see, I needn’t have doubted the light and shadows created.

NeoPixel applications

I had read about and seen some interesting applications of Adafruit’s NeoPixels and understood them to be plenty bright enough. They come in all shapes and sizes and can be chained together. They can also be wired up individually or even sewn into fabric with conductive thread as shown here on Adafruit’s channel.

I couldn’t wait to see how they’d look inside a paper lamp.

My design

I began saving Tetrapak cartons, but after realising my wife would need to get through 400 litres of soya milk before I would have enough, I lost patience, headed to Tesco and bought a bunch more coloured paper. I made a quick mock up using equilateral folded triangles, and while the throw of light from my phones led gave a pleasing pattern, the channels around the pentagon pieces looked like chasms, which would diminish the spherical look I was going for.

Test piece with all equalateral triangles
Test piece with all equalateral triangles
Test piece with all equilateral triangles

I’d learnt from my experiments with geodesic domes that at the heart of a geometric sphere is an icosahedron, a 20 sided shape comprised of equilateral triangular faces, each vertex being the meeting point of five edges. To give the faces their curve, each triangle is broken into smaller triangles with edges of various lengths. The smaller the triangles, the more spherical the look.

Triangles on an icosahedron
Triangles on an icosahedron
The beginnings of a 2 frequency icosahedron

My geodesic prison, sun and earth, and my cardboard dome were all three frequency domes: there were three points between each vertex. Ed Chews Tetrapak lamp was a massively complex six frequency sphere! For my lamp, I decided I would settle on a four frequency structure.

A four frequency panel of a geodesic sphere
A four frequency panel of a geodesic sphere
A four frequency panel of a geodesic sphere

While using equilateral triangles could create funky designs like the below, I was really going for as spherical look as possible.

A multicoloured sphere using only equilateral triangles

I used the same geodesic dome calculator I had previously used, which revealed that for a four frequency sphere I would in theory need six different lengths for edges of the inner triangles, but as that would be a nightmare to fold, I went for just two of triangles: isosceles triangles for the vertices where pentagon pieces would form with two smaller edges, then equilateral triangles for everything else. According to the dome calculator this would make a sphere with a diameter of 15cm.

To create these pieces I folded my 2cm paper strips around a piece of thin cardboard with a smaller and wider end. The trianglular pieces fold around six times to give each triangle a double wall. Each triangle connects to the next with a connector strip equivalent to four faces in length.

Tool for folding

Now, I realise fans of Raspberry Pi and Adafruit might be feeling fatigue with all this talk of paper folding, so here is a quick look at some imaginary origami Python code.

If folding was a Python task

I deliberately didn’t work this out beforehand as I knew the numbers would be daunting, but each of the 20 faces was made of 16 smaller triangles, for a total 320 triangles and over 600 connector pieces.

The truth is it was actually quite calming to assemble - I can recommend it if you are looking for a mindfulness type activity, or you’re trying to give up smoking. I can even imagine a class full of kids folding away while listening to the teacher. Oh the arguments though! Sir, Johnny won’t give back my partially completed Rhombicuboctahedron! Well, it was a nice thing to do while sitting in front of the telly watching old episodes of friends. A bit like knitting I imagine.

Partially completed sphere with phone’s LED

It really started to take shape and halfway through I was starting to get a sense of what it may look like with the Neo Pixels shining through. Or what it would be like if Oscar cat were to take up fencing!

Fencing mask for Oscar Cat!

I bought a Raspberry Pi Zero W for £13, a plastic case for £3 and a NeoPixel Ring for £7. The ring has 12 RGB leds, which can be individually programmed. I also bought a SD card with NOOBS pre-installed and set it up using our lounge TV. Before long it was all connected and I was able to login to it via SSH.

NeoPixel Ring

While the Raspberry Pi had the headers pre-soldered, there was no escaping the need to get the soldering iron out to connect the NeoPixel Ring to the jumper leads which I thankfully achieved without issue.

I followed tutorials on the Pi Hut and Adafruit websites to get the Pi up and running with Circuit Python, a version of Python designed for micro-controllers. Amazingly, this went without a hitch!

Once completed, it was relatively easy to get my “Hello world” on, or should I say get my “Hello Green”!

In a Python file, you just need to import board, and NeoPixels, define a variable telling the pi which pin you’ve connected to, the number of pixels, and the brightness level.

import board
import neopixel
pixels = neopixel.NeoPixel(board.D18,12,brightness=1)

Then you can either fill all leds with a colour like this with a value of up to 255 for RGB - so shown here is full green! Hello Green!

pixels.fill((0, 255, 0)

Or specify one LED only like this (first pixel is blue).

pixels[0] = (0, 0, 255)

It was really satisfying to see the lights come on - I’d been a bit worried that I might need a second power source beyond the 5v that the Pi’s pin puts out, but with just 12 Neo pixels this wasn't a problem.

With previous Pi projects I coded directly on the Pi with a monitor plugged in. However, having a monitor next to the lamp on a shelf would have killed the look I was going for, so I quickly began editing the code using the Juice SSH Android App on my phone, but as you can imagine this soon proved a bit piddly and problematic. As part of the set up process I had run several wget commands, and so I thought perhaps I could just edit and host the python files on my own website, and wget them over to the pi. So that’s what I ended up doing, using the CodeTasty web IDE on my Chromebook.

With 12 LEDs and 16 million colours combinations, the possibilities were endless and before long I had coded a few sequences and had managed to sit the NeoPixel ring in the base of the lamp. See the video above for the lamp in action.

I had two programs to substitute for the GRO clock day and night settings: A drifting off program which slowly dims from full blue, and then remains at a low level as a night light; Mr Sunshine slowly warms up to full brightness at a scheduled time in the morning.

Goodbye Mr Sunshine:

def goodbye_mr_sunshine():
for x in range(5, 256, 5):
brightness = 256 - x
print(brightness)
for y in range(12):
pixels[y]=(0,0,brightness)
time.sleep(0.5)
print(y)
goodbye_mr_sunshine()
Night light after fading from full blue
Night light after fading from full blue
Night light after fading from full blue

Hello Mr Sunshine:

On the way to full brightness
On the way to full brightness
On the way to full brightness
pixels = neopixel.NeoPixel(board.D18,12)
def hello_mr_sunshine():
for x in range(5, 256, 5):
print(x)
for y in range(12):
pixels[y]=(x,x,0)
time.sleep(0.1)
print(y)
hello_mr_sunshine()

To get these programs to run remotely I first considered whether I could have the Pi broadcast its own WiFi network, for a device to join and then some how control the lamp.

In the end, I wrote a program selector python script which checks a JSON file on my site to see if the program status has changed. A super simple webform sets the program by passing its name to the JSON file through a URL variable and a PHP script.

import urllib.request
import datetime
import time
import json
import re
import mechanize
import psutil
import os
url = 'https://reveleigh.com/lamp/sunshine-lamp/alarm.json'
req = urllib.request.Request(url)
r = urllib.request.urlopen(req).read()
cont = json.loads(r.decode('utf-8'))
h = cont["hour"]
m = cont["minute"]
#Get times info
now = datetime.datetime.now()
alarm = now.replace(hour=h, minute=m, second=0, microsecond=0)
alarmEnd = alarm.replace(hour=h, minute=m+5, second=0, microsecond=0)
alarmReset = alarm.replace(hour=h, minute=m+10, second=0, microsecond=0)
#killing process function.
def killAllButParent():
for proc in psutil.process_iter():
pinfo = proc.as_dict(attrs=['pid', 'name'])
procname = str(pinfo['name'])
procpid = str(pinfo['pid'])
if "python" in procname and procpid != str(os.getpid()):
print("Stopped Python Process ", proc)
proc.kill()
#I it time to wake up?
if now > alarm and now < alarmEnd:
#If alarm is inactive run alarm
try:
url = 'https://reveleigh.com/lamp/sunshine-lamp/alarm-status.json'
req = urllib.request.Request(url)
r = urllib.request.urlopen(req).read()
cont = json.loads(r.decode('utf-8'))
print(cont["status"])

if cont["status"] == "I":

br = mechanize.Browser()
br.open("https://reveleigh.com/lamp/sunshine-lamp/alarm.php?a=A")
#Kill any other programs running
killAllButParent()
#Run the morning alarm
import morning
#Set alarm to activeexcept:
print("An alarm error occurred")
else:try:
url = 'https://reveleigh.com/lamp/sunshine-lamp/program.json'
req = urllib.request.Request(url)
r = urllib.request.urlopen(req).read()
cont = json.loads(r.decode('utf-8'))
br = mechanize.Browser()

#Stop other Python processes if not clear
if cont["program"] != "Clear":
killAllButParent()

print(cont["program"])
if cont["program"] == "Off":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import off
elif cont["program"] == "Morning":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import morning
elif cont["program"] == "Drifting":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import drifting
elif cont["program"] == "Maze of Triangles":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import random_triangle
elif cont["program"] == "Vortex":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import single_dance
elif cont["program"] == "Shimmer":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import shimmer
elif cont["program"] == "Colour Wheel":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import colour_pulse
elif cont["program"] == "Reboot":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import reboot
elif cont["program"] == "Shutdown":
br.open("https://reveleigh.com/lamp/sunshine-lamp/program-select.php?p=Clear")
import shutdown
else:
print("Clear")

except:
print("An light exception occurred")
#Set the alarm to inactive
if now > alarmEnd and now < alarmReset:
#Reset the alarm
br = mechanize.Browser()
br.open("https://reveleigh.com/lamp/sunshine-lamp/alarm.php?a=I")

Finally, I used the crontab file on the pi to schedule the program selector script to run once a minute, which felt a bit strange if I’m honest. I know it’s just a computer, but it seemed odd to think about a lamp checking my site over a thousand times a day, would my web server get irritated?

* * * * * python3 /home/pi/program-selector.py

Would my web server do whatever the web server equivalent of shouting “Shut up” is. Perhaps I could start serving the lamp some adverts - for filament enlargement kits, say.

As well as being a bit of fun, the lamp has worked a treat as a morning sunrise light. The message is clear: if it’s yellow, let it mellow, if it’s brown, flush it down. Wait. That is not it. Well, if it’s night, it will be blue so stay in bed, yellow means get up and, as it fades in, it’s a gentle wake up call without any retinas being fried.

I’m definitely going to be playing around with NeoPixels in the future. I’d love to put them in a quilt — maybe a quilt alarm clock, or a light up quilted fraction wall for the classroom. Or a Snapology moon with phases perhaps. Or a beacon that lights up every time the international Space station passes over. Or there’s a tweet by Elon Musk. Or when the vehicle behind gets too close...

A primary school teacher in the UK who likes tinkering with code and who sometimes tries to write good.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store