Hello friends, I hope you all are doing great. Today, I am going to share the new OLED 128x32 Library for Proteus V1.0. The 0.91" OLED is the little brother of the popular 0.96" display: a long, thin module of 128 x 32 pixels, with the same SSD1306 controller and the same four I2C wires, GND, VCC, SCL and SDA. It fits where a bigger display does not: in a small box, under a knob, on a badge, or as a status line next to a project. With this OLED 128x32 Library for Proteus, your sketch draws on a 0.91" OLED that behaves like the real one, pixel by pixel.
This is our second OLED library, after the OLED SSD1306 Library for Proteus V1.0, and it runs on the same own SSD1306 model, now with the 32-row glass wired the way the real 0.91" module is. You get four devices: a white and a blue OLED, each as OLED 128x32 Simple, with a live STATUS panel on the schematic, and OLED 128x32 Advance, with a pop-up window, a bus log and four OLED test tools. And it is the first library whose demo runs on our new Arduino UNO V4.0: working LEDs, a working RESET and a serial monitor built into the board, so the demo needs no extra monitor parts at all.
NOTICE: This library is very special to our team. A 0.91" OLED looks like a smaller copy of the 0.96", but its glass is wired differently inside, and a sketch written for the bigger display shows a squashed picture on it. We modelled that wiring exactly, together with the charge pump, the controller's own scrolling and the 512-byte frames, and we moved the demo to our own Arduino UNO V4.0. 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 128x32 Library for Proteus V1.0:
What is a 0.91" OLED 128x32 Display?
A 0.91" OLED 128x32 display is a small graphic display module: a 0.91" glass with 128 x 32 pixels and the SSD1306 controller behind it, on a long blue board of about 38 x 12 mm with a 4-pin I2C header at one end. OLED means organic LED: every pixel makes its own light, so there is no backlight, black is really black, and the text stays sharp from any angle. The glass is one colour, most often white or blue.
The OLED has no character set of its own. The SSD1306 only knows pixels: your Arduino library draws the letters, lines and pictures into a picture in memory and sends it to the display. On the Arduino, that is the job of the Adafruit SSD1306 library together with the Adafruit GFX library. If you know our 0.96" OLED, almost everything carries over: the same library, the same commands, the same address, just a quarter of the pixels, 4,096 instead of 8,192.
The 0.91" OLED at a Glance
| Feature | Value |
|---|---|
| Display | 0.91", 128 x 32 pixels, one colour (white or blue) |
| Controller | SSD1306 with 1 KB display RAM; this glass shows pages 0 - 3 (512 bytes) |
| Board | About 38 x 12 mm, the 4-pin header on one end |
| Interface | I2C: SDA and SCL (A4 and A5, or the SDA / SCL header pins, on an Arduino UNO), plus GND and VCC |
| Address | 0x3C (most modules) or 0x3D, set by a resistor on the back (marked 0x78 / 0x7A) |
| Supply | 3.3 V or 5 V on VCC (the module has its own regulator) |
| Panel voltage | Made by the internal charge pump; the sketch must switch it on |
| I2C speed | Up to 400 kHz; a full picture is 512 bytes, about 18 ms at 400 kHz |
| Arduino libraries | Adafruit SSD1306 + Adafruit GFX: Adafruit_SSD1306 display(128, 32, &Wire, -1) |
Terms You Will See in This Article
| Term | Meaning |
|---|---|
| I2C | A two-wire bus: SDA carries the data, SCL the clock; many devices share it, each with its own address |
| Address | The 7-bit number a device answers to, written in hex (0x3C) |
| GDDRAM | The SSD1306's display memory: 128 columns x 8 pages, 1024 bytes |
| Page | A band of 8 pixel rows; one byte of a page is 8 pixels on top of each other |
| COM line | One of the controller's 64 row drivers; the glass is wired to some of them |
| Multiplex ratio | How many COM lines the controller scans: 32 for this glass, 64 for a 0.96" |
| Charge pump | The circuit inside the SSD1306 that makes the high panel voltage from 3.3 V or 5 V |
| Frame | One whole picture: 512 bytes on this glass, sent by display() in the Adafruit library |
How the SSD1306 Drives a 32-Row Glass
The SSD1306 keeps the picture in its GDDRAM: 128 columns and 8 pages, every byte standing for 8 pixels on top of each other, bit 0 at the top. The pixel at x, y lives in page y / 8, column x, bit y % 8. A 32-row glass needs only pages 0 to 3, 512 bytes; pages 4 to 7 stay in the chip but never reach the glass.
The controller has 64 row drivers, the COM lines. A 0.91" module wires its 32 rows to 32 of them, and the sketch must tell the controller how: 32 rows (the multiplex ratio, command A8 1F) and the sequential COM layout (command DA 02). That is exactly what Adafruit_SSD1306 display(128, 32, ...) sends. A sketch made for the 0.96" sends 64 rows and the alternative layout (DA 12) instead, and then the glass shows only every second row of its picture. You will see that below, in our model too.
The rest works as on every SSD1306. Each I2C transaction starts with a control byte: 0x00 means "commands follow", 0x40 "picture data follows". The Adafruit library keeps a copy of the picture in the Arduino's RAM, all drawing functions change only that copy, and display() sends it in pieces of 31 bytes, because Arduino's Wire library has a 32-byte buffer and the control byte takes one. And the charge pump must be switched on (8D 14) before the display, or the panel stays black: display.begin(SSD1306_SWITCHCAPVCC, 0x3C) does that.
What's New in OLED 128x32 Library for Proteus V1.0
Here is what the first version brings:
- The 0.91" 128x32 module on our own SSD1306 model in
TEPOLED.DLL, with the 32-row glass wired like the real module (32 rows, sequential COM pins). - The 128x64 trap made visible: a sketch written for the 0.96" shows the squashed picture, and the panel and the Init check tell you why.
- A real 0.91" module on the schematic: the long blue board drawn at twice the real size, with a slim TEP control strip under it for the badge, the address selector and the panel button.
- Four devices in
TEPOLED12832.LIB: white and blue glass, each Simple and Advance. - Four OLED test tools on the Advance: Init check, I2C bus, Speed and Pixels, plus Freeze and a pixel grid with x / y numbers on the big glass.
- A two-UNO demo on our Arduino UNO V4.0: working LEDs and the built-in serial monitor on each board, the OLEDs on the UNO's own SDA / SCL pins, and Serial commands such as TEXT, BAR, GRAPH and SCROLL.
- A compact package: about 1.30 MB, without the C++ source code.
The model file TEPOLED.DLL is shared with our 0.96" OLED library and runs its six devices too. If you have both, keep this newer DLL.
OLED 128x32 Simple vs OLED 128x32 Advance
All four devices share one model and the same module. They differ in the glass colour and in where you see the extras:
| Device | Name in Pick Devices | Glass | Extras |
|---|---|---|---|
| OLED12832WHITETEP | OLED SSD1306 128x32 V1.0 White - Simple | White | STATUS panel on the sheet |
| OLED12832WHITEADVTEP | OLED SSD1306 128x32 V1.0 White - Advance | White | Pop-up window and tools |
| OLED12832BLUETEP | OLED SSD1306 128x32 V1.0 Blue - Simple | Blue | STATUS panel on the sheet |
| OLED12832BLUEADVTEP | OLED SSD1306 128x32 V1.0 Blue - Advance | Blue | Pop-up window and tools |
Pick a Simple OLED when you want to see the controller's state and its I2C address right on the schematic. Pick an Advance OLED when the schematic is crowded, or when you want the bus log, the tools and a big copy of the glass. The address selector works on all four.
Download OLED 128x32 Library for Proteus
Click the button below to download OLED-128x32-Library-for-Proteus-v1.0.zip (about 1.30 MB, without the C++ source code):
OLED 128x32 Library for Proteus V1.0- README.txt: a detailed guide to the files, the wiring, the controller, the test tools and real hardware.
- Proteus Library Files:
TEPOLED12832.LIB(all four devices) and our Arduino library V4.0,ArduinoV4TEP.LIB, with the Arduino UNO V4.0 of the demo. - Proteus Model Files:
TEPOLED.DLLandTEPARDUINO.DLL. - Proteus Simulation:
OLED-128x32-ArduinoUnoV4.pdsprj,OLED_128x32_Demo.hex(both UNOs run it) and copies of both DLLs. - Arduino Code:
OLED_128x32_Demo.ino, the demo sketch. It needs the "Adafruit SSD1306" library from the Library Manager, which offers Adafruit GFX and Adafruit BusIO too.
Want all three OLEDs? This OLED is also part of our OLED Library for Proteus V1.0: the 0.96" SSD1306, the 0.91" 128x32 and the 1.3" SH1106 in one library (14 parts, one DLL), with a demo in which one Arduino UNO drives all three.
The Arduino files are the ones of our Arduino Library for Proteus V4.0, so if you have it installed, they are the same. 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 128x32 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. - Delete
TEPOLED12832.IDXfrom the LIBRARY folder if there is one; Proteus makes a new index. - Start Proteus, press P and search for OLED12832. You get the four devices.
Tip: the demo project needs the .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.
The OLED 128x32 Board in Proteus
The part looks like the real module: the long blue board with the glass taking most of it and the 4-pin header on the left end, pins pointing left in the order printed on most modules: GND, VCC, SCL, SDA. A real 0.91" OLED is tiny, so we drew it at twice the real size, and the real board has no room for our extras, so the SIMPLE / ADVANCE badge, the address selector and the panel button sit on a slim TEP control strip under it. Here is OLED1, the white Simple OLED, running the demo's dashboard:
Pinout
| Pin | Name | What it does | Demo connection |
|---|---|---|---|
| 1 | GND | Ground | GND (net label) |
| 2 | VCC | Supply, 3.3 V or 5 V | VCC (net label, the 5 V rail) |
| 3 | SCL | I2C clock | The UNO's SCL pin, through the label SCL_1 |
| 4 | SDA | I2C data (open drain, with the module's pull-up) | The UNO's SDA pin, through the label SDA_1 |
The Board Up Close
Everything on the board is drawn by the model and changes while the simulation runs. The pixels glow in the glass colour, at the brightness the CONTRAST command sets. The PWR LED is lit while the module has power, and the I2C LED flashes green whenever the Arduino talks to this address. A real module has no LEDs at all, so these are our additions to help you see what happens.
LEDs and Indicators
| Indicator | What it shows | On the real module? |
|---|---|---|
| The pixels | The picture in the controller's RAM, at the contrast's brightness | Yes |
| PWR LED (red) | Lit while the module has power | TEP addition |
| I2C LED (green) | Flashes on every I2C transaction to this address | TEP addition |
| ADDRESS selector | 0x3C or 0x3D, clickable while the simulation runs | TEP addition (a resistor on the back) |
| SIMPLE / ADVANCE badge, PANEL / OPEN PANEL | Which device this is, and the panel button | TEP addition |
Component Properties
| Property | Meaning | Default |
|---|---|---|
| PANEL | Simple devices only: the STATUS panel at the start, OPEN or CLOSED | OPEN |
| ADDRESS | The I2C address, 0x3C or 0x3D; the selector follows it | 0x3C |
Every run starts from these properties; a click on the selector changes the address for that run only. In the demo, OLED2 has ADDRESS = 0x3D.
The Address Selector: 0x3C or 0x3D
Most 0.91" modules answer at 0x3C. On the back, a small resistor chooses the address; the print says 0x78 or 0x7A, the same addresses written as 8-bit numbers (0x3C x 2 = 0x78, 0x3D x 2 = 0x7A). On our board, the ADDRESS selector on the strip does this with a click, even while the simulation runs. We clicked 0x3D on OLED1 while its sketch kept writing to 0x3C: nothing reaches the OLED any more, the glass keeps its last picture, exactly as a real module would, and the banner turns red:
Click the selector again and the clock runs on. On a real module, a wrong address simply looks like a dead display; in our model you see the reason at once, and the I2C bus tool of the Advance tells you both addresses.
The 128x64 Trap: Why a 0.96" Sketch Looks Squashed
Here is the mistake almost everybody makes once with a 0.91" OLED: the sketch was written for the 0.96", so it creates Adafruit_SSD1306 display(128, 64, ...). The library then sets 64 rows and the alternative COM layout, while the glass is wired for 32 rows and the sequential layout. The result on a real module is a squashed picture, every second row of the 64-row image, and that is exactly what our model shows. We loaded our 0.96" demo's HEX into the 0.91" demo:
The Init check of the Advance names the two culprits in red: the multiplex ratio (64 rows, the glass has 32) and the COM pins (ALTERNATIVE, DA 12, a 128x64 setting):
The fix is one number in the sketch: Adafruit_SSD1306 display(128, 32, &Wire, -1). The other way round works too: our 0.96" OLED with a 128x32 sketch shows an interleaved picture and its own warning.
OLED 128x32 Simple: The STATUS Panel
Under the Simple OLED sits the OLED STATUS panel (see the pictures above):
| Part | What it shows |
|---|---|
| Banner | READY (128x32, the I2C address, DISPLAY ON), WAITING FOR I2C, WRONG ADDRESS, DISPLAY OFF, DARK - THE CHARGE PUMP IS OFF, 128x64 SETTINGS ON A 128x32 GLASS, MIRRORED or UPSIDE DOWN, or NO POWER |
| DISPLAY, CHARGE PUMP | Whether the display and the charge pump are on |
| CONTRAST | The contrast value, 0 to 255 (Adafruit's 128x32 default is 143) |
| ADDRESSING, SCROLL | The addressing mode and the scrolling |
| VCC | The supply voltage |
| I2C | This OLED's address and the measured clock, or the address the sketch uses instead |
| FRAME | How long one whole picture takes on the bus |
| WRITES, LOST | Bytes the controller took, and unknown commands or bytes sent without power |
| Bus | The last 6 transfers, newest first |
The red X in the panel's header closes it, and PANEL on the strip opens it again.
OLED 128x32 Advance: The Pop-Up Window
The Advance OLED keeps only the module on the schematic. Here is OLED2, the blue Advance OLED at 0x3D:
At Run, the "TEP OLED 128x32 Advance" pop-up opens with the look of our TEP Serial Monitor: move it by its header, resize or minimise it, and reopen it with OPEN PANEL. The header has the Display, Bus log and Tests tabs and the theme, Settings and Help icons.
The Display Page
- The glass: a big copy of the OLED, every pixel visible.
- Tiles: DISPLAY, CHARGE PUMP, CONTRAST, ADDRESSING, ORIENTATION, MULTIPLEX (32 ROWS), COM PINS (SEQUENTIAL) and SCROLL.
- GDDRAM as stored: the controller's memory as it really is, with the write pointer in blue; pages 4 to 7 are marked "not on this 128x32 glass".
- Supply, frames and mapping: VCC, the panel's own refresh rate (175.2 Hz: with only 32 rows to scan, twice the 0.96"'s), the frames received and how long the last one took, the start line and offset.
- The latest transfers: the last runs of picture data, newest first, such as "31 bytes from page 3, column 19", with the time and the gap between them.
Above the glass, GLASS: Live / Freeze holds the picture, and PIXEL GRID: On (x / y) draws a line every 8 pixels with the x and y numbers, Adafruit GFX's coordinates:
The Bus Log Page
The Bus log lists what the controller took, newest first: one row per command with its parameters and meaning, or one row per run of picture data. Read it from the bottom up: a frame on this glass is four pages of 128 bytes, sent in runs of 31 bytes; then the sketch sent SCROLL SETUP LEFT for pages 0 to 3 and SCROLL ON, and from that moment the controller moves the picture by itself. Filters, Pause and Clear help you catch one moment.
The Tests Page: Four OLED Test Tools
The tools read the bus as the model sees it during the running simulation. Each has a bold "Good for:" line and a verdict per row: green is fine, amber means check, red means wrong. All the results below come from OLED2 in Proteus 8.5.
1. Init Check: Is the Start-Up Right?
| Check | Result in the picture |
|---|---|
| First command | DISPLAY OFF (AE), as the datasheet starts |
| Charge pump | ON (8D 14) |
| Multiplex ratio | 32 rows (A8 1F) |
| COM pins | SEQUENTIAL (DA 02), right for 128x32 |
| Orientation | UPRIGHT (A1 + C8) |
| Addressing mode | HORIZONTAL (Adafruit_SSD1306 sends whole frames this way) |
| Contrast | 143 (0x8F) |
| Display on | Yes (AF), 68.2 ms after power-on |
| RAM before display on | Amber: not written, so the random power-on RAM shows until the first frame |
| Verdict | Initialised like the datasheet's flow for this 128x32 glass |
Good for: "an OLED that stays dark, mirrored, upside down or striped - is the sketch's begin() right?" The multiplex and COM rows are the ones that catch the 128x64 trap. The amber row is honest, not a fault: Adafruit's begin() switches the display on before the first picture, so a real module shows its random power-on memory for a moment too.
2. I2C Bus: Is the Sketch Talking to This OLED?
| Row | Result in the picture |
|---|---|
| This OLED | 0x3D - SA0 high (the address resistor: 0x7A) |
| The sketch writes to | 0x3D - this OLED (10598 writes since power-on) |
| Measuring for | 266.600 s of simulation: 10600 transactions to 0x3D, 284655 bytes |
| Commands / data | 1605 command transactions (3209 bytes), 8993 data transactions (270848 bytes) |
| Data per transaction | Up to 31 bytes after the 0x40 control byte (Arduino's Wire buffer is 32 bytes) |
| Address checks | 2 to this address, 112 to other addresses (a scanner / auto-detect) |
| SCL clock | 400 kHz (the SSD1306 is rated for 400 kHz) |
Good for: "a dark OLED - the wrong address, SDA / SCL swapped, the clock and Wire's 32-byte buffer." The address checks come from the sketch's search at the start (0x3C, then 0x3D) and from the SCAN command we typed, which tries every address from 0x08 to 0x77.
3. Speed: How Fast Can the Picture Change?
| Result | Value |
|---|---|
| Time per frame | 18.23 ms on the bus (min 18.22 ms, max 18.27 ms) |
| Best possible | 55 frames per second if the sketch only sent frames |
| The sketch sends | 2.0 frames per second (one every 504 ms) |
| Bus busy | 3.1 % of the time |
| SCL clock | 400 kHz: about 22.5 us per byte (9 clocks + the gaps) |
| Panel refresh | 175.2 Hz: the controller redraws the glass by itself from its RAM |
Good for: "slow animations - one full frame is 512 bytes; at 100 kHz it takes four times as long as at 400 kHz." A 0.91" frame is half the 0.96"'s, so it travels twice as fast: 55 frames per second at best instead of 27, a nice reason to choose the small OLED for animations.
4. Pixels: Where Does a Pixel Live in the RAM?
Good for: "drawing code and bitmaps - click a pixel: its page, column, bit and the byte the RAM holds." We clicked x 61, y 24, a pixel of the wave's middle line: page 24 / 8 = 3, bit 24 % 8 = 0, and in Adafruit's buffer the byte number 61 + 3 x 128 = 445. Below, the 16 bytes around it are drawn as columns of 8 bits.
OLED 128x32 with Arduino in Proteus
Open OLED-128x32-ArduinoUnoV4.pdsprj from the Proteus Simulation folder, with OLED_128x32_Demo.hex and both DLLs beside it. The demo runs on two of our Arduino UNO V4.0 boards from the Arduino UNO Library for Proteus V4.0: the board has working ON / L / TX / RX LEDs, a RESET button and a serial monitor built into the board, so there is no Virtual Terminal and no separate monitor to wire. Both UNOs run the same HEX file:
- NODE 1 - SIMPLE (on-sheet panel): ARD1 with OLED1 (white, Simple, address 0x3C).
- NODE 2 - ADVANCE (pop-up panel): ARD2 with OLED2 (blue, Advance, address 0x3D).
Wiring
| OLED pin | Arduino UNO | Why |
|---|---|---|
| GND | GND | Ground |
| VCC | 5V | Supply |
| SCL | SCL (= A5) | I2C clock |
| SDA | SDA (= A4) | I2C data |
| Serial monitor | Nothing to wire | Built into the UNO V4.0 on D0 / D1, like the real UNO's USB chip |
On an Arduino UNO, SDA and SCL are A4 and A5, and the UNO R3 repeats them on the top header next to AREF (see our Introduction to Arduino UNO). Our UNO V4.0 has those header pins too, and the demo uses them. Every OLED pin goes through a short wire to a net label: terminals with the same name are connected. SDA_1 at OLED1 meets SDA_1 at ARD1's SDA pin, and node 2 has its own SDA_2 and SCL_2, so the two buses stay apart. For more about I2C addresses and the ACK, see our I2C LCD 16x2 Library for Proteus V1.0 article.
The Arduino Code
The demo sketch, OLED_128x32_Demo V1.0, uses the Adafruit SSD1306 library (version 2.5.17) with the Adafruit GFX library (version 1.12.6) and Arduino's Wire library. It starts with the display object, and here is the number that matters: 128 x 32:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 32, &Wire, -1); // width, height, the I2C bus, no reset pin
The sketch finds the address itself with an I2C address check, an empty write that a device answers with ACK, then starts the display with the charge pump on:
bool answers(byte a) { // an address check: does a device ACK?
Wire.beginTransmission(a);
return Wire.endTransmission() == 0;
}
if (answers(0x3C)) { address = 0x3C; found = true; }
else if (answers(0x3D)) { address = 0x3D; found = true; }
if (!display.begin(SSD1306_SWITCHCAPVCC, address)) {
Everything the sketch draws goes into the buffer first; display() sends it, and the demo counts the frames, the "F" number on the glass:
void show() { display.display(); frames++; }
With only 32 rows, the dashboard is split in two halves. The top 16 rows carry the header in the small font (6 x 8 pixels per character): the name and address, the up time and the right-aligned frame count:
snprintf_P(buf, sizeof buf, PSTR("F%lu"), frames % 100000); // the frames sent, right-aligned
display.setCursor(128 - 6 * strlen(buf), 8);
display.print(buf);
The lower 16 rows show one of three things: the big text line, a bar or a moving sine wave around y 24:
if (lower == L_TEXT) { // rows 16-31: the big line
display.setTextSize(textSize);
display.setCursor(0, textSize == 2 ? 17 : 20);
display.print(text);
int phase = (millis() / 125) % 32;
for (int x = 0; x < 128; x++) {
int y = 24 - (int8_t)pgm_read_byte(&wave[(x / 2 + phase) % 32]);
display.drawPixel(x, y, SSD1306_WHITE);
}
display.drawFastHLine(0, 24, 128, SSD1306_WHITE);
The LOGO screen draws our 40 x 32 logo, which fills the full height of this glass, beside three lines of text:
display.drawBitmap(0, 0, logo, 40, 32, SSD1306_WHITE);
SCROLL uses the controller's own scrolling. On this glass only pages 0 to 3 are visible, so the demo scrolls just those:
if (!strcasecmp_P(arg, PSTR("LEFT"))) { display.startscrollleft(0x00, 0x03); scroll = S_LEFT; }
The loop reads the serial monitor and redraws the dashboard twice a second, without delay(), and not while the controller scrolls:
if (screen == DASH && scroll == S_OFF && now - lastDraw >= 500) { // twice a second (not while it scrolls)
lastDraw = now;
drawDash();
}
To change the sketch, install the libraries from the Library Manager, export a new HEX file and load it into both UNOs; 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 address, the screen, the lower half, contrast, inverse, scroll, display and frames |
| SCAN | Every I2C device on the bus (0x08 - 0x77) |
| TEXT <text> | The big line in the lower half (10 characters at size 2, 21 at size 1) |
| SIZE <1-2> | Its text size |
| GRAPH / BAR <0-100> | A moving sine wave / a bar in the lower half |
| LOGO, SHAPES, DASH | The TEP logo, the GFX shapes, the dashboard again |
| INVERT ON / OFF | Inverse: the controller swaps lit and dark pixels |
| CONTRAST <0-255> | The brightness (Adafruit's 128x32 default is 143) |
| DISPLAY ON / OFF | The panel on or off (the RAM is kept) |
| SCROLL LEFT / RIGHT / DIAG / STOP | The controller's own scrolling (pages 0 - 3) |
| CLEAR | An empty screen (DASH brings the dashboard back) |
How to Run the Demo
- Press Run. Both UNOs' monitor windows and OLED2's pop-up open; move them aside, as they open over the schematic. The UNOs' ON LEDs light, and the OLEDs show the TEP logo for a second, then the dashboard.
- Type TEXT with your own text, BAR 37 and INVERT ON in ARD1's monitor; SCAN, GRAPH and SCROLL LEFT in ARD2's.
- Click the ADDRESS selector of OLED1 and watch the panel; click it again.
- On OLED2's pop-up, turn on the pixel grid, look at the Bus log, and run the four tools.
- Press the RESET button of a UNO: the bootloader flashes L, and the sketch starts again 1 s later.
OLED 128x32 Proteus Simulation Results
The Built-in Serial Monitor in Its Simple Interface
Each Arduino UNO V4.0 carries its own copy of our TEP Serial Monitor Advance, wired inside the board to D0 / D1 like the USB chip of a real UNO. Its window, "TEP Arduino UNO - ARD1", opens at Run, and a click on the board's USB port opens it again. The screenshots show 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, and the Board tab shows the UNO's LEDs, pins and RESET key live.
Read all about the monitor in TEP Serial Monitor Advance for Proteus.
ARD1: HELP and STATUS
OLED 128x32 V1.0 demo - The Engineering Projects
OLED found at 0x3C
Type HELP for the commands
HELP
Commands:
TEXT <text> the big line (lower half)
SIZE <1-2> its text size
GRAPH a moving sine wave instead
BAR <0-100> a bar instead
LOGO SHAPES DASH (the dashboard)
INVERT ON|OFF CONTRAST <0-255> DISPLAY ON|OFF
SCROLL LEFT|RIGHT|DIAG|STOP
CLEAR SCAN STATUS HELP
STATUS
OLED 128x32 at 0x3C, found
Screen: dashboard
Lower half: text Hello, TEP (size 2)
Contrast 143, inverse off, scroll off, display on
Frames sent: 40
The second line is the address search at work: the sketch found the OLED at 0x3C by itself. Contrast 143 is Adafruit's value for a 128x32 display.
ARD2: SCAN, GRAPH and STATUS
OLED 128x32 V1.0 demo - The Engineering Projects
OLED found at 0x3D
Type HELP for the commands
SCAN
I2C devices: 0x3D
GRAPH
OK - the sine wave
STATUS
OLED 128x32 at 0x3D, found
Screen: dashboard
Lower half: sine wave
Contrast 143, inverse off, scroll off, display on
Frames sent: 72
SCAN finds one device, the OLED at 0x3D: each UNO has its own I2C bus in this demo. The featured picture at the top shows the wave GRAPH drew on the blue glass.
Troubleshooting
- The glass stays black and the PWR LED is off: no power. Check VCC and GND (the panel says NO POWER with the voltage; the module needs 3.3 to 5 V).
- WAITING FOR I2C: nothing reached this address. Check SDA and SCL (swapped lines look the same: nothing works), and that the sketch runs.
- WRONG ADDRESS: the sketch writes to another address. Change the address in
display.begin(), or the ADDRESS property or the selector; the I2C bus tool shows both. - A squashed picture / 128x64 SETTINGS ON A 128x32 GLASS: the sketch was written for the 0.96". Use
Adafruit_SSD1306 display(128, 32, ...). - DARK - THE CHARGE PUMP IS OFF: the sketch turned the display on without 8D 14. Use
SSD1306_SWITCHCAPVCC. - Random dots: the RAM before the first frame. Call
display.display()after drawing. - Mirrored or upside down: the remap commands (A0 / A1, C0 / C8);
display.setRotation(2)turns the picture in software instead. - The part or the UNO is not simulated, or no monitor window: TEPOLED.DLL or TEPARDUINO.DLL is missing from MODELS and the project folder; a closed monitor opens again with a click on the UNO's USB port.
- The Advance pop-up does not appear: click OPEN PANEL on the strip, or turn "Open the panel at Run" back on in Settings.
Things to Know Before Using a Real 0.91" OLED
The demo sketch uses only Wire, the Adafruit libraries and Serial, so it runs on a real UNO and 0.91" OLED too. Keep in mind:
- Check the pin order on YOUR module: most are GND, VCC, SCL, SDA, but some are VCC, GND, SCL, SDA. Swapped supply pins can kill the module.
- Find the address: run an I2C scanner (or the demo's SCAN). Most modules are 0x3C.
- Tell the library the size:
display(128, 32, ...); with 128, 64 the picture is squashed. - Plan for 32 rows: text size 1 gives 4 lines of 21 characters, size 2 gives 2 lines of 10.
- RAM: the Adafruit library needs 512 bytes for a 128x32 buffer, a quarter of an UNO's RAM; keep texts in flash with
F("..."). - Supply and pull-ups: the module has its own regulator and SDA / SCL pull-ups, so it runs from 3.3 V and from 5 V; 400 kHz I2C is fine.
- Burn-in: OLED pixels age; turn the display off or dim it when nobody looks.
Limitations of the Simulation
- Not modelled: reading from the OLED (libraries never read it; a read is not acknowledged), the fade / blink and zoom extras of later datasheet revisions, the SPI interface of other modules, an external VCC, the effect of the pre-charge and VCOMH settings on the picture, I2C timing violations, the current draw and pixel ageing.
- The board is drawn at twice the real size, with a TEP control strip under it; the LEDs and the address selector are TEP additions.
- The model is our own implementation, written from the SSD1306 datasheet. SSD1306 is a Solomon Systech part; this library is not made or endorsed by Solomon Systech, Adafruit or Labcenter.
- Licences: the demo sketch uses Adafruit SSD1306 2.5.17, Adafruit GFX 1.12.6 (BSD licence) and Arduino's Wire library. The HEX file contains 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 demo as shipped on two Arduino UNO V4.0 boards with their built-in monitors, all four devices, the dashboard, the Serial commands, scrolling, the address selector, the panel, the pop-up and the four tools, the 128x64 trap, and every screenshot here; about 0.62 x real time with the pop-up and both monitors open) and with automatic PC checks, 0 failed: 48 with the real demo sketch and the unmodified Adafruit libraries talking bit by bit to the model, where the glass equals Adafruit's own buffer after every frame, 66 on the SSD1306 controller, and the demo project read back from disk. Proteus 7 is not supported.
So, that was all about the OLED 128x32 Library for Proteus V1.0. I hope the 32-row glass, the 128x64 trap made visible and our new Arduino UNO V4.0 make the little 0.91" OLED easy to understand, so your display works the first time you wire a real one. If you use the OLED 128x32 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!