OLED Display (SSD1306/SH1106)
OLED Display (SSD1306/SH1106)
Quick Reference
| Type | type value | Description |
|---|---|---|
| LCD | 36 | LCD/OLED display device |
| Parameter | Description |
|---|---|
| width | Screen width in pixels |
| height | Screen height in pixels |
| interface | Interface type: 0=Parallel, 1=SPI, 2=I2C |
Display Action Template Syntax
| Syntax | Description |
|---|---|
#Title | First line starting with # is a centered title |
${id.field} | Reference sensor cached value (id=peripheral ID, field=field name) |
$value | Reference the value received at trigger time |
\n | Newline |
Overview
FastBee-Arduino now supports OLED/LCD displays, enabling data display through simple configuration.
The Lite edition retains OLED/LCD and TM1637 seven-segment display capabilities by default. On the Peripheral Execution page, display-related actions are grouped under the "Display" category. Users only need to choose from four action types: "Display Number", "Display Text", "Seven Segment Clear", and "OLED Custom Display". If the hardware project does not require a display, FASTBEE_ENABLE_LCD or FASTBEE_ENABLE_SEVEN_SEGMENT can be disabled in the build configuration to further save resources.
The OLED workflow starts with adding a display object in Peripheral Configuration, then selecting display actions in Peripheral Execution to write fixed text, sensor variables, or template content to the screen.
For display debugging, start with static text, then connect sensor variables, and finally use peripheral execution rules for timed refresh, event refresh, or alert text.
Supported Displays
FastBee uses the U8g2 library at the low level to drive displays, selecting controllers through the DisplayController enumeration. Currently supported controllers:
| Controller Enum | Number | Typical Size/Resolution | Interface | Description |
|---|---|---|---|---|
SSD1306 | 0 | 0.96"/1.3" · 128x64 / 128x32 | I2C / SPI | Most common monochrome OLED, default option |
SH1106 | 1 | 1.3" · 128x64 | I2C / SPI | 1.3-inch OLED, compatible model of SSD1306 |
SSD1309 | 2 | 2.42" · 128x64 | I2C / SPI | Large-size OLED |
ST7567 | 3 | 128x64 LCD | I2C / SPI | Monochrome LCD |
ST7920 | 4 | 128x64 LCD | SPI | LCD with built-in Chinese font |
PCD8544 | 5 | 84x48 LCD | SPI | Nokia 5110 classic screen |
Interface Type (DisplayInterface):
| Enum | Number | Description |
|---|---|---|
PARALLEL | 0 | Parallel interface (reserved for now) |
SPI_MODE | 1 | SPI serial interface |
I2C_MODE | 2 | I2C serial interface (default recommended) |
Recommended Configuration: I2C interface SSD1306 128x64 OLED, low driver cost and minimal resource usage.
Hardware Connection
I2C OLED (SSD1306) Wiring
OLED Display ESP32 Dev Board
----------------------------------
VCC → 3.3V
GND → GND
SCL → GPIO22 (or custom)
SDA → GPIO21 (or custom)Configuration Methods
Method 1: Web Interface Configuration (Recommended)
- Open the Web management interface
- Navigate to the "Peripheral Management" page
- Click "Add Peripheral"
- Select type: LCD
- Configure parameters:
- Name: OLED Display
- Width: 128
- Height: 64
- Interface: I2C
- SDA pin: 21
- SCL pin: 22
- Save configuration
Method 2: Configuration File
Edit /config/peripherals.json:
{
"peripherals": [
{
"id": "oled_01",
"name": "OLED Display",
"type": 36,
"enabled": true,
"pinCount": 2,
"pins": [21, 22],
"params": {
"lcd": {
"width": 128,
"height": 64,
"interface": 2
}
}
}
]
}Method 3: Create in Code
#include "peripherals/LCDManager.h"
#include "core/PeripheralConfig.h"
void setup() {
PeripheralConfig config;
config.id = "oled_display";
config.name = "OLED Display";
config.type = PeripheralType::LCD;
config.enabled = true;
config.pinCount = 2;
config.pins[0] = 21; // SDA
config.pins[1] = 22; // SCL
config.params.lcd.width = 128;
config.params.lcd.height = 64;
config.params.lcd.interface = 2; // I2C
LCDManager::getInstance().initialize(config);
}Usage Methods
1. Display Text
API Call
# Display text (coordinate mode)
curl -X POST http://192.168.x.x/api/lcd/text \
-d "text=Hello FastBee" \
-d "x=0" \
-d "y=10" \
-d "align=1"
# Display text (line number mode)
curl -X POST http://192.168.x.x/api/lcd/text \
-d "text=Temperature: 25.5 C" \
-d "line=0"Code Call
LCDManager& lcd = LCDManager::getInstance();
// Display single line
lcd.printLine("Hello FastBee", 0);
// Display multiple lines
String lines[] = {
"FastBee IoT",
"IP: 192.168.1.100",
"Temp: 25.5 C",
"Humidity: 60%"
};
lcd.printLines(lines, 4);2. Display Sensor Data
LCDManager& lcd = LCDManager::getInstance();
// Display sensor data (auto-formatted)
lcd.showSensorData("Temp", 25.5, "C", 0);
lcd.showSensorData("Humidity", 60.0, "%", 1);
lcd.showSensorData("Pressure", 1013.2, "hPa", 2);
lcd.refresh();3. Display System Information
# API call
curl -X POST http://192.168.x.x/api/lcd/info// Code call
LCDManager::getInstance().showSystemInfo();Display content:
- Project name
- IP address
- Memory usage
- Uptime
4. Clear Screen
# API call
curl -X POST http://192.168.x.x/api/lcd/clear// Code call
LCDManager::getInstance().clear();
LCDManager::getInstance().refresh();5. Set Font
# API call
curl -X POST http://192.168.x.x/api/lcd/font -d "font=1"// Code call
LCDManager& lcd = LCDManager::getInstance();
lcd.setFont(0); // Small font
lcd.setFont(1); // Medium font (default)
lcd.setFont(2); // Large font6. Query Status
# API call
curl http://192.168.x.x/api/lcd/statusResponse:
{
"success": true,
"data": {
"initialized": true,
"width": 128,
"height": 64,
"maxLines": 6,
"fontHeight": 10
}
}Complete Examples
Example 1: Temperature Monitor
#include "peripherals/LCDManager.h"
void displayTemperature(float temp, float humidity) {
LCDManager& lcd = LCDManager::getInstance();
lcd.clear();
lcd.printLine("Weather Monitor", 0);
lcd.showSensorData("Temp", temp, "C", 2);
lcd.showSensorData("Humidity", humidity, "%", 3);
lcd.refresh();
}
void loop() {
float temp = readTemperature();
float humidity = readHumidity();
displayTemperature(temp, humidity);
delay(5000);
}Example 2: Device Status Display
void displayDeviceStatus() {
LCDManager& lcd = LCDManager::getInstance();
String status[] = {
"Device Status:",
WiFi.status() == WL_CONNECTED ? "WiFi: OK" : "WiFi: OFF",
"Free: " + String(ESP.getFreeHeap() / 1024) + "KB",
"Uptime: " + String(millis() / 60000) + "min"
};
lcd.printLines(status, 4);
}Performance Optimization
1. Reduce Refresh Frequency
// Recommendation: no more than 10Hz (once every 100ms)
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 100; // ms
void loop() {
if (millis() - lastUpdate >= updateInterval) {
updateDisplay();
lastUpdate = millis();
}
}2. Refresh on Demand
// Only refresh when data changes
float lastTemp = 0;
void updateTemperature(float temp) {
if (temp != lastTemp) {
lcd.showSensorData("Temp", temp, "C", 0);
lcd.refresh();
lastTemp = temp;
}
}3. Partial Update
// Only update changed areas (reduce data transfer)
lcd.print("Temp: 25.5C", 0, 20); // Only update temperature area
lcd.refresh(); // Push entire buffer (OLED feature)FAQ
Q1: Display not lighting up?
Check:
- Wiring is correct (VCC, GND, SDA, SCL)
- I2C address is correct (default 0x3C, some modules use 0x3D)
initialize()method has been called
Q2: Display shows garbled characters?
Cause:
- Font does not support certain characters
- Chinese characters require special font support
Solution:
// Use a font that supports Chinese (requires additional configuration)
// Or only display English and numbersQ3: Insufficient memory?
Symptoms: ESP32 restarts or display behaves abnormally
Solution:
- Use SSD1306 instead of large-size TFT
- Reduce display buffer
- Use ESP32-WROVER (with PSRAM)
Q4: Refresh too slow?
Optimization:
- Reduce refresh frequency (10Hz is sufficient)
- Only refresh when necessary
- Avoid frequently calling
clear()in loops
API Reference
REST API
| Endpoint | Method | Parameters | Description |
|---|---|---|---|
/api/lcd/text | POST | text, x, y, line, align | Display text |
/api/lcd/clear | POST | - | Clear screen |
/api/lcd/info | POST | - | Display system information |
/api/lcd/font | POST | font(0-2) | Set font |
/api/lcd/status | GET | - | Get status |
C++ API
Initialization & Status
| Method | Description |
|---|---|
initialize(config) | Initialize display based on peripheral configuration |
deinitialize() | Release display resources |
isInitialized() | Query initialization status |
getWidth() / getHeight() | Return screen pixel width/height |
getFontHeight() | Line height of current font |
getMaxLines() | Maximum rows displayable with current font |
Basic Display
| Method | Description |
|---|---|
clear() | Clear buffer |
refresh() | Push buffer to screen (with 50ms anti-tearing interval) |
print(text, x, y, align) | Display text by coordinates |
printLine(text, line) | Display text by line number |
printLines(lines[], count) | Display multiple lines at once |
showCustomText(content) | Parse \n multi-line text; first line starting with # auto-detected as centered title with separator line |
showSystemInfo() | Display IP/WiFi/memory/uptime system information |
Sensor Data Display Module (Auto-pagination)
LCDManager has a built-in universal sensor data table (up to 16 entries) and auto-pagination mechanism, working with peripheral execution for rotating display of multiple sensor data.
| Method | Description |
|---|---|
updateSensorEntry(id, label, value, unit, decimals) | Register or update a sensor data entry |
invalidateSensorEntry(id) | Mark sensor entry as invalid (called on collection failure) |
showSensorPage(page=-1) | Display specified page or auto-rotate |
autoRefreshSensorDisplay(intervalMs) | Call in main loop to auto-page at specified interval |
getSensorEntryCount() | Current number of registered sensor entries |
getSensorPageCount() | Total pages of current data |
showSensorData(name, value, unit, line) | Simple single-entry display (not added to table) |
Graphics Drawing
| Method | Description |
|---|---|
drawLine(x1, y1, x2, y2) | Draw line |
drawRect(x, y, w, h) | Draw hollow rectangle |
drawBox(x, y, w, h) | Draw filled rectangle |
drawCircle(x, y, r) | Draw hollow circle |
drawDisc(x, y, r) | Draw filled circle |
Appearance & Font
| Method | Description |
|---|---|
setFont(index) | Set font (0=small, 1=medium (default), 2=large) |
setContrast(value) | Set contrast (0-255) |
setFlip(flip) | Flip display (for flipped mounting) |
setDisplayOn(on) | Turn display on/off |
Precautions
- I2C Pins: ESP32 defaults to SDA=21, SCL=22; other chips may differ
- Display Refresh: Frequent refresh (<100ms) may cause flickering; interval ≥1 second is recommended
- Character Limit: 128x64 screen can display approximately 4-6 lines of text (depending on font size)
- Power Consumption: OLED is self-emissive; full-white screen consumes more power; dark backgrounds save power
- Lifespan: OLED has burn-in risk; avoid displaying fixed content for extended periods
Resource Usage
| Item | Usage |
|---|---|
| Flash | +50KB (u8g2 library) |
| RAM | +1KB (128x64 OLED buffer) |
| CPU | < 3% (10Hz refresh) |
Conclusion: Minimal impact on ESP32 performance, safe to use.
Related Documentation
- TM1637 Seven-Segment Display — Four-digit seven-segment display configuration
- LCD1602 Character Screen — I2C character screen placeholder reference
- Display Actions — Peripheral execution display action details
