GM12864-59N I2C LCD Display

Low power, low cost graphical displays are super useful for many embedded systems. My applications generally use them to provide status and a basic UI; high speed is not required. I am particularly fond of displays that can use the ubiquitous I2C communications bus since that doesn’t consume extra uC pins. I2C also makes it easy to retrofit peripherals into existing designs; I always bring the I2C bus + power and an interrupt line out to an expansion port.

I’ve used small (1.3″) OLED displays with I2C interface in several designs and they work great, but the screen is fairly small (albeit high contrast), OLEDs consume a lot of power, and you can’t leave ’em on all the time without burning them out (OLEDs have a limited number of on-time hours). So I decided to try an I2C LCD display.

The GM12864-59N by TZT is a 128 x 64 pixel LCD display with LED backlight. It comes in blue, gray, and black. It is available for $3.30 in qty 1 on AliExpress (if you’re only buying a few, this vendor has lower shipping cost). It combines the popular Sitronix ST7567S LCD controller (datasheet) with a 128×64 LCD display with 10+2 flexible connector. It comes with a pre-installed 1×4 0.100″ connector (3v3, GND, SCL, SDA) on a PCB with 4 corner mounting holes.

It’s almost perfect; the display works great and the ST7567S is both well supported with libraries if you don’t want to roll your own (e.g. U8G2 and U8G8 or this one derived from here) and provides a great deal of flexibility. The only problem is that the LED backlight (side light) is hard-wired to power (you can’t turn it off) which is fine for AC-mains powered applications, but a real bummer for battery-powered devices (where LCD displays are normally so attractive).

GM12864-59N LCD display with backlight

I tried disconnecting the backlight (remove the 100R current limiting resistor R5), but the LCD contrast is then so poor that it is unusable. It’s actually much worse than the picture below suggests which benefited from the optimal camera angle and the more sensitive camera sensor; for mere humans, the display is completely unusable without the LED backlight.

GM12864-59N without backlight

So this display might make it into my next AC-powered design, but for battery powered devices, I need something that lets me control the backlight.

Nordic Power Profiler Kit II (PPK2)

I do a lot of IoT development involving battery-powered wireless devices. These devices must have very low average power consumption to facilitate long battery life. They typically spend most of their time in a low-power sleep mode, drawing a few uA or even nA and then wake periodically to take measurements, operate controls, and transmit and receive messages. Transmitting can draw hundreds of mA.

So the dynamic range of current draw can span 5 orders of magnitude! Moreover active periods are often very brief (sometimes just tens of uS). Measuring that sort of highly dynamic power consumption with fast transient events is a big challenge.

Current is generally measured by measuring the voltage drop across a shunt resistor. Unfortunately, a shunt resistor large enough to allow measuring a few uA will introduce unacceptable voltage drop if trying to pass 500mA. So measurement devices must have many shunts and measurement circuits and be able to switch them in/out of line very rapidly while sampling the voltage drops across the shunts very fast.

My go-to device for this sort of dynamic power analysis is the Joulescope which is simply phenomenal. It has 1.5nA-1mA resolution (depending on the measurement range), samples at 2MS/s (250kHz BW) and switches shunts as fast as 1us. The software is excellent too. The only problem is: it’s expensive (around $1K), so it’s not something I can put on every bench or easily design into test fixtures.

Hence my latest tool: the Nordic Power Profiler Kit II (PPK2) which is sort of a poor-man’s Joulescope. It has many of the Joulescope’s features, but all are spec’d significantly worse. It’s also 1/10 the price. It also has one feature that the Joulescope lacks and is quite useful. The PPK2 is a credit-card sized device, powered by one or two micro-USB cables (depends on how much current you need…in my case, one is usually enough). It samples much slower (100Ks/s max) and is limited to 5V; resolution varies from 100nA to 1mA depending on the shunt range, it doesn’t measure voltage at all (so you can’t use it to observe voltage drop), and the software is significantly less mature. It looks like a bare board, but the components are actually covered/protected by a clear acrylic shield so it’s bench/desk safe.

On the plus side it has a built in programmable power supply that can output 0v8 to 5v0 (drawn from the USB supply). That by itself is an incredibly handy feature. With the Joulescope, I need it and a bench power supply to power the DUT. The ability to power a 3v5 DUT *and* monitor its dynamic power behavior while only tying up one USB port and the bench space needed for a credit-card-sized device is super-cool. It also has 8 digital inputs you can use as a poor-man’s logic analyzer to correlate digital events (e.g. turn on transmitter) with power consumption. The Joulescope has such inputs too.

So far, I like it. The measurements match my Joulescope nicely – except for very fast transient events where the Joulescope shines and the PPK2 suffers. The built-in programmable supply is awesome. The software needs some work. Most critically, the data logger needs a continuous mode where it fills the RAM buffer and then wraps; the software currently fills the buffer and then stops, requiring a manual restart to keep monitoring current consumption and resetting all counters. This is particularly bad when what you want to do is measure average power consumption over a long period (e.g. a day or a week). At 100Ks/s, the RAM buffer fills very quickly so you can’t monitor the DUT at high speed for more than 500s. At 1Ks/s you can monitor for 13h, but fast events will be missed or improperly measured which defeats the purpose of such devices. What’s needed is a continuous mode that wraps when the RAM buffer is full but keeps accumulating average, max, and total power used. (Nordic are you listening?)

Overall, I’m pleased with the PPK2 so far and expect to buy more for use on benches and in test fixtures. If you can’t afford a Joulescope (or just want a super-compact USB-powered variable supply), the PPK2 seems like a great choice.


There are three things every STM32 developer wants from a debug dongle:

  1. Power (3v3, 1v8)
  2. SWD
  3. UART

    So I was excited when ST released their next gen debug interfaces (STLinkV3) and had included support for 1v8 targets and a UART. Was third time a charm? Unfortunately, not. Although the UART and support for lower-voltage targets is a welcome addition, ST made three unfortunate moves with the MINIE that are hard to fathom:
  1. Most notable was their attempt to force use of the STDC14 connector by *only* providing a 0.050 pin header for connections to the target via a fairly fragile connector. It would have been *much* better for it to have a shrouded 2×5 0.100″ pin header (like the “aluminum shell” STLinkV2 clones show below). These would allow use with the ubiquitous Dupont jumper wires that litter every developer’s desk. A tiny PCB with an SMT 2×5 female 0.100 on one side and STDC14 male on the other could have easily adapted to STDC14 when desired, but it’s much harder to go the other direction.
  2. It can’t power the target. Even the sub $3 STLinkV2 clones can power targets at 3v3 and 5v. This is incredibly useful, adds virtually no cost (5V is available from the USB i/f and there’s already a regulator on the STLink for its own uC). An STLink that has SWD, UART, and Power is exactly what every STM32 developer wants…now you need the MINIE and an external power supply!
  3. Finally, there’s the USB-C female connector. Even new laptops have very few USB-C ports (but many USB-A ports); the desktop situation is even worse. The interface itself is only USB 2.0 and the board and can’t supply power to the target, so I can see no rational reason for this choice. I suspect some PLM who has never done any development decided this would be “forward looking”.

The sub-$3 “aluminum shell” STLinkV2 clones nail the mechanical design. They can also power 3v3 and 5V targets. It’s only missing a UART and 1v8 support to be perfect.

So what to do?

You can keep using STLInkV2s, but as designs increasingly move to 1v8, that becomes a problem, requiring a high-speed voltage converter…The STLinkV2 runs an STM32F103 which only runs to 2v0 so you can’t just replace the regulator…and the STLink V2 lacks a UART.

There are adapter boards to convert STLink V3 STC-14 connector to 0.100 pin headers; I covered these in an earlier post discussing the STLink V3-PWR (which does supply power and is a single device solution for most STM32 development/debugging). However, the adapter boards just add another set of wires to clutter your bench and come loose at inopportune times. Fortunately, ST provided an edge connector on the V3MINIE for an imagined board-to-board configuration, and although they spaced the pads at 2mm, you can make them work for a 2.54mm pin header.

The JTAG/SWD pins map to SWD as:

  • TDO = SWO (which I rarely use)

It’s easy to solder a 2×5 0.100″ (2.54mm) pin header onto the 2mm pads; just center the middle pin on the middle pad and the other pins are close enough that you can easily make it work.

The soldering here is sloppy, but it shows the concept. The 2×5 pin-header is rock solid when mounted and provides access to all of the pins I use. The UART-side pins (shown to the left) are obvious.

Next time I’ll use a shrouded connector, to prevent accidental contacts and also to have a place to put a small label for each pin (you can’t see the silkscreen for the edge connector contacts when the board is in the 3D-printed enclosure)

ST has also kindly placed an STL file for a 3D-printable case on the product page (under CAD Resources). If you’re using Cura to slice the model, you’ll also need to uncheck the “Union Overlapping Volumes” box in the Mesh Fixes section of the print settings or it will fill in the STDC14 opening. Otherwise, it’s a very nice, compact enclosure with an excellent snap-fit and it holds the PCBA securely.

The original version of the enclosure posted on ST’s product page had the opening for the STDC14 connector slightly shifted and so you had to cut it a bit to make room for the connector. Within a day or so of reporting this to ST (8/2/2023) they had fixed the issue and sent a new STL file to test and it fit perfectly. I expect it will replace the original version shortly.

Go ST!

Next up:

  • Figure out how to get the SWD functionality working from the 0.100 header pins
  • Find a solution for powering the target. If you know of any, please let me know!

ST: if you’re listening, PLEASE give us a nice compact dongle like the V3MINIE but with a USB-A connector, pads for 0.100 pin headers, and 3v3 and 1v8 power outputs.


Update 2023-July: I no longer recommend using this until ST software support improves. At present, there are simply too many issues and it is a frustrating experience. The software seems somewhere between alpha and beta quality: the software that does work has major issues and many important software applications (including from ST) don’t work with it at all (including openocd which works fine with other STLink V3s).

I do a lot of design and development work using STM32 microcontrollers. The low-cost STLinkV2 hardware debug tool is part of what has made these processors so successful: the ability to quickly, inexpensively, and easily flash and debug firmware is a big deal. ST has gone a long way to make life easy for developers and we love them for it!

I have boxes of STLink V2s and clones; I use them all the time. Recently, I’ve started migrating to the STLink V3 and this post covers their most expensive variant: the STLINK V3-PWR which integrates some interesting features including:

  • SWD debug tool (flashing, debugging target)
  • USB-to-serial converter
  • variable power source for target (1v6 to 3v6 in 100mV steps)
  • dynamic current monitoring (100nA to 500mA) with 100ksps (50kHz BW)

It has additional hardware capabilities (SPI, I2C, GPIO, JTAG) that I haven’t tried yet (and it’s not clear that software support for them is ready).

Key Strengths

  • The STLink v3 is fast for flash/debug – even faster than the V2 (which was plenty fast)
  • The integrated serial interface works perfectly and saves another plug
  • Nice injection molded enclosure
  • The variable power source lets me test devices at voltages other than 3v3 and 5v which is more useful than it sounds…it’s often important to understand how the DUT will operate at 1v8.
  • The ability to monitor dynamic power consumption during development is incredibly useful. I didn’t fully understand this until I started using a Joulescope and realized how much added visibility it provided. I now routinely develop with the DUT powered through a Joulescope so I can better “see” what’s happening. The V3-PWR dynamically switches between 4 current ranges to provide a huge dynamic measurement range without imposing excessive burden voltage.


  • $95 is crazy expensive for an STLink and serial dongle (V2 clones and serial dongles are individually available for as little as $2 from AliExpress in nice compact aluminum shells).
  • $95 is crazy cheap for a dynamic power monitor that covers a wide enough current range for IoT development is hard to come by for even a fraction of the price. The Joulescope, is roughly 10x the price (but much more powerful).
  • If ST make the design public as they did with the V2, we can expect to see the price decline dramatically once Chinese clones appear.

Hardware Limitations:

  • 100ksps (50kHz claimed BW) sounds great, but in reality, that sample rate doesn’t provide enough resolution to understand the dynamic power consumption of many IoT devices. It’s super-common for battery-powered devices to wake briefly (uSeconds), do something, and go back to sleep. This is one of the major differences with the Joulescope (2Msps, 300kHz BW).
  • No pass-through current/power monitoring. Batteries have higher impedance than most line-powered supplies and that impedance varies with temperature and other dynamic feactors (e.g. passivation). The V3-PWR lets you observe the consumption of the DUT, but not its dynamic interaction with a battery. (another difference with the Joulescope).
  • Power to the DUT is via ~3.5mm screw terminals…not banana jacks, not pluggable screw terminals, not even lever terminals…this was the wrong place to save a few cents.
  • Connection to the computer *requires* USB-C or the rare USB-A port that supports both data and charging. Maybe this isn’t a big deal or even a limitation, but it’s worth being aware of.

That Dang STC14 connector

  • The biggest DOH! with the entire STLinkV3 series is ST’s adoption of a 50-mil “STDC14″ connector. 0.050” (1.27mm) connectors are simply awful, particularly for developers. Many targets won’t have the same STDC14 connector and now you can’t use the ubiquitous 100-mil dupont jumpers as we did with STLinkV2. Instead, you need a breakout board to adapt the 0.050 pins to 0.100. You can get inexpensive STDC14 breakout boards from OSHPark (9 PCBs for $11.10 shipped) and mount either these nice but very expensive and somewhat fragile Samtec connectors (left) or these much cheaper and more rugged CNC Tech connectors (right).
    OSHPark STC14 breakout board with Samtec and CNC connectors

Software Limitations

  • No cumulative or average power measurement. This is a huge deal for battery-powered devices (and one that ST can and should add to their software). Understanding average power consumption is key for most battery-powered IoT devices. The sampling limitation might limit accuracy, but this is an easy-to-implement and important missing feature.
  • The UI is limited (something ST will also hopefully improve over time). It provides a graphical display of current measurement (see below), but is missing features we’ve come to expect from scope-type equipment such as: horizontal or vertical cursors to make and document precise measurements, automatic axis scaling, adjusting the time-base dynamically, etc. ST software developers would be smart to license Joulescope software for the V3-PWR.

When the software associated with the V3-PWR matures, it will get a thumbs up from me. If/when cheaper clones start appearing, I’ll probably have a box of these to replace my STLink V2s. If ST provides an API, these could also form a very useful building block in many factory test fixtures.


  • Nordic Power Profiler Kit 2 (PPK2) – similar price, wider voltage/current ranges, can measure external current sources (i.e. battery), but no debug/serial functions and no enclosure.
  • NXP MCU Link Pro – half the cost, but you must select one of two current measurement ranges using a jumper and neither of those ranges fully cover my measurement needs. Within the selected range, the MCULink dynamically switches between 2 sub-ranges, allowing good dynamic range, but not on the level of the other devices. It also has more limited power supply capabilities (two fixed voltages: 1v8, 3v3) and has no enclosure.

Disk Abuse

I left the monitor running overnight at a high sample rate with acquisition time set to infinite. It turns out that this writes a ton of data to the disk and by morning it had chewed through 160GB of disk space! Even worse, it’s not obvious where the disk space went! So for other users who find this issue, the power acquisition log files are in Users/myUserName/AppData/Local/Temp/Power_Monitor/Acquisition.

ST could significantly improve the software application (STM32CubeMonitor-Power) by adding a few features, some of which seem quite easy:

  • Checkbox to En/Disable logging (off by default) so you can watch power consumption as you develop/test.
  • Link to the acquisition logs folder so users can find it easily
  • Stop/play button so you can pause acquisition to measure an event and then resume
  • Cumulative power usage counter (so you can confirm expected average power consumption over a long test)
  • Cursors (current and time) so you can measure and document events
  • Auto-scale of the Y-axis should adjust to mA when appropriate. A scale from 0..500000uA is just silly and it’s surprisingly annoying to try to distinguish 15000 from 150000.

Internet Security

We all know things are ugly out there, but things are particularly ugly in the growing world of connected devices where security is often an afterthought or under-powered for the modern internet.

I was reminded of this yesterday when I needed to recover the root password for an internet device (with the permission of the device’s owner who had forgotten it…so it was legit to hack). Like many such devices, it used a scaled-down older linux kernel, BusyBox, and an old-fashioned /etc/passwd file where salted passwords are stored md5-crypt hashed. (format: $1$<salt>$<128-bithash>.

Fortunately (but also worrying), a popular hacking tool (John the Ripper) makes short easy work of such files. And when I say “easy”, I mean ridiculously easy and when I say “short”, I mean weak passwords are cracked in seconds. If you have access to the passwd file (let’s call it passwd.txt) you would just run the command “john passwd.txt” and in a few minutes, voila: out pop the decrypted passwords. You can enhance JtR with (big) lists of common passwords; there are free lists here and you can also buy lists. You can run JtR on a multi-core machine with a word list using a command like:

john –fork=8 –wordlist=mywordlist.txt filetocrack.txt

In the past, I wouldn’t make a post like this for fear of encouraging hacking, but these days, that fear is misplaced. Tools like JtR (and many much more powerful) are so easy to use and so widely available that *any* hacker at any level knows about them. So rather than keeping head in sand, it’s time to bite the bullet and start assessing (and fixing) your products’ security.

  1. Hire someone to help with security if:
    • your system stores plaintext passwords
    • your passwords aren’t salted before hashing
    • you don’t have a delay before re-entering the password after a few failed attempts
  2. If your products run on small/old linux kernels and/or otherwise use md5crypt for password hashing, consider upgrading and hash passwords using at least SHA256.
  3. Prompt users when they are entering new passwords for what makes a quality password: use an obscure phrase rather than single words or a word with some numbers or some variation on their username.
  4. Store usernames and passwords separately such that only the root user has access to the password file (/etc/passwd and /etc/shadow)
  5. Check new passwords against known lists of pwnd passwords and warn the user.
  6. Run tools like JtR against your own passwd stores and if it quickly guesses your passwords, know that hackers will be doing the same thing.
  7. If possible, don’t use passwords at all on internet-facing systems; use public key certificates instead.
  8. In your own (home/business) networks, segregate insecure devices (i.e. nearly every internet-enabled appliance: cameras, TV streamers, doorbells, etc.) from your computers and storage systems. Devices belong on the guest network or separate VLANs…not on your main WiFi/LAN.
  9. Don’t use the same passwords in internet appliances that you use for things you care about. Assume the internet devices have been cracked. The security in internet appliances is usually *vastly* worse and when hackers crack that doorbell/camera, you don’t want that giving them access to the rest of your network, bank account, etc.
  10. Ideally, use a different, good password for every account. Use a free tool like PasswordSafe to keep your passwords secure; encrypt the safe where your passwords are stored with a single very good password that you don’t use anywhere else and then you can store it on the cloud (OneDrive, GoogleDrive, whatever) so you have easy access to your passwords, but hackers don’t.

Raspberry Pi alternatives

Libre ROC-RK3328-CC Single Board Linux Computer

When folks need a small embedded linux machine for control applications, a Raspberry Pi is usually the first thought. I’ve made good use of Raspberry Pi Zeros and 3Bs but have been reluctant to adopt the RPi 4 due to the apparent need for active cooling, high power consumption, very poor availability, and high pricing (it makes little sense to use an RPi when you could use a much more powerful x86-family platform).

With RPis out of stock for months and being scalped everywhere, I decided to try a Libre Computer ROC-RK3328-CC which is footprint/form factor compatible with the Raspberry Pi and can run Ubuntu, Raspberry Pi OS, Armbian, Debian, Android, and many other OS. The docs are here. The board comes in two versions: 2GB for $45 and 4GB for $55 – those prices are with free one-day shipping via amazon prime and they are available immediately. I bought the 4GB version which is 4x the memory of an RPi 3B+; the memory is also DDR4 vs. the DDR3 used on the Pi. The board is easily passively cooled; I bought the custom heat sink ($10) although any similarly sized heatsink should work fine.

I tried Ubuntu desktop but was disappointed by the bloat and installed Raspberry Pi OS (a Debian derivative) instead and am very happy with it; I installed the desktop (not lite) version. The board is DIN-rail mounted using this high-quality mounting solution. It runs several minicom sessions monitoring/logging other embedded boards as well as a Postgres database and Java backend data collection application. Even over TightVNC, it feels snappy and doesn’t break a sweat (stays between 45 and 47C); it is using less than 1/4 of the available RAM (but would have used nearly all of the RAM on an RPi3).

Other upsides: 4K video (mainly of value for HTPC applications) and USB 3.0 – much more important because it makes it worthwhile to connect an external SSD which will be much faster and more reliable than uSD storage. The main downsides relative to the Raspberry Pi are: no WiFi/Bluetooth and no Pi-compatible camera connector. I didn’t need those for my application (which is rack-mounted and connected to Ethernet), but if you need either, you can easily solve them via USB connection.

For storage, I use Sandisk Extreme uSD cards. 64GB costs $11 and is plenty of storage for my application (I’m only using 6%); if I need more, storage or speed, I’ll use an external M.2 card connected via USB 3.0. Note: there is a huge difference in performance and reliability between SD storage cards used in RPi applications; some cards won’t work at all, some will work but at half the speed of others (see this performance comparison). I’ve tried a bunch and settled on the Sandisk Extreme which offer good speed with a cost only slightly higher than lesser cards; the benchmarks bear this out. If I were doing something more disk-intensive, I’d consider either a board with a native M.2 interface (like the Odroid M1) or an x86 board with a native SATA or M.2 interface.

Note: uSD cards aren’t meant for frequent writing (as in linux logs), so if you want your card to last, I strongly recommend using a utility like log2ram that creates a small RAM disk for the /var/log partition (you can add others) and then periodically flushes that partition to SD storage. This will dramatically lengthen the life of your SD card; see here for more info.