玩转 ESP32 + Arduino (八) U8G2驱动OLED
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玩转 ESP32 + Arduino (八) U8G2驱动OLED相关的知识,希望对你有一定的参考价值。
参考技术A 目前Arduino平台上使用最广泛的OLED库: U8G2github地址: https://github.com/olikraus/u8g2/
设置和参考手册: https://github.com/olikraus/u8g2/wiki
U8g2:单色显示器库,版本2
U8g2是用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,包括以下控制器:SSD1305,SSD1306,SSD1309,SSD1322,SSD1325,SSD1327,SSD1329,SSD1606,SSD1607,SH1106,SH1107,SH1108,SH1122,T6963,RA8835,LC7981,PCD8544,PCF8812,HX12 ,UC1601,UC1604,UC1608,UC1610,UC1611,UC1701,ST7565,ST7567,ST7588,ST75256,NT7534,IST3020,ST7920,LD7032,KS0108,SED1520,SBN1661,IL3820,MAX7219(完整列表请参见 此处 )。
为什么要运用U8g2库?
支持单片机平台:
再platformIO.ini中配置库
方法可以分为四大类:
初始化显示器, 清屏, 唤醒屏幕
只是初始化显示器, 并不清屏, 也不唤醒屏幕
开启UTF-8后,我们可以使用其UTF-8字库
如果支持绘制颜色(也就是不是单色显示器),那么由setDrawColor设置;
例: 画圆动画 (4帧😂😂😂😂)
实例:
示例:下面例子,ascent是18
示例:下面例子,descent是-5
启用(1)或禁用(0)透明模式
U8g2支持三种绘制模式:
特点:
用法:
特点:
特点:
看例程里有无数条代表着各种屏幕的写好的U8g2初始化语句,选择适合的一条解除注释即可
我的ESP32 DEVKIT V1+SSD1306(IIC)是选择这个:
https://github.com/olikraus/u8g2/wiki/fntlistall
https://github.com/olikraus/u8g2/wiki/fntgrpiconic
示例: 显示所有iconic图标
https://github.com/olikraus/u8g2/wiki/fntgrpwqy
可以看到, 最小的字高12px, 最大的字高18px,如果想要更大的字,请取XBM格式字模
我使用了在线转换器:
https://convertio.co/zh/image-converter/?utm_source=chrome_extension
整个转换过程很简单, 转换好的XBM文件用记事本打开就能看到数组了, 感觉比传统的 Img2Lcd 或者 PCtoLCD2002 好用
掌控板IO接口编程入门 | 用Arduino玩转掌控板(ESP32)系列
众所周知,掌控板在创客教育中用的非常广泛,它是一块基于 ESP32 的学习开发板。大家对掌控板编程,用的比较多的都是图形化编程的方式,比如 mPython、Mind+ 等。但是,既然掌控板是基于 ESP32 芯片的,所以我们也可以用 Arduino 软件对其编程。所以,有时间的话,我准备给大家分享一系列用 Arduino 代码对掌控板(ESP32)编程的教程:用 Arduino 玩转掌控板(ESP32)系列。
本系列历史文章目录:
本期给大家带来的是:掌控板IO接口编程入门,教你用 Arduino IDE 学会掌控板 IO 接口的简单编程操作。IO 就是 INPUT 与 OUTPUT 的缩写,即输入与输出。
其实本篇是这个系列的入门篇之一,但是由于我一直偷懒,这篇一直放着没写,先写了一些进阶的内容。本篇比较简单,所以就不放案例演示视频了。
# 概述
掌控板的 IO 接口主要是用来连接外部传感器、执行器等相关外设的。平时我们使用最多最常见的一些外设,一般都是数字量或模拟量的,传感器一般都是输入设备、执行器一般都是输出设备。所以,一般情况下学习一个主控板的 IO 接口基本操作,我们都是从数字输入、数字输出、模拟输入、模拟输出这个 4 个方面来进行学习的,本篇也不例外。
这里需要注意的是,输入和输出是相对主控板来说的:
当信号是由主控板向外设发送时,相应的外设就是主控板的输出设备;
当信号是由外设向主控板发送时,也就是主控板去读取外设的信号时,相应的外设就是主控板的输入设备。
所以:
大部分传感器都是输入设备,因为他们的功能是测量数据,然后主控板去读取他们的数据;
大部分执行器都是输出设备,因为是主控板向他们发送信号、控制他们完成相应的操作。
# 数字输入
数字输入(或数字量输入)设备是生活中最常见的设备,比如房间里的开关、按钮、楼道里的人体感应设备,这些设备有一个共同的特点,即只有 2 种情况:有或无、开或关、1 或 0,这些只有 2 种情况的设备,一般称为数字量设备。相应地,如果他们是传感器,则称为数字输入设备,或数字输入传感器。
掌控板上的按键 A 和 B,其实就是数字输入传感器。所以本节就以读取掌控板上的按键 A 和 B 为例,教你对数字输入设备编程。
先来看一下完整的程序:
// 设置掌控板按键 A 的引脚编号
const int buttonAPin = P5;
// 设置按键 A 的状态值变量
int buttonAState = 0;
void setup()
// 初始化串口监视器
Serial.begin(9600);
// 初始化按键 A 对应的引脚为输入模式
pinMode(buttonAPin, INPUT);
void loop()
// 读取按键 A 的值
buttonAState = digitalRead(buttonAPin);
// 如果按键 A 被按下了,串口监视器输出信息
if (buttonAState == LOW)
Serial.println("Button A pressed");
delay(100);
这个程序很简单,程序中也有相应的注释了,我们简单来讲解一下。
首先在程序开头定义了两个变量,buttonAPin 用来定义按键 A 对应的引脚,buttonAState 用来存储按键 A 的状态。
// 设置掌控板按键 A 的引脚编号
const int buttonAPin = P5;
// 设置按键 A 的状态值变量
int buttonAState = 0;
这里讲一下命名变量的小技巧,变量一般要命名成方便用户辨别、并且有一定实际字面意义的名称,这样当程序比较长的时候更加容易读懂。尽量不要命名成 a、b 这些没有太多实际字面意义的名称,当然特殊情况除外。
那么我们是如何知道按键 A 对应的引脚编号是 P5 呢?
实际上掌控板官方 Wiki 上提供了非常详细的说明和电路图,我们阅读相应的文档,就可以知道掌控板上的板载资源对应的引脚了。我们可以直接点击下方链接,查看掌控板官方 Wiki 资料。
https://mpython.readthedocs.io/zh/master/board/hardware.html
在上面的网页中,我们可以查到一张表格,上面记录了掌控板上所有板载资源对应的引脚。从这里我们可以查到按键 A 对应的引脚编号为 P5。
接下来在初始化程序 setup() 中,我们可以看到下面两句代码,分别用来对串口监视器进行初始化、以及设定按键 A 引脚的模式。对串口监视器初始化时,我们要设定串口波特率,常用的波特率是 9600 和 115200,设置波特率的作用是让电脑和掌控板保持相同的通信速率,以便可以互相收发信息。引脚模式,最常用的一般为输入模式 INPUT 和输出模式 OUTPUT,我们知道按键是数字输入传感器,所以要设置为输入模式 INPUT。
// 初始化串口监视器
Serial.begin(9600);
// 初始化按键 A 对应的引脚为输入模式
pinMode(buttonAPin, INPUT);
这里顺便再提一下,在 Arduino IDE 中编程,一般会有两个自带的函数,分别为初始化函数 setup() 和循环函数 loop()。setup() 函数的功能是在程序开始前做相应的设置,设备上电后(或者按下 RESET 按键之后)只执行一次;loop() 函数是在 setup() 运行完成之后开始运行的,它的功能是不断重复执行其中的代码,因此需要重复运行的代码或任务,一般放在 loop() 函数中,比如不断读取按键的状态。当然也有一些特殊情况,比如中断的设置等,是不用放在 loop() 中的,这部分等讲到相应内容的时候再来展开。
接下来在 loop() 函数中,首先读取按键 A 的状态值,并且赋值给变量 buttonAState。读取数字量输入的程序为 digitalRead(),跟变量命名一样,程序中函数命名也是带有一定的意义、简单易读的。
// 读取按键 A 的值
buttonAState = digitalRead(buttonAPin);
然后根据按键 A 的状态值,通过串口监视器打印出相应的信息。这里需要注意的是,一般情况下,按键弹起时的默认值为 LOW(或 0),当按键被按下时,按键的值变为 HIGH(或 1)。但是这不是绝对的,跟电路设计有关,掌控板的按键值与按键状态,就正好相反。所以当掌控板的按键 A 被按下时,它的状态值为 LOW。为了防止程序运行太快,导致串口监视器一下子输出太多信息,我们这里加了一个延时函数:delay(100),让程序每次都延时 100 毫秒再去运行下一次循环任务。
// 如果按键 A 被按下了,串口监视器输出信息
if (buttonAState == LOW)
Serial.println("Button A pressed");
delay(100);
在工具菜单中,将主控板选为掌控板,并选择正确的串口号,上传程序。然后打开串口监视器,我们看看程序运行的效果。在串口监视器中将波特率设置为 9600,然后按下掌控板上的按键 A。每按下一次按键 A,串口监视器中就会输出相应的信息,说明程序编写成功!
试一试:改写程序,让程序同时也可以读取按键 B 的状态,并在串口监视器输出相应的信息。你会了么?
# 数字输出
学会了数字输入,我们再来学一学数字输出。我们生活中最常见的电灯,一般情况下,都是数字输出设备。数字输出也是只有 2 种控制状态的设备,高或低、1 或 0。这里以控制 LED 灯为例,来学习一下数字输出的程序编写。我们现在掌控板的 P0 端口外接一个 LED 灯,这里你可以选择自己喜欢的任意扩展板。电路比较简单,所以这里不放电路图了。
来看一下完整的程序:
// 设置掌控板按键 A 的引脚编号
const int buttonAPin = P5;
// 设置 LED 灯的引脚编号
const int ledPin = P0;
// 设置按键 A 的状态值变量
int buttonAState = 0;
void setup()
// 初始化串口监视器
Serial.begin(9600);
// 初始化按键 A 对应的引脚为输入模式
pinMode(buttonAPin, INPUT);
// 初始化 LED 对应的引脚为输出模式
pinMode(ledPin, OUTPUT);
void loop()
// 读取按键 A 的值
buttonAState = digitalRead(buttonAPin);
// 如果按键 A 被按下了,点亮 LED 灯,否则熄灭 LED 灯
if (buttonAState == LOW)
Serial.println("Button A pressed");
digitalWrite(ledPin, HIGH);
else
digitalWrite(ledPin, LOW);
delay(100);
仔细观察,我们发现这个程序跟上一节数字输入中的程序非常类似,我们只是在这基础之上加了几行代码。这里只讲差异部分。
首先在程序开头,定义了 LED 灯的引脚编号,我们将 LED 灯通过扩展板接在掌控板的 P0 引脚,这个与定义按键 A 引脚编号的方法一致。
// 设置 LED 灯的引脚编号
const int ledPin = P0;
然后在 setup() 初始化函数中设置了 LED 连接的引脚为输出模式 OUTPUT,这个与设置按键 A 的方法也一样,只不过一个是 LED 设置为输出模式、按键 A 设置为输入模式。
// 初始化 LED 对应的引脚为输出模式
pinMode(ledPin, OUTPUT);
然后在 loop() 函数中,当检测到按键 A 被按下时,点亮 LED,否则熄灭 LED 灯。点亮 LED 灯的代码为:
digitalWrite(ledPin, HIGH);
熄灭 LED 灯的代码为:
digitalWrite(ledPin, LOW);
将程序上传到掌控板,按下按键 A,看看 LED 灯是否点亮了呢?松开按键 A 呢?
试一试:改写程序,实现:按下按键 A,点亮 LED 灯;按下按键 B,熄灭 LED 灯。
# 模拟输入
讲完数字输入、数字输出,我们再来看一看模拟输入。模拟输入是相对数字输入来说的,数字输入只要 2 种状态,但是模拟输入有很多种连续的状态,比如各种旋钮、温度值等。
在掌控板上也有 2 个模拟输入传感器:声音传感器与光线传感器。下面我们以声音传感器为例,讲一讲模拟输入的程序编写方法。
// 设置掌控板声音传感器引脚编号
const int soundPin = P10;
// 设置声音大小值变量
int soundValue = 0;
void setup()
// 初始化串口监视器
Serial.begin(9600);
// 初始化声音传感器引脚为输入模式
pinMode(soundPin, INPUT);
void loop()
// 读取声音传感器的值
soundValue = analogRead(soundPin);
// 串口监视器中打印声音传感器的值
Serial.println(soundValue);
delay(10);
这个程序与数字输入部分的程序也是非常类似的。
在程序开头,定义了两个变量,用来设置声音传感器的引脚编号、声音传感器的值。
// 设置掌控板声音传感器引脚编号
const int soundPin = P10;
// 设置声音大小值变量
int soundValue = 0;
接着在 setup() 初始化函数中,初始化串口监视器和声音传感器的引脚模式:
// 初始化串口监视器
Serial.begin(9600);
// 初始化声音传感器引脚为输入模式
pinMode(soundPin, INPUT);
接着在 loop() 函数中读取声音的值,并且在串口监视器中打印出来。读取模拟量的函数为 analogRead()。
// 读取声音传感器的值
soundValue = analogRead(soundPin);
// 串口监视器中打印声音传感器的值
Serial.println(soundValue);
delay(10);
将程序上传到掌控板中,打开串口监视器,对着声音传感器说话,我们看看效果。
我们还可以以曲线图的形式,将声音传感器数据的变化展现出来。在 Arduino IDE 菜单栏中,依次点击:工具 → 串口绘图器,打开串口绘图器,对着声音传感器说话,看看曲线图变化吧。
试一试:改写程序,让程序同时也可以读取光线传感器的值,看看串口绘图器会输出什么信息呢?
# 模拟输出
你有没有注意到,有些人家里的电灯,亮度是可以调节的?这个其实就是模拟输出。相比于数字输出只有两种状态,模拟输出可以有连续的多种状态。
由于在 Arduino IDE 中,用掌控板自带的函数功能实现模拟输出比较复杂。因此我们这里调用别人做好的适用于掌控板 ESP32 的模拟输出函数库。函数库下载地址为:
https://github.com/ERROPiX/ESP32_AnalogWrite
我们要先将这个库导入到 Arduino IDE 中。这个库的功能是可以让掌控板像 Arduino 一样,方便的使用模拟输出功能,有个这个库,掌控板模拟输出的语法,就跟 Arduino 完全一样了。
这里以控制 LED 灯实现呼吸灯效果为例,完整的程序如下:
#include <Arduino.h>
#include <analogWrite.h>
// 设置 LED 灯引脚编号
const int ledPin = P0;
void setup()
// 初始化 LED 灯引脚为输出模式
pinMode(ledPin, OUTPUT);
void loop()
for (int brightness = 0; brightness <= 255; brightness++)
analogWrite(ledPin, brightness);
delay(5);
for (int brightness = 255; brightness >= 0; brightness--)
analogWrite(ledPin, brightness);
delay(5);
在程序最开始,我们先引入两个头文件,在头文件中定义了实现模拟输出相关的功能函数。然后定义了 LED 灯的引脚编号。
#include <Arduino.h>
#include <analogWrite.h>
// 设置 LED 灯引脚编号
const int ledPin = P0;
接着在 setup() 函数中设置 LED 灯引脚为输出模式。
然后在 loop() 函数中,通过 for 循环结构,控制 LED 灯由暗变亮,再由亮变暗。亮度通过局部变量 brightness 来设置。
for (int brightness = 0; brightness <= 255; brightness++)
analogWrite(ledPin, brightness);
delay(5);
for (int brightness = 255; brightness >= 0; brightness--)
analogWrite(ledPin, brightness);
delay(5);
将程序上传到掌控板中,LED 灯是不是呈现呼吸灯闪烁变化的样子?说明程序编程成功了。
# 总结
在本章中,我们学习了:
如何查阅掌控板各引脚相应的资源配置;
数字量与模拟量的区别;
简单的数字输入、数字输出、模拟输入、模拟输出的程序编写;
Arduino IDE 的基本使用方法。
学习了这些基础内容之后,就可以学习后面更加进阶的内容啦,其实进阶内容与入门内容类似,都是由一个个小功能组成的,有了这些基础功能的组合,通过不同的排列组合和逻辑设置,就可以实现各种好玩的创意啦!
我们下期见!如果本文对你有帮助的话,点个“ 在看 ”支持一下喽。
欢迎转发朋友圈。如需转载,请注明出处和原作者。
我知道你在看呦
以上是关于玩转 ESP32 + Arduino (八) U8G2驱动OLED的主要内容,如果未能解决你的问题,请参考以下文章
玩转 ESP32 + Arduino (十一) EEPROM NTP对时 蓝牙透传
玩转 ESP32 + Arduino(二十八) TFT_eSPI库驱动ST7789
掌控板IO接口编程入门 | 用Arduino玩转掌控板(ESP32)系列
玩转 ESP32 + Arduino (二十五) SSD1306库驱动OLED