// Transparent OLED display 128x128px SH1107 1.12" with custom driver board and Arduino UNO
// created by upir, 2025
// youtube channel: https://www.youtube.com/upir_upir
// YouTube Video: https://youtu.be/HFeO1TjBkfM
// Source Files: https://github.com/upiir/transparent_oled_128x128px_sh1107
// Links from the video:
// Do you like this video? You can buy me a coffee ☕: https://www.buymeacoffee.com/upir
// Transparent OLED display 128x128px SH1107 1.12": https://s.click.aliexpress.com/e/_okz25Yz
// Arduino UNO R3: https://s.click.aliexpress.com/e/_oF3T34V
// Breadboard wires: https://s.click.aliexpress.com/e/_o2c75TF
// Arduino UNO Pinout: https://docs.arduino.cc/hardware/uno-rev3/
// PCB: https://www.pcbway.com/project/shareproject/Driver_PCB_Board_for_Transparent_OLED_display_128x128px_SH1107_1_12_660950bb.html
// Lopaka graphics editor: https://lopaka.app
// SJM406 Channel: https://www.youtube.com/@sjm4306/videos
// Related videos with transparent OLED displays / SH1107 displays:
// SH1107 Clock: https://youtu.be/srgsBWHSNSQ
// Compass SH1107: https://youtu.be/G1C09eoJ07c
// Thank you for 100 Subscribers: https://youtu.be/hIFDcksXgBk
// Arduino + OLED = 3D: https://youtu.be/kBAcaA7NAlA
// Smaller & Faster Arduino: https://youtu.be/4GfPQoIRqW8
// Arduino 3D Menu: https://youtu.be/uEkksez7qvE
// Arduino OLED Segmented Clock: https://youtu.be/OqqPvb8FEHs
#include <U8g2lib.h> // u8g2 library for drawing on OLED display - needs to be installed in Arduino IDE first
// display inside WOKWI uses I2C connection
U8G2_SH1107_128X128_2_HW_I2C u8g2(U8G2_R0); // final display, 128x128px [page buffer, size = 256 bytes], HW IIC connection
// I2C connection:
// GND > GND
// VCC > +5V
// SDA (serial data) > A4
// SCL (serial clock) > A5
// my transparent display uses SPI connection, in that case, please comment the previous initialization and uncomment this one
// U8G2_SH1107_PIMORONI_128X128_1_4W_HW_SPI u8g2(U8G2_R0, /*cs*/ 10, /*dc*/ 9, /*reset*/ 8);
// SPI Connection to Arduino UNO
// Display <> Arduino UNO
// SCK / CL Clock > 13
// COPI / DA / MOSI Data > 11
// SS / CS Chip Select > 10
// DC Data Command > 9
// RS Reset > 8
// 5V > 5V
// GND > GND
int frame = 0; // current frame
const int sprite_count = 10; // number of sprites
int sprite_x[sprite_count];
int sprite_y[sprite_count];
int sprite_img[sprite_count];
// images generated by image2cpp
// 'frame_01', 8x8px
const unsigned char epd_bitmap_frame_01 [] = {
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
};
// 'frame_02', 8x8px
const unsigned char epd_bitmap_frame_02 [] = {
0x00, 0x00, 0x28, 0x10, 0x28, 0x00, 0x00, 0x00
};
// 'frame_03', 8x8px
const unsigned char epd_bitmap_frame_03 [] = {
0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00
};
// 'frame_04', 8x8px
const unsigned char epd_bitmap_frame_04 [] = {
0x82, 0x44, 0x28, 0x00, 0x28, 0x44, 0x82, 0x00
};
// 'frame_05', 8x8px
const unsigned char epd_bitmap_frame_05 [] = {
0x82, 0x44, 0x00, 0x10, 0x00, 0x44, 0x82, 0x00
};
// 'frame_06', 8x8px
const unsigned char epd_bitmap_frame_06 [] = {
0x82, 0x00, 0x10, 0x38, 0x10, 0x00, 0x82, 0x00
};
// 'frame_07', 8x8px
const unsigned char epd_bitmap_frame_07 [] = {
0x00, 0x10, 0x10, 0x6c, 0x10, 0x10, 0x00, 0x00
};
// 'frame_08', 8x8px
const unsigned char epd_bitmap_frame_08 [] = {
0x10, 0x10, 0x00, 0xc6, 0x00, 0x10, 0x10, 0x00
};
// 'frame_09', 8x8px
const unsigned char epd_bitmap_frame_09 [] = {
0x10, 0x00, 0x00, 0x82, 0x00, 0x00, 0x10, 0x00
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 288)
const int epd_bitmap_allArray_LEN = 9;
const unsigned char* epd_bitmap_allArray[9] = {
epd_bitmap_frame_01,
epd_bitmap_frame_02,
epd_bitmap_frame_03,
epd_bitmap_frame_04,
epd_bitmap_frame_05,
epd_bitmap_frame_06,
epd_bitmap_frame_07,
epd_bitmap_frame_08,
epd_bitmap_frame_09
};
const unsigned char upir_logo [] = { // this is another way how to define images, using binary notation
B00010101, B11010111,
B00010101, B01000101,
B00010101, B10010110,
B00011001, B00010101
};
void setup() {
u8g2.begin(); // begin the u8g2 library
u8g2.setColorIndex(1); // set color to white
// setup random X and Y position and image for sprites
for (int i = 0; i < sprite_count; i++) {
sprite_x[i] = random(0, 128-8);
sprite_y[i] = random(0, 128-8);
sprite_img[i] = i % 8; // previously was sprite_img[i] = random(0, 8);, but this one looks better
}
}
void loop() {
u8g2.firstPage();
do {
// draw all sprites
for (int i = 0; i < sprite_count; i++) {
u8g2.drawBitmap( sprite_x[i], sprite_y[i], 8/8, 8, epd_bitmap_allArray[sprite_img[i]]);
}
// thank you for 100K subs labels - generated using Lopaka.app
u8g2.setFontMode(1);
u8g2.setBitmapMode(1);
u8g2.setFont(u8g2_font_profont17_tr);
u8g2.drawStr(6, 44, "Thank you for");
u8g2.drawStr(15, 94, "subscribers");
u8g2.setFont(u8g2_font_profont29_tr);
u8g2.drawStr(8, 74, "100 000");
// draw upir logo
u8g2.drawBitmap(128-16, 128-4, 16/8, 4, upir_logo);
} while ( u8g2.nextPage() );
// update sprites with next image
for (int i = 0; i < sprite_count; i++) {
sprite_img[i]++; // increase current image
if (sprite_img[i] > 8) {
// last image == set new random position and first image
sprite_x[i] = random(0, 128-8);
sprite_y[i] = random(0, 128-8);
sprite_img[i] = 0;
}
}
//delay(10); // this is no longer needed, perhaps for the emulator to slow down the drawing a little bit
}
Loading
grove-oled-sh1107
grove-oled-sh1107