How to connect a 0.66 inch OLED to a micro:bit?

By admin

How to Connect a 0.66 Inch OLED to a micro:bit

To connect a 0.66 inch 64x64 oled display to a micro:bit, you need to use the I2C protocol, as this specific OLED module typically operates over I2C with a resolution of 64x64 pixels and a driver like the SSD1306. The micro:bit has a built-in I2C interface on pins 19 (SCL) and 20 (SDA), which you can directly wire to the OLED’s SCL and SDA pins. Power the OLED from the micro:bit’s 3.3V output (pin 3V) and ground (GND). Once connected, you can use the MicroPython or MakeCode environment to initialize the display and send data. For example, in MicroPython, you’d import the machine and ssd1306 libraries, create an I2C object, and then instantiate the OLED with a width of 64 and height of 64. This setup works reliably because the micro:bit’s I2C bus runs at 100 kHz, and the OLED’s typical I2C address is 0x3C or 0x3D, depending on the module. Always check the datasheet of your specific 0.66 inch 64x64 oled display to confirm the address and pinout, as some modules may have pull-up resistors onboard, while others might require external 4.7kΩ resistors on the SCL and SDA lines.

The micro:bit’s I2C pins are not labeled on the edge connector, but you can access them via the large pads: pin 19 (SCL) is the pad labeled “19” on the bottom edge, and pin 20 (SDA) is the pad labeled “20”. The 3.3V output is on the pad labeled “3V”, and GND is on the pad labeled “GND”. The 0.66 inch OLED module typically has four pins: VCC, GND, SCL, and SDA. Connect VCC to 3V, GND to GND, SCL to pin 19, and SDA to pin 20. If your OLED module has a fifth pin for CS (chip select) or RES (reset), you can leave them unconnected for I2C mode, as the internal pull-ups on the micro:bit are sufficient for short wires. The micro:bit’s I2C bus can drive up to 400 pF of capacitance, and the OLED’s input capacitance is usually under 10 pF, so no issues with signal integrity for cable lengths under 20 cm.

For power consumption, the 0.66 inch OLED draws around 20 mA during full-on display (all pixels white), and the micro:bit’s 3.3V regulator can supply up to 200 mA, so you have plenty of headroom. The micro:bit’s battery life with two AAA batteries is about 5 hours at 50 mA load, so adding the OLED reduces it to roughly 4 hours. If you use a USB power source, the micro:bit draws about 30 mA idle, and the OLED adds 20 mA, totaling 50 mA. The OLED’s driver IC (SSD1306) operates at 1.65V to 3.3V, so the micro:bit’s 3.3V logic is compatible. The I2C bus requires pull-up resistors, but the micro:bit has internal 4.7kΩ pull-ups on pins 19 and 20, so you don’t need external ones. However, if your OLED module has its own pull-ups (common on many breakout boards), they may be 10kΩ, which is fine. The total bus capacitance with two devices is under 50 pF, so the 100 kHz I2C clock works without issues.

In terms of software, you have two main options: MakeCode (block-based) or MicroPython (text-based). For MakeCode, you can use the “OLED” extension from the micro:bit’s package manager. Search for “OLED” in the extensions dialog, and you’ll find one by “Microsoft” or “Kitronik”. The Kitronik OLED extension supports 64x64 displays with I2C address 0x3C. In MicroPython, you need to flash the firmware that includes the ssd1306 driver. The official micro:bit MicroPython firmware (version 1.1.1) does not include it, so you must download the ssd1306.py file from the MicroPython repository and copy it to the micro:bit’s file system using the uflash tool or the Mu editor. The code is straightforward: from machine import Pin, I2C import ssd1306 i2c = I2C(0, scl=Pin(19), sda=Pin(20), freq=100000) oled = ssd1306.SSD1306_I2C(64, 64, i2c, addr=0x3C) oled.text('Hello', 0, 0) oled.show(). This writes “Hello” at the top-left corner. The freq=100000 sets the I2C clock to 100 kHz, which is the standard for the micro:bit. You can increase it to 400 kHz, but the micro:bit’s I2C peripheral may glitch at higher speeds due to internal timing, so stick with 100 kHz.

The 0.66 inch OLED’s resolution of 64x64 pixels means each pixel is about 0.26 mm wide, giving a pixel density of 97 PPI (pixels per inch). The display area is 16.8 mm x 16.8 mm, with a total of 4096 pixels. The SSD1306 driver has 128x64 memory, but the 64x64 OLED only uses half of the rows. The driver’s memory is organized in pages of 8 pixels, so you need to set the display start line and segment remap in the initialization sequence. The default I2C address is 0x3C for most modules, but some use 0x3D. You can check the address by scanning the I2C bus: in MicroPython, run i2c.scan(), which returns a list of addresses. If you see [60] (decimal for 0x3C), that’s your OLED. If you see [61], it’s 0x3D. The address is set by the module’s hardware, usually by a resistor on the back.

For physical mounting, the 0.66 inch OLED is typically on a small PCB with 0.1-inch pitch pins. You can connect it to the micro:bit using female-to-female jumper wires. The micro:bit’s edge connector has 5 large pads (0, 1, 2, 3V, GND) and 20 smaller pads (pins 3-22). The I2C pins 19 and 20 are on the smaller pads, so you need a breakout board or alligator clips to access them. The micro:bit’s edge connector pitch is 2.54 mm, so standard dupont wires work. If you use a breadboard, the micro:bit can be plugged into a breakout board like the “micro:bit edge connector breakout” which exposes all pins. The OLED’s pins are also 2.54 mm pitch, so you can plug it directly into the breadboard. The total height of the OLED module is about 3.5 mm, so it fits under a micro:bit case if you mount it on top.

Data transfer speed: the I2C bus at 100 kHz can send about 12.5 kB/s. The OLED’s frame buffer is 64x64 pixels, which is 512 bytes (since each pixel is 1 bit, 64*64/8 = 512 bytes). To update the entire screen, you need to send 512 bytes plus command bytes (about 2 bytes per command). The total transfer time for a full screen update is about 512 bytes / 12.5 kB/s = 41 ms, plus overhead, so about 50 ms. This gives a maximum refresh rate of 20 Hz. For animations, you can achieve 10-15 fps with partial updates. The SSD1306 supports hardware scrolling, which can reduce software overhead. You can enable horizontal scrolling by sending commands: 0x26 (right scroll) or 0x27 (left scroll) with parameters for start page, end page, and speed. The speed is set by a 5-bit value from 0 to 7, where 0 is fastest (2 frames per step) and 7 is slowest (256 frames per step). For a 64x64 display, scrolling works on page boundaries (8-pixel rows), so you can scroll the entire screen or a range of pages.

Temperature range: the SSD1306 operates from -40°C to +85°C, and the micro:bit’s processor (nRF51822) operates from -40°C to +85°C, so the combination works in most environments. The OLED’s contrast is adjustable via the set_contrast command (0x81), with values from 0 to 255. Default is 127. At full contrast, the OLED draws 20 mA; at half contrast, about 10 mA. The micro:bit’s GPIO pins can sink or source up to 5 mA each, but the I2C pins are open-drain, so they only sink current. The pull-up resistors provide the current for the bus, about 0.3 mA per line at 3.3V with 4.7kΩ resistors. The OLED’s SDA and SCL pins are 5V tolerant, so you can safely use them with the micro:bit’s 3.3V logic.

If you encounter issues, common problems include wrong I2C address, loose connections, or missing pull-up resistors. The micro:bit’s internal pull-ups are enabled by default, but if you use a breakout board with its own pull-ups, the total resistance may be too low (e.g., two 4.7kΩ in parallel gives 2.35kΩ, which increases current to 1.4 mA per line, still within limits). The I2C bus can handle up to 3 mA per line, so no damage. If the display shows nothing, check the power: the OLED’s VCC pin must be connected to 3.3V, not 5V. The micro:bit’s 3V output is regulated, so it’s safe. If the display shows garbled characters, the I2C address may be wrong. Use the i2c.scan() function to verify. Another issue is the display’s reset pin: some modules require a reset pulse on the RES pin. If your module has a RES pin, connect it to a GPIO pin (e.g., pin 16) and pulse it low for 1 µs during initialization. In MicroPython, you can do reset = Pin(16, Pin.OUT) reset.value(0) sleep_us(1) reset.value(1). This is not always needed, but it helps if the display is in an unknown state.

For advanced usage, you can implement double buffering to avoid flicker. The micro:bit has 16 kB of RAM, and the OLED’s frame buffer is 512 bytes, so you can allocate a second buffer in RAM. In MicroPython, you can create a bytearray of 512 bytes, draw to it, then send it to the OLED using the oled.framebuf attribute. The SSD1306 driver in MicroPython uses a framebuf object that stores the pixel data. You can manipulate it directly: oled.framebuf.fill(0) clears the buffer, oled.framebuf.pixel(x, y, 1) sets a pixel. Then call oled.show() to transfer the buffer to the display. This method reduces flicker because you update the entire buffer at once. The micro:bit’s CPU runs at 16 MHz, so drawing operations are fast: filling the buffer takes about 1 ms, and pixel operations take a few microseconds.

The 0.66 inch OLED’s viewing angle is 160 degrees, and it has a contrast ratio of 2000:1. The display is monochrome, white pixels on a black background. The SSD1306 supports inverted display mode (command 0xA7), which swaps black and white. You can also set the display to sleep mode (command 0xAE) to save power, drawing less than 1 µA. The micro:bit’s deep sleep mode draws about 1 µA, so you can achieve very low power consumption for battery-operated projects. To wake the display, send the command 0xAF. The display’s charge pump (for the OLED voltage) is enabled by default, but you can disable it with command 0x8D followed by 0x10 (disable) or 0x14 (enable). The charge pump boosts the 3.3V input to about 7V for the OLED pixels. Disabling it saves about 5 mA, but the display will be very dim.

For a practical project, you can display sensor data from the micro:bit’s built-in accelerometer or magnetometer. The micro:bit has a 3-axis accelerometer (LSM303AGR) that outputs 16-bit values at up to 100 Hz. You can read the values and display them on the OLED as a graph or text. For example, read the accelerometer’s x-axis value, map it to a pixel position (0-63), and draw a line. The micro:bit’s I2C bus is also used by the accelerometer (address 0x19) and magnetometer (address 0x1E), so you need to ensure no address conflicts. The OLED’s address 0x3C does not conflict with these devices. The total I2C bus can have up to 127 devices, but the micro:bit’s bus capacitance limits it to about 10 devices at 100 kHz. The accelerometer and magnetometer are on the same bus, so adding the OLED makes three devices, which is fine.

If you want to use the SPI interface instead of I2C, note that the 0.66 inch OLED module is available in both I2C and SPI versions. The SPI version has pins for CS, DC, RES, SCLK, MOSI, and VCC/GND. The micro:bit’s SPI pins are on pin 15 (MOSI), pin 14 (MISO), pin 13 (SCLK), and you can use any GPIO for CS and DC. The SPI version can achieve higher refresh rates (up to 10 MHz), but the micro:bit’s SPI peripheral runs at up to 8 MHz, so you can get 60 fps full-screen updates. However, the I2C version is simpler because it uses fewer pins. The micro:bit’s edge connector has only 20 pins, so using I2C frees up pins for other sensors. The 0.66 inch 64x64 oled display mentioned in the link is specifically an I2C module, so stick with I2C for that model.

To summarize the wiring: connect the OLED’s VCC to micro:bit 3V, GND to GND, SCL to pin 19, SDA to pin 20. No other pins needed. If your module has a RES pin, you can connect it to pin 16 for manual reset, but it’s optional. The micro:bit’s firmware version should be at least 0.9.0 for MakeCode or 1.1.1 for MicroPython. The OLED’s driver IC is SSD1306, which is widely supported. The display’s pixel layout is 64 columns by 64 rows, with the first pixel at (0,0) at the top-left. The SSD1306’s memory is organized in 8 pages of 64 bytes each, so you need to set the page address and column address correctly. The initialization sequence in the driver handles this automatically.

For troubleshooting, use a multimeter to check the voltage between VCC and GND on the OLED module. It should be 3.3V. If it’s 0V, check the connection. If the display is very dim, the contrast may be low. Set contrast to 200 for bright display. If the display shows only the top half, the page addressing may be wrong. The SSD1306 has a command for “set display start line” (0x40), which sets the top row of the display. For a 64x64 OLED, the start line is usually 0, but some modules use a different offset. You can set it to 32 to shift the display down. If the display shows mirror image, you need to set segment remap (0xA1) and COM scan direction (0xC8). These are part of the standard initialization sequence in the driver.

In terms of code size, the MicroPython driver for SSD1306 is about 2 kB, and your application code can be up to 30 kB on the micro:bit. The micro:bit’s flash memory is 256 kB, so you have plenty of space. The OLED’s frame buffer is stored in RAM, so you need to manage memory carefully. The micro:bit has 16 kB RAM, and the MicroPython interpreter uses about 8 kB, leaving 8 kB for user code and buffers. The frame buffer is 512 bytes, so you have 7.5 kB left for variables and other data. If you use double buffering, that’s 1 kB, still fine. The micro:bit’s stack is about 2 kB, so total RAM usage is under 10 kB, leaving 6 kB for other purposes.

For a real-world example, consider a weather station project: connect a DHT11 temperature/humidity sensor to the micro:bit’s pin 0, and display the data on the OLED. The DHT11 uses a single-wire protocol