I’ve now built the aluminium frame and completed the Y-axis. Of course, this was not without it’s problems.
Firstly, I misordered – I was one set of uprights short. This may not be a massive problem though, as I hadn’t taken into account the size of the spindle when designing the X-axis, and it wouldn’t have fitted in the configuration I had designed for – That’s what you get for forging ahead with out good engineering drawings.
Other minor issues were easily fixed by reprinting some parts – I added limit switches into the motor and bearing holders (though I haven’t worked out how to make the switch on the bearing holder work yet), I made the driver carriage wider so the whole anti-backlash nut fitted completely and I changed the shape of the passenger carriage so it could slide over the entire stroke.
Everything went together quite well – I did my best to square everything up, using a shim I printed – the holders may not be exactly in the middle, but they are all consistently out, which is the main thing.
I was a little concerned that both carriages were rotating around the z-axis, but realised that was because they weren’t joined yet, so there was only two points of contact, rather than four.
To fix that, I cut out a 205mm x 205mm MDF spoil board, and attached it using a 0.33mm feeler gauge squared it against one of the uprights.
I’m not sure I can do more alignment without having a X-axis, which requires a redesign.
See the video below for the test! (Excuse the upright video – I need to get an iPhone holder)
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.
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.
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).
I’m pretty happy with how the aluminium frame has come together. I’ve kept the X-axis pretty simple, though I tried a few iterations before coming to this shape.
Originally I had the vertical X-axis supports butted on the top of the horizontal Y axis base, but I was concerned with keeping the vertical… vertical. I could have used right angle brackets, but decided that by putting them in the inside of the base, I can add additional points of contact that would better support them. This configuration also gives a slightly larger base, so should make it slightly more stable. They are now attached in two dimensions which effectively works like a right-angle bracket.
The motor mount and bearing mounts are pretty simple, bridging the two verticals on each side. I toyed with running the bolts in a horizontal extrusion that would stop them from slipping down, but that would stop me from adjusting the heights when tramming.
On the topic of adjustments, I’m starting to regret the dual-carriage design, as there is an extra dimension that needs to be aligned – not only do I need to align the X, Y and Z axes, I need to make sure both slides are exactly parallel. I’ve bought a digital dial indicator which should help in squaring everything up – we’ll see how that goes.
I now have a complete bill of materials for the frame:
40×40 Aluminium Extrusion
40×40 Aluminium Extrusion
40×40 Aluminium Extrusion
40×40 Aluminium Extrusion
8mm Square Washer
16x16x6/M8 Square nut
M8x16 Button Head Socket Screw
End cap 40×40 Black
The order cost me just shy of $200, which already takes me over my $250 budget, but I’ve been reconsidering how much I’m spending, as I assumed I could use my Dremel 4300. After a bunch of reading, I think I’ll need to by a different spindle that has less runout.
Initially I thought about mounting the electronics in the back of the H, trying to fit everything in the footprint of the mold. But if I could get lights on the back, there would be some cool effects I could achieve. To get a consistent glow, the LEDs would need to be wedged in the middle of the H.
This did make mounting the PCB difficult though. I decided that I would mount the H on a small plyth that would house the electronics.
Autodesk Fusion 360 can extrude type, so all I needed to do was pick my type face. I wanted something childlike (not Comic Sans) so I went with Titan One.
Next, shelled, then mirrored to form the two halves. I added some alignment holes, to make gluing easier and finally created some nubs that will act as anchors for the plyth. The nubs were printed as separate parts so I didn’t need to print supports.
Each of the two halves took around 2 hours to print. Of course, because of how FDM printing works, the result was pretty streaky. The silicon I had literally talks about how fine detail it is, so I would need to do something about the streaks.
My dad used to make scale model aeroplanes, and I always remember him filling the joints with wood putty and then sanding to get a smooth finish, so I thought I would try that.
It turns out the gaps were just too big, and using a water based putty while wet and dry sanding meant the putty would come off.
Next I tried an auto sealer that was supposedly sandable. This didn’t work either because it was too rubbery.
At this point I spent AGES wet and dry sanding, starting at 80-grit and worked my way up to 240 before I found out about auto primer/filler.
This stuff is designed to cover up small scratches in car body work, and is sandable, allowing you to get a really smooth finish.
I did two coats, and sanded with wet and dry, 400 grit, and then a final coat before finishing with an 800 grit. It worked really well. It also saved a lot of time – sanding to a smooth finish is hard.
You might remember the Makibox A6 – it was a sub-$400 3D printer that, like a lot of cheap printers at the time, was crowd-funded. It took forever to deliver, and there were a lot of problems with it.
Personally, I managed to print a single cube on my first print. On my second print something went wrong and I blew up the control board. I suspect because of the stalled extruder motor. The extruder needed replacing, as did one of the plastic lead screws (that was my fault – I over tightened it).
In the process of trying to get the parts replaced, the delivery got lost – they claimed it had been delivered, but I hadn’t received yet. While trying to work this out, I had to quickly move interstate for work. To make matters worse, the company that made the Makibox disappeared around the same time, so I resolved myself to writing off the printer.
I decided to move to Melbourne permanently, so I flew back to Perth to collect my belongings – included what was left of the Makibox – and jammed it into my car for long drive over the Nullarbor.
And there is sat almost four years – dejected, in a cardboard box in my workshop.
On a recent trip back to Perth, my mother handed me a package which a person I worked with have given her. Apparently. it was delivered to the office years ago – so I had no idea what it was.
Low and behold, It was the replacement parts from my Makibox! Well, this was a sign. I put the parts next to the printer, as I wasn’t sure what I was going to do with it. I had an M3D printer which was pretty terrible – maybe I could frankenstein the two designs and get one printer out of them?
Fast forward a couple of months – I come in to a bit of spare cash after selling off my time tracking application, and I decide to bite the bullet and buy a real 3D printer – a Lulzbot Mini. After setting it up and kicking out a number of awesome prints, I placed the M3D next to the Makibox. I now had a collection of old, cheap and not very good printers. I had to do something about that.
Upcycling a Makibox
The Makibox has some decent steppers and screws in it (the M3D really doesn’t – half the problem really) so I started looking at the parts and wondering if I could convert it to a PCB mill. Ideally I’ll eventually want a proper mill that can do aluminium and stuff, but I reckon I can cobbled together something good enough to grind a few hundred micros of copper off some fibre glass. Bonus points if it’ll drill through holes.
What’s the worst that can happen? I have a broken Makibox?
I’ve been doing some research into PCB mill designs over the past couple of weeks, and I’ve decided to go with a fixed gantry design (based heavily off the cheap Chinese machines). This means I only need three motors, and three lead screws.
I’m giving myself a $250 budget for the conversion.
Due to the existing hardware that I want to reuse, the actual build area for this machine will be relatively small, so I’m hoping that will help with the rigidity of the system (smaller builds should be stronger than larger ones). Given that this PCB mill gets decent results with a wood base, I’m feeling pretty confident we can get some good results with this.
1 x 218mm T8.8 (8mm diameter, 8mm travel per revolution) trapezoidal lead-screw
1 x 165mm T8.8 trapezoidal lead-screw
1 x 147mm T8.8 trapezoidal lead-screw
2 x 226mm x 4mm steel rod
1 x 170mm x 4mm steel rod
1 x 164mm x 4mm steel rod
A bunch of cap hex screws
Plastic anti-backlash nuts
The plastic anti-backlash nuts are surprisingly good – I can’t detect any backlash (with the naked eye). The injected plastic piece has some thread that acts as a preloader – quite clever really. Regardless, I decided to order some metal anti-backlash nuts – I’m not sure how the plastic will hold up to the additional force of milling.
Everything else looks useable (at this stage) – I’m a bit concerned that the steel rods aren’t straight enough, but I’ll run with them for the moment.
I’m going with 4040 aluminium t-slot for the frame. I’ve found a Melbourne based supplier so I should be able to get high-quality stock quickly (and cut to size!). But before I order them, I’m going to design the mill in Fusion 360 so I can test for fit and size.
You can see the render of the Y-axis here:
The X-axis will be a (wider) copy, rotated 90 degrees. The Z-axis will still need some thinking.
I will print the motor bracket, bed and bearing holder on my Lulzbot Mini. This is is the cause of the weird design – it needs to fit in the 150mm x 150mm build envelope of the 3D printer.
Based on the dimensions from Fusion 360 the design should allow a Y-axis travel of around 168mm 156mm (Update: I didn’t take in to account the linear bearing width). I still have to work out the X-axis travel.
Long before Hugo was born, I had hatched a plan to build him a nightlight. Originally inspired by this, I decided to go for something less fragile – a simple H with some RGB LEDs.
Just before Hugo was born, I added a LIFX bulb to our bed side table, and added some Flic buttons that gave us better control on the lights. Using a Node Red flow, I setup the light to go to 5% brightness on a single click, 20% on a double click and a 2 second hold set the light to 100%. This worked really well: if we wanted to check on the baby, we could just single click, and get enough light to see him without waking him.
The downside was if the Flics stopped working we needed to use our phones, so the second requirement was a hardware switch to turn the light on and off. It should have configurable single, double and hold actions.
After Hugo moved to his own room, I wired up the same LIFX and Flic setup, adding a slow fade to the lights, so as to not startle the little fella when the lights switched on or off. I wanted the night light to do the same, so it would need some sort of tweening library.
Finally, a mate of mine was telling me about his kids grow light that turns on in the morning to let the child know that it’s time to wake up. I thought it would be kind of fun to have a cute sun rising animation. I thought about adding an alarm feature in to the light, but decided that I can do that using home assistant and node red, which saved me adding a Real-time clock and having to deal with times and other such nonsense.
Giving these requirements I went and ordered a tape of WS2812B LEDS from AliExpress ($12 for 100!) and got to work.
Making a plastic H
I needed a translucent H. My first thought was to try the usual places to see if there was something I could buy off the shelf. There was a few places that sold acrylic signs that would have been suitable, but they weren’t quite what I was looking for. I really wanted a completely milky white H with the LEDs embedded in the middle.
Well, I have a 3D printed, could I do something with that? I went in a hunt for translucent white filament. It turns out (for reasons I will discover later) that isn’t a thing. Odd.
I picked up some light blue translucent filament and did a small test print, but the print came out really streaky. Not what I wanted.
Then I remembered reading about resin casting. What if I could print a master, cast a mold in silicon, then cast the whole thing in resin? A quick Google for some tutorials and it sees plausible – in fact a bunch of people embed LEDs for cos play jewellery.
The problem is, all the examples I see are clear. You can get pigments to embed in the resin, but a white translucent one alludes me. Hmmm.
At this point I decided to go in to the local Barnes (a store that specialised in casting and other craft stuff) and had a chat with the staff. Apparently white translucent is really hard. The lady I spoke to thought that I might be able to get the effect I want by using a really small amount of pigment. Like, really small (she says that fully opaque happens at about 2%).
I buy a starter pack which has the 500mL of pink silicon, 500mL of resin and a bunch of measuring cups, containers and stirrers. I also bought some modelling clay and some spray on wax as I needed to make a two part mold. Unfortunately, this stuff ain’t cheap – all up it cost me $150.
We have two IKEA FILUR bins that we use in our kitchen – one for waste and one for recycling. To stay out of the way, they live in the butler’s pantry. This is a little bit inconvenient though – moving scraps around inevitably means dirty floors.
My wife decided to do a spring clean, and managed to free up a cupboard with the intention of installing cupboard bins. Easy enough. We started looking around, and found them quite small – we’d become accustomed to the good size bins that we already had. Not only that, but new units seemed quite expensive. We weren’t going to spend a lot of money and end up with something worse.
So I decided to build some.
The cupboard have shelf support holes, as most modern kitchens do, so I set myself a constraint: No drilling holes into the existing cupboards. This would allow us to restore the shelves if the bin-in-a-cupboard thing didn’t work, or we decided to move them to another cupboard, or we decided to move house, or some other reason that forced us to remove them.
The first step was the make sure the bins would both physically fit in the cupboard – and they did. By placing them sideways (Which actually made a lot of sense in this case) they fit with just enough space around them. This also allowed us to test a MVP – would having the bins in the cupboard work for us? After a week, we didn’t hate it, so on to the next step.
Time to jump in to Fusion 360, and have a bit of a play around with a few ideas and some dimensions.
My first thought was to have attach some drawer runners to two rectangles of wood that ran around the inside of the cupboard, but this seemed overkill, and the dimensions were a little too tight to make it really work. Next, I wondered about 3D printing some brackets that would hold the drawer runners. I jumped on to the Bunnings web site to find some drawer runners, and I found some likely candidates for just $11. The problem was (as always) no accurate design drawings or dimensions.
But for $11 (and Bunnings’ generous returns policy), I was willing to take a punt.
The next problem was how to attach the brackets to the walls of the cupboard. 3D printed plastic nubs probably wasn’t going to cut it – I could see them snapping off in the holes. Next, I thought about embedding some 5mm metal rod, or perhaps removing the plastic off the existing shelf supports. I then did a quick search on the Bunnings website and found these all metal shelf supports with metal lugs that would work perfectly (for a grand total off $2.67!). Off to Bunnings!
One sausage sizzle later, I had the bits I needed.
Now I had the dimensions of the drawer runners and the supports, I whipped up a quick design, and 2 hours later I had printed the first bracket to test for fit. Initially, I was going to rely on brass inserts and screws to secure the runners, but I added a small curve to add a some additional support. This worked out better than expected – the curves would happily hold the runners without the screws (although I still added two screws on the back off the runners to keep them in place when pulling out the bins). When it came to attaching the metal inserts, I thought of using heat like I did with the brass inserts, but it turned out a hammer and friction was enough to hold them in – and the platform that the bins would live in would actually push the runners out, holding the whole thing together.
So over the next 6 hours, I printed the remainder of the brackets.
Once the were done and installed, I could get final measurements for the shelf. This was where designing it in CAD helped – according to my calculations, it would need to be 420mm, and I was dead on. Initially, I was going to buy some melamine coated MDF, but then I decide to cut the existing shelf (which just so happened to be melamine coated MDF) to size.
Cutting the 500x550mm panel to 420x550mm was easy work, but the internal holes for the bins were a little more challenging as I couldn’t find my jigsaw. I used a multisaw, which in theory should be the same, but was ended up being slower and more difficult to use. As a result, the holes looked like it was cutout by a drunk monkey. Nothing a bit of rasping couldn’t fix. Besides – the bins will cover a multitude of sins. All in all, the result was good enough.
It was at this point, I made a minor mistake in drilling the holes for the runners – they are offset from centre, and I drilled one side on the wrong side, but that was easy enough to fix, just by drilling them on the other side of the centre line.
Putting it together was slightly more challenging, as I needed to screw in the support screws whilst in-situ, and had to do a bit of a contortion act to get them in. But once it was in, it all worked really well. The shelf could have possibly done with 1mm extra cutout, so the run was a little smoother, but it’s totally fine as is.
The other thing I would change it to make the non-door side thinner, so the there wasn’t such a massive gap between the cupboard wall and the runner – the gap on he door side is needed to give clearance from the hinges, and I went for symmetry, but it does look a little odd. It would have made the print time much less too. Oh well – next time!
So for a grand total of $13.67 (plus about $3 in plastic), 45 minutes off design time, and 8 hours of print time, our bins now live in a cupboard!
Technically, the OrangePI Zero supports a type of Power of Ethernet, but this makes it compliant.
..and uses a cheat – you can buy POE splitters off Aliexpress – this hack removes the Ethernet port off the OrangePI, and permanently attaches the splitter. I also 3D printed a case for it, which is the interesting part, as I experiment with post production.
I use an OrangePi as a server for my Flic bluetooth buttons. I use POE to power it, so I don’t need to bother with plug packs, however, it all looks a little untidy (why do Pi clone manufacturers always put the power plug on the front!?).
I’ve also been meaning to experiment with sanding and spray painting 3D prints, so I thought I’d kill two birds with one stone.
Desolder the ethernet and power cable from the POE splitter
Use ethernet cable to join to the two Ethernet pads. Make sure you maintain the twists between pairs. I also soldered two pin headers into the support holes either side of the Ethernet sockets, to give some physical support.
No need for to print supports – 20% infill is fine. Once printed, you need to cut off the board support clips at the top of the pylons – they don’t work. Drill two 2.5mm holes in the two rear pylons.
Insert brass inserts into the corner holes.
FDM 3D printing is quite streaky, and looks… well, like it was 3D printed. I print in PLA, so acetate vapor is out off the question, making good, old fashioned sanding and painting the easiest way to get it looking it good.
The first time I tried this I sanded the thing completely smooth, and it took ages. I found other people have had success using automotive primer/filler which fills smaller scratches.
I tried this, but the gaps were too big. I went aggressive, and started with 120grit wet-and-dry sand paper. I added another two coats of primer/filler. Next, I went to town with 400 grit, then 800 grit.
I wanted to see if I could paint a logo in the top, so I did an undercoat of satin silver, placed a sticker over it and then painted a top coat of satin grey.
It looked terrible.
The sticker lifted, so the edges off the logo were blurry.
Satin shows up ALL the gaps, so even after all the sanding, the lines were still visible
I over painted, so there was drips, and it looked thick and gross
The colour wasn’t… great.
I re-sanded with 400-grit to get rid of the paint, and polished again with 800-grit. This time I omitted the extra coat of primer/filler, and just applied two LIGHT coats of flat (matt) black paint. This time the result was great!
Matt paint actually fills gaps a little bit, so the result is much better. There are still some visible lines (in the right light), so clearly I need to sand more. Also – I missed some bits on the bottom section. Clearly I still need some practice.
I wouldn’t mind trying the satin finish again, with out being so heavy handed on the pain
DISCLAIMER: This project plugs in to the mains, which has dangerous voltages and can kill you. Never plug in the device working on this project – you can re-program using an external 5V supply wired up to the same pads that the red and black wires connect to (CONN1).
I have a Rancilio Silvia coffee machine, that needs time to warm up correctly in the morning – 30 minutes gets everything up to temperature, allowing me to draw excellent coffee shots.
For the past couple of years, I run a simple mechanical timer that turns on at 6am, and goes off at 8am which is fine for the days I go to work, but if I work from home, or it’s the weekend, I’m left with a cold coffee machine unless I turn it to manual mode – which often results in me forgetting to turn it off!
To get around this, I’d been planning on getting a smart switch which would integrate with my Home Assistant setup. I looked at the Belkin Wemo, but it seems a little expensive at $80 a pop.
I thought about designing and building my own one, but the prospect of messing around with mains power didn’t excite me, nor did 3D-printing a case – 3D printing plastic, by definition isn’t very fire resistant.
Browsing Hackaday.io, I stumbled across this project, and it got me wondering if I could find an ESP8266-based Australian WiFi outlet. After a bit of googling, I found something that at least looked the same for $AU20 delivered. Even if it wasn’t ESP8266, I could probably gut it and insert a custom board, so I ordered one.
It arrived pretty quickly.
I promptly pulled it apart. There was a daughter board that looked suspiciously like a ESP8266 although the footprint wasn’t the same as any reference design I could find.
So, I pulled the little metal shield off, and low-and-behold! An ESP8266! Now that I knew we were in business, I installed the iPhone application that comes with it, to try and work out how it was wired up.
This particular switch has an obnoxious blue LED that is used to indicate power, and network connection (it flashes when not connected). It also has a red LED that is on when the relay is turned on. Finally, there is a button that allows you to turn the relay on and off manually.
A quick google, and I found the pin out of the ESP8266 chip – now it was just a matter of tracing the wiring back to each LED and the switch. I also needed to find where the TX, RX, Reset and GPIO0 were so I could program it.
Here is what I found:
GPIO 4 is the Blue LED
GPIO 5 is both the Red LED and the Relay
GPIO 13 is the button
I’ve marked the TX, RX, Reset and GPIO0 pins on the above image. By wiring these pins up to a FTDI cable, I was able to reprogram the switch, thus freeing me from the shackles of the crappy iOS app, and allowing my home-assistant.io server to talk to the switch.
Now, thanks to a Home Assistant and a NodeRed flow, the coffee machine will turn on between 6:30am and 1pm everyday UNLESS it detects that I’m not home. Nice!
Now that I have the proof of concept code running, it’s time to modify the built in Arduino core library that handles OTA updates.
The existing OTA library takes a binary object and an optional MD5 hash (to verify the upload), stores it in flash memory, then swaps the old binary out of the new binary and reboots the device.
To do verification via digital signatures, we need three additional pieces of information: the developers certificate (used to decrypt the hash), the encrypted hash, and the Certificate Authority certificate used to verify the developers signature.
The CA needs to be compiled in to the source code – there is little point sending that along with our payload.
The developer certificate and encrypted hash on the other hand, need to be supplied with the binary . One option is to upload the three files separately, but this would require extensive reworking of the updater API, and of the OTA libraries.
A better option would be to somehow bundle all three files in one package, which is the path I am looking to go down.
So, the first thing to do is work out what the file format looks like.
The binary blob is of an arbitrary size, and starts with the magic byte: 0xE9, which I assume is an instruction that is required to start the boot process.
Our certificate is also an arbitrary size. The signature will be fixed size, but dependent on the algorithm we use. Clearly we need some way of instructing the updater code where the boundaries for each file are.
We could pack them at the beginning, and set the byte before the file with the expected length – ie if our signature was four bytes, and certificate was 6 bytes it might look like this:
[ 4 | s | s | s | s | 6 | c | c | c | c | c | c | … ]
but that would mean we’d have to move the data around, as the bootloader would be looking for the magic number in the position 0. I’ve decided to do it the other way around – I’m going to use the last two bits to signify the lengths, and then count backwards. ie:
[ … | c | c | c | c | c | c | s | s | s | s | 6 | 4 ]
I wrote a quick little c program that packages everything up.
This produces a Bundle.bin file that can be uploaded.So far, I’ve managed to decode the lengths, and find where the two files I’m interested are live. Next I need to pull the files out, and do the verification. I think I’ll sign the binary using MD5 for the moment, as the updater class already has that function built in, so I effectively get it for free.