Wow! Phew! I reached a prototyping milestone for a new project. Time to celebrate!
This post describes the The Dino Timer Concept. It focusses on explaining the functional prototype. Download the code at the end of this post. In the files I’ve tried to demystify each line.
This post is a resource that, I hope, will make it easier for others to create something similar. (Without having to be a programming genius).
The Dino Timer is a remote controlled timer. Like an egg timer, but with a dinosaur and remote control. The dinosaur turns to indicate the countdown. When it stops turning, time is up!
Why on earth do we need a Dino Timer?
The concept initially came while generating ideas for interactive wall art to entertain my 14 month-old boy. I intend to develop the Dino Timer as an interactive wall art piece, and maybe as a desktop or wall mounted work timer (a focus timer).
Today’s milestone is a functional prototype!
Getting to this stage was surprisingly difficult. It was like wrestling a dinosaur! Strangely I find the process of learning how to program electronics projects kind of addictive. It’s like I’m on a perilous quest to find some magical artefact. I know I’ll get there, it’s just a matter of persistence! And coffee.
The hardware is quite straightforward:
- Button(s) – the timer starts when the button is pushed. these are momentary (MOM) buttons, they’re only ‘on’ while the button is pushed.
- Radio transmitter and receiver – I’m using nrf24L01 radio modules for the remote control.
- Servo – to control where and when the dinosaur moves. Unlike a plain motor, you can tell a servo to go to a specific position. I could also use a stepper motor but the servo is fine for now. (Here‘s a good comparison of motor types.)
- Micro controller – I’m using a couple of Arduino prototyping boards.
- Dinosaur – I’ve decided to upgrade from a small plastic one to a bigger one made of silicon, which wobbles when it moves.
Circuit diagram (click to enlarge):
Programming the Dino Timer involved several elements of code. This is all explained in the code files, below. But in summary the elements are:
- The reading an input from the button.
- Writing an output to the servo.
- Transmitting and receiving using the radio modules. I learned this on a previous project. Not so straightforward, nor easy to find clear help for. I’ll explain that in a future post.
- The code for the timer, which involved two parts:
- to calculate the servo position, and
- to recognise a button press and activate the timer, and allow it to run to completion.
This last part was the real challenge for this project. It’s quite long-winded to explain the problem. But in short I needed a way to make the timer run once to completion, regardless of how long it takes you to press and release the button. AND for the timer to run to completion even if the button is pressed again while the timer is running (except in the case of a reset button, which I haven’t included yet).
I used three programming ‘tools’ I wasn’t familiar with – typedef, struct and function pointer. It seems there are not many resources that explain these things, and how they relate, without assuming a lot of prior knowledge. So for me, trying to figure out how these worked and how to use them was a frustrating process of trial and error.
Thanks to some expert tutelage from Clinton Freeman, I finally got the Dino Timer working!
I also found the following particularly helpful:
- The Bald Engineer has some easy to understand advice and videos.
- Craig Hollinger explained typedef and struct clearly in his youtube video.
What did I learn?
This kind of project (seemingly simple and kind of silly) is a great way to learn how to code. Some useful tips are:
Early on I relied too much on assumptions about what the code was doing, and what was going wrong. Including Serial.print messages throughout the code, wherever something is supposed to happen, helps track and troubleshoot the program. It’s like leaving breadcrumbs so you know where you are, and when you’ve been teleported somewhere totally unexpected. I would say de-bug, but I think for a while it was more like de-infest. Serial monitor helped a lot.
Annotated snapshot from serial monitor:
Draw the Logic
Stepping away from computer to draw the logic flow made it clearer what I needed to do. Particularly when it came to activating the timer in the right scenarios, and allowing it to run to completion. Drawing this out earlier and more iteratively would’ve saved me some time.
The timer has two states:
- Timer5Mode (timer is starting or running) and
- IdleMode (timer is not running. We’re waiting for a button push).
We need to change between these states at the right time, in addition to letting the timer keep going if it is going.
Here’s the drawing:
Here’s the corresponding code:
Understand syntax (programming language)
Sounds silly but there was one thing I kept ignoring, that eventually bit me. CHOMP! When declaring an array you specify how many spots it has eg int msg has one spot (why don’t I just use a plain single number variable in my prototype?). But arrays are 0 (zero) indexed – ie the first location is location 0, not location 1! So when reading or writing to the array you need to specify the location accordingly. And you need to specify the location, not just specify the array name. Easy place for silly mistakes.
Download it here (zip file contains ino and header files).
Please let me know if it’s useful. Post a reply with your own project.
- Fine tune the button delay
- Add a few more timer durations (buttons)
- Add a way to save the Dinosaur from extinction (a reset button)
- Maybe add a volcano and hot lava (LEDs that glow when time is up)
- Change to a continuous-rotation servo for full 360 rotation.
- Fine tune sweep angle.
- Test intuitiveness with neighbours and friends.
- Design bespoke circuit and PCB layout.
- Design the physical form, assembly, materials, hanging etc. Estimate production cost.
- Make and build final prototype.
- Take orders!