-
Reverse engineering my new LCD
06/25/2022 at 14:51 • 2 commentsOK, “reverse engineering” is a bit of an exaggeration here, but that was essentially the vibe when I first hooked up my mystery LCD component to an Arduino Nano.
I’m not big on either Fritzing or Eagle, so I made a sketch of the wiring for you in Excalidraw :) The only thing that might need some explanation here is the 330Ω resistor between GND and the Nano board’s 3.3V output. I’m powering the board over USB, which is 5V. The 3.3V output comes from the on-board voltage regulator, but with no load I’m getting a higher voltage. The LCD component doesn’t like that: the off segments are turning black at a normal viewing angle. So I just did the easiest hack I could think of and added the resistor to create some load on the 3.3V VCC pin. This helps just enough, so I’m leaving it at this.
A bit of googling lead me to Valerio Nappi’s ht1621-7-seg library, so I went and wrote up a sketch that counted rapidly from 0 to 9999, took a deep breath, and uploaded it to the Nano. Here’s what happened:
That is actually... splendid news! The board can clearly talk to the LCD component, information is getting transmitted, and the display’s segments get turned on and off in response.
All that’s left is to figure out which bit in the library’s buffer corresponds to which segment on my display, because apparently this component is wired very differently from what Valerio was working with.
The magic in the library essentially boils down to this code snippet:
void HT1621::wrData(uint8_t data, uint8_t cnt) { uint8_t i; for (i = 0; i < cnt; i++) { digitalWrite(PIN_WR, LOW); delayMicroseconds(4); digitalWrite(PIN_DATA, (data & 0x80) ? HIGH : LOW); digitalWrite(PIN_WR, HIGH); delayMicroseconds(4); data <<= 1; } }
The loop transfers cnt number of bits from data, starting with the highest-order bit and moving right. This technique of controlling the levels on the communication pins straight from code is called bit-banging, and it’s a straightforward implementation of the wire protocol described in the HT1621 datasheet:
As I was experimenting I altered and reduced Valerio’s code in various ways:
- The original library has a 6-byte buffer, and always transmits all of it when updating the display. For some related display drivers that can control more segments this makes sense. But with my 32-segment LCD, only 4 bytes are ever used, so I reduced the buffer and don’t transmit the always-zero 16 bits during updates.
- The original class stores the index of the 3 pins it uses in memory, which makes sense in a general-purpose library. I switched to defines for this, eliminating another 3 bytes from my program’s memory footprint. This matters in the ATTiny85, where I only have 128 bytes! I’ll want to use them for cool animations and other funky behavior in the creature.
- I removed all functionality related to encoding digits and characters and moved that to a separate class. I consider that a different, higher layer; my HT1621 class only deals with controlling the display’s segments based on the bit values in a 4-byte buffer.
- I rewrote the command codes in binary notation, as that mirrors the specification in the datasheet more transparently than hex values. And I totally kept the Chinese comments, which must date back to anxzhu’s original library that Valerio forked :)
#define BIAS 0b01010010 // 1/3 duty 4 commons #define SYSDIS 0b00000000 // 关振系统荡器和LCD偏压发生器 ~ disable sys oscillator and LCD bias #define SYSEN 0b00000010 // 打开系统振荡器 ~ enable system oscillator #define LCDOFF 0b00000100 // 关LCD偏压 ~ disable LCD bias generator #define LCDON 0b00000110 // 打开LCD偏压 ~ enable LCD bias generator #define XTAL 0b00101000 // 外部接时钟 ~ external quartz crystal #define RC256 0b00110000 // 内部时钟 ~ internal RC oscillator #define WDTDIS1 0b00001010 // 禁止看门狗 ~ disable watchdog timer
Now that we've come this far, let me present to you the result of my hard labor: the mystery LCD component's segment <-> bit mapping!
You can find this in code/src/HT1621.h on Github.And this, of course, also means it's time to start being silly. Here’s a smiley frog face on a 7-segment display:
Links:
- HT1621 datasheet [archived]
- HT162x Application Guidelines [archived]
- Valerio Nappi’s ht1621-7-seg library
- The original library has a 6-byte buffer, and always transmits all of it when updating the display. For some related display drivers that can control more segments this makes sense. But with my 32-segment LCD, only 4 bytes are ever used, so I reduced the buffer and don’t transmit the always-zero 16 bits during updates.
-
Low-power LCD is... hard!
06/12/2022 at 11:42 • 0 commentsSimple, 7-segment monochrome LCDs have been on every cheap calculator and digital wrist watch for decades, so you'd think they are the easiest component to find for a low-power electronics project... But they are not! In reality, this has probably been the part of where I spent the most time looking for a solution.
There is no shortage of easy-to-use display modules for microntrollers if you're looking for an OLED display or even a 7-segment LED display. These are fun, but they are definitely not low-power.
Then there is an abundance of bare-bones LCD displays without a driver. These are parts with lots and lots of connectors, looking a little something like this:
And I don't need to, either: there are ready-made components to drive an LCD. After a great deal of searching I zoomed in on the HT1621, which seems to be the most widely used one for small displays with up to 32 segments. I could get one of these and hook it up with a bare-bones LCD display, except... The HT1621 has a lot of pins, and it comes in an extremely tiny form factor. Just to get started I would need to get a custom PCB manufactured, and I'm pretty convinced I wouldn't even be able to solder parts this small. I need a breakout board.
Which is where things get really, really difficult. It's exactly these breakout boards that seem to barely exist. Mohit Bhoite has apparently found one for his latest satellite, but it's unclear where it comes from. Maybe it's this part from Hexpert systems? There's something inside me that rebels against spending 12 bucks on what's supposed to be a super simple mass-produced component. [UPDATE: Mohit just tweeted about this, and it's exactly as I thought: his satellite uses the part from Hexpert.]
And so I turned to Aliexpress, where I eventually struck gold. The link will most likely be gone soon, so here's a screenshot of my bounty:
I placed my order, crossed my fingers, and waited... And true enough, in about four weeks I had a padded envelope in my mailbox with a literal bag of 10 of these things.
NOW the fun can start! But that will be a separate update.
Useful links:
- Driving an LCD display directly with ATtiny [archived]
- @MohitBhoite's LCD satellite [archived]
- Hexpert Systems LCD module [archived]