Appearance
Arduino硬件交互实战:OLED显示
一、 OLED显示模块简介
OLED(Organic Light-Emitting Diode,有机发光二极管)显示模块因其自发光、高对比度、低功耗和轻薄的特点,在Arduino项目中被广泛应用。常见的规格有0.96英寸和1.3英寸,分辨率通常为128x64或128x32。
主要特性
- 自发光:无需背光源,黑色显示时像素点完全关闭,对比度极高。
- 低功耗:仅在显示亮色时消耗电流,适合电池供电项目。
- 宽视角:几乎可以从任何角度清晰观看。
- 接口灵活:支持I2C和SPI两种主流通信协议,I2C接线更简单。
二、 硬件连接
以最常见的0.96寸I2C接口OLED为例,其与Arduino UNO的连接方式如下:
| OLED引脚 | Arduino引脚 | 说明 |
|---|---|---|
| GND | GND | 电源地 |
| VCC | 5V (或3.3V) | 电源正极,请根据模块规格选择 |
| SCL | A5 | I2C时钟线 |
| SDA | A4 | I2C数据线 |
注意:不同Arduino板卡的I2C引脚可能不同,例如Arduino Mega的SCL为21,SDA为20。
三、SSD1306 OLED 显示基础
SSD1306 是一款常见的单色 OLED 驱动芯片,支持 I2C 或 SPI 接口。在 Arduino 开发中,主要有两套主流库:
- Adafruit_SSD1306:官方推荐,API 简洁,适合快速原型开发。
- u8g2:功能更强大,支持更多屏幕型号和字体,内存优化更好,适合复杂项目。
四、Adafruit 库实战
完整代码示例
cpp
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306初始化失败,检查接线和地址。"));
while (true);
}
Serial.println(F("SSD1306初始化成功!"));
display.setRotation(0);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("Hello, World!"));
display.println(F("SSD1306 OLED Test"));
display.drawLine(0, 16, SCREEN_WIDTH, 16, SSD1306_WHITE);
int rectSize = 20;
int rectX = (SCREEN_WIDTH - rectSize) / 2;
int rectY = (SCREEN_HEIGHT - rectSize) / 2;
display.drawRect(rectX, rectY, rectSize, rectSize, SSD1306_WHITE);
display.display();
delay(2000);
}
void loop() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 25);
display.print("Time:");
display.setCursor(5, 45);
display.print(millis());
display.display();
delay(100);
}核心逻辑
- 初始化:通过
display.begin()初始化屏幕,使用setRotation()设置方向。 - 静态显示:绘制文本、线条、矩形后调用
display()刷新。 - 动态刷新:在
loop()中执行“清屏 → 绘制 → 刷新”循环,实现动态内容更新。
常见问题
- 屏幕不亮:检查 VCC/GND 是否接反。
- 初始化失败:尝试将
SCREEN_ADDRESS从0x3C改为0x3D。 - 显示方向错误:调整
setRotation()参数(0-3)。
五、u8g2 库实战
完整代码示例
cpp
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
void setup() {
u8g2.begin();
u8g2.enableUTF8Print(); // 启用UTF-8支持
}
void loop() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 10, "Hello, U8g2!");
u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
u8g2.drawUTF8(0, 25, "这是一个中文示例");
u8g2.drawLine(0, 30, 127, 30);
u8g2.drawBox(10, 40, 20, 10);
u8g2.drawCircle(50, 50, 8, U8G2_DRAW_ALL);
u8g2.sendBuffer();
delay(2000);
}核心 API 速查表
初始化与控制
| 函数 | 说明 |
|---|---|
U8G2_... u8g2(...) | 构造函数,根据屏幕型号和连接方式选择 |
u8g2.begin() | 初始化屏幕 |
u8g2.clearBuffer() | 清空内存缓冲区 |
u8g2.sendBuffer() | 刷新屏幕显示 |
u8g2.setDisplayRotation(r) | 设置旋转方向(R0/R1/R2/R3) |
文本显示
| 函数 | 说明 |
|---|---|
u8g2.setFont(*font) | 设置字体 |
u8g2.drawStr(x, y, "text") | 绘制ASCII字符串 |
u8g2.drawUTF8(x, y, "中文") | 绘制UTF8文本 |
u8g2.enableUTF8Print() | 启用UTF8支持 |
u8g2.getUTF8Width("text") | 获取UTF8字符串像素宽度 |
图形绘制
| 函数 | 说明 |
|---|---|
u8g2.drawPixel(x, y) | 绘制像素点 |
u8g2.drawLine(x1, y1, x2, y2) | 绘制直线 |
u8g2.drawBox(x, y, w, h) | 绘制实心矩形 |
u8g2.drawFrame(x, y, w, h) | 绘制空心矩形 |
u8g2.drawCircle(x, y, r, option) | 绘制圆形 |
u8g2.drawEllipse(x, y, rx, ry, option) | 绘制椭圆 |
六、附录:u8g2 中文字体资源对比
在 u8g2 库中,中文字体以 UTF-8 编码支持,需通过 u8g2.drawUTF8(x, y, "中文") 绘制。以下为常用中文字体参数对比:
| 字体名称 | 字号 | 字符宽度 (px) | 字符高度 (px) | 闪存占用 (KB) | RAM 占用 (B) | 推荐开发板 |
|---|---|---|---|---|---|---|
u8g2_font_wqy12_t_utf8 | 12 | 6 | 12 | 20 | 约 500 | Mega / ESP32 / ESP8266 |
u8g2_font_wqy12_mf_utf8 | 12 | 6 | 12 | 20 | 约 500 | 同上 |
u8g2_font_wqy16_t_utf8 | 16 | 8 | 16 | 30 | 约 800 | Mega / ESP32 |
u8g2_font_wqy16_mf_utf8 | 16 | 8 | 16 | 30 | 约 800 | 同上 |
u8g2_font_wqy20_t_utf8 | 20 | 10 | 20 | 40 | 约 1200 | ESP32 / 资源充足开发板 |
u8g2_font_wqy20_mf_utf8 | 20 | 10 | 20 | 40 | 约 1200 | 同上 |
说明:
- wqy12 / wqy16 / wqy20:文泉驿字体,字号分别为 12/16/20 点。
- _t:精简版(部分字符可能缺失)。
- _mf:完整版(支持更多汉字,文件更大)。
优化建议
- 资源受限开发板(如 Uno):使用
u8g2_font_wqy12_t_utf8或更小字体,避免同时加载多个字体。 - 资源充足开发板(如 ESP32):可加载
_mf完整版字体,使用分页模式显示长文本。 - 内存不足排查:若编译报错 "Out of memory",更换更小字体或升级开发板。
- 中文乱码排查:确认已调用
u8g2.enableUTF8Print(),检查字体名称是否正确。
掌握执行器控制与OLED显示,意味着你的Arduino项目从“数据展示”迈向了“物理交互+人机反馈”的完整闭环。建议先从低压、小功率设备开始调试,确认逻辑无误后再接入大功率负载,并始终注意高压安全。