《Arduino 手册(思路与案例)》栏目介绍:
在电子制作与智能控制的应用领域:广泛涉及了Arduino BLDC、Arduino CNC、Arduino ESP32 SPP、Arduino FreeRTOS、Arduino FOC、Arduino GRBL、Arduino HTTP、Arduino HUB75、Arduino IoT Cloud、Arduino JSON、Arduino LCD、Arduino OLED、Arduino LVGL、Arduino PID 及 Arduino TFT 等方面的相关拓展思路和众多参考案例。本专栏目前博客近2300篇。
https://blog.csdn.net/weixin_41659040/category_12422453.html
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用Arduino IDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Arduino的功能和学习Arduino的知识。
Arduino的特点是:
1、开放源码:Arduino的硬件和软件都是开放源码的,你可以自由地修改、复制和分享它们。
2、易用:Arduino的硬件和软件都是为初学者和非专业人士设计的,你可以轻松地上手和使用它们。
3、便宜:Arduino的硬件和软件都是非常经济的,你可以用很低的成本来实现你的想法。
4、多样:Arduino有多种型号和版本,你可以根据你的需要和喜好来选择合适的Arduino板。
5、创新:Arduino可以让你用电子的方式来表达你的创意和想象,你可以用Arduino来制作各种有趣和有用的项目,如机器人、智能家居、艺术装置等。
概念概述
Arduino OLED 指的是将 Arduino 开发平台与 OLED(有机发光二极管)显示屏相结合的应用组合。Arduino 是开源电子原型平台,具备灵活的硬件扩展性和简单易上手的编程环境;OLED 显示屏则以其自发光、高对比度、宽视角、响应速度快等优势,为信息展示提供了优质的视觉体验。二者结合能实现各类数据显示、图形绘制及交互界面展示等功能,在电子制作、物联网、机器人等诸多领域广泛应用。
详细解释
Arduino 相关特性
硬件特性
开源设计:Arduino 的硬件设计方案完全公开,用户能够获取其原理图、PCB 版图等详细资料。这不仅降低了开发成本,还方便开发者根据自身需求对硬件进行修改和扩展,例如制作自定义外形或功能的开发板。
丰富接口资源:Arduino 开发板配备了多种类型的接口。数字输入输出引脚可用于连接开关、继电器、LED 等设备,实现数字信号的读取和输出控制;模拟输入引脚能够采集如温度传感器、光照传感器输出的连续模拟信号,经内部 ADC(模拟 - 数字转换器)转换为数字值供程序处理。
多种供电方式:支持 USB 供电、外接电源适配器供电以及电池供电等多种方式。使用 USB 供电时,可方便地与计算机连接进行程序上传和调试;外接电源适配器则能提供稳定的电源,适用于长时间运行的项目;电池供电赋予了 Arduino 设备便携性,可应用于移动监测等场景。
软件特性
简易编程环境:Arduino 使用基于 C/C++ 的编程语言,其语法简洁易懂。Arduino IDE 是专门为其开发的集成开发环境,具有跨平台性,可在 Windows、Mac OS、Linux 等操作系统上运行。IDE 提供了直观的代码编辑界面、便捷的编译和上传功能,还内置了大量示例代码,帮助初学者快速入门。
庞大的库资源:Arduino 社区拥有丰富的开源库,涵盖了传感器驱动、通信协议、图形绘制等各个领域。例如,Wire 库用于 I2C 通信,SPI 库用于 SPI 通信,开发者可以直接调用这些库,无需从头编写底层代码,大大提高了开发效率。
OLED 显示屏特性
显示原理
OLED 基于有机材料的电致发光特性工作。当在有机材料层两端施加电压时,电子从阴极注入,空穴从阳极注入,二者在有机材料中相遇并复合,释放出能量以光的形式呈现,从而实现发光显示。由于每个像素都能独立发光,OLED 显示屏无需背光源。
性能优势
自发光与高对比度:自发光特性使得 OLED 能够实现真正的黑色显示,因为不发光的像素完全不产生光线。这使得其对比度极高,图像的亮部更亮,暗部更暗,色彩表现更加生动逼真。
宽视角:OLED 的视角非常宽广,通常可达 170° 以上。从不同角度观看显示屏,画面的颜色和亮度变化极小,能为用户提供一致的视觉体验,适用于各种需要多角度观察的应用场景。
快速响应时间:OLED 的响应时间极短,一般在几微秒到几十微秒之间。相比传统的液晶显示屏,OLED 在显示动态画面时不会出现拖影现象,能够清晰、流畅地展示快速变化的图像,如动画、视频等。
轻薄与低功耗:由于无需背光源,OLED 显示屏的结构更加简单,厚度更薄,重量更轻。同时,其在显示黑色画面时几乎不消耗电能,只有发光的像素才会消耗功率,因此在显示深色画面较多的场景下,功耗显著降低。
Arduino 与 OLED 的连接和通信
通信接口类型
SPI(Serial Peripheral Interface):SPI 是一种高速的全双工串行通信协议,Arduino 通过 SPI 接口与 OLED 显示屏连接时,通常需要使用时钟线(SCK)、主输出从输入线(MOSI)、主输入从输出线(MISO)和片选线(SS)。SPI 通信速度快,适合需要快速传输大量数据的应用场景,如显示高分辨率的图像或视频流。
I2C(Inter - Integrated Circuit):I2C 是一种串行通信协议,使用两根线进行通信,即时钟线(SCL)和数据线(SDA)。I2C 接口简单,占用 Arduino 的引脚资源少,并且支持多个设备挂载在同一总线上,通过不同的设备地址进行区分。在一些对引脚资源要求较高的项目中,I2C 接口更为适用。
通信流程
初始化:在 Arduino 代码中,首先需要初始化所选的通信接口(SPI 或 I2C),并设置相关的通信参数,如时钟频率、设备地址等。
发送数据:Arduino 根据需要显示的内容,将数据按照 OLED 显示屏的通信协议进行编码,然后通过通信接口发送给 OLED 显示屏。数据可以是字符、数字、图形等信息。
显示更新:OLED 显示屏接收到数据后,对其进行解码和处理,将相应的内容显示在屏幕上。为了实现动态显示效果,Arduino 可以定期更新发送的数据,使 OLED 显示屏不断刷新显示内容。
应用场景
数据监测与显示:在环境监测系统中,Arduino 连接各种传感器(如温度传感器、湿度传感器、空气质量传感器等)采集环境数据,然后将数据通过通信接口传输到 OLED 显示屏上进行实时显示。用户可以直观地了解环境参数的变化情况。
智能家居控制:在智能家居系统中,Arduino 作为控制核心,连接各种家电设备和传感器。OLED 显示屏可以显示家电设备的状态(如开关状态、温度设置等),并提供操作菜单,用户可以通过触摸按键或其他输入设备在 OLED 显示屏上进行操作,实现对家电设备的远程控制。
机器人交互界面:在机器人项目中,OLED 显示屏可以作为机器人的交互界面,显示机器人的工作状态、任务进度、传感器数据等信息。同时,还可以显示一些动画或图标,增强机器人的人机交互体验。
手持设备与可穿戴设备:由于 OLED 显示屏的轻薄和低功耗特性,与 Arduino 结合可用于开发手持设备和可穿戴设备。例如,制作一个便携式的健康监测设备,通过 Arduino 连接心率传感器、计步器等,将监测数据显示在 OLED 显示屏上,方便用户随时查看自己的健康状况。
在Arduino项目中,OLED之滚动文本显示(Scrolling Text Display on OLED) 是一种有效利用有限屏幕空间展示大量信息的技术。通过滚动文本,可以在小尺寸的OLED屏幕上连续显示超出屏幕宽度或高度的信息,提高信息传递效率和用户体验。以下是关于这一技术的主要特点、应用场景以及需要注意的事项的专业解析。
主要特点
- 高效利用屏幕空间
滚动文本允许在有限的显示屏区域内显示更多的内容,特别适用于需要显示长文本或动态更新信息的场景。
支持水平滚动、垂直滚动及双向滚动等多种模式,可根据实际需求灵活调整。 - 增强用户体验
动态滚动效果可以吸引用户的注意力,使得信息展示更加生动有趣。
对于快速浏览信息或需要逐步阅读的内容,滚动文本提供了一种自然流畅的交互方式。 - 易于实现
Arduino平台上有多个支持OLED屏的库(如Adafruit_SSD1306、U8g2lib),这些库通常都提供了方便的API来实现文本滚动功能。
开发者可以根据具体需求定制滚动速度、方向等参数,实现个性化的滚动效果。 - 低功耗与高对比度
OLED屏幕具有自发光特性,相较于传统LCD屏幕,在显示黑色背景时更加节能,且提供更高的对比度,适合长时间显示滚动文本。 - 兼容性强
支持多种OLED屏幕尺寸和分辨率,开发者可以根据项目的具体要求选择合适的硬件配置。
易于与其他传感器或模块集成,构建复杂的应用系统。
应用场景
- 智能穿戴设备
在智能手表或健身追踪器上滚动显示通知消息、健康数据(如步数、心率)等信息,让用户无需频繁查看手机即可获取重要通知。 - 智能家居控制面板
展示当前天气预报、室内环境监测数据(温度、湿度)、设备状态更新等信息,便于用户及时了解家居环境状况。 - 工业自动化系统
在工业控制系统中用于实时显示机器运行状态、故障报警信息等,帮助操作人员监控生产过程中的关键指标。 - 公共交通信息系统
如公交站牌上的电子指示牌,滚动显示即将到达的公交车班次、预计到达时间等信息,提升乘客体验。 - 教育与培训工具
制作基于Arduino的学习装置,滚动显示编程概念、语言学习资料等内容,辅助教学活动。
注意事项
- 性能优化
滚动文本可能会增加CPU负担,特别是在处理较长文本或较高刷新率的情况下。合理设置滚动间隔时间,避免因过度频繁刷新导致性能下降。
使用高效的字符串处理方法减少内存占用,特别是对于资源受限的微控制器。 - 字体大小与样式
根据屏幕尺寸选择合适的字体大小,确保文字清晰可读。同时,考虑使用不同风格的字体以突出重点信息。
注意字符间距和行距的设置,保证文本排列整齐美观。 - 内容管理
当文本长度超过屏幕容量时,设计合理的滚动策略(例如循环滚动或一次性完整滚动),并确保过渡平滑自然。
考虑到多语言支持的需求,测试不同字符集下的显示效果,确保兼容性良好。 - 电源稳定性
特别是在电池供电的设备中,关注电源电压波动对OLED显示质量的影响。必要时添加滤波电容或其他稳压措施,维持稳定的电源供应。 - 用户体验设计
设计滚动逻辑时考虑到用户的阅读习惯,避免过快或过慢的速度影响阅读体验。
提供暂停/恢复滚动的功能选项,允许用户根据需要停止滚动以便仔细阅读感兴趣的部分。
1、基础滚动文本显示
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED显示屏幕的宽度,以像素计
#define SCREEN_HEIGHT 64 // OLED显示屏幕的高度,以像素计
#define OLED_RESET -1 // 不使用复位引脚
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const char* message = "Hello, OLED! This is a long message to scroll.";
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 连接到OLED显示屏
Serial.println(F("SSD1306 allocation failed"));
for (;;); // 进入无限循环,无法初始化显示屏
}
display.clearDisplay(); // 清屏
display.setTextSize(1); // 设置文本大小
display.setTextColor(SSD1306_WHITE); // 设置文本颜色为白色
}
void loop() {
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(message, 0, 10, &x1, &y1, &w, &h); // 获取文本边界
for (int16_t x = SCREEN_WIDTH; x > -w; x--) {
display.clearDisplay(); // 清屏
display.setCursor(x, 10); // 设置文本起始位置
display.print(message); // 显示文本
display.display(); // 刷新显示
delay(50); // 控制滚动速度
}
delay(1000); // 滚动结束后延迟1秒
}
要点解读:
文本滚动:通过逐步减少x坐标值实现文本的水平滚动。
文本边界获取:使用getTextBounds函数获取文本的宽度和高度,确保文本完全滚动。
清屏操作:每次更新位置前清屏,避免文本叠加。
显示更新:使用display.display函数刷新屏幕,显示滚动的文本。
2、多行滚动文本显示
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED显示屏幕的宽度,以像素计
#define SCREEN_HEIGHT 64 // OLED显示屏幕的高度,以像素计
#define OLED_RESET -1 // 不使用复位引脚
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const char* message1 = "Hello, OLED! This is the first line.";
const char* message2 = "This is the second line of text.";
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 连接到OLED显示屏
Serial.println(F("SSD1306 allocation failed"));
for (;;); // 进入无限循环,无法初始化显示屏
}
display.clearDisplay(); // 清屏
display.setTextSize(1); // 设置文本大小
display.setTextColor(SSD1306_WHITE); // 设置文本颜色为白色
}
void loop() {
int16_t x1, y1;
uint16_t w1, h1, w2, h2;
display.getTextBounds(message1, 0, 10, &x1, &y1, &w1, &h1); // 获取第一行文本边界
display.getTextBounds(message2, 0, 20, &x1, &y1, &w2, &h2); // 获取第二行文本边界
for (int16_t x = SCREEN_WIDTH; x > -max(w1, w2); x--) {
display.clearDisplay(); // 清屏
display.setCursor(x, 10); // 设置第一行文本起始位置
display.print(message1); // 显示第一行文本
display.setCursor(x, 20); // 设置第二行文本起始位置
display.print(message2); // 显示第二行文本
display.display(); // 刷新显示
delay(50); // 控制滚动速度
}
delay(1000); // 滚动结束后延迟1秒
}
要点解读:
多行文本滚动:通过逐步减少x坐标值实现多行文本的水平滚动。
文本边界获取:分别获取每行文本的宽度和高度,确保文本完全滚动。
清屏操作:每次更新位置前清屏,避免文本叠加。
显示更新:使用display.display函数刷新屏幕,显示滚动的文本。
3、动态更新的滚动文本显示
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED显示屏幕的宽度,以像素计
#define SCREEN_HEIGHT 64 // OLED显示屏幕的高度,以像素计
#define OLED_RESET -1 // 不使用复位引脚
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const char* message = "Hello, OLED! This is a dynamic message.";
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 连接到OLED显示屏
Serial.println(F("SSD1306 allocation failed"));
for (;;); // 进入无限循环,无法初始化显示屏
}
display.clearDisplay(); // 清屏
display.setTextSize(1); // 设置文本大小
display.setTextColor(SSD1306_WHITE); // 设置文本颜色为白色
}
void loop() {
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(message, 0, 10, &x1, &y1, &w, &h); // 获取文本边界
for (int16_t x = SCREEN_WIDTH; x > -w; x--) {
display.clearDisplay(); // 清屏
display.setCursor(x, 10); // 设置文本起始位置
display.print(message); // 显示文本
display.display(); // 刷新显示
delay(50); // 控制滚动速度
}
// 动态更新文本内容
message = "Updated message for dynamic display.";
delay(2000); // 滚动结束后延迟2秒
}
要点解读:
动态文本更新:在滚动结束后更新文本内容,实现动态显示效果。
文本滚动:通过逐步减少x坐标值实现文本的水平滚动。
文本边界获取:使用getTextBounds函数获取文本的宽度和高度,确保文本完全滚动。
清屏操作:每次更新位置前清屏,避免文本叠加。
显示更新:使用display.display函数刷新屏幕,显示滚动的文本。
4、动态信息栏(新闻标题滚动)
功能:模拟新闻标题滚动效果,实现从右向左的无限循环文本显示。
硬件:Arduino UNO + SSD1306 OLED(128x64)。
核心代码片段:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
String newsTitle = "Breaking News: Arduino OLED Tutorial Released! ";
int scrollPos = 128; // 初始位置在屏幕右侧外
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
void loop() {
display.clearDisplay();
display.setCursor(scrollPos, 10);
display.print(newsTitle);
display.display();
scrollPos--; // 向左移动
if (scrollPos < -newsTitle.length() * 6) { // 6为字符宽度近似值
scrollPos = 128; // 重置位置实现循环
}
delay(50);
}
要点解读:
滚动逻辑:通过scrollPos变量控制文本起始位置,每次循环递减实现向左移动。
循环复位:当文本完全移出屏幕左侧时,重置位置到右侧形成无缝循环。
性能优化:clearDisplay()避免残影,但频繁调用可能影响刷新率,需权衡速度。
5、消息推送系统(带缓冲队列)
功能:实现多条消息的队列管理,新消息自动上屏并滚动显示。
硬件:Arduino Nano + SSD1306 OLED。
核心代码片段:
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
String messages[3] = {
"System Booted",
"Temp: 25C",
"Low Battery Alert!"
};
int currentMsg = 0;
int scrollOffset = 0;
void setup() {
u8g2.begin();
}
void loop() {
u8g2.firstPage();
do {
u8g2.setCursor(scrollOffset, 20);
u8g2.print(messages[currentMsg]);
if (scrollOffset < -u8g2.getStrWidth(messages[currentMsg].c_str())) {
scrollOffset = 128;
currentMsg = (currentMsg + 1) % 3; // 循环消息队列
} else {
scrollOffset -= 2; // 较慢的滚动速度
}
} while (u8g2.nextPage());
delay(50);
}
要点解读:
队列管理:通过数组存储多条消息,currentMsg索引实现循环播放。
滚动终止条件:当文本完全移出屏幕后,切换至下一条消息。
库差异:使用u8g2.getStrWidth()动态计算文本宽度,适配不同内容长度。
6、交互式菜单(按键控制滚动)
功能:通过按键上下翻页浏览菜单项,OLED高亮当前选中项。
硬件:Arduino Pro Micro + SSD1306 OLED + 2个按钮。
核心代码片段:
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
String menuItems[] = {"Start", "Settings", "About", "Shutdown"};
int selectedItem = 0;
bool scrollUp = false, scrollDown = false;
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(2, INPUT_PULLUP); // 上键
pinMode(3, INPUT_PULLUP); // 下键
}
void loop() {
if (!digitalRead(2)) { scrollUp = true; }
if (!digitalRead(3)) { scrollDown = true; }
if (scrollUp && selectedItem > 0) {
selectedItem--;
scrollUp = false;
}
if (scrollDown && selectedItem < 3) {
selectedItem++;
scrollDown = false;
}
display.clearDisplay();
for (int i = 0; i < 4; i++) {
if (i == selectedItem) {
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); // 反色高亮
} else {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // 背景色
}
display.setCursor(0, 10 + i * 12);
display.print(menuItems[i]);
}
display.display();
delay(100);
}
要点解读:
交互逻辑:通过按键状态变量(scrollUp/scrollDown)控制菜单项切换。
视觉反馈:使用setTextColor()反转颜色高亮当前选中项。
布局计算:通过i * 12动态计算每行菜单的Y坐标,实现垂直排列。
注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。