I2C OLED (ssd1306)
Introduction
The ssd1306 is a very common I2C OLED display controller.
It is often found on small monochrome displays up to 128x64 pixels. These displays can easily be found for under five US dollars and are extremely simple to wire up.
The most typical interface is just four wires, basically just power and I2C:
- VCC
- GND
- SCL
- SDA
However some displays also feature additional pins for a 'reset' signal and possibly an SPI interface.
If the display features a 'reset' pin, it must be connected to a digital output on our microcontroller / ioNode.
To use these displays, we provide the ssd1306 driver library, which integrates with the Graphics Framework.
Wiring
As mentioned above, the wiring for these displays is generally extremely simple.
We just need to hook up the power (VCC / GND) and I2C (SDA / SCL). Again, if a 'reset' pin is present on the display, we need to also hook it up to a digital output.
Note: some displays actually have a solder jumper (usually on the backside) to select between I2C and SPI interface. Since the ssd1306 library only uses I2C, always make sure that this solder jumper is set correctly (if present).
Using the library
To use the display driver, we must first add it to our dependencies in dfe.conf:
# ... deps: - ssd1306
Initialization
Next, we need to initialize the display so we can use it with the Graphics Framework.
The easy way to do this is to simply declare our display in our substrate.
With substrate
We can declare our display in our substrate as shown below:
# 64x32 OLED Display with reset pin connected to DIO 5 (I2C addr = 0x7a) uses :ssd1306_gfx, name: 'dsp0', width: 64, height: 32, addr: 0x7a, rst_pin: 5
However, because many displays have very similar configurations, we can also just use a standard profile:
# Generic 128x32 OLED Display with no reset pin uses :ssd1306_gfx, name: 'dsp0', profile: :gen128x32
The table below shows available profiles:
Profile | I2C address | Display format |
---|---|---|
:gen128x32 | 0x78 | 128x32 |
:gen128x64 | 0x7a | 128x64 |
We can even mix a profile with custom options if needed. For example, some displays ALMOST match these generic settings, maybe requiring only a small adjustment like the reset pin:
# Generic 128x32 OLED Display with reset pin on DIO 3 uses :ssd1306_gfx, name: 'dsp0', profile: :gen128x32, rst_pin: 3
Or maybe a slightly different I2C address:
# Generic 128x32 OLED Display (I2C addr = 0x7a) uses :ssd1306_gfx, name: 'dsp0', profile: :gen128x32, addr: 0x7a
This will create a struct gfx_dsp *dsp0;
that we can use right away.
Manual initialization (without substrate)
For those who prefer to go without the substrate, we can still initialize the display manually:
1 #include <ssd1306/ssd1306.h> 2 #include <gfx/dsp.h> 3 #include <gfx/gfx.h> 4 5 // OLED Display Driver 6 struct ssd1306 dsp0_drv; 7 8 // GFX Interface 9 struct gfx_dsp dsp0_data; 10 struct gfx_dsp *dsp0; 11 12 void init() 13 { 14 // ... 15 16 // Display Params 17 uint8_t rst_pin = 0xff; 18 uint8_t addr = 0x78; 19 uint8_t width = 128; 20 uint8_t height = 32; 21 22 // Initialize ssd1306 driver 23 ssd1306_init(&dsp0_drv, rst_pin, addr, width, height); 24 25 // Initialize GFX interface 26 dsp0 = &dsp0_data; 27 gfx_dsp_init(dsp0, &dsp0_drv); 28 29 // ... 30 }
Drawing
Once the display is initialized and we have a struct gfx_dsp *dsp0;
, we can start using the Graphics Framework to actually do stuff with the display.