Optimizing access to serial (I2C/SPI) displays

Intro I've been thinking about writing this post for a while. I decided to do it because I've recently been working on my SPI LCD library and have been more engaged with other engineers on working with serial displays. The purpose of this post is to share some thoughts on getting the best performance from serially connected displays. I've randomly reached out to a few people I saw on Twitter having performance issues and thought it would be better to collect my thoughts here to reach a wider audience.

The Problem
Hobbyists typically buy a serial (I2C/SPI) display for their project, make use of a third party library to drive it and wonder why the performance of their software is disappointing. I believe this is due to the following misconception:

"Every pixel takes the same amount of time to draw, right? If I write data to my 240x320 LCD at 40Mhz, I should be able to get 30+ FPS of full screen updates."

Serially connected displays use the same basic prog…

How much current do OLED displays use?

Those little OLED displays are everywhere, and there's a good reason. They're inexpensive, easy to program and they look good. I wanted to explore how much current they draw so that I can plan better for battery powered projects.

Questions I want answered:

How much idle current is drawn when the controller is off versus on (blank display)?What's the minimum current to see text indoors?What's the maximum current when all pixels are on at their brightest?How does display size affect current draw?How does active data writing affect current draw?It's obvious they use more, but how much current do grayscale and color OLEDs use?How practical are OLED displays compared to common LCDs for battery powered projects?

Cheap multimeter (manual scale, assumed accuracy +/-10% at worst)Various OLED displays (72x40, 96x16, 128x32, 64x32, 128x64-0.96", 128x64-1.3")Arduino compatible microcontroller (Adafruit nRF52840 Feather Express)Software (my ss_oled library)

Powering your Arduino with batteries

The Premise So, you've created an Arduino project and you want to power it with batteries to take it on the road. Your board's components are designed to run on 5 Volts and you know you can't feed 9V directly into the Vcc of a 5V board because it will damage it. Arduino has you covered - the pin marked "RAW" is for that purpose and according to the documentation, you can feed it between 6 and 12V and it will regulate that voltage down to the 5V needed by the board. Perfect, right? Well, not quite.

Voltage Regulation There are 2 main ways to regulate (aka control) the voltage. A linear regulator allows you to supply a higher voltage than desired (in our case 9V) and get a stable, lower voltage as output. It essentially does this by generating heat from the excess energy. Let's say your board uses 100mA @5V while executing your code. If you're powering it from a 9V battery through a linear regulator, then you're creating 4V x 100mA = 400mW of waste hea…

Trade storage for code - stretching a font in real time

I've published several Arduino libraries for controlling inexpensive OLED and LCD displays, for example, my oled_96 library drives SSD1306/SH1106 OLEDs. It's gone through several iterations with additional functionality added. Recently I was using it on a new ATmega32u4 (Arduino Leonardo) project and ran out of FLASH space. I wanted to keep using the large fixed font for the project, but the font data takes up 6K of the 28K available. My first idea was to just #ifdef the font out of existence on targets with small amounts of FLASH memory.

I couldn't move forward with my project until I solved the space problem and then decided that a slightly blocky looking large font would be better than no large font. The code to stretch the pixels isn't very complicated, so I added the logic to draw the large font as a 2x2 stretch of the 8x8 font.  AVR target MCUs tend to have very little FLASH space, so I singled them out as the target which would get this font stretching. Luckily …

Controlling lots of OLED displays with a few GPIO pins

On my mission to learn as much as possible about "IoT" and all of the accessories/sensors/displays that are popular in the market, I came across some projects which were using multiple OLED displays to form dashboards and control panels. I hadn't thought about this usage, but it makes sense considering how inexpensive (and small) they are. The challenge presented with this idea is that the inexpensive hobby parts either have a fixed I2C address (usually 0x3C) or a single jumper to select an alternate address (usually 0x3D).

The photo above shows a collection of readily available and inexpensive I2C OLED displays. The top 3 have a single address selection jumper. The bottom 2 don't show any specific jumper for changing the address, although one or more of the SMD resistors might control it. Either way, most hobbyists are not prepared to work with tiny, surface mount resistors.

If they all are set to the same I2C address, then in order to get more than 1 display workin…

Optimizing your nRF24 range with a simple test rig

I'm working on a commercial project and I need a low power wireless interface to send data reliably in a crowded indoor environment. There are many standards and protocols to choose from, but the Nordic Semiconductor nRF24 and its 'shockburst' small packet protocol seemed like the best fit for the job. Three advantages of the nRF24 are its incredibly simple interface, that it uses very little power when idle and that it operates in the unlicensed spectrum near 2.4Ghz. Bluetooth low energy (BLE) could potentially do the same job, but the available devices and RF protocol are a bit more complicated and more expensive than this project requires. I started by buying some inexpensive nRF24L01+ development boards from Amazon that cost around $1 each.

I wired them up to some ATmega328's for testing and tried the simple "Hello World" chat app; they worked as expected. Next, I added them to my product prototype and that's where the trouble began. My project has an…