Setting up & reverse-engineering the Kello display
To start on the project, I need to get my development environment up and running.
I'm used to working on frontend projects, where I can edit and run code on the same machine. But since I'm using a spare Raspberry Pi Zero W I have on hand, I'm going to be working mostly over SSH. Either that, or shell out for a mini HDMI adapter and a micro USB to USB-A hub, which won't be relevant to the final product. Plus, it will probably be a huge plus to be able to connect to the final alarm clock at any time to update software, fix bugs, or add new features.
So to start out, I followed this guide, which worked great. Within a few minutes, I've got an SSH connection and I'm installing packages.
Up next, I want to be able to connect to the device and edit files from my main computer using VS Code. After reviewing a few options, I was disappointed to learn that the official Remote extensions for VS Code don't support the ARM V6 architecture used on the Pi Zero. But, I was able to get the SSH-FS extension working as an alternative.
Putting that aside for the moment, I returned to my open SSH connection with the Pi in my terminal and installed Python 3.
sudo apt-get install python3-dev python3-venv -y
Next, I'd like to be able to push my code to Git, so it's time to install that and setup SSH access to my Github account.
sudo apt-get install git -y
ssh-keygen -t rsa -b 4096 -C ****@********
From there, I could view the generated file in VS Code using the SSH-FS extension, copy the public key, and add it to my Github account. Now I can push code from my Pi device directly to Github.
With the basics ready, it was time to define what I actually wanted to accomplish first.
I figure the best place to start will be the bare essentials of an alarm clock:
Displaying the current time
Waking me up on a schedule
That's a good MVP. Of course, I have all sorts of ideas for Spotify integration, controlling smart lights, and telling me the weather in the morning. But for now, those things will wait.
As I look forward on how to construct the alarm clock, though, I want to play to my strengths. Here's a few aspects of the interaction design I'm planning right now:
The device itself will have a simple interface, either via a 7-segment display, an LED dot matrix, a monochrome OLED display, or some combination of those. If I wanted a bright, hi-res touchscreen, I'd just stick with my phone.
The device will have a set of tactile buttons for all of the major functions which I care about when I'm in bed. Right now I can only think of a few:
Turning off the alarm in the morning
Turning off and on the alarm altogether
Turning off and on the lights in my bedroom
Maybe, activating a voice assistant (instead of hotword detection)
For everything else, including management of alarms and other features, I'll have the clock host a simple web interface accessible on my local network. I can connect via my phone before I go to bed to configure things if I want to change them.
Hacking the LED Matrix
Now that I'd decided on some basic features, it was time to figure out the display situation.
A few years back I first developed my interest in a smart alarm clock when I came across the Kello project on Kickstarter. I'd always wanted to be able to wake up to Spotify (I have a playlist full of Gregorian chants just for that purpose), but I also really wanted to leave my phone outside the bedroom, as I have a bad habit of getting sucked into newsfeeds in the morning instead of getting out of bed.
So I funded the project. A part of me was definitely hoping it would succeed and develop into something more mature than what launched, but that's a rarity with things on Kickstarter I suppose. Kello delivered on what was promised, but with compromises and little further development. For one, it was kind of annoying that it didn't connect to 5GHz Wifi, and I could never get my router to allow traffic between the 5 and 2.5 GHz networks, so I had to switch my phone's network every time I wanted to tweak my alarms or use any of the software features in the Kello app. It was such a hassle I just stopped using the device.
Besides the limitations, though, I eventually realized what I really wanted was an alarm clock I could hack on - improving the feature set, trying new ideas for my morning routine, even just telling me whether I can bike to work each morning.
So the Kello has been sitting in the supply bin - until now.
At first, I ripped it open because I figured the speaker would be useful. But then I started shopping online for an LED display and discovered there really wasn't anything better, or even comparable, to what the Kello offered. They've got 3 mini 8x8 LED matrixes with a footprint of just about 4 inches. It's enough space to write a simple word or two, but small enough for a reasonable device profile. Everything I found online was either too little real estate, too large, or some variant of 7-segment which wouldn't let me do alphabet characters very easily or legibly. My heart got set on the display which I ripped out of the Kello.
There was good news and bad news. The good news was, the LED matrixes were already conveniently rigged up on a discrete board which connected to the mainboard on the Kello via a 10-pin ribbon cable. That told me they had an LED driver on-board, which would be a huge shortcut on a lot of research and work for me. I kind of don't like soldering, and I'd like to avoid printing my own PCB.
The bad news was I had no idea how they were communicating with this board or how I could mimic it.
So the hard part began - I pulled the pins out of the plug connector on one end of the ribbon cable, fastened them onto a line of jumpers on my breadboard, and started playing around. I really didn't know what I was doing.
After a bit of running power to random things (probably not a great idea in retrospect), all I'd managed to do was get the chip on the board really hot. I decided to hold off on the experimentation and do a little research.
That hot chip was a HT1632C, an LED driver chip with onboard memory for storing the current display pattern, and it could communicate via SPI over 4 pins. That was a start! I read over the datasheet, but as a software developer I was starting to feel overwhelmed. There's a lot I don't know.
Luckily, just searching for the name of the chip surfaced some existing code which claimed to interface. Of course, nobody was using a board quite like the one I pulled out of the Kello. After at least getting the code running on my Pi, I now had the difficult task of determining which of the 10 wires did what.
With 4 pins to drive the LED controller, plus 2 for power and ground, I figured there was a chance I could brute-force it. Several hours later, I gave up on that.
In my defense, the Kello engineers made the very strange choice of making one of the 10 wires red - which I figured was an obvious tell - but not actually using it for power input. So I spent a pretty long time swapping around wires trying to wake up a display that stayed dead, as I routed 5v power into a completely unrelated pin.
Back to the motherboard
Eventually, though, I got a little smarter. I plugged in the Kello motherboard and started reading the current it sent over the 10 pins on that end using a multimeter. At this point I discovered that the red wire was actually connected to the 10th pin, not the 1st one - a closer inspection of the board itself revealed the 1st pin was on the other end - and sure enough, when I tested the real 1st pin, it as delivering 5v power compared to a known ground. From there I basically guessed that pin 2 was ground, which checked out on the multimeter. So I basically started working from that assumption, which turned out to be a good one.
I'd like to say from there it was downhill, but it really wasn't. I now had 8 contiguous pins to search across for the right set of 4. I wasn't even really confident in the order of the 4 pins I would need to find. In fact, I didn't know what the code I was using actually did, nor was I confident in how I'd mapped the pins documented in the code with the ones shown in the chip datasheet - whose names were subtly different. The software wanted CS, WR, CLK, and DATA - but the datasheet documented CS, WR, RD, and DATA. Could I assume RD = CLK?
Turns out I didn't have to worry much about it - after inspecting the PCB design a bit more of the board itself, I came to realize the RD pin wasn't even connected to anything. The downside was, that left me with even less information - did I need to find 4 pins or 3? What did I do with CLK? Did Kello even use SPI, or was I barking up the wrong tree?
The light at the end of the board
Having only learned about most of these things in the past 24 hours, my chances didn't seem high of discovering the right answer through guesswork or brute forcing. Just as I was about to give up and turn back to buying a new display, though, I happened to connect a jumper from a pin on my Pi which was already set to high to position 7 on the board wiring, and there was a flash of bright red. I couldn't believe it at first - something had actually happened!
Turns out the 7th wire in the cable is a control wire for a single LED which is mounted directly on the board, next to the matrixes. So I didn't have any leads on the matrixes themselves, but now I could control this auxillary LED - which also proved my assumptions about the power and ground wires. I was back in business.
Although I was definitely questioning my sanity, I at least felt certain that I could get existing HT1632C code to talk to this board somehow - there weren't any other microcontrollers on the board itself, so at some level the Kello engineers had to be sending those signals on some of the remaining 7 pins I had not discovered the purpose of - and, since humans designed the thing, I could hopefully operate on the assumption that those pins would be contiguous. But I still didn't know whether it was 3 or 4, or what order. I wanted to narrow things down a bit further before returning to brute force.
There were still a lot of unknowns. Not to mention after so much random testing, I wasn't even sure I hadn't killed the HT1632C at some point. It did get really hot that one time.
Back to the motherboard, again
So I returned to detective work with the motherboard. I reassembled the original 10-pin ribbon cable connector and got all the components back together again in their original form. I crossed my fingers and powered it up - and to my relief, the display lit up. At least I hadn't fried anything.
From there it was a matter of pulling random wires out of the harness and cycling the power on the motherboard. If the display turned on, I could assume that the wire I pulled was related to one of the other components on the board. If not, I'd hopefully found one of the control wires.
This ended up working really well! Along the way, I discovered wire 3 was somehow related to the brightness of the display - when I pulled it, the display still lit up, but very dimly. I know the Kello had a display dimming feature, so perhaps that was the control wire for that. Still not sure.
But after pulling the rest of the wires out, I could safely say that only the final 3 - 8, 9, and 10 - were responsible for the LED matrix. The rest had no effect when I removed them from the harness.
We have our suspects
Of course, with only 3 controllers, SPI seemed to be off the table. I'd need to find some new code to try. Scrolling a bit further down on Google, I happened to find zzxydg/RaspPi-ht1632c, which came to my rescue. It seems @zzxydg had likewise not had luck with SPI and taken to bit-banging over the DATA wire, and their code was beautifully documented. I made a few modifications so it would work with only 1 panel, then I loaded it up on my Pi.
And at long last - after a few iterations of rearranging my 3 control wires - there was light!
There are still a few wires which I don't know the usage of, but I have what I need to start working on my own code to power the display. I found an NPM module that will interface with the Pi's GPIO, so I think I'll return to my comfort zone and write some TypeScript for the rest of the project if I'm able. Since the logic is so well-documented in @zzxydg's library, I think I'll be able to port it.
I have a (partial) pinout!
When all's said and done, here's what I now know about the pins on the Kello LED board:
1 - 5v in
2 - GND
3 - Seems to control display brightness - HIGH is bright, LOW dim
4 - ???
5 - ???
6 - ???
7 - Aux LED control, HIGH is on, LOW is off
8 - HT1632C CS (chip select) pin
9 - HT1632C DATA pin
10 - HT1632C WR (write clock) pin
This information was hard-won, and maybe it won't be useful to anyone else. After all, I doubt too many people bought a Kello in the grand scheme of things, and of those who did probably don't want to reuse its components. But hey, providing the information is free, so if you're out there, I hope you find this before you spend a few long days swapping jumper wires like I did.
Next up: I'll need to figure out how they're mapping the unusual display size (24x8) to the HT1632C, which usually powers 24x16 or 32x8 displays. I figure they're either using half of the former, or the first 24 rows of the latter.
And of course, actually telling time. And hooking up the speaker. And providing a web interface. I hope I've gotten past the worst of it!