Hello friends, I hope you all are doing great. Today, I am going to share the new OLED Library for Proteus V1.0. It brings all our OLED displays together in one library: the popular 0.96" OLED with its SSD1306 controller, the long and thin 0.91" 128x32 OLED, and the bigger 1.3" OLED with its SH1106 controller. You get one LIB file with 14 parts, one model file that runs them all, and a new demo in which a single Arduino UNO drives all three OLEDs at the same time.
Each of these OLEDs already has its own library and its own article: the OLED SSD1306 Library for Proteus V1.0, the OLED 128x32 Library for Proteus V1.0 and the OLED SH1106 Library for Proteus V1.0. This OLED Library for Proteus puts the three of them in one package, the same way our LCD Library for Proteus V3.0 does for the character LCDs, so you install one LIB file and one DLL and find every OLED in Pick Devices. It is our own OLED model, written from the SSD1306 and SH1106 datasheets: the I2C address, the control byte, the RAM with its random dots at power-on, the charge pump and the DC-DC, contrast, inverse and the classic mistakes, each one shown on the board.
NOTICE: This library is very special to our team. Three OLED modules, two controllers written from their datasheets, and now all of it in one library, with a demo that runs three OLEDs on one Arduino UNO. It took our team a lot of hard work and many test runs. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the OLED Library board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the OLED Library for Proteus V1.0:
What is in OLED Library for Proteus V1.0?
An OLED has no backlight: every pixel is a tiny organic LED that lights up by itself, so the picture has deep blacks and is easy to read from the side. A small controller sits on the glass. Your Arduino sends it commands and picture bytes over I2C, it keeps the picture in its own RAM and refreshes the pixels from there. The library has the three I2C OLED modules you find in most Arduino kits:
| Module | Glass | Controller | Pins | Its own article |
|---|---|---|---|---|
| OLED SSD1306 0.96" V1.0 | 128 x 64 pixels; white, blue or yellow-blue | SSD1306 | GND, VCC, SCL, SDA on top | OLED SSD1306 Library for Proteus V1.0 |
| OLED 128x32 0.91" V1.0 | 128 x 32 pixels; white or blue | SSD1306 | GND, VCC, SCL, SDA on the left end | OLED 128x32 Library for Proteus V1.0 |
| OLED SH1106 1.3" V1.0 | 128 x 64 pixels; white or blue | SH1106 | VDD, GND, SCK, SDA on top | OLED SH1106 Library for Proteus V1.0 |
Every module comes as two devices: Simple, with a live OLED STATUS panel right under the board on the schematic, and Advance, with a pop-up window, a bus log and four test tools. Together with the glass colours, that makes the 14 parts:
| Module | Simple | Advance |
|---|---|---|
| OLED SSD1306 0.96" V1.0 | OLED12864WHITETEP, OLED12864BLUETEP, OLED12864YELLOWBLUETEP | OLED12864WHITEADVTEP, OLED12864BLUEADVTEP, OLED12864YELLOWBLUEADVTEP |
| OLED 128x32 0.91" V1.0 | OLED12832WHITETEP, OLED12832BLUETEP | OLED12832WHITEADVTEP, OLED12832BLUEADVTEP |
| OLED SH1106 1.3" V1.0 | SH1106WHITETEP, SH1106BLUETEP | SH1106WHITEADVTEP, SH1106BLUEADVTEP |
These are exactly the parts of the three single-OLED libraries, with the same names, so a design you made with one of them opens with this library too. On every board, a PWR LED and an I2C LED show the power and each transaction to this OLED, and an ADDRESS selector moves the address between 0x3C and 0x3D with a click while the simulation runs. A real module has no LEDs and sets its address with a resistor on the back.
Looking for the Nokia 5110 display? It is not an OLED: its pixels darken a liquid crystal in front of a backlight. So it has its own library, the Nokia 5110 LCD Library for Proteus V1.0.
What's New in OLED Library for Proteus V1.0
- One library, three OLED modules:
TEPOLED.LIBwith all 14 parts, andTEPOLED.DLL, the model that runs them all. - Two controllers: the SSD1306 of the 0.96" and the 0.91" OLED, and the SH1106 of the 1.3" OLED, with its 132-column RAM and the column offset of its glass.
- A showcase demo: one Arduino UNO V4.0 drives all three OLEDs. Two share the UNO's I2C bus, and the third one gets a second I2C bus that the sketch makes itself on D2 and D3.
- No display library in the showcase: plain Wire code that draws one page at a time, so three OLEDs fit in the UNO's 2 KB of RAM.
- The three single-OLED demos, all on our Arduino UNO V4.0 with its built-in serial monitor.
- A compact package: about 1.47 MB, without the C++ source code.
The TEPOLED.DLL in this package is the newest one, the DLL of the OLED SH1106 library. The 0.96" and 0.91" packages carry older copies. This one runs all 14 parts, and their demos run on it unchanged, so keep this one.
Download OLED Library for Proteus
Click the button below to download OLED-Library-for-Proteus-v1.0.zip (about 1.47 MB, without the C++ source code):
OLED Library for Proteus V1.0- README.txt: a detailed guide to the 14 parts, the installation, the showcase wiring and commands, the properties, the test tools and real hardware.
- Proteus Library Files:
TEPOLED.LIB(all 14 parts) andArduinoV4TEP.LIBfrom our Arduino Library for Proteus V4.0, with the Arduino UNO V4.0 of the demos. - Proteus Model Files:
TEPOLED.DLLandTEPARDUINO.DLL. - Proteus Simulation: four demo projects with their HEX files: the showcase
OLED-Library-ArduinoUnoV4.pdsprjand the demos of the three single-OLED libraries, plus copies of both DLLs. - Arduino Code: the four sketches. The showcase needs no extra library; the single-OLED demos use the Adafruit SSD1306 and Adafruit SH110X libraries with Adafruit GFX from the Library Manager.
No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.
How to Install OLED Library for Proteus
- Close Proteus and extract the whole zip file to a normal folder, for example your Desktop.
- Copy the two files from Proteus Library Files into the LIBRARY folder, usually
C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY(on some PCsC:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY; use the folder that already holds Proteus's own .LIB files). - Copy
TEPOLED.DLLandTEPARDUINO.DLLfrom Proteus Model Files into the MODELS folder. If one of our OLED libraries put an older TEPOLED.DLL there, replace it with this one. - Installed one of our single-OLED libraries before? Delete its LIB file (
TEPOLED12864.LIB,TEPOLED12832.LIBorTEPOLEDSH1106.LIB) from the LIBRARY folder, or Pick Devices lists those parts twice. Your designs keep working, as the parts are the same. DeleteTEPOLED.IDXtoo, if there is one. - Start Proteus, press P and search for OLED and SH1106. The 14 parts are in the category Optoelectronics > Graphical LCDs.
Tip: every demo project needs its .hex file and the two DLLs beside it, so keep the Proteus Simulation folder together. The library was tested in Proteus 8.5; Proteus 7 is not supported.
0.96", 0.91" or 1.3": Which OLED Should You Use?
All three talk I2C on four pins and answer at 0x3C or 0x3D, and all three keep their picture in pages: strips 8 pixels tall and one column per byte. They differ in the glass and in the controller behind it:
| OLED 0.96" | OLED 0.91" | OLED 1.3" | |
|---|---|---|---|
| Pixels | 128 x 64 | 128 x 32 | 128 x 64 on a bigger glass |
| Controller | SSD1306 | SSD1306 | SH1106 |
| RAM | 128 columns x 8 pages | 128 columns x 8 pages; the glass shows pages 0 - 3 | 132 columns x 8 pages; the glass shows columns 2 - 129 |
| Panel supply | Charge pump: 8D 14 | Charge pump: 8D 14 | DC-DC: AD 8B |
| COM pads | Alternative: DA 12 | Sequential: DA 02 | Alternative: DA 12 |
| Addressing modes | Page, horizontal, vertical | Page, horizontal, vertical | Page only |
| Hardware scrolling | Yes | Yes | No |
| Pin order | GND VCC SCL SDA | GND VCC SCL SDA | VDD GND SCK SDA |
| A full frame at 400 kHz | 36.77 ms (1,024 bytes) | 18.23 ms (512 bytes) | 38.89 ms (1,024 bytes) |
| Arduino library | Adafruit_SSD1306 | Adafruit_SSD1306 | Adafruit_SH1106G (Adafruit SH110X) |
So pick the 0.96" OLED for most projects, the 0.91" when you need a slim status line under a button or in a small case, and the 1.3" when the text must be readable from further away. Just remember that the 1.3" needs an SH1106 driver: an SSD1306 sketch shows only random dots on it, and its supply pins are swapped compared to the 0.96" board. Each single-OLED article shows those traps step by step. And you can run several OLEDs on one Arduino, which is what the new demo shows.
The Showcase: One Arduino UNO Drives All Three OLEDs
Open OLED-Library-ArduinoUnoV4.pdsprj from the Proteus Simulation folder, with OLED_Library_Demo.hex and both DLLs beside it. One Arduino UNO V4.0 from our Arduino UNO Library for Proteus V4.0 runs all three OLEDs (see our Introduction to Arduino UNO for its pins):
- OLED1: the 0.96" SSD1306 with the yellow-blue glass, Simple, at address 0x3C on the UNO's I2C bus, SDA and SCL.
- OLED2: the 1.3" SH1106 with the white glass, Advance, at address 0x3D on the same bus.
- OLED3: the 0.91" 128x32 with the blue glass, Simple, at address 0x3C, on a second I2C bus: SDA on D2, SCL on D3.
- The monitor: no Virtual Terminal to wire. The UNO V4.0 has our serial monitor built in, on D0 / D1 like the USB chip of a real UNO.
At the start, the monitor names the three OLEDs it found, all three show the TEP logo for a second, and then each one gets its own dashboard: OLED1 a title in its yellow zone, the up time, a big line and a bar; OLED2 a big line, a moving sine wave and the number of frames sent; OLED3 a clock and a big line. The dashboards are redrawn twice a second.
Three OLEDs, Only Two Addresses
I2C is a bus: every device on it has an address, and the Arduino starts every transfer with it. Two OLEDs can share SDA and SCL as long as their addresses differ. But an OLED module offers only two addresses, 0x3C and 0x3D, picked with a resistor on its back (the ADDRESS selector in our parts). So OLED1 takes 0x3C and OLED2 0x3D on the UNO's bus, and a third OLED cannot join them. It needs a second I2C bus. On real hardware you could use an I2C multiplexer for that; the showcase simply makes the second bus itself on two free pins, D2 and D3:
| OLED | Signals | Power, address |
|---|---|---|
| OLED1 0.96" SSD1306 | SDA to A4 (the SDA header pin), SCL to A5 | VCC 5V, GND; address 0x3C |
| OLED2 1.3" SH1106 | SDA to A4, SCK to A5 (the same bus) | VDD 5V, GND; address 0x3D |
| OLED3 0.91" 128x32 | SDA to D2, SCL to D3 (the second bus) | VCC 5V, GND; address 0x3C |
Every connection is a short wire to a terminal with a net label: in Proteus, terminals with the same name are connected. So the SDA label on the UNO's I2C pin meets the SDA pins of OLED1 and OLED2, and SDA2 on D2 reaches only OLED3. The labels are SDA, SCL, SDA2, SCL2, VCC and GND.
Why the Showcase Uses No Display Library
A display library such as Adafruit SSD1306 keeps the whole picture in the Arduino's RAM and sends it with display(): 1 KB for a 128x64 OLED and 512 bytes for a 128x32. Three OLEDs would need 2.5 KB, and the UNO has only 2 KB. So the showcase draws one page at a time into a buffer of just 128 bytes, sends it, and moves on to the next page. The whole sketch uses 807 bytes of RAM. U8g2's page mode works the same way, if you want a library for this.
The Arduino Code
The showcase sketch, OLED_Library_Demo V1.0, uses only Arduino's Wire library and Serial. Each OLED is described by a small structure: its name, its address, its bus, its controller and its number of pages:
Oled oleds[3] = {
{"0.96\" SSD1306 128x64", 0x3C, false, false, 8, false},
{"1.3\" SH1106 128x64", 0x3D, false, true, 8, false},
{"0.91\" SSD1306 128x32", 0x3C, true, false, 4, false},
};
Every controller needs its own start-up. This is the one of the 0.96" SSD1306, with the charge pump on (8D 14), page addressing (20 02), the upright orientation (A1 C8), the alternative COM pads of a 64-row glass (DA 12) and DISPLAY ON (AF) last:
const byte INIT_SSD1306_64[] PROGMEM = {0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0x8D, 0x14, 0x20, 0x02, 0xA1, 0xC8,
0xDA, 0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0xAF};
The 0.91" OLED gets the same with 32 rows (A8 1F) and the sequential COM pads (DA 02). The SH1106 has no charge pump command and no addressing modes; it turns on its DC-DC converter with AD 8B and sets its pump voltage with 33:
const byte INIT_SH1106[] PROGMEM = {0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0xAD, 0x8B, 0xA1, 0xC8, 0xDA, 0x12,
0x81, 0xFF, 0xD9, 0x1F, 0xDB, 0x40, 0x33, 0xA4, 0xA6, 0xAF};
The Second I2C Bus on D2 and D3
I2C lines are open drain: a device pulls a line low or lets it go, and a pull-up resistor pulls it high. That matters for SDA, because the OLED pulls SDA low itself to answer. So the sketch never drives SDA high: for a 1 it switches D2 to INPUT_PULLUP and lets go, for a 0 it drives D2 low. SCL on D3 is driven directly, as only the UNO ever moves it. A START is SDA falling while SCL is high, a STOP SDA rising while SCL is high:
void swSda(bool high) { // open drain: released (the pull-ups pull it high) or driven low
if (high) pinMode(SW_SDA, INPUT_PULLUP);
else { digitalWrite(SW_SDA, LOW); pinMode(SW_SDA, OUTPUT); }
}
void swScl(bool high) { digitalWrite(SW_SCL, high ? HIGH : LOW); }
void swStart() { swSda(true); swScl(true); swSda(false); swScl(false); }
void swStop() { swSda(false); swScl(true); swSda(true); }
A byte goes out bit by bit, the highest bit first, each with one clock pulse. Then the sketch lets SDA go and gives a ninth clock pulse: if an OLED with this address is there, it pulls SDA low, the ACK:
bool swWrite(byte b) { // 8 bits, MSB first, then the ACK clock: true = the slave pulled SDA low
for (byte m = 0x80; m; m >>= 1) { swSda(b & m); swScl(true); swScl(false); }
swSda(true);
swScl(true);
bool ack = digitalRead(SW_SDA) == LOW;
swScl(false);
return ack;
}
One function sends a transaction on either bus. The first byte after the address is the control byte: 0x00 says commands follow, 0x40 says picture data follows. The address byte on the software bus is the 7-bit address shifted left with a 0 for "write", so 0x3C goes out as 0x78, just as Wire sends it:
bool send(const Oled& o, byte control, const byte* d, byte n) { // control 0x00 = commands follow, 0x40 = data follows
if (o.sw) {
swStart();
bool ok = swWrite(o.addr << 1);
if (ok) { swWrite(control); for (byte i = 0; i < n; i++) swWrite(d[i]); }
swStop();
return ok;
}
Wire.beginTransmission(o.addr);
Wire.write(control);
Wire.write(d, n);
return Wire.endTransmission() == 0;
}
The address check, which the sketch uses at the start and in the SCAN command, is a transaction without data: did anybody answer with an ACK?
bool answers(bool sw, byte addr) { // an address check: does a device ACK?
if (sw) { swStart(); bool ack = swWrite(addr << 1); swStop(); return ack; }
Wire.beginTransmission(addr);
return Wire.endTransmission() == 0;
}
Drawing One Page at a Time
A page is 8 rows of 128 pixels, one byte per column with bit 0 at the top. The drawing functions write only the pixels that fall on the page being drawn, curPage, and ignore the rest:
byte buf[128]; // one page: 8 rows x 128 columns
byte curPage; // the page being drawn
void px(int x, int y) { if (x >= 0 && x < 128 && y >= 0 && (y >> 3) == curPage) buf[x] |= 1 << (y & 7); }
show() runs the same drawing code once per page: it clears the buffer, draws, sends three commands (the page and the column in two halves) and then the 128 bytes in eight transactions of 16. The one difference between the controllers is the start column: the 1.3" glass shows the SH1106's RAM columns 2 to 129, so its pages start at column 2:
void show(byte i) { // draw and send OLED i, page by page
Oled& o = oleds[i];
if (!o.found) return;
unsigned long s = millis() / 1000;
byte col = o.sh1106 ? 2 : 0; // the 1.3" glass starts at RAM column 2
for (curPage = 0; curPage < o.pages; curPage++) {
memset(buf, 0, sizeof buf);
if (screen == DASH) drawDash(i, s);
else if (screen == LOGO) drawLogo(i);
byte c[3] = {byte(0xB0 + curPage), byte(col & 0x0F), byte(0x10 | (col >> 4))}; // page, column low / high nibble
send(o, 0x00, c, 3);
for (byte x = 0; x < 128; x += 16) send(o, 0x40, buf + x, 16); // 16 data bytes per transaction (Wire buffer: 32)
}
}
In setup(), the sketch sets the hardware bus to 400 kHz, makes the second bus idle (both lines high), starts the three OLEDs and clears their RAM at once, as an OLED shows random dots after power-on:
Wire.begin();
Wire.setClock(400000); // 400 kHz on A4 / A5
pinMode(SW_SCL, OUTPUT); // the software bus: SCL driven, SDA open drain
swSda(true); swScl(true);
for (byte i = 0; i < 3; i++) begin(oleds[i]);
screen = BLANK; showAll(); // clear each RAM at once (an OLED holds random dots after power-on)
Contrast and inverse are single commands that every controller understands, so the CONTRAST and INVERT commands just send them to each OLED that was found. INVERT swaps lit and dark pixels inside the controller, without sending a new picture:
for (byte i = 0; i < 3; i++) if (oleds[i].found) command(oleds[i], inverted ? 0xA7 : 0xA6);
The loop reads the monitor and redraws the dashboards twice a second. To change the sketch, export a new HEX file and load it into the UNO; see How to get the HEX file from Arduino. New to Arduino? Start with our Arduino Tutorial for Beginners.
Serial Monitor Commands
| Command | What it does |
|---|---|
| HELP | The command list |
| STATUS | The three OLEDs (found or NOT FOUND, bus, address), the screen, the bar, inverse, the frames sent |
| SCAN | Every address from 0x08 to 0x77 on both buses |
| TEXT1 <text> ... TEXT3 <text> | The big line of OLED1 ... OLED3 (10 characters) |
| ALL <text> | The big line of all three |
| BAR <0-100> | The bar on OLED1 |
| CONTRAST <0-255> | The contrast of all three |
| INVERT ON / OFF | Inverse on all three |
| LOGO | The TEP logo on all three |
| DASH | The dashboards again |
| CLEAR | All three empty (DASH brings the dashboards back) |
How to Run the Showcase
- Press Run. ARD1's monitor window, "TEP Arduino UNO - ARD1" (9600 baud), and OLED2's pop-up open; move them aside, as they open over the schematic. The monitor lists the three OLEDs, the logo shows for a second, then the dashboards.
- Type SCAN and STATUS in the monitor and press Enter.
- Type ALL Hello, TEP and watch the big line of all three OLEDs change, then BAR 75 for OLED1.
- Type LOGO, INVERT ON, INVERT OFF and DASH.
- Click the ADDRESS selector of OLED1 or OLED3 and watch its panel say WRONG ADDRESS; click it again.
- On OLED2's pop-up, look at the Display page, the Bus log and the four tests.
OLED Library for Proteus Simulation Results
The Built-in Serial Monitor in Its Simple Interface
The Arduino UNO V4.0 carries its own copy of our TEP Serial Monitor Advance, wired inside the board to D0 / D1. Its window opens at Run, and a click on the board's USB port opens it again after you close it. The screenshot shows its Simple interface: only the log and the line to send.
- Switch to it: press Ctrl+Shift+U, or use the monitor's ... menu.
- Back to the full view: press Esc; the full view has the Board, Monitor and Plotter tabs.
Read all about the monitor in TEP Serial Monitor Advance for Proteus. At the start, and for SCAN, it shows:
OLED Library V1.0 demo - The Engineering Projects
OLED1 found: 0.96" SSD1306 128x64 on A4/A5 at 0x3C
OLED2 found: 1.3" SH1106 128x64 on A4/A5 at 0x3D
OLED3 found: 0.91" SSD1306 128x32 on D2/D3 at 0x3C
Type HELP for the commands
SCAN
A4/A5 bus: 0x3C 0x3D
D2/D3 bus: 0x3C
SCAN tries every address on both buses. The UNO's bus answers at 0x3C and 0x3D, the second bus at 0x3C: three OLEDs, and the two at 0x3C never see each other's bytes.
ALL, BAR and STATUS
ALL Hello, TEP
OK - all three: Hello, TEP
BAR 75
OK - bar 75%
STATUS
OLED1 0.96" SSD1306 128x64, A4/A5 0x3C: found
OLED2 1.3" SH1106 128x64, A4/A5 0x3D: found
OLED3 0.91" SSD1306 128x32, D2/D3 0x3C: found
Screen: dashboard
Bar 75%, inverse off
Frames sent: 154
ALL writes its text into the big line of every OLED and redraws all three at once. STATUS lists each OLED with its bus and its address. "Frames sent" counts the redraws of all three.
The Three Dashboards
OLED1's title sits in the yellow zone of its glass, the top 16 rows; the rest is blue. The 0.91" OLED is the same controller with half the rows, so its dashboard has just a clock and the big line. Both STATUS panels say READY with the glass, the address and DISPLAY ON. They also measure the bus: OLED1's panel reads its clock as 400k and a frame in about 60 ms, OLED3's reads 45k and about 120 ms for half the bytes. A bus made in software is much slower than the UNO's I2C hardware, but for a status display it is fast enough.
LOGO and INVERT
LOGO draws the TEP logo, a frame and three lines of text, on all three OLEDs. drawLogo() checks the number of pages, so the 0.91" OLED gets a short version that fits its 32 rows. Then INVERT ON:
The picture did not change in the RAM: INVERT sends one command, A7, and the controller shows the RAM inverted. INVERT OFF sends A6 and the logo is back. On a real OLED, an inverted screen lights almost every pixel and draws much more current, so use it for short alerts.
OLED2 Advance: Two OLEDs on One Bus, as the SH1106 Sees It
OLED2 is an Advance part, so it keeps only the board on the schematic and opens a pop-up window with the Display, Bus log and Tests tabs. Here is its Display page:
The tiles read the controller: COLUMNS 2 - 129 is the sketch's column offset at work, the pages start at RAM column 2, right where the 1.3" glass begins. The RAM card shows all 132 columns, with the two unused columns at each side. Frames received counts 140 frames of about 56 ms each: 8 pages on the bus, with the drawing of each page in between.
The Init Check
The Init check compares the start-up with the SH1106 datasheet and the 1.3" glass: SH1106 commands only, the DC-DC on, the column offset right, 64 rows, the alternative COM pads, upright, and DISPLAY ON 67.9 ms after power-on. The table below lists the 16 commands exactly as the sketch sent them; the gap of 180.9 us before DA 12 is where begin() starts its second transaction, as it sends the start-up in two pieces.
The one amber line, RAM before display on, is a note, not an error: the sketch turns the display on first and clears the RAM right after, so for a moment the glass could show the random dots of the power-on RAM. The Adafruit libraries do the same, and the verdict stays green.
The I2C Bus Test: Other Devices
This tool shows the bus from OLED2's side. Since power-on it counts 10806 transactions to its own address: 1204 with commands, 9600 with picture data, 16 bytes each after the 0x40 control byte, and 2 address checks. The Address checks are the empty transfers of the sketch: 2 reached 0x3D (the start and SCAN), 112 went to other addresses. And Other devices counts 10804 writes with data for another address: those are OLED1's, at 0x3C. OLED2 sees them all on the bus and ignores them, just like a real SH1106. The clock is 400 kHz, which the SH1106 is rated for. Press Start measuring to count from that moment instead of from power-on.
The Bus Log
The log shows show() at work: three commands per page (B7, 02 and 10 for page 7 at column 2), then eight runs of 16 bytes, from column 2 up to column 114, about 0.6 ms apart. The longer gap of 1 to 3 ms before each PAGE command is the sketch drawing the next page into its buffer. The Tests tab has four tools on every Advance OLED:
| Tool | Good for |
|---|---|
| Init check | Random dots, a dark, mirrored or shifted picture: is the start-up right for this controller and this glass? |
| I2C bus | A dark OLED: the address the sketch writes to, the address checks, other devices on the bus, the clock, Wire's 32-byte buffer |
| Speed | Slow animations: how long a full frame takes on the bus, the frames a second |
| Pixels | Click a pixel: its RAM page, column, bit and byte |
The Three Single-OLED Demos
The package also has the demos of the three single-OLED libraries, so you can study one OLED at a time with the Adafruit libraries. Each one runs on two Arduino UNO V4.0 boards, with a Simple OLED on NODE 1 and an Advance OLED on NODE 2, and each is explained step by step in its own article.
OLED SSD1306 0.96": Adafruit SSD1306 and GFX, the dashboard, scrolling, the address search and the yellow-blue glass. This demo is new in this package: the same parts and the same HEX file as in its own package, now on our Arduino UNO V4.0. Read the OLED SSD1306 Library for Proteus V1.0.
OLED 128x32 0.91": the slim glass with 32 rows, and what happens when a sketch sends it the settings of a 128x64 OLED. Read the OLED 128x32 Library for Proteus V1.0.
OLED SH1106 1.3": Adafruit_SH1106G, the column offset (try OFFSET 0), the SSD1306 trap and the reversed supply pins. Read the OLED SH1106 Library for Proteus V1.0.
Troubleshooting
- Every part shows up twice in Pick Devices: a single-OLED library's LIB file is installed too. Delete it (step 4 of the installation).
- The part is not simulated, or there is no panel: TEPOLED.DLL is missing from MODELS and from the project folder. No UNO or no monitor window: TEPARDUINO.DLL is missing, or click the UNO's USB port.
- The glass stays black and the PWR LED is off: no power. Check VCC / VDD and GND; on the 1.3" board the pins are VDD, GND, SCK, SDA, and swapped supply pins show SUPPLY REVERSED.
- WAITING FOR I2C: nothing reached this address. Check SDA and SCL, and that the sketch runs. In the showcase, OLED3 is on D2 and D3, not on A4 and A5.
- WRONG ADDRESS: the sketch writes to another address. Change it in the sketch, or the ADDRESS property or the selector.
- NOT FOUND in the showcase's monitor: that OLED did not answer its address: its wires, its ADDRESS, or two OLEDs with the same address on one bus.
- Random dots or a stripe on the 1.3" OLED: an SSD1306 driver on the SH1106. Use an SH1106 driver (Adafruit_SH1106G, U8g2's SH1106).
- The Advance pop-up does not appear: click OPEN PANEL on the board, or turn "Open the panel at Run" back on in Settings.
Things to Know Before Using Real OLEDs
The showcase sketch uses only Wire and Serial, so it runs on a real UNO with the same three OLEDs too. Keep in mind:
- RAM: a display library keeps the whole picture in RAM, 1 KB for a 128x64 OLED. On an UNO, two 128x64 OLEDs with the Adafruit libraries are already too much: draw page by page, as this sketch does or U8g2 in page mode, or use a board with more RAM.
- Pull-ups: the modules have their own I2C pull-ups; on the software bus, the UNO's internal pull-up helps too. Keep the wires short.
- Check the pin order: the 1.3" board's pins are VDD, GND, SCK, SDA. Check your module before you wire it like a 0.96" (GND, VCC, SCL, SDA); swapped supply pins can kill it.
- Check the address: most modules come at 0x3C. Run SCAN before you write the address into the sketch.
- Burn-in: OLED pixels age. Turn the display off or dim it when nobody looks, and do not leave an inverted screen on for hours.
Limitations of the Simulation
- Not modelled: reading from the OLED (a read is not acknowledged), the SPI interface of the 7-pin modules, I2C timing violations (any clock the AVR makes is accepted; the tools show it), the current draw and pixel ageing.
- The PWR and I2C LEDs, the ADDRESS selector, the badges, the panel buttons, the STATUS panels and the pop-ups are TEP additions; a real module has none of them.
- The model is our own implementation, written from the SSD1306 and SH1106 datasheets. SSD1306 is a Solomon Systech part and SH1106 a Sino Wealth part; this library is not made or endorsed by Solomon Systech, Sino Wealth, Adafruit or Labcenter.
- Licences: the showcase sketch uses only Arduino's Wire library. The single-OLED demos use Adafruit SSD1306 2.5.17, Adafruit SH110X 2.1.15 and Adafruit GFX 1.12.6 (BSD licence) with Adafruit BusIO. The HEX files contain them and the Arduino AVR core 1.8.6, which includes LGPL-licensed code; its source code is on GitHub. The README holds the Adafruit licence texts.
- Tested in Proteus 8.5 in October 2026 (the showcase as shipped on the Arduino UNO V4.0 with its built-in monitor: all three OLEDs, SCAN, STATUS, ALL, BAR, LOGO, INVERT, the panels, OLED2's pop-up and tools, and every screenshot here; the 0.96" demo on the UNO V4.0; the 0.91" and 1.3" demos on this same DLL) and with automatic PC checks, 0 failed: 52 with the real showcase sketch against three OLED models on two buses at once, 46, 48, 57 and 38 with the single-OLED sketches and the unmodified Adafruit libraries, 66 on the SSD1306 controller, 8 on the pop-up pages, and the showcase project (120 checks) and the 0.96" UNO V4.0 project (97 checks) read back from disk. Proteus 7 is not supported.
So, that was all about the OLED Library for Proteus V1.0. I hope having all three OLEDs in one library, and seeing them run on one Arduino UNO with two I2C buses, makes your next display project much easier. If you use the OLED Library for Proteus in a project, please share your feedback in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!