DEMO: 96×16 OLED display

It has been a while since a demonstration was posted. We whipping up new projects for you like the USB LCD backpack, HVP adapter, Buspirate v4 prototype, breakout boards, and several other project that are TOP-SECRET but will be released soon! Now that everything is at to manufacturing, we have some time off for our family and for fun stuff. So we found a bit of time to connect interesting stuff to the Bus Pirate and see what makes things tick.

We are always on the look for new and interesting things, and we were exited when we saw that they stocked several OLED displays. OLEDs are just like LEDs, but are more power efficient (glass display module is rated 8.2mW). Displays using LED provide a large viewing angle (>160 degrees) and good visibility (contrast ratio >2000:1). Together with the low power requirements they are ideal for small battery powered devices like MP3 players. Downside is the degradation of the OLED, as the brightness will fade after many hours of use. Lifetime according to the datasheet is 10.000hrs, but burning in will probably happen sooner.

OLED demo continues after the break.

Get your own handy Bus Pirate for $30, including world-wide shipping. Also available from our friendly distributors Adafruit, Open Source Control Systems, and eHaJo.

Now back to the fun part! The display uses a SSD1307 interface chip, this chip is capable of driving up to 128×64 pixels. The 96×16 OLED matrix is connected to COL32-COL127 and COM8-COM23. The host side of the SSD1307 can be either 6800 parallel, 8080 paralles, SPI(3/4 wire) or I2C. The display module has only a I2C brought out, and thus perfect to use when I/O pins are scarce (and for the Bus Pirate to interface!!).

First enter the I2C mode and enable the Vreg and pull-up resistors on the Bus Pirate:

HiZ>m 4 3
I2C (mod spd)=( 0 2 )
Ready
I2C>WP
Power supplies ON
Pull-up resistors ON
I2C>

As most display it has a command and a data mode. In commandmode it accepts commands to setup the display, in datamode it accepts bitmapdata to display. Luckily Seeedstudios did provide some code (and datasheetsheets too) to start with. Unfortunately it is in arduino so it needs some translation.

The init code:

void init_OLED(void)
{
sendcommand(0xae); //display off
sendcommand(0xa1); //seg re-map 127->0
sendcommand(0xaf); //display on
}

It references to the sendcommand subroutine:

void sendcommand(unsigned char state)
{
Wire.beginTransmission(OLED_address); //
Wire.send(0x80);//command mode
Wire.send(state);
Wire.endTransmission(); // stop transmitting
}

Basically it generates an I2C start condition, sends the OLED_address, sends 0x80 to indicate a commandbyte will follow, the command itself and a STOP condition. The OLED address is defined earlier and is 0x3c. I2C uses a 7 bit address followed by a R/W bit, so this translates t0 0x78 as writing and 0x79 as reading address. So the init string translate in Bus Pirate slang as:

[0x78 0x80 0xAE] [0x78 0x80 0xA1] [0x78 0x80 0xAF]

I was tempted to send everything just in one go, but commandbytes must be sent one byte a time (writing multiple display data is ok)! 0xAE turns the display off, 0xA1 enable the remap of the columns (COL127 -> COL0) and 0xAF re-enables the display. Commands are preceded with 0x80 and data bytes with 0x40. At this time the display is showing garbage (due to the memory not being initialized). The next thing is to set the cursor to a known position.

[0x78 0x80 0xB1] [0x78 0x80 0x00] [0x78 0x80 0x10]

0xB1 set the page to 1 (COM8-16), 0x00 and 0x10 sets  the column address to 0x00 (COL127). Command 0x0X (X=0..F) and 0x1Y (Y=0..7) set the column to 0x7F-0xXY (due to remapping).

Now for the funpart! We send some display data (display data is preceded with 0x40):

[0x78 0x40 0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00]
[0x78 0x40 0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00]
[0x78 0x40 0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00]
[0x78 0x40 0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00]
[0x78 0x40 0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00]
[0x78 0x40 0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00]
[0x78 0x40 0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00]
[0x78 0x40 0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00]
[0x78 0x40 0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00]
[0x78 0x40 0x00:24]

For those who counted the bytes we did send to the display, it is 96 and so we need to do a cariage return.

[0x78 0x80 0xB2] [0x78 0x80 0x00] [0x78 0x80 0x10]

This will set the page to 2 (COM16-23) and the collumn address to 0x00. now send the remaining of the data:

[0x78 0x40 0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00]
[0x78 0x40 0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00]
[0x78 0x40 0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00]
[0x78 0x40 0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00]
[0x78 0x40 0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00]
[0x78 0x40 0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00]
[0x78 0x40 0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00]
[0x78 0x40 0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00]
[0x78 0x40 0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00]
[0x78 0x40 0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00]

Now you should have the same displayed the display as we have!

Leave a comment

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.