Skip to content

How to use a 0.96 inch OLED with a Teensy?

· ·BR2H

How to Use a 0.96 Inch OLED with a Teensy

To get a 0.96 inch OLED working with a Teensy, you need to wire it up for either I2C or SPI, install the right library, and run a simple sketch. The most straightforward method is using I2C with a 0.96 inch 128x64 spi i2c oled display module, which only requires four connections: VCC, GND, SDA, and SCL. On a Teensy 4.0, for instance, SDA is pin 18 and SCL is pin 19. Power the display at 3.3V, since the Teensy’s logic level is 3.3V, and avoid using 5V unless you have a level shifter. The OLED’s driver chip, typically an SSD1306, draws around 20mA during operation, making it safe to power directly from the Teensy’s 3.3V rail. For SPI, you’ll need six wires: VCC, GND, MOSI (pin 11 on Teensy 4.0), SCK (pin 13), CS (any digital pin, say pin 10), and DC (pin 9). The SPI version updates faster, hitting about 10 MHz clock speed versus I2C’s 400 kHz, but for most text and bitmap displays, the difference is negligible.

Let’s dive into the hardware specifics. The 0.96 inch OLED has a resolution of 128x64 pixels, each pixel individually controlled, so you get crisp text and graphics. The SSD1306 controller supports both I2C and SPI, but the default address for I2C is 0x3C, though some modules use 0x3D. You can check this with an I2C scanner sketch. For SPI, the CS pin must be pulled high when not in use, and the DC pin differentiates between command and data bytes. The OLED’s contrast is adjustable via the `setContrast()` function, with a range of 0 to 255, but 128 works well for indoor use. The refresh rate is around 60 Hz, but this drops if you’re updating the entire frame buffer. The display consumes about 20mA with all pixels on, but if you’re only showing a few lines of text, it’s closer to 10mA. The Teensy 4.0’s 3.3V regulator can handle up to 250mA, so you’re safe.

For the software side, the Adafruit SSD1306 library is the go-to, but it’s bloated for simple tasks. A lighter alternative is the U8g2 library, which supports monochrome displays and has a smaller footprint. Install it via the Arduino Library Manager. For I2C, include `` and `` or ``. The U8g2 constructor for I2C on a Teensy 4.0 is `U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 19, /* data=*/ 18);`. For SPI, use `U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE);`. The `U8G2_R0` parameter sets rotation to 0 degrees; you can change it to `U8G2_R1`, `U8G2_R2`, or `U8G2_R3` for 90, 180, or 270-degree rotations. The `F` in the constructor means full frame buffer, which uses 1024 bytes of RAM (128x64/8). The Teensy 4.0 has 2MB of RAM, so memory isn’t an issue, but on a Teensy 3.2 (64KB RAM), you might want to use the `U8G2_SSD1306_128X64_NONAME_1_HW_I2C` version, which uses a 128-byte page buffer.

Here’s a concrete example of initializing the display with U8g2 in I2C mode. First, call `u8g2.begin()` in setup, then `u8g2.clearBuffer()`, `u8g2.setFont(u8g2_font_ncenB08_tr)`, `u8g2.drawStr(0, 20, "Hello Teensy")`, and `u8g2.sendBuffer()`. The `setFont` function loads a font from the library; the `ncenB08_tr` font is 8 pixels tall, but you can pick larger ones like `u8g2_font_ncenB14_tr` for 14-pixel height. The `drawStr` function takes x and y coordinates, where y is the baseline of the text. The display’s coordinate system starts at the top-left corner, with x ranging 0 to 127 and y 0 to 63. For bitmaps, use `u8g2.drawXBM(0, 0, 128, 64, your_bitmap_array)`, where the array is a byte array of 1024 elements. The bitmap data must be in horizontal orientation, meaning each byte represents 8 pixels in a row. You can generate this from any image converter tool, like the online “image to C array” converters, but ensure the output is monochrome and 128x64.

Performance-wise, the Teensy 4.0 runs at 600 MHz, so the OLED updates almost instantly. The U8g2 library’s `sendBuffer()` function takes about 2ms for a full frame over I2C at 400 kHz, and about 1ms over SPI at 10 MHz. If you’re updating only a small portion, use `u8g2.setDrawColor(0)` to clear a region, then redraw. The library supports drawing primitives like `drawCircle`, `drawLine`, `drawBox`, and `drawTriangle`. For example, `u8g2.drawBox(10, 10, 20, 20)` draws a filled rectangle from (10,10) to (30,30). The `setDrawColor` function accepts 0 for black, 1 for white, and 2 for XOR, which is useful for animations. The display’s pixel memory is static, meaning you don’t need to refresh it constantly; just update the buffer when the content changes. This makes it ideal for low-power projects, as you can put the Teensy to sleep and the OLED retains its image.

Now, let’s talk about common pitfalls. The OLED’s I2C address might conflict with other devices on the same bus. The Teensy 4.0 has two I2C buses: Wire (pins 18 and 19) and Wire1 (pins 17 and 16). If you’re using multiple I2C devices, assign each to a different bus. For SPI, ensure the CS pin is not shared with other SPI devices, as the Teensy’s SPI bus is shared among multiple peripherals. The OLED’s reset pin is optional; if you don’t use it, set the reset parameter to `U8X8_PIN_NONE`. However, some modules require a reset pulse after power-up. If the display stays blank, try adding a digitalWrite to a pin that’s connected to the reset line, or simply toggle the power. The OLED’s operating voltage is 3.3V to 5V, but the logic level must match the Teensy’s. If you’re using a 5V OLED with a 3.3V Teensy, you’ll need a level shifter for the data lines, but the SSD1306 is typically 3.3V tolerant. Check your module’s datasheet; the common 0.96 inch modules from DisplayModule are 3.3V only.

For advanced usage, you can control the OLED’s contrast via the `setContrast` function. The SSD1306 has a built-in charge pump that generates the 7-15V needed for the OLED pixels. The contrast register controls the current, and setting it too high (above 200) might cause ghosting or burn-in over time. For battery-powered projects, you can reduce the contrast to 50 to save power, dropping the current draw to about 5mA. The display also supports sleep mode via `u8g2.sleepOn()` and `u8g2.sleepOff()`. In sleep mode, the display draws less than 1µA, but the Teensy must still power the module. You can also use the `u8g2.setPowerSave()` function to save power between updates. The Teensy’s low-power modes, like `SLEEP_MODE_STANDBY`, can be used in conjunction with the OLED’s sleep mode to extend battery life in a data logger or sensor project.

Let’s look at a practical example: displaying sensor data from a DHT22. Connect the DHT22 to pin 2 on the Teensy. In the loop, read the sensor every 2 seconds, then update the OLED. The U8g2 library handles text formatting, but you need to convert floats to strings. Use `dtostrf(temperature, 4, 1, buffer)` to convert a float to a string with 1 decimal place. Then call `u8g2.drawStr(0, 20, buffer)`. The display’s buffer is cleared each cycle, so you don’t get ghosting. For a more complex UI, use `u8g2.setFont(u8g2_font_6x10_tf)` for a 6x10 pixel font, which fits 21 characters per line (128/6 ≈ 21) and 6 lines (64/10 ≈ 6). That’s 126 characters total, enough for a simple dashboard. You can also draw a progress bar using `u8g2.drawBox(0, 50, map(value, 0, 100, 0, 128), 5)`. The `map` function scales the value to the display width.

Below is a table summarizing the key parameters for the 0.96 inch OLED with a Teensy 4.0:

Parameter I2C Mode SPI Mode
Pins used 4 (VCC, GND, SDA, SCL) 6 (VCC, GND, MOSI, SCK, CS, DC)
Clock speed 400 kHz (max) 10 MHz (typical)
Full frame update time ~2 ms ~1 ms
Current draw (all pixels on) 20 mA 20 mA
Library memory usage 1024 bytes (full buffer) 1024 bytes (full buffer)

For troubleshooting, if the display shows nothing, check the I2C address with a scanner sketch. The Teensy’s Wire library is built-in, but you need to call `Wire.begin()` in setup. If using SPI, verify that the CS pin is set as an output and pulled high initially. The OLED’s initialization sequence is handled by the library, but some modules require a delay after power-up. Add a `delay(100)` after `u8g2.begin()`. If characters are garbled, the font might be too large for the buffer; ensure the buffer is cleared before each draw. The U8g2 library’s `u8g2.firstPage()` and `u8g2.nextPage()` loop is useful for large graphics, but for simple text, the `clearBuffer`/`sendBuffer` approach is faster. The Teensy’s serial monitor can help debug, but the OLED itself doesn’t output debug info. Use `Serial.println()` to print the I2C address or SPI status.

Another angle: the Teensy 4.0’s 3.3V output is rated for 250mA, but the OLED’s inrush current can spike to 50mA during the charge pump startup. To avoid voltage dips, add a 10µF capacitor between VCC and GND near the OLED. The Teensy’s onboard regulator is stable, but if you’re powering multiple peripherals, use an external 3.3V regulator like the AMS1117-3.3. The OLED’s pixel lifetime is rated at 100,000 hours at 25°C, but high contrast or UV exposure can degrade it faster. For permanent installations, set contrast to 100 or lower. The display’s viewing angle is >160 degrees, but the glass substrate is fragile; handle it by the edges. The module’s PCB has mounting holes for M2 screws, but the Teensy can be placed on a breadboard for prototyping.

If you’re building a project that requires fast updates, like a scope or a waveform display, use SPI with DMA. The Teensy 4.0’s SPI library supports DMA transfers, but the U8g2 library doesn’t use it natively. You can write a custom driver that uses the Teensy’s DMA engine to send the buffer to the display, achieving update times under 500µs. The SSD1306’s maximum SPI clock is 10 MHz, but the Teensy can push 30 MHz; however, the display might miss bits at higher speeds. Stick to 10 MHz for reliability. For I2C, the maximum clock is 400 kHz, but the Teensy’s Wire library can be overclocked to 1 MHz if you set `Wire.setClock(1000000)`. This works with most SSD1306 modules, but test it first. The I2C bus capacitance limits the speed; keep the wires short, under 10 cm.

Finally, consider the form factor. The 0.96 inch OLED is 26.7mm x 19.26mm, with a thickness of about 3.5mm including the PCB. The Teensy 4.0 is 35mm x 18mm, so the OLED can sit on top of the Teensy if you use headers. The total height with headers is about 10mm. For a compact project, solder the OLED directly to the Teensy’s pins, but be careful not to short the pins. The display’s 4-pin I2C header is standard 2.54mm pitch, compatible with breadboards. The SPI version has a 6-pin header. The module’s back is blank, but you can add a piece of foam tape to prevent shorting against the Teensy’s USB port. The Teensy’s USB port is on the end, so the OLED can be placed on the top side without interference. Power the Teensy via USB, which provides 5V, and the onboard regulator drops it to 3.3V. The OLED’s VCC pin connects to the 3.3V pin on the Teensy. If you’re using a battery, the Teensy’s VIN pin accepts 3.6V to 6V, and the 3.3V output is still stable. The OLED’s current draw is negligible compared to the Teensy’s 100mA at 600 MHz, so battery life is more dependent on the Teensy’s processing load. Use the Teensy’s `set_arm_clock()` to reduce the clock speed to 24 MHz for a 10x power reduction, and the OLED will still update smoothly.

Editor's Note

The 4.7% of a workforce driving half of next year's claims is identifiable today — not in a year, not in a quarter. Inside nine days.

Next step

See the 4.7% in your population — quantified, not guessed.

30 minutes with a BR2H solutions architect. We bring your claims history; you leave with a stratified risk map of your covered lives.

Request Your Risk Assessment Demo Review the validation