前面我们学了超声波传感器,让 Arduino 有了"眼睛"。现在给它装上一张"脸"——OLED 显示屏,让它能显示文字、数字、图形,甚至画表情包!
学完这篇,你会完成:
- 认识 OLED 显示屏:了解 I2C 通信协议
- 显示文字和数字:让屏幕显示各种信息
- 综合项目:超声波测距仪:实时显示距离数据
一、OLED 显示屏是什么?
OLED(有机发光二极管)是一种自发光的显示屏,不需要背光灯,每个像素自己发光。
OLED 的优点
- 超薄超轻:厚度通常只有 1~2mm
- 省电:显示黑色时像素完全不发光,几乎不耗电
- 高对比度:黑色极黑,白色极亮,显示效果清晰
- 可视角度大:从各个角度看都清晰
- 响应速度快:刷新率高,适合动态显示
常见规格
| 尺寸 | 0.96 英寸 |
| 分辨率 | 128×64 像素 |
| 颜色 | 白色 / 蓝色 / 黄色 |
| 通信方式 | I2C / SPI |
| 工作电压 | 3.3V ~ 5V |
本篇使用最常见的 0.96 英寸 128×64 I2C OLED,价格通常在十几元左右。
二、I2C 通信协议
我们使用的 OLED 采用 I2C(Inter-Integrated Circuit) 通信方式,只需要 2 根线就能传输数据。
I2C 的两根线
| SDA | 数据线(传输数据) |
| SCL | 时钟线(同步信号) |
I2C 的优点
- 只需要 2 根线,节省引脚
- 可以连接多个设备(每个设备有唯一地址)
- 传输稳定可靠
Arduino Uno 的 I2C 引脚:SDA → A4,SCL → A5
三、安装库文件
使用 OLED 需要安装两个库:
方法一:通过 Arduino IDE 安装
- Adafruit SSD1306(OLED 驱动库)
- Adafruit GFX Library(图形绘制库)
方法二:手动安装
四、接线方式
| VCC | 5V(或 3.3V) |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
接线非常简单,只有 4 根线!
五、实验一:显示文字
在 OLED 上显示 "Hello Arduino!"。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// 屏幕参数:宽128,高64,I2C地址0x3C
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
// 初始化 OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED 初始化失败!");
while (true); // 初始化失败就停在这里
}
// 清屏
display.clearDisplay();
// 设置文字大小(1~5,越大字越大)
display.setTextSize(2);
// 设置文字颜色(白色)
display.setTextColor(SSD1306_WHITE);
// 设置光标位置(x=0, y=20)
display.setCursor(0, 20);
// 显示文字
display.println("Hello!");
display.println("Arduino");
// 刷新屏幕(必须调用!)
display.display();
}
void loop() {
}
代码解读
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C):初始化 OLED,0x3C 是 I2C 地址
- display.clearDisplay():清空屏幕
- display.setTextSize(2):设置字体大小(1 最小,5 最大)
- display.setCursor(0, 20):设置文字起始位置
- display.println():显示文字并换行
- display.display():将缓冲区内容刷新到屏幕(非常重要!)
注意:display.println() 只是把内容写入"缓冲区",必须调用 display.display() 才能真正显示到屏幕上。
六、实验二:显示动态数字
让屏幕实时显示一个不断变化的数字(模拟计数器)。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
}
void loop() {
static int count = 0;
// 清屏
display.clearDisplay();
// 显示标题
display.setTextSize(1);
display.setCursor(20, 5);
display.println("Counter");
// 显示数字(大字体)
display.setTextSize(3);
display.setCursor(30, 25);
display.print(count);
// 刷新屏幕
display.display();
// 计数器加1
count++;
if (count > 999) count = 0;
delay(500);
}
七、综合项目:超声波测距仪
将超声波传感器和 OLED 结合,实时显示前方距离。
所需元件
- Arduino Uno
- HC-SR04 超声波模块
- 0.96 英寸 OLED 显示屏
- 面包板 + 杜邦线
接线
| 超声波 Trig | – | D9 |
| 超声波 Echo | – | D10 |
| OLED SDA | – | A4 |
| OLED SCL | – | A5 |
| OLED VCC | – | 5V |
| OLED GND | – | GND |
代码
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define TRIG 9
#define ECHO 10
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
// 初始化 OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20, 0);
display.println("Ultrasonic");
display.println(" Ruler");
display.display();
delay(2000); // 显示启动画面 2 秒
}
void loop() {
// 测量距离
float dist = getDistance();
// 清屏
display.clearDisplay();
// 显示标题
display.setTextSize(1);
display.setCursor(0, 0);
display.println("=== Distance ===");
// 显示距离(大字体)
display.setTextSize(3);
display.setCursor(10, 20);
display.print(dist, 1); // 保留1位小数
// 显示单位
display.setTextSize(2);
display.setCursor(90, 30);
display.println("cm");
// 显示距离条(可视化)
int barLength = map(dist, 2, 100, 0, 128);
if (barLength > 128) barLength = 128;
display.fillRect(0, 55, barLength, 8, SSD1306_WHITE);
// 刷新屏幕
display.display();
delay(200);
}
float getDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH);
return duration * 0.034 / 2;
}
效果
- 屏幕顶部显示标题 "Distance"
- 中间大字显示当前距离
- 底部有一个进度条,距离越远条越长
八、进阶:绘制图形
OLED 不仅能显示文字,还能画线、画圆、画矩形!
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
// 画矩形
display.drawRect(10, 10, 50, 30, SSD1306_WHITE);
// 画填充矩形
display.fillRect(70, 10, 50, 30, SSD1306_WHITE);
// 画圆
display.drawCircle(35, 50, 12, SSD1306_WHITE);
// 画填充圆
display.fillCircle(95, 50, 12, SSD1306_WHITE);
// 画线
display.drawLine(0, 0, 127, 63, SSD1306_WHITE);
display.display();
}
void loop() {
}
常用绘图函数
| drawPixel(x, y, color) | 画一个点 |
| drawLine(x1, y1, x2, y2, color) | 画线 |
| drawRect(x, y, w, h, color) | 画矩形 |
| fillRect(x, y, w, h, color) | 画填充矩形 |
| drawCircle(x, y, r, color) | 画圆 |
| fillCircle(x, y, r, color) | 画填充圆 |
| drawTriangle(x1,y1,x2,y2,x3,y3,color) | 画三角形 |
九、常见问题
| 屏幕不亮 | 检查 VCC 和 GND 是否接反 |
| 显示乱码 | I2C 地址不对,尝试改为 0x3D |
| 初始化失败 | 检查 SDA/SCL 是否接 A4/A5 |
| 只显示部分 | 分辨率设置错误,确认是 128×64 |
| 画面闪烁 | 减少 display.display() 的调用频率 |
十、本篇小结
回顾一下今天学到的核心知识:
- OLED 特点:自发光、超薄、省电、高对比度
- I2C 通信:只需 SDA + SCL 两根线传输数据
- Adafruit 库:begin() 初始化,display() 刷新屏幕
- 显示文字:setTextSize()、setCursor()、println()
- 绘制图形:drawRect()、drawCircle()、fillRect() 等
- 综合项目:超声波测距仪,实时显示距离 + 进度条
OLED 显示屏让 Arduino 项目有了"可视化"能力,可以显示传感器数据、菜单界面、动画效果等。下一篇,我们学习温湿度传感器 DHT11——让 Arduino 感知环境温度和湿度!




