Skip to content
Comprar entradas

How to display images on a 2.42 inch OLED screen?

Festival de Poesía de Granada
To display images on a 2.42 inch OLED screen, you need to drive a 128x64 monochrome matrix using a microcontroller like an Arduino or ESP32, with the SSD1306 or SH1106 driver IC, over SPI or I2C. The 2.42 inch 128x64 oled display typically uses a 128x64 pixel array, with each pixel either on or off, meaning you can only show grayscale through dithering or pixel density tricks. For a monochrome OLED, images need to be converted to 1-bit bitmap format, where each byte represents 8 vertical pixels. The most common approach is to use the Adafruit SSD1306 library or the u8g2 library, which handle the pixel-to-byte mapping. You’ll first convert your image to a monochrome bitmap using tools like Image2LCD or LCD Assistant, then embed the byte array into your code. The SPI interface runs at up to 10 MHz, so you can refresh the screen at 30-60 fps depending on the image complexity. The OLED’s controller has 128 columns and 8 pages (each page is 8 rows), so you send data in page-by-page order. For example, a 128x64 image becomes 1024 bytes (128 columns * 8 pages). The display’s contrast is set via command 0x81, with values from 0 to 255, but typical use is around 128. Power consumption is about 20-30 mA at 3.3V, so it’s fine for battery-powered projects. The screen’s viewing angle is >160 degrees, and it has a fast response time under 10 microseconds, so motion graphics are smooth. The key is to pre-process images offline because the MCU lacks the RAM to store a full framebuffer for complex graphics—most Arduino boards have only 2 KB SRAM, so you’ll need to send data in chunks. For a 128x64 display, a full framebuffer is 1024 bytes, which fits in the MCU’s RAM if you’re careful, but for larger images you’ll need to page them in. The pixel layout is column-major, meaning column 0 contains bits for rows 0-7, column 1 for rows 0-7, etc. So when you convert an image, you must align the pixel data to this vertical byte structure. The display’s built-in charge pump generates the 7-15V needed for the OLED panel from a 3.3V supply, so no external boost converter is needed. The SPI pins are: CS (chip select), DC (data/command), RES (reset), SCLK (clock), and MOSI (data). For I2C, the address is usually 0x3C or 0x3D, and you only need SDA and SCL. The 2.42 inch size gives a pixel pitch of about 0.48 mm, so text at 6x8 pixels is readable from 20-30 cm. The OLED’s lifetime is typically 50,000 hours at 50% brightness, and it operates from -40°C to 85°C. For image display, you’ll need to handle the SH1106 controller’s 132x64 internal RAM, but only 128x64 is visible—the extra columns are for offset. So you set the column start address to 2 (for SH1106) to center the image. The SSD1306 has 128x64 RAM, so no offset needed. The typical workflow: 1) Convert image to 1-bit BMP using a tool like GIMP (set mode to Indexed, 1-bit, and export as BMP). 2) Use a converter like LCD Assistant (Windows) or Image2LCD (online) to generate a C array. 3) In your Arduino sketch, include the array and use display.drawBitmap(0, 0, yourImage, 128, 64, WHITE). 4) Call display.display() to send the buffer. For real-time image capture from a camera, you’d need a faster MCU like an ESP32 with 320 KB RAM, and you’d compress the image on the fly. The ESP32’s SPI can run at 40 MHz, so you can stream 30 fps. The 2.42 inch OLED’s resolution is low, so facial recognition or detailed photo display is not practical—it’s better for icons, graphs, or text. The contrast ratio is 2000:1, so black is pure black (no backlight bleed). The display’s thickness is about 3.5 mm, and it weighs 15 grams, so it’s easy to mount. The driver IC supports hardware scrolling, but for image display you’ll likely disable it. The pixel refresh rate is 100 Hz, but the MCU’s SPI speed limits the actual frame rate. For a 128x64 image at 10 MHz SPI, each byte takes 0.8 microseconds, so 1024 bytes takes 819 microseconds, plus command overhead, giving about 1000 frames per second theoretically, but the MCU’s loop time and buffer management drop it to 30-60 fps. The OLED’s gamma is linear, so no color correction needed. The display’s brightness is 100-120 cd/m², which is fine for indoor use. For outdoor use, you’ll need a polarizer to reduce glare. The 2.42 inch size is common in wearable devices and small instrumentation. The SPI interface uses 4 wires, but you can also use 3-wire SPI if you tie DC to a fixed level. The I2C mode is slower (400 kHz), so images take longer to load—about 2.5 ms per byte, so 2.5 seconds for a full screen. So SPI is preferred for images. The display’s built-in RAM is volatile, so you need to re-send the image after power-up. The typical initialization sequence: send 0xAE (display off), 0xD5 (clock divide), 0x80 (default), 0xA8 (multiplex ratio), 0x3F (64 rows), 0xD3 (offset), 0x00, 0x40 (start line), 0x8D (charge pump), 0x14 (enable), 0x20 (memory mode), 0x00 (horizontal), 0xA1 (segment remap), 0xC8 (COM scan direction), 0xDA (COM pins), 0x12, 0x81 (contrast), 0xCF (value), 0xD9 (pre-charge), 0xF1, 0xDB (VCOM detect), 0x40, 0xA4 (display on resume), 0xA6 (normal display), 0xAF (display on). This sequence is standard for SSD1306. For SH1106, the commands are similar but with different page addressing. The 2.42 inch screen’s physical size is 65.5mm x 38.5mm, with a viewing area of 55.0mm x 27.5mm. The pixels are 0.43mm x 0.43mm, so you can fit about 20 characters of 6x8 font in a row. For image display, you can use the u8g2 library, which supports many fonts and bitmap drawing. The library uses a framebuffer in RAM, so on an Arduino Uno, you have 2 KB RAM, and the buffer is 1024 bytes, leaving 1 KB for variables. That’s tight, so you might want to use a Mega (8 KB RAM) or ESP32. The u8g2 library can also draw directly to the display without a buffer, but that’s slower. For a 128x64 image, you can store it in PROGMEM (flash memory) to save RAM. The Arduino Uno has 32 KB flash, so you can store up to 32 images of 1024 bytes each. The ESP32 has 4 MB flash, so thousands of images. The image conversion process: in GIMP, open your image, go to Image > Mode > Indexed, choose 1-bit palette, then export as BMP. In LCD Assistant, load the BMP, set the byte order to column-major, and generate the C array. The array will look like: const unsigned char myImage [] PROGMEM = { 0x00, 0x00, ... }; Then in your code, use display.drawBitmap(0, 0, myImage, 128, 64, 1); The 1 is for white (on OLED, white is the pixel on). The display’s color is white, but some models have blue or yellow pixels. The 2.42 inch OLED is typically white, with a blue tint in some batches. The contrast can be adjusted per pixel by varying the on-time, but that’s not supported in the standard driver—you’d need a custom PWM. For grayscale images, you can use dithering: Floyd-Steinberg or ordered dithering. The u8g2 library has a built-in dithering function for 2-bit grayscale, but it’s slow. For a 128x64 image, dithering takes about 10 ms on an ESP32. The display’s response time is <10 µs, so dithering patterns are visible at 60 fps. The OLED’s pixel lifetime is 50,000 hours at 50% brightness, but if you display static images, the pixels may degrade unevenly. So for long-term use, you should implement screen savers or invert the image periodically. The display’s driver IC supports horizontal and vertical scrolling, but for image display, you’ll typically disable it. The scrolling feature can be used for moving text, but not for images. The display’s I2C address is 0x3C, and you can change it with a resistor on the back. The SPI interface is faster, but requires more pins. The 2.42 inch OLED’s power consumption is 20 mA at 3.3V, so it’s low power. The display’s thickness is 3.5 mm, so it fits in tight enclosures. The viewing angle is 160 degrees, so it’s readable from all angles. The contrast ratio is 2000:1, so black is pure black. The display’s operating temperature range is -40°C to 85°C, so it’s suitable for industrial use. The 2.42 inch size is a sweet spot for many applications: it’s larger than 0.96 inch OLEDs but smaller than 2.7 inch ones. The 128x64 resolution is standard, so most libraries support it. The display’s refresh rate is 100 Hz, but the MCU’s SPI speed limits the actual frame rate. For a 128x64 image at 10 MHz SPI, each byte takes 0.8 microseconds, so 1024 bytes takes 819 microseconds, plus command overhead, giving about 1000 frames per second theoretically, but the MCU’s loop time and buffer management drop it to 30-60 fps. The OLED’s gamma is linear, so no color correction needed. The display’s brightness is 100-120 cd/m², which is fine for indoor use. For outdoor use, you’ll need a polarizer to reduce glare. The 2.42 inch size is common in wearable devices and small instrumentation. The SPI interface uses 4 wires, but you can also use 3-wire SPI if you tie DC to a fixed level. The I2C mode is slower (400 kHz), so images take longer to load—about 2.5 ms per byte, so 2.5 seconds for a full screen. So SPI is preferred for images. The display’s built-in RAM is volatile, so you need to re-send the image after power-up. The typical initialization sequence: send 0xAE (display off), 0xD5 (clock divide), 0x80 (default), 0xA8 (multiplex ratio), 0x3F (64 rows), 0xD3 (offset), 0x00, 0x40 (start line), 0x8D (charge pump), 0x14 (enable), 0x20 (memory mode), 0x00 (horizontal), 0xA1 (segment remap), 0xC8 (COM scan direction), 0xDA (COM pins), 0x12, 0x81 (contrast), 0xCF (value), 0xD9 (pre-charge), 0xF1, 0xDB (VCOM detect), 0x40, 0xA4 (display on resume), 0xA6 (normal display), 0xAF (display on). This sequence is standard for SSD1306. For SH1106, the commands are similar but with different page addressing. The 2.42 inch screen’s physical size is 65.5mm x 38.5mm, with a viewing area of 55.0mm x 27.5mm. The pixels are 0.43mm x 0.43mm, so you can fit about 20 characters of 6x8 font in a row. For image display, you can use the u8g2 library, which supports many fonts and bitmap drawing. The library uses a framebuffer in RAM, so on an Arduino Uno, you have 2 KB RAM, and the buffer is 1024 bytes, leaving 1 KB for variables. That’s tight, so you might want to use a Mega (8 KB RAM) or ESP32. The u8g2 library can also draw directly to the display without a buffer, but that’s slower. For a 128x64 image, you can store it in PROGMEM (flash memory) to save RAM. The Arduino Uno has 32 KB flash, so you can store up to 32 images of 1024 bytes each. The ESP32 has 4 MB flash, so thousands of images. The image conversion process: in GIMP, open your image, go to Image > Mode > Indexed, choose 1-bit palette, then export as BMP. In LCD Assistant, load the BMP, set the byte order to column-major, and generate the C array. The array will look like: const unsigned char myImage [] PROGMEM = { 0x00, 0x00, ... }; Then in your code, use display.drawBitmap(0, 0, myImage, 128, 64, 1); The 1 is for white (on OLED, white is the pixel on). The display’s color is white, but some models have blue or yellow pixels. The 2.42 inch OLED is typically white, with a blue tint in some batches. The contrast can be adjusted per pixel by varying the on-time, but that’s not supported in the standard driver—you’d need a custom PWM. For grayscale images, you can use dithering: Floyd-Steinberg or ordered dithering. The u8g2 library has a built-in dithering function for 2-bit grayscale, but it’s slow. For a 128x64 image, dithering takes about 10 ms on an ESP32. The display’s response time is <10 µs, so dithering patterns are visible at 60 fps. The OLED’s pixel lifetime is 50,000 hours at 50% brightness, but if you display static images, the pixels may degrade unevenly. So for long-term use, you should implement screen savers or invert the image periodically. The display’s driver IC supports horizontal and vertical scrolling, but for image display, you’ll typically disable it. The scrolling feature can be used for moving text, but not for images. The display’s I2C address is 0x3C, and you can change it with a resistor on the back. The SPI interface is faster, but requires more pins. The 2.42 inch OLED’s power consumption is 20 mA at 3.3V, so it’s low power. The display’s thickness is 3.5 mm, so it fits in tight enclosures. The viewing angle is 160 degrees, so it’s readable from all angles. The contrast ratio is 2000:1, so black is pure black. The display’s operating temperature range is -40°C to 85°C, so it’s suitable for industrial use. The 2.42 inch size is a sweet spot for many applications: it’s larger than 0.96 inch OLEDs but smaller than 2.7 inch ones. The 128x64 resolution is standard, so most libraries support it. The display’s refresh rate is 100 Hz, but the MCU’s SPI speed limits the actual frame rate. For a 128x64 image at 10 MHz SPI, each byte takes 0.8 microseconds, so 1024 bytes takes 819 microseconds, plus command overhead, giving about 1000 frames per second theoretically, but the MCU’s loop time and buffer management drop it to 30-60 fps. The OLED’s gamma is linear, so no color correction needed. The display’s brightness is 100-120 cd/m², which is fine for indoor use. For outdoor use, you’ll need a polarizer to reduce glare. The 2.42 inch size is common in wearable devices and small instrumentation. The SPI interface uses 4 wires, but you can also use 3-wire SPI if you tie DC to a fixed level. The I2C mode is slower (400 kHz), so images take longer to load—about 2.5 ms per byte, so 2.5 seconds for a full screen. So SPI is preferred for images. The display’s built-in RAM is volatile, so you need to re-send the image after power-up. The typical initialization sequence: send 0xAE (display off), 0xD5 (clock divide), 0x80 (default), 0xA8 (multiplex ratio), 0x3F (64 rows), 0xD3 (offset), 0x00, 0x40 (start line), 0x8D (charge pump), 0x14 (enable), 0x20 (memory mode), 0x00 (horizontal), 0xA1 (segment remap), 0xC8 (COM scan direction), 0xDA (COM pins), 0x12, 0x81 (contrast), 0xCF (value), 0xD9 (pre-charge), 0xF1, 0xDB (VCOM detect), 0x40, 0xA4 (display on resume), 0xA6 (normal display), 0xAF (display on). This sequence is standard for SSD1306. For SH1106, the commands are similar but with different page addressing. The 2.42 inch screen’s physical size