使用Arduino Nano与OLED显示屏:显示图形和图像(二)

ChangeCode
原创
发布时间: 2025-06-10 17:30:51 | 阅读数 0收藏数 0评论数 0
封面
在前一篇文章中,我们探讨了如何使用Arduino Nano点亮并控制一个SSD1306驱动的OLED显示屏。接下来,我们将深入探讨如何利用这个小巧但强大的显示屏来展示各种图形,包括一些基本的数学原理、实现步骤以及最终效果。
1

基础概念

在开始之前,了解几个关键概念是非常重要的。首先,我们需要知道OLED显示器是如何工作的。每个像素都是独立发光的,这意味着我们可以精确地控制每一个像素的状态——亮或灭。这种特性使得OLED非常适合用于显示复杂的图形和动画。

其次,要理解的是坐标系的概念。大多数OLED显示屏使用的是笛卡尔坐标系,其中左上角是(0,0)点,x轴向右增加,y轴向下增加。这对于绘制任何形状都至关重要。

2

绘制点

在笛卡尔坐标系中,一个点由其x和y坐标唯一确定。要在屏幕上绘制一个点,可以使用drawPixel(x, y, color)函数。这里的color参数指定了像素的颜色(对于单色OLED屏来说,通常是黑色或白色)。

display.drawPixel(20, 30, WHITE); // 在坐标(20,30)处绘制一个白点



示例代码

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// 定义屏幕宽度和高度,通常为128x64或128x32
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// 声明OLED显示对象,这里我们使用I2C接口
#define OLED_RESET -1 // 如果你的显示屏需要连接复位引脚,请相应修改此值
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
// 初始化串口监视器用于调试
Serial.begin(9600);

// 初始化OLED显示
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 使用实际的I2C地址0x3C
Serial.println(F("SSD1306 allocation failed"));
for(;;); // 停止程序执行
}

// 显示启动画面
display.display();
delay(2000); // 等待2秒

// 清除屏幕缓冲区
display.clearDisplay();

// 在坐标(20,30)处绘制一个白点
display.drawPixel(20, 30, SSD1306_WHITE);

// 将绘图命令发送到屏幕
display.display();
}

void loop() {
// 主循环内无操作
}


3

绘制线段

根据两点P1(x1,y1)P1​(x1​,y1​)和P2(x2,y2)P2​(x2​,y2​),我们可以用直线方程y−y1=y2−y1x2−x1(x−x1)yy1​=x2​−x1​y2​−y1​​(xx1​)来表示一条直线。然而,在实际编程中,我们通常使用Bresenham算法来决定哪些像素应该被点亮以形成这条线。幸运的是,Adafruit GFX库为我们提供了一个简便的方法:

display.drawLine(10, 10, 50, 50, WHITE); // 从(10,10)到(50,50)绘制一条白线



示例代码

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// 定义屏幕宽度和高度,通常为128x64或128x32
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// 声明OLED显示对象,这里我们使用I2C接口
#define OLED_RESET -1 // 如果你的显示屏需要连接复位引脚,请相应修改此值
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
// 初始化串口监视器用于调试
Serial.begin(9600);

// 初始化OLED显示
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 使用实际的I2C地址0x3C
Serial.println(F("SSD1306 allocation failed"));
for(;;); // 停止程序执行
}

// 显示启动画面
display.display();
delay(2000); // 等待2秒

// 清除屏幕缓冲区
display.clearDisplay();

// 绘制一条从点(10, 10)到点(100, 50)的白线
display.drawLine(10, 10, 100, 50, SSD1306_WHITE);

// 将绘图命令发送到屏幕
display.display();
}

void loop() {
// 主循环内无操作
}


4

绘制矩形

绘制矩形可以通过连续调用drawLine()函数完成,但更高效的方式是直接使用drawRect(x, y, width, height, color)函数来绘制空心矩形,或者使用fillRect(x, y, width, height, color)函数来填充整个矩形区域。

display.drawRect(10, 10, 40, 40, WHITE); // 绘制左上角位于(10,10),宽高为40的空心矩形
display.fillRect(60, 10, 40, 40, WHITE); // 填充左上角位于(60,10),宽高为40的矩形



示例代码

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// 定义屏幕宽度和高度,通常为128x64或128x32
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// 声明OLED显示对象,这里我们使用I2C接口
#define OLED_RESET -1 // 如果你的显示屏需要连接复位引脚,请相应修改此值
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
// 初始化串口监视器用于调试
Serial.begin(9600);

// 初始化OLED显示
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 使用实际的I2C地址0x3C
Serial.println(F("SSD1306 allocation failed"));
for(;;); // 停止程序执行
}

// 显示启动画面
display.display();
delay(2000); // 等待2秒

// 清除屏幕缓冲区
display.clearDisplay();

// 绘制一个无填充的矩形,左上角坐标(10, 10),宽50像素,高30像素
display.drawRect(10, 10, 50, 30, SSD1306_WHITE);

// 绘制一个填充的矩形,左上角坐标(70, 10),宽40像素,高30像素
display.fillRect(70, 10, 40, 30, SSD1306_WHITE);

// 将绘图命令发送到屏幕
display.display();
}

void loop() {
// 主循环内无操作
}


5

绘制圆形

圆的标准方程是x2+y2=r2x2+y2=r2。虽然这个方程有助于理解圆形的概念,但在实践中,我们采用“中点圆算法”来绘制圆形。Adafruit GFX库中的drawCircle(x, y, radius, color)fillCircle(x, y, radius, color)函数实现了这一算法。

display.drawCircle(30, 30, 20, WHITE); // 在坐标(30,30)处绘制半径为20的圆
display.fillCircle(70, 30, 20, WHITE); // 在坐标(70,30)处填充半径为20的圆


示例代码

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// 定义屏幕宽度和高度,通常为128x64或128x32
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// 声明OLED显示对象,这里我们使用I2C接口
#define OLED_RESET -1 // 如果你的显示屏需要连接复位引脚,请相应修改此值
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
// 初始化串口监视器用于调试
Serial.begin(9600);

// 初始化OLED显示
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 使用实际的I2C地址0x3C
Serial.println(F("SSD1306 allocation failed"));
for(;;); // 停止程序执行
}

// 显示启动画面
display.display();
delay(2000); // 等待2秒

// 清除屏幕缓冲区
display.clearDisplay();

// 绘制一个无填充的圆形,中心坐标(64, 32),半径20像素
display.drawCircle(64, 32, 20, SSD1306_WHITE);

// 绘制一个填充的圆形,中心坐标(64, 32),半径10像素
display.fillCircle(64, 32, 10, SSD1306_WHITE);

// 将绘图命令发送到屏幕
display.display();
}

void loop() {
// 主循环内无操作
}


6

创建复杂图形

除了上述的基本图形外,还可以通过组合多个简单图形来创建更复杂的图案。比如,可以通过连接多个圆形和矩形来设计一个卡通形象,或者利用线条模拟出自然界中的物体如树木、花朵等。

此外,还可以引入渐变色、阴影等效果来增强视觉冲击力。虽然SSD1306控制器本身不支持真彩色,但我们可以通过调整亮度级别(即不同的灰度值)来模拟色彩的变化。


示例代码

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
// 绘制一个带填充的背景矩形
display.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
// 在背景上绘制一些形状
display.drawCircle(30, 32, 15, SSD1306_BLACK);
display.fillCircle(90, 32, 15, SSD1306_BLACK);
display.drawLine(0, 0, 127, 63, SSD1306_WHITE);
display.drawLine(0, 63, 127, 0, SSD1306_WHITE);
display.drawRect(10, 10, 107, 43, SSD1306_BLACK);
display.display();
}

void loop() {
}


阅读记录0
点赞0
收藏0
禁止 本文未经作者允许授权,禁止转载
猜你喜欢
评论/提问(已发布 0 条)
评论 评论
收藏 收藏
分享 分享
pdf下载 下载