Posts

Showing posts from May, 2018

Practical animation on I2C SSD1306 displays

Image
Intro
I can hear the thought forming in your head already, "Why write another blog post about those ubiquitous little OLED displays, isn't this old news already?" It's a valid question, and there have been plenty of articles and libraries written for these displays over the last 6+ years. It's still new to me because I just started working with AVR MCUs and all of the common parts in the Arduino ecosystem not too long ago. I still see fun challenges with these parts because I encounter my favorite phrases while searching for projects - "It can't be done" or "That's as good as it gets". In this case, I came across a few new projects which would benefit from some animated graphics on a small, inexpensive display and MCU. The existing projects I found use uncompressed graphics and can only fit a few frames on an ATMega328.

What
Ideally, it would be great to be able to play animated GIF files right on an Arduino, but there are some insurmou…

Optimized Bresenham line drawing on the SSD1306

Image
What Jack Bresenham invented a low computation line drawing algorithm many years ago. The benefit of his algorithm is that it uses only integer variables and only addition and subtraction operations to calculate the pixel at each point along an arbitrary line. It's a very efficient method and has become the 'standard' way of drawing a line on computers.
Why On a display device like the SSD1306 OLED, the image is changed by sending data (and commands) serially over the SPI or I2C bus. When the Bresenham algorithm is written for the SSD1306, the traditional way to implement it is to transmit each pixel (set the memory position and write the byte containing the pixel data) one at a time to the display. Essentially, to change a single bit of the display memory, at least 8 bytes need to be transmitted to the display. They are:

0x00 (0xb0 + y) - set y offset
0x00 (0x00 + (x & 0xf)) - set low 4 bits of x offset
0x00 (0x10 + (x >> 4)) - set high 4 bits of x offset
0x40 …

Fast SSD1306 OLED drawing with I2C bit banging

Image
What

The SSD1306 OLED displays are very popular with hobbyists due to their low cost and easy interfacing. The majority of the ones sold expose a two wire interface (TWI) aka I2C. The default speed for I2C is 100Khz and the "fast" mode is 400Khz. These are the 2 standard speeds supported by most AVR Arduinos. An I2C clock rate of around 800Khz is also possible on AVR MCUs, but not supported directly by the Wire library. The I2C standard recently added some higher speeds (1Mhz and 3.4Mhz). The 3.4Mhz version uses a slightly different protocol. At 400Khz, using the I2C hardware and the Wire library, I was able to refresh the display around 23.5 frames per second (FPS) with my code.

Why
I have already written a SSD1306 library for both Linux and Arduino, but I wanted to drive the display from an ATtiny85 and learn about the I2C protocol in the process. The ATtiny85 doesn't have I2C hardware built in, so it needs to be emulated in software using GPIO pins. There are several p…