Trying to Reverse Engineer the Nanoleaf Shapes Controller
|I, and I think most people that have these Nanoleaf Shapes panels have a bit of a problem. See the controllers – these things, the thing that actually runs the panels – keep dying. I’m on my FOURTH in around three years, and while Nanoleaf are sending me free replacement controllers, at some point they are going to run out and stop making more. They are going to shelve the whole product line, and I’ll have some very expensive plastic hung on my wall that’s completely useless. This, by the way, is why I hate closed source stuff. When Nanoleaf does end-of-life the Shapes line, and that is when not if, everyone who has one will be up a creek without a paddle when it comes to repairing or replacing broken parts. If it was open source, or at least mandatory to make it open source when a line gets discontinued, the community could keep that stuff working and keep it from going to a landfill.
Anyway, the point is, I’m trying to do something about that. I am attempting to reverse engineer at least the very basics of how to get the panels to change colours, and this video is a mix of what I’ve learned so far, a bit of a guide on how you might go about reversing engineering electronics like this yourself, and a request for your help in figuring out the UART communication data. Let’s start with what I know so far.
The failure mode for the controllers is they utterly brick themselves. No lights on the controller, none on the panels, nothing. Dead as a doornail. No level of reset does anything, it’s just fully bricked. If your Shapes controller does that, at least for the time being you can head to Nanoleaf’s recall page and claim your free replacement controller. Since I have three bricked controllers – actually I can only find two, I think I threw one away – I decided to crack one open and see what’s inside. This thing is remarkably complicated. There are three separate microcontrollers in here – one MediaTek MT7688AN which runs OpenWRT and WiFi communications, one EFR32MG21 for BLE and Thread communications, and one EFM8BB10F8G microcontroller that does the communications with the panel itself. Yeah, complicated. The panels themselves are powered by a 42V power supply, and even more interestingly there are only three pins to connect the controller and the panels together – power, ground, and signal, and unlike the older Aurora panels this uses 3V communications rather than line voltage.
Each panel not only has three sets of LEDs, but it has its own microcontroller. Sadly I don’t know exactly what IC that is – although if anyone knows please do let me know in the comments below. Anyway, the signal wire I believe is a single-wire UART connection with an open drain for transmitting. It’s active low, and if it follows the Aurora signal it should be 8N1 and 115200 baud. I know that the controller does quite a lot of initialisation to work out what orientation the panels are in – the panels have six possible connection points on them, and I think each data line is connected to a different port on the controller the panel knows which ports are in use and what is connected either side of it. The controller, I assume anyway, does a tree search and that’s how it knows what order and orientation the panels are in.
Now before we go too deep into the weeds of the UART data, I wanted to talk you through how you might start to reverse engineer your own electronics, and what sort of tools you might need too. Generally you need access to the electronics – sometimes that is destructive like these controllers and panels, and sometimes you can get by with external access, but if you need internal access to see how it works, you’ll want a toolkit like the iFixit one. That’s not an ad by the way, I just genuinely like it and use it an awful lot. Once you have access, you can then work out at very least what chips are there and how it is wired. In my case that was to work out that the communications pin was connected to the EFM8 chip. Then you can start probing. Use a multimeter to check voltages – careful not to short anything though. You might then use an oscilloscope to look at what is going on, or maybe you’ll want a logic analyser. I bought this ridiculously cheap one from Amazon and use it with PulseView to capture the UART data. It’s a pretty handy bit of kit to have really. You might also want to try isolated testing – in which case you might need a lab bench power supply. I got this one on Amazon too – and I’ll link to everything in the description for you. Anyway, then you can look at the signals that are flowing and see if you can work out anything useful. You might be able to find SWD pads near a microcontroller and use something like this Segger clone to pull the firmware, but that is way above beginner levels – and frankly over my head too, despite writing firmware for multiple microcontroller boards myself – so I’ll leave some links to some excellent hardware hackers you can learn from in the description too.
I’m struggling to come up with any more general advice, so let’s move onto the UART data. Now this is the part where I need your help. I’ve published the pulseview captures on a github repo linked in the description, but I’m having a hard time deciphering them. I know that it does I think 4 byte pulse every 19 milliseconds, and 6 bytes for colour changes. I’m sure that part of it is the address for the panel, then I’m guessing red green and blue colour values, but I’m not sure on the order, and that would only make up 4 bytes. I’ve also captured the frame when you connect a new panel – which is frankly an insane amount of comms I can’t make heads or tails of. PulseView seems to pick different start and stop blocks randomly per byte and per frame, so I’m having a hard time decoding it. I’m incredibly new to PulseView though so I’m probably just missing a step or something.
I’ve also captured data while it was changing colours in manual mode – that might be 7 bytes instead.. Yeah I’m pretty lost here. I’m going to keep pouring over it, but if anyone with more experience in decoding this sort of stuff would like to give me a hand, I’d greatly appreciate it. Once I get a rough idea what data to fire at the panel, I’ll write some code on an arduino compatible board and use these flexible linkers I bought and chopped up to feed in 42V and give out data. Once I’ve got one panel working, the rest should be easy, right? Right… Anyway, that’s what I’ve got so far. I’m looking forward to getting this working, and of course anything I make will be open source on that repo. Right now I’m mostly just looking to make the panels change colours. Anything past that, like panel placement, is a lower priority for me. But again being open source if you want to give it a go, I’d love to see it. Submit a pull request!