2020 Update - Much of the code and recommendations in this post will be well out of date! But I’ve kept it up as inspiration.
For Christmas, I decided to attempt to make magic as real as I could using the wonder that is electronics, programming and determination.
I set out to make a ‘Weasley’ clock. For those who don’t know, this is a magical device that lives in the Weasley household, however instead of displaying the time, it displays the whereabouts of each family member by pointing a named hand at a defined location such as ‘school, travelling, magic-ville etc’. My version has only one hand and that points to six different locations and consists of a Raspberry Pi, USB Mobile Broadband Modem, Arduino, ‘Servo’ Motor, Some Microswitches and more Pritt Stick than I’d like.
There were many quite drastic changes throughout the build process and as a pretty fixed deadline (christmas) so please accept that the solution I came up with may not be as elegant as possible - and I wouldn’t recommend anyone copy the code/circuits presented here verbatim for anything, but rather use it as a guide and a way of saving yourself the trouble of learning some things the hard way…
Requirements
The device has to work as if by magic. Therefore, apart from power, there could be no external connections to other devices (no Ethernet) and also without any configuration whatsover (no WiFi). It also had to be portable and not require much maintenance. Naturally, I couldn’t actually figure out how to make it really magical - so in order to know where I am - the clock looks up my location over the internet (that I update with a phone app or web interface) and positions the hand accordingly. Discounting WiFi and ethernet meant that GPRS or Mobile broadband was the way to go.
Design
It is possible to purchase GPRS modems that are compatible directly with an Arduino or PIC interface that would’ve done the job well, however the cost for such devices was always around £40 for a device to be sent from Hong Kong / China, taking time I simply didn’t have. The solution was clear - a Raspberry Pi (which I already had) and a second hand USB mobile broadband stick which I picked up on Tottenham Court Road for £8. This coupled with a pre-pay data plan should hopefully have the connection problem solved. The next stage was figuring out the hardware, and in particular some way of moving a hand to a precise location around an entire 360 degree rotation, and finally bringing it all together (hardware and software) into something that resembled a clock.
Step 1 - An Internet Connected LED
The RPi GPIO Librarires provide a good way of accessing the GPIO poins on the Raspberry Pi 2020: Use gpiozero instead and use the code on their website There are other ways such as wiringpi for those familiar with Ardunio and C++.
wvdial
Although the Raspberry Pi has the drivers already for a huge number of USB mobile broadband modems - the E160 included, Linux actually needs to know what to do with it! That is, what to dial, what information to send, and how to establish a connection. A great utility for doing nearly all of this is wvdial. This, when used with the pppd, will establish a working GPRS connection as a network interface. When the Pi first came out - getting this working was a bit of a nightmare, however now things have vastly improved. I’ll post some information about how I got it all connected shortly - but there are some excellent tutorials on this a quick Google search away!
The above script will do nothing other than light up the LED as connected in the configuration shown in the image above. If we’d like to control it remotely, there are two options, either someone of something pushes a command to the RPi, or the RPi pulls this comand from somwhere.
Push Commands
This would certainly be the most efficient way to control the LED. All we’d need to do would be to set up a server on the RPi and have it wait for something to connect and tell it what to do. Unfortunately, that last bit was the hard part with the current set-up. Whilst the USB modem reported an IP address to the Raspberry Pi, it turns out that it may not be the only thing with that address. Some research confirms that phone networks do tend to use NAT (similar to that on a home modem - except you can’t configure it!) to share out one address between multiple devices. Another way could be to have the RPi make a connection to a server somewhere and that server keep the socket open, but I didn’t want to set up a dedicated VPS somewhere in order to do this (my webhost would, understandably, not support this).
I also originally planned on having the Pi listen out for SSH connections and setting up a dynamic dns daemon on it so I could connect to it remotely. Unfortunately the situation with NAT rules this out too, which is a pain.
Pull Commands
This is the method I ended up using for all of the communications with the clock. The idea is that every minute, the RPi polls a web server for a file, and depending on the contents of said file, the light is turned off or on. This is simple as it only requires a few lines of Python code, however has the downside of requiring additional traffic which will mean more expense from the point of view of network traffic and data usage.
Step 2 - Making Stuff Move
Initially, I decided that a stepper motor would be the best choice for the project. I needed something that could rotate through a full 360 degrees in a constant direction (clockwise) and that I could control the speed and position of the spindle. Stepper motors are controlled by sending pulses of varying duration to the motor in order to control the angle of rotation. Check out the wikipedia page for more info about how they work.
The essential part of controling a stepper is the timing of the signal. Knowing this, I was unsure about whether or not the RPi would be suitable for this task as given that it’s running the whole linux operating system it isn’t really a real-time system, so timings might not be too accurate. Either way, I tried attaching the stepper motor’s driver board to the GPIO pins on the RPi and pulsing them in the same way the example Arduino sketch supplied with the motor did. Everything seemed to work perfectly, so I sat back and had myself an enjoyable Club Mate at the London Hackspace, where I did pretty much all of the work on the project after moving to the capital.
I was starting then to work out how to get the pointer to move to the correct part of the clock - however I wanted to be sure that the motor wasn’t drifting, so I set it off to do 100 rotations, came back, and, ah. Turns out it was drifting, and by quite a lot (about 20-30 degrees). So no good. I assumed this must be the timing problem, so tried again using just an Arduino, but no luck! I was using a very cheap stepper motor, but with no dedicated driver circuit to handle accel/decelleration, missed steps and the like. One of the ICs alone would’ve cost more than the motor, and good quality NEMA motors themselves also cost about £15, and are too large for what I wanted. I also didn’t like how the whole system was ‘open-loop’, with no feadback on the position of the motor shaft. Basically, what I needed was a servo. A 360 degree servo? Why yes, it turns out such things exist! Except it wasn’t quite what I was expecting.
I ordered a ‘Full Rotation Servo’ without properly reading the datasheet or understanding what it does. It’s not actually a servo in the traditional sense as far as I can tell, the only thing that you can control is the speed of rotation. I spent a while thinking about how to resolve this issue and decided that the best way forward would be to somehow add feedback to the motor. I had thought about using some kind of rotary encoder but these can be very expensive and would’ve required a fair bit of mechanics. I happened to have a few micro-switches with rollers on the arms and using one of the ‘heads’ supplied with the servo I put together this hack:
On the left is a ULN2003 control IC. This consists of several ‘Darlington Pairs’ and allow the Arduino to switch a higher current than it would be able to do so on its own. In the centre, an Arduino Duemillnova and at the right the stepper motor with a microswitch epoxy-ed on to the side. Every time one of the arms from the wheel passes over roller on the arm of the microswitch - it pulls an input on the arduino low. The Arduino counts these pulses and can hopefully work out how far the shaft has turned. I had to be careful to ‘debounce’ the signal coming in from the switch. ‘Bouncing’ happens when the mechanical contacts on a switch almost literally bounce off of one another, creating a noisy signal - shown on the right of the image below, instead of a nice clean one like that on the left:
If the Arduino simply counts all of the pulses it receives, it’ll count all of the short ones in between the switch being pressed by the arm and then it springing back up! Despite having come across this countless times before it caught me out again and it took me a few minutes of wondering what was going on and worrying that I’d irreversably glued a broken switch to the side of the motor to figure out what’d happened. I’ll post the Arduino Sketch I used to solve this on the code page [TODO - Link]. I’ve since discovered the ‘bounce’ library that may solve this problem better than my quick and dirty code, so I’d recommend checking that out.
(By the way - I know that all this is possible with a Raspberry Pi on it’s own, but as I was really pressed for time I found it quicker and easier to prototype the software and electronics with the Arduino I already had)
Whilst this solution was all very well for rotating the arm around 60 ( = 360 / 6) degrees, it’s no good for being able to work out where the hand is. This could be solved by always remembering the last place it was moved to and then counting 60 degree rotations from then to move it to a new place, but, like the stepper motor, one click out and it’s never going to be back in the right place (by itself), and that’s assuming the counting method always works. I decided that the quickest, cheapest and simplest way to solve this was simply to glue another microswitch on the side of the first one and then extend one of the arms out so it only hit it once per revolution. Then, whenever a pulse is received from the second microswitch the Arduino knows it’s got round to the start - a fixed point of reference. The first iteration whilst I was testing it extended this arm with several bits of old credit card glued onto the arm. Needless to say, this was totally useless for anything more than testing (it fell off after 10 mins) - but it was great ok for prototyping. Here’s a video of it in action:
The final version of this mechanism does away with the naff bit of plastic and has a nice aluminium disk mounted flush on the hub of the wheel and a M6 bolt head in line with the second microswitch. Stupidly I didn’t get a photo of it - I could’ve sworn I had! Sorry :(
As you can see - there’s a Raspberry Pi with a prototyping plate hat I’ve used to break out the GPIO pins on the Pi. Seeing as I had developed all the code for driving the motor for the Arudino, the Raspberry Pi needs a way to send the data it retrieves from the internet to the Arduino. There are many ways of doing this and I chose probably the most ridiculous and quick and dirty one that’s probably never been seen before. A couple of things I didn’t want to do:
-
Use the Arduino board with the RPi over USB - Seemed expensive, slightly wasteful for the tiny amount of data I needed to transfer and would’ve used up a lot of my power budget (more about that in the next section). Easily the simplest way though in terms of software.
-
I2C / SPI - I’m not even sure if both the Arduino (or at least the Atmega328) supports these without heaps of coding, and it looks like getting it to work reliably on the Pi is a bit of a work in progress without again lots of software/config problems. (I’m probably wrong about both of these but I didn’t get a chance to look into this. Please correct me in the comments if you’re knowledgeable - it’d be great to find out) Also the Rpi runs at 3v3 not 5v like the Arduino - which would mean some kind of level shifting or at the very least a resistor network would be needed to get them to play nice (i.e. Not destroy each other)
-
TTY from RPi’s serial port to Arduino - The only reason I didn’t do this was because all the development I was doing with the Pi was over it’s TTY port that I was logging in to with a USB -> RS232 at 3v3 lead. I don’t recommend this (it’s so much better just to SSH into it) as all the formatting (especially on something like VIM) just gets completely messed up. I don’t know why I stuck at it like this.
Given that the only data I was going to be sending would be a number between 1 and 6 and probably at the ver most every half an hour - I made my own protocol. It’s illustrated well in the video with the LEDs on the PiPlate - one line rises high and then an amount of pulses made on the other line. The Arduino counts these pulses and then starts the motor - waiting until the second microswitch is hit (12 o’clock) and then stops after counting this many pulses on the first switch input. This does mean that the hand always passes through 12 o’clock whenever it moves (so going from 1 to 11 means rotating almost 2 full rotations) - but I thought this an acceptable cost to almost guarantee that the hand will always be in the intended place.
In case you didn’t catch the video, here’s that last bit illustrated:
This works because the Arduino is capable of registering 3.3v signals as ‘logic high’ despite being run at 5v, although we can’t send signals back to the Pi. This is something I’d like to fix when it’s time to ‘upgrade’ the clock as it’d be very useful to know if the hand gets stuck or something. (I believe the Atmega328 will happily work at 3.3v - so might be simpler just to give it its own power supply).
Step 3 Code
This will be incredibly out of date!
It’s not elegant work but it gets the job done!
Raspberry Pi
As I mentioned earlier - all the programming on the Raspberry Pi is done in Python. Sure - it has quite a serious overhead of being interpretted, especially on an embedded platform like the Pi, but in this situation it’s hardly a dealbreaker!
Arduino
Step 4: Putting it all together - circuits and glue
So, all the parts are made as a prototype. At this point I had about two days before I was skipping town to spend christmas with my family (as was my girlfriend) - so I needed to get this finished fast. Please forgive the lack of photos of the builds!
Putting together a circuit
I didn’t want to have to use up the Arduino shield to make this and decided to make the power supply, motor control circuit and Arduino circuit all on one piece of veroboard. This is another bit I don’t have a photo of :( - so here’s the circuit diagram:
That’s all there is to it really! Surrounding the voltage regulator is a chunky heatsink. This is mainly because the RasPi and GPRS dongle combined happily much through about 800 mA of power. Given that there’s a 2v drop across the regulator that (2 * 0.800) = 1.6w of power that’s being dissapated across it. On its own it will get incredibly hot, so a heatsink does a good job of bringing it down to a good temperature.
The last thing I took a picture of before finishing it and wrapping it all up was the many iterations of the clock face. Originally I was going to laser cut the dial out of MDF and print the design onto paper but there was just no time! It was back to good ol’ handwriting and drawing that saved the day!
The body itself was an old chinese clock from a car-boot sale in Vauxhall. It was pretty beaten up and needed new feet. I removed the original mechanism (and sold it on eBay). I discovered that spray-paint is wonderful and made a nice heavy board backing for the face that hides some of the workings. In this photo you can just about see the circuit board that I made for the Arduino and motor driver.
And so that’s it! She got it on Christmas day and was working - checking in every minute with my webserver until the begining of February when it got moved next to a wall. Unfortunately the mobile broadband stick doesn’t seem to be able to pick up and maintain a solid connection there - and it’s location at the bottom right of the clock under the pi and pi-plate probably doesn’t help. Even worse, the Pi doesn’t know to try to reconnect if no connection is detected. I wrote a simple script to try and fix this but it’s not really helped much. Fortunately however, the mobile broadband stick contains a connection for an external antenna. I’m about to order one and install it when I’m next visiting, although maybe having a GSM antenna stuck out the back of it might take away from the magic - it’d be good to have it reliably working again!
The next step is to figure out a way of always getting it to update correctly, instead of trying to use the terrible webapp I made on my iPhone. Perhaps attaching a modem and arduino to my bag or car?!
Anyway - if you’ve got this far reading, thank you very much!
Again, massive thanks must go to the London Hackspace and its wonderful community for the inspiration and encouragement to go for it, and think of new ways to solve problems and setbacks.