Hugo just turned one, and to celebrate we bought him a Duktig kitchen from IKEA. Like everyone else we painted and added fake subway tiles, but I wanted to take it a bit further and add a working microwave panel.
Hugo is obsessed with pressing buttons and turning knobs – We were staying at an AirBNB recently that had a microwave that you controlled using one big knob and he loved it – so I thought I would model that.
I ordered a 4-digit 7 segment display, a rotary encoder and an aluminium knob, which I planned to run off an Arduino Nano.
A rotary encoder looks a lot like a potentiometer, however they work quite differently. For starters, there is no limiter so they rotate through a full 360 degrees.
But the main difference is how you interface with them: they output a digital code called a Gray code. Named after Frank Gray, it ensures that one-bit only ever changes at one time so we can be sure of the direction the shaft turns.
Of course, the library we are using hides this from us, so all we care about is the value that comes back.
The encoder I’m using also has a push button, which I’ll use to start and stop the timer. The library also abstracts this.
The four-digit seven-segment display has a built in driver chip that means we only need two pins to drive it: a clock and data. Again, there is a convenient library that deals with pushing data to the board.
I had six yellow LEDs that I pulled out of the night light I gutted to make an interim night light, so I repurposed them for this project. As the draw a total of about 120mA when on, they can’t be driven by the Arduino directly – I’m using a BC547 transistor to drive them.
I added a cheap, 8 ohm streaker than I’m driving directly off one of the Arduino digital outputs. There is a tone library that turns a GPIO on and off quickly enough to create a tone. I maybe regretting this already though – it can get quite annoying.
This microwave controller needs to be battery operated. To do that without costing me a small fortune in batteries, the controller needs to turn itself off. Luckily, the Arduino Nano supports a deep sleep which reduces it’s current draw. The Nano can then be woken up by a pulse on either pin 2 or pin 3.
By feeding the signal from the rotary encoder and the switch into those pins, any rotation of button pressing will wake up the processor.
There is a slight problem though: there are two pins on the rotary encoder, and one on the switch: we need another input.
Or do we?
Rotary encoders have a physical “click” (called a segment). On the particular encoder I have, each click goes through a complete Gray code cycle, meaning there is a guaranteed two logic level transitions on each pin per segment. And, if you have ever watched a small child spin a knob, you would have noticed that their developing fine motor skills result in big rotations. In this case I can happily take the output of one of the encoder pins, and be confident that it will always wake.
So, the switch is wired to GPIO 2, encoder pin A is wired to GPIO 3 and pin B is wired to GPIO 4.
There are four main parts of the code: reading the encoder, the display code, the code that puts the MCU to sleep, and the interupt handler that wakes it back up again.
Most of the heavy lifting for interfacing with the encoder and display is done by two libraries.
The encoder library uses polling rather than hardware interrupts (which is good because I would have run out of interruptible pins). Every millisecond it checks the state of the encoder, and can work out if it has been spun or not. This library exposes the delta, we we use to increment or decrement the display.
The library also provides a callback that is fired on button clicks. Each clock toggles the running variable and the returns control back to the loop.
The display library at it’s lower levels takes four bytes – one for each number. Each bit of each byte represents a segment of the display. Thankfully there are some helper methods to display common things like numbers.
You can download the code on Github.
Because all of the inputs are handled via interupts, the loop just needs to deal with updating the display.
The left variable represents the number of seconds remaining. The first thing to do is adjust it if the encoder changed. We simply add the delta to it. Note that his happens regardless of whether the timer is running or not – this means you can add or remove time even when the microwave is running.
If the timer is running and the LED is off, I turn it on (and vis-e-versa).
If the timer is running the variable automatically gets decremented every 1000 milliseconds.
If the variable is 0, the timer stops and I display the word end and sound the beeper. (The LEDs will also go off)
The display routine gets called every 500ms. Why every half second? So we can flash the dot to show that the timer is running!
I was hoping this would be a quick weekend project, so I threw the circuit together using perf board. Of course everything always takes longer than you expect, but it kind of worked out well, because the perf board made the feature creep easier to deal with.
I 3D printed a “case” though my printer’s build area was too small to cover the whole area, so I made an MDF backing plate. Pro tip: don’t use pin to mark construction lines: paint won’t stick to it. Also: prime MDF – it absorbs paint like no body’s business. What should have been two coats required four.
During testing I realised that there were LEDs on both the Arduino and the display that stayed on regardless of whether the Arduino was asleep or not. I measure the power draw whilst sleeping at it was sitting at about 15mA. A AA battery has a capacity of around 2400mAH, so a set would last around 160 hours or 6 days.
Clearly that is too high.
I removed the LEDs and that brought the draw down to 2mA, which buys me 1200 hours or 50 days. Better, but not amazing. Unfortunately, the Nano isn’t great as a lower power device. If I could be bothered removing the chip from the perf board, I could remove the FTDI drive and power regulator and probably claw back a bit of quiescent current.
I have ordered a boost converter so I can run the board off two batteries at 95% efficiency rather than the four at the moment so I might just use a couple of C cells which have 8,000 mAH capacity (nearly half a year).
See the microwave in action!