Fake candles, and flame algorithms

The Birch Books LEGO set that I have been modifying has an interesting “fireplace” at the first floor of the townhouse. I have been wanting to wire that up to light up for the evening scenes in my smart lighting board, but I want it to look at least a bit realistic. But how do you do that?

As I previously noted, there’s flame effect LED lamps out there, which were looked at by both bigclive and Adam Savage, this very year. But those are way too big for the scale we’re talking about here. Simplifying this too much, you can think of those lamps as round, monochrome LED panels showing a flame animation, like an old DOS demo. Instead what I have to work with is going to be at most two LEDs — or at least two independent channels for the LEDs.

Thankfully, I didn’t have to look far to find something to learn from. A few months ago a friend of my wife gave us as a present a very cute candle holder, but since we’re renting, that’s not really a good idea. Instead I turned on Amazon (but AliExpress would have done the trick just as well) for some fake candles (LED Candles) that would do the trick. These are interesting because they are not just shaped like a candle, but they have a flickering light like one as well. Three of them in the holder fit fairly nicely and did the trick to give a bit of an atmosphere to our bedroom.

I was full ready to sacrifice one of the candles to reverse engineer it, but the base comes off non-destructively, and that the board inside is very easy to follow. Indeed, you can see the schematic of the board here on the right (I omitted the on/off switch for clarity), even though the board itself has space for more components. The whole of the candle is controlled by a microcontroller, with a PIC12F-compatible pinout (but as Hector pointed out, much more likely to be some random chinese microcontroller instead).

It’s interesting to note that the LED starts in “candle” mode once turning the switch to the “on” position, without using the remote control. My guess is that if you buy one of the versions that does not come with a remote control, you can add that functionality by just soldering a TSOP381x decoder. It also shows why the battery on these things don’t really last as long as you may want it to, despite using the bigger, rarer and more expensive CR2450 batteries. The microcontroller is powered up all the time, waiting to decode some signal from the remote control, even if the LED is off. I wanted to record the current flowing through in standby, but it’s fairly hard to get the battery in series with the multimeter — maybe I should invest on a bench supply for this kind of work.

So how does this all work? The LED turns out to be a perfectly normal warm white LED, with a domed form factor that fits nicely in the carved space in the fake candle itself, and that helps it diffuse it. To produce the flame effect, the microcontroller uses PWM (pulse-width modulation) — which is a pretty common way to modulate intensity of LEDs, and the way most RGB LEDs work to produce combined colours, just like on my insulin reminder. Varying the duty cycle (the ratio between “high” and “low” of the digital line) allows changing the intensity of the light (or of the specific colour for RGB ones). If you keep varying the duty cycle, you get a varying intensity that simulates a flame.

The screenshot you can see is from Saleae Logic software. It shows the variable duty cycle in span of a few seconds, and it’s pretty much unreadable. It’s possible that I can write code for a decoder in the Saleae logic, and export the actual waveform it uses to simulate the flickering of a flame — but honestly that sounds a lot of unjustified work: there’s not really “one” true flame algorithm, as long as the flickering looks the part, it’s going to be fine.

Example of a generated Perlin noise waveform for the LED flickering

So, how do you generate the right waveform? Well, I had a very vague idea of how when I started, but thanks to the awesome people in the Adafruit Discord (shout out to IoTPanic and OrangeworksDesign!) I found quite a bit of information to go by — while there are more “proper” way to simulate a fire, Perlin noise is a very good starting point for it. And what do you know? There’s a Python package for it which happens to be maintained by a friend of mine!

Now there’s a bit of an issue on how to properly output the waveform in PWM — in particular its frequency and resolution. I pretty much just thrown something at the wall, it works, and I’ll refine it later if needed, but the result is acceptable enough for what I have in mind, at least when it comes to just the waveform simulation.

The code I thrown at the wall for this is only going to be able to do the flickering. It doesn’t allow for much control and pretty much expects full control of the execution — almost the same as in the microcontroller of the original board, that literally turns off the moment the IR decoder receives (or thinks it’s receiving) a signal.

I was originally planning to implement this on the Adafruit M4 Express with PWMAudioOut — it’s not audio per-se, but it’s pretty much the same thing. But unfortunately it looks like the module needed for this is not actually built into the specific version of CircuitPython for that Feather. But now we’re in the business of productionizing code, rather than figuring out how to implement it.

Upcoming electronics projects (and posts)

Because of a strange alignment between my decision to leave Google to find a new challenge, and the pandemic causing a lockdown of most countries (including the UK, where I live), you might have noticed more activity on this blog. Indeed for the past two months I maintained an almost perfect record of three posts a week, up from the occasional post I have written in the past few years. In part this was achieved by sticking to a “programme schedule” — I started posted on Mondays about my art project – which then expanded into the insulin reminder – then on Thursday I had a rotating tech post, finishing the week up with sARTSurdays.

This week it’s a bit disruptive because while I do have topics to fill in the Monday schedule, they start being a bit more scatterbrained, so I want to give a bit of a regroup, and gauge what’s the interest around them in the first place. As a starting point, the topic for Mondays is likely going to stay electronics — to follow up from the 8051 usage on the Birch Books, and the Feather notification light.

As I have previously suggested on Twitter, I plan on controlling my Kodi HTPC with a vintage, late ’80s Sony SVHS remote control. Just for the craic, because I picked it up out of nostalgia, when I went to Weird Stuff a few years ago — I’m sad it’s closed now, but thankful to Mike for having brought me there the first time. The original intention was to figure out how the complicated VCR recording timer configuration worked ­— but not unexpectedly the LCD panel is not working right and that might not be feasible. I might have to do a bit more work and open it up, and that probably will be a blog post by itself.

Speaking of Sony, remotes and electronics — I’m also trying to get something else to work. I have a Sony TV connected to an HDMI switcher, and sometimes it get stuck with the ARC not initializing properly. Fixing it is relatively straightforward (just disable and re-enable the ARC) but it takes a few remote control button presses… so I’m actually trying to use an Adafruit Feather to transmit the right sequence of infrared commands as a macro to fix that. Which is why I started working on pysirc. There’s a bit more than that to be quite honest, as I would like to have a single-click selection of inputs with multiple switchers, but again that’s going to be a post by itself.

Then there’s some trimming work for the Birch Books art project. The PCBs are not here yet, so I have no idea if I have to respin them yet. If so, expects a mistakes-and-lessons post about it. I also will likely spend some more time figuring out how to make the board design more “proper” if possible. I also still want to sit down and see how I can get the same actuator board to work with the Feather M0 — because I’ll be honest and say that CircuitPython is much more enjoyable to work with than nearly-C as received by SDCC.

Also, while the actuator board supports it, I have currently left off turning on the fireplace lights for Birch Books. I’m of two minds about this — I know there are some flame effect single-LEDs out there, but they don’t appear to be easy to procure. Both bigclive and Adam Savage have shown flame-effect LED bulbs but they don’t really work in the small scale.

There are cheap fake-candle LED lamps out there – I saw them the first time in Italy at the one local pub that I enjoy going to (they serve so many varieties of tea!), and I actually have a few of them at home – but how they work is by using PWM on a normal LED (usually a warm light one). So what I’m planning on doing is diving into how those candles do that, and see if I can replicate the same feat on either the 8051 or the Feather.

I don’t know when the ESP32 boards I ordered will arrive, but probably will spend some time playing with those and talking about it then. It would be nice to have an easy way to “swap out the brains” of my various projects, and compare how to do things between them.

And I’m sure that, given the direction this is going, I’ll have enough stuff to keep myself entertained outside of work for the remaining of the lockdown.

Oh, before I forget — turns out that I’m now hanging out on Discord. Adafruit has a server, which seems to be a very easygoing and welcoming way to interact with the CircuitPython development team, as well as discussing options and showing off. If you happen to know of welcoming and interesting Discord servers I might be interested in, feel free to let me know.

I have not forgotten about the various glucometers I acquired in the past few months and that I still have not reversed. There will be more posts about glucometers, but for those I’m using the Thursday slot, as I have not once gone down to physically tapping into them yet. So unless my other electronics projects starve out that’s going to continue that way.

Insulin, routine, lockdown, and electronics

As you may know if you read this blog, I have insulin-dependent diabetes. In particular, I use both fast and long acting insulin, which basically means I need to take a shot of insulin every morning (at around the same time, but there’s at least a bit of leeway around it).

This is not usually a problem: the routine of waking up, getting ready to leave, making a coffee and either drinking it or taking it with me makes it very hard to miss the step “taking the insulin”. Unfortunately, like for many others, this routine is gone out of the window due to the current lockdown. Maybe a bit worse for me since I’m currently still between jobs, which means I don’t even have the routine of logging in to work form home, and of meetings.

What this meant, is that days blurred together, and I started wondering if I remembered to take my insulin in the morning. A few too many times that answer was “I don’t know”, and I think at least twice in the past couple of weeks I did indeed forget. I needed something to make it easier to remember and not to forget.

Because insulin injections tend to be one of those things that I do “in autopilot”, I needed something hard to forget to do. Theoretically, the Libre App allows annotating that you took long-acting insulin (and how much) but that requires me to remember to scan my sensor right after and write down that I did. It’s too easy to forget. I also wanted something that would be a lot more explicit about telling me (and my wife) that I forgot to tell my insulin. And hopefully something that I wouldn’t risk telling I took my insulin too soon in the interaction, and then not actually doing the right thing (as sometimes I reach out for my insulin pen, realise there’s not enough insulin there, and need to pick up a new one from the fridge).

The Trigger: Yes, I Took My Insulin

The first thing I decided to do was to use the spare Flic Button. I bought Flics last year upon suggestion of Luke, and they actually helped immensely — we have one in the study and one in the bedroom, to be able to turn on the smart lights quietly (in the night) and without bothering with the phone apps. We kept a third one “spare”, not quite sure what to use it for until now. The button fits on the back of the cabinet where I keep my “in use” insulin pen. And indeed, it’s extremely easy and obvious to reach while putting the pen down — as an aside, most European insulin pens fit perfectly on a Muji 3-tier slanted display, which is what I’ve been using to keep mine in.

This is not exactly the perfect trigger. The perfect trigger wouldn’t require an action outside of the measured action — so in a perfect world, I would be building something that triggers when I throw an used needle into the needle container. But since that’s a complex project for which I have no obvious solution, I’ll ignore that. I have a trigger, it doesn’t risk getting too much in my way. It should be fine.

But what should the trigger do? The first idea I had was to use IFTTT to create a Google Calendar event when I pressed the button. It wouldn’t be great for notifying if I forgot the insulin, but it would at least allow me to keep track of it. But then I had another idea. I had a spare Adafruit Feather M4 Express, including an AirLift FeatherWing coprocessor for WiFi. I originally bought it to fix an issue with my TV (which I still have not fixed), and considered using it on my art project, but it also has a big bright RGB LED on it (an AdaFruit NeoPixel), which I thought I would use for notifications.

A quick Flask app later, and I had something working — the Flic button would hit one endpoint on the web app, which would record me having taking my insulin, while the Feather would be requesting another endpoint to know how to reconfigure the LED. The webapp would have the logic to turn the LED either red or quiescent depending on whether I got my insulin for the day. There’s a bit of logic in there to define “the day”, as I don’t need the notification at 1am if I have not gone to bed yet (I did say that my routine is messed up didn’t I?) but that’s all minor stuff.

The code for the webapp (Python, Flask) and the Feather (CircuitPython) I pushed to GitHub immediately (because I can), but there’s no documentation for it yet. It also doesn’t use the NeoPixel anymore, which I’ll explain in a moment, so you may not really be able to use it out of the box as it is.

For placement, I involved my wife — I want her to be able to tell whether I didn’t take my insulin, so if I’m having a “spaced out day”, she can remind me. We settled for putting it in the kitchen, close to the kettle, so that it’s clearly visible when making coffee — something we do regularly early in the morning. It worked out well, since we already had an USB power supply in the kitchen, for the electric cheese grater I converted.

Limitations of the Feather Platform.

The Feather platform by itself turned out to be a crummy notification platform. Don’t get me wrong, the ease of using it is extremely nice. I wrote the CircuitPython logic in less than an hour, and that made it very nice. But if you need a clear LED to tell you whether something was done or not, you can’t just rely on the Feather. Or at least not on the Feather M4 Express. Yes it comes with a NeoPixel, but it also comes with two bright, surface-mount LEDs by the sides of the USB connector.

One of the two LEDs is yellow, and connected to the optional LiPo battery charging circuitry, and according to the documentation it’s expected to “flicker at times” — as it turns out, it seems to be continuously flickering for me, to the point at first I thought it was actually the RX/TX notification on the serial port. There’s also a red LED which I thought was just the “power” LED — but that is actually controlled by a GPIO on the board, except it’s pulled high (so turned on) when using the AirLift Wing.

The battery charging LED does appear to behave as documented (only at times flickering) on the M0 Express I ended up getting in addition to the M4. But since that is not compatible with the AirLift (at least using CircuitPython), it might just be that this is also a side-effect of using the AirLift.

Why am I bringing up these LEDs? Well, if you want a notification light that’s either red-or-off, having a bright always-on red LED is a bad idea. Indeed, a day after setting it up this way, my wife asked me if I took my insulin, because she saw the red light in the corner. Yeah it’s too bright — and easy to confuse for the one that you want to check out for.

My first reaction was to desolder the two LEDs — but I have hardly ever desoldered SMD components, and I seem to have fallen for the rookie mistake of trying to desolder them with a solder iron rather than a hot air gun, and actually destroyed the microUSB connector. Oops. A quick order from Mouser meant I had to wait a few days to go back playing with the Feather.

A Better, Funnier Light

This turned out to be a blessing in disguise as it forced me to take a few steps back and figure out how to make it less likely to confuse the LEDs, beside trying to glue them down with some opaque glue. So instead, I figured out that there’s plenty of RGB LED lamps out there — so why not using those? I ordered a cheap Pikachu from Amazon, which delivered about at the same time as Mouser. I knew it was probably coming from AliExpress (and, spoilers, it pretty much did — only the cardboard looked like printed for the UK market by a domestic company), but ordering it at the source would have taken too long.

The board inside turned out to be fairly well organised, and it was actually much easier to tap into it than expected — except for me forgetting how transistors work, and bridging to the wrong side of the resistor to try turning on the LEDs manually, thus shorting and burning them. I ended up having to pretty much reimplement the same transistor setup outside of the board, but if you do it carefully, you only need three GPIO lines to control the lamp.

The PCB from the RGB LED light I bought. Very well organised. If you want to pair it to a MCU to control it, remove the crossed out IC, then tap into the blue-marked connections. Pay attention to the side of the resistor you connect this on!

The LED colour can be varied by PWM, which is fairly easy to do with CircuitPython. You only need to be careful with which GPIO lines you use for it. I used “random” lines when testing on the breadboard, but then wanted to tidy it up using lines 10, 11, and 12 on the finalized board — turns out that line 10 does not appear to have timer capabilities, so you can’t actually use it for PWM. And also, lines 11 and 12 are needed for the AirLift — which means the only lines I could use for this were 5, 6 and 9.

At this point, I had to change the webapp so that instead of turning the LED off to signify I took my insulin, it would instead turn the LEDs yellow, to have a bright and happy Pikachu on the kitchen counter. And an angry red one in the morning until I take my insulin.

Of course to be able to put the lamp in the kitchen next to the kettle, I had to make sure it wouldn’t be just a bunch of boards with cables going back and forth. So first of all, I ended up wiring together a Feather Doubler — which allows a feather (and a wing) to sit side-by-side. The doubler has prototype areas in-between the connectors, which were enough to solder in the three transistors and three resistors — you won’t need those if you don’t burn out the original transistors either!

Unfortunately, because I had stacking headers on my AirLift, even with the cover off, the lamp wouldn’t sit straight. But my wife got the idea of turning the cover inside out, using the space provided by the battery compartment, which worked actually fairly good (it requires some fiddling to make it stable, and I was out of Sugru glue to build a base for it, but for now it’ll work).

Following Up: Alternative Designs and Trimmings

So now I have a working notification light. It works, it turns red in the morning, and turns back yellow after I click the button to signal I took my insulin. It needs a webapp running – and I have been running this on my desktop for now – but that’s good enough for me.

Any improvement from here is pretty much trimming, and trying something new. I might end up getting myself another AirLift and solder the simpler headers on it, to make the profile of the sandwiched board smaller. Or if I am to remake this from an original lamp with working transistors, I could just avoid the problem of the doubler — I would only need GPIO wirings, and could use the prototyping space next to the M4 Express to provide the connection.

I did order a few more lamps in different styles from AliExpress — they will take their due time to show up, and that’s okay. I’ll probably play with them a bit more. I ordered one that (probably) does not have RGB LEDs — it might be interesting to design a “gut replacement” board, that just brings in new LEDs altogether. I ordered one that has “two-colour” images, which likely just means it has two sets of LEDs. I’ll be curious to see how those look like.

I also ordered some ESP32-based “devkits” from AliExpress — this is the same CPU used in the AirLift wing as a WiFi co-processor only, but it’s generally powerful enough that it would be able to run the whole thing off a single processor. This might not be as easy as it sounds to prototype, particularly given that I’m not sure I can just provide the 5V coming from the lamp’s connector to the ESP board (ESP32 uses 3.3V), and I burnt the 3.3V regulator on the lamp’s original board. Also since I need the transistor assembly, I would have to at least get a prototype board to solder everything on and — well, it might just not work out. Still nice to have them in a drawer though.

While I don’t have a 3D printer, and I’m not personally interested in having one at home, and I’m also not going into an office, which may or may not have one (old dayjob did, new dayjob I’m not sure), I might also give a try to software to design a “replacement base” that can fit the Feather, and screw into the rest of the lamp that is already there. It might also be a starting point for designing a version that works with the ESP32 — for that one, you would need the microUSB port from the USB module rather than the one present in the lamp, to go through the on-board regulator. This one is just for the craic, as my Irish friends would say, as I don’t expect that to be needed any time soon.

All in all, I’m happy with what I ended up with. The lamp is cute, and doesn’t feel out of place. It does not need to broadcast to anyone but me and my wife what the situation is. And it turns out to be almost entirely based on Python code that I just released under MIT.

My new friend who reminds me to look after myself!

Birch Books MCU Selection

A couple of people have asked me why I started the art project down the path of using an 8051 MCU, which is a fairly old microcontroller (heck, I found out I looked at those chips back in 2006!), rather than using one of the more modern hacker/maker solutions such as Arduino. The answer I already gave in that post: I had it already here.

I bought a devkit for it hoping to be able to hack on the LED heart I bought as a surprise for my wife on Valentine’s day, which was centered around the same micro. Now, with hindsight, that was silly: the board was explicitly marked with an AT89S52 name, which is a much more common chip, and probably one for which I could have found a devkit/programmer in much shorter time, but it turned out to be a nice exercise nonetheless.

Indeed, I ended up having to learn a lot more about this chip, its programming, and refreshing my (terrible) electronics understanding. And while this has been breaking my brain at times, it also stretched it to learn something new. I guess I now know how my wife is feeling while learning Python coming from a humanities background.

I had another micro at home. Some time ago I wanted to figure out how to send a certain sequence of infrared commands to my TV via Google Assistant (it’s a long story, sometimes my TV doesn’t initialize the audio return channel correctly), and I ended up buying (but never using) an Adafruit Feather M4 and an AirLift FeatherWing. I soldered the terminals and made sure they worked, but only played with it briefly.

The Feather comes with CircuitPython, a MicroPython implementation firmware, which actually is fairly nice to write simple logic for the microcontroller, and is very easy to deploy: you just need to copy the Python files in the virtual USB flash drive that appears when you connect the board to the computer. It also includes a very nice interactive Python shell you can use to experiment without needing to commit to code (yet). And with the AirLift you also get support for controlling remotely via WiFi, and setting up all kind of request handling.

On the other hand, the 8051 is a fairly complicated tool. The ISA has not had any refresh since 1980 for what I can tell, and that’s on purpose: binary and pin compatibility appears to be the main advantage on using 8051 derivatives chips (or cores on FPGA). You’d think that with that having stayed the same we would have very advanced toolchains for it, but you’d be wrong. As far as I can tell, the only maintained open-source compiler for this is SDCC, and even that barely just. You might have seen my rants about this on Twitter, and if not, fear not: I’ll write a post about it next week.

So why did I go for the 8051, which is significantly older, harder to write code for, harder to program (you either need a devboard, or make sure you provide the right ISP headers on the board), and with quite a few question marks on its availability?

Well, the Feather only has a few really general purpose I/O lines. While both the M4 and the ESP32 supposedly should have enough GPIO lines, the Feather is a specific configuration, that commits a lot of lines to specific usage, such as an I²C/SPI bus to communicate with different Feathers. The usual answer to this is to include something like the MCP23017, which is an I/O expander that you drive via the I²C bus. But as it turns out, not only I don’t have one of those at home, but even Adafruit appears to only sell it on an Expander Bonnet for the Raspberry Pi. I’m not sure why there’s no FeatherWing with it, despite the fact that they document how to use one with CircuitPython, and while I’m sure I could design one, or look for an unofficial one, it’s something I don’t want to get to right now.

On the other hand, 8051 and its clones come with a lot more GPIO lines, and most of those are uncommitted if you start from nothing. The DIP-40 packages have 32 lines, and if you don’t need to use external memory, you have at the very least 16 uncommitted lines. Of the other 16 lines, some are shared with other functions, including external hardware interrupts, serial port, and most in-system programming interfaces.

Now, theoretically it seems like the ESP32 chip also have quite a few GPIO lines, although I only counted 14 uncommitted lines on their QFN packages. I guess you can scavenge a few more lines by not using some of the features, but that might end up conflicting with the MicroPython interfaces anyway.

So yeah I will probably eventually move to a different design that includes the MCP23017. Maybe I’ll end up designing a Feather Base (if not a proper FeatherWing) for it after all, to prototype with the already designed (and sent to fab) actuator board. But that’s a story for another time.