电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
【实例演示】ESP8266+U8g2库,玩转OLED显示
分 享
扫描二维码分享
【实例演示】ESP8266+U8g2库,玩转OLED显示
esp8266
U8g2
oled
码农爱学习
关注
发布时间: 2022-03-14
丨
阅读: 1278
上篇文章,介绍了ESP8266在Arduino IDE中的基础使用方法,本篇,来继续学习OLED显示屏如何使用ESP8266来控制。 # 1 ESP8266引脚 首先来看一下ESP8266的引脚定义,因为本篇需要外接OLED,就要先看看ESP8266具有哪些功能的引脚。 ESP8266的引脚定义如下: ![](https://cf05.ickimg.com/bbsimages/202203/f215c52d4324050d6b5fbe1dd9b32b6c.png) 可以看出,ESP8266的功能引脚包括: - **3个串口**:TXD、RXD - **2个SPI接口**:MOSI、MISO、SCLK、CS - **1个IIC接口**:SDA、SCL - **多个数字输入/输出接口**:D1~D8 - **1个模拟输入/输出接口**:A0 # 2 OLED简介 OLED模块的尺寸多种多样,比较常用的是0.96寸的矩形的,也有其它尺寸的OLED。 此外,屏幕的接口,一般有IIC接口和SPI接口两种。加上电源,IIC接口需要4根线,而SPI接口需要6根线,IIC的通信比SPI通信慢,但4线接线更方便。 ![](https://cf05.ickimg.com/bbsimages/202203/0eac96fcd455fbcc17f159bf34536b96.png) 本篇使用最为常用的**0.96寸的OLED,分辨率128x64,黄蓝双色**。 注意这里的双色,不是值一个像素点可以显示两种颜色,而是**屏幕的上部1/4只能显示黄色,下部的3/4只能显示蓝色**,并且黄色和蓝色之间,不是紧密靠在一起的,而是有约一个像素点的间隙。 ![](https://cf05.ickimg.com/bbsimages/202203/6b8924f735d1b03e9c34b189b5050b19.png) # 3 U8g2库简介与安装 ## 3.1 U8g2库简介 U8g2 是一个用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,并支持如SSD1306等多种类型的OLED驱动。 U8g2源码的开源库地址:
U8g2**专为Arduino提供**的方便安装的库地址:https://github.com/olikraus/U8g2_Arduino 想要研究U8g2源码的可以看看这里的源代码,C和C++写的。 比如画直线这个函数和具体实现如下: ![](https://cf05.ickimg.com/bbsimages/202203/29c3eaadc1f83b018d144579db46a8df.png) ## 3.2 U8g2库安装 和上篇介绍ESP8266库的安装类似, U8g2库的安装也有两种方式: - **在线安装** 在线安装,在Arduino IDE的菜单的“项目->加载库->**管理库**”中搜索u8g2后安装即可,对网络环境要求较高 ![](https://cf05.ickimg.com/bbsimages/202203/98fbdde5bcb4784e0563dfe21d62f7f3.png) - **源码安装** 将U8g2**专为Arduino提供**的库(https://github.com/olikraus/U8g2_Arduino)整个下载下来,然后还是在Arduino IDE的菜单的“项目->加载库”中选择“**添加.ZIP库...**”,然后选到你刚下载的**U8g2_Arduino源码文件夹**后即可安装,也十分的方便。 ![](https://cf05.ickimg.com/bbsimages/202203/8a9b4afdfb3d4de6fbdbe08526af945a.png) ## 3.3 U8g2库的基础使用 使用U8g2库进行OLED的显示十分简单,首先要包含两个库,U8g2lib和Wire,后者是IIC通信需要用。 对于IIC接口的OLED,需要在程序中指定一下引脚的接口定义,如果是SPI接口,可以参考U8g2库自带例程中SPI接口是使用方法。 然后在Ardunio的setup中进行u8g2的初始化。 最后在Ardunio的loop中就可以编写自己的逻辑了。 另外,U8g2库在loop中的通用写法是使用do{}while()的形式: ```c u8g2.firstPage(); do { //自己的的逻辑 } while (u8g2.nextPage()); delay(1000); ``` 一个简单的HelloWord在OLED中的显示如下: ```c #include
#include
#define SCL 5 #define SDA 4 U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /@@*clock=*/SCL, /@@*data=*/SDA, /@@*reset=*/U8X8_PIN_NONE); void setup() { u8g2.begin(); u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function } void loop() { u8g2.setFont(u8g2_font_unifont_t_symbols); u8g2.firstPage(); do { u8g2.setCursor(0, 15); //指定显示位置 u8g2.print("Hello World!"); //使用print来显示字符串 } while (u8g2.nextPage()); delay(1000); } ``` 注意,**setCursor(0, 15),是将画图位置移动到x=0,y=15处,然后以这个点的右上区域进行字符串的显示,这样看起来就是显示在OLED的第一行**,如果你设置setCursor(0, 0),字符串实际是到屏幕外面了,不会显示! ![](https://cf05.ickimg.com/bbsimages/202203/e9d0dd1807ba76ef6b7c5ad47b8e2459.png) # 4U8g2常用API函数 ## 4.1 基础设置 - setFont(font) **设置字体** - `font`:u8g2的字体,比较常用的有**u8g2_font_unifont_t_symbols**(通常使用这个)和**u8g2_font_wqy12_t_gb2312b**(用于显示汉字)等 - setFontMode(num) 设置字体背景颜色模式 - `num`:启用(`1`)透明模式 - `num`:禁用(`0`)透明模式 - setDrawColor(color) 设置所有绘图函数的位值 - `color`:`0`(显示RAM中的清晰像素值) - `color`:`1`(设置像素值) - `color`:`2`(异或模式) ## 4.2 画像素点 - drawPixel(x,y) 只有指定位置即可显示像素点,比如把所有的点都显示出来: ```c //画像素点-填充屏幕 void testDrawPixelToFillScreen() { int t = 1000; u8g2.clearBuffer(); for (int j = 0; j < 64; j++) { for (int i = 0; i < 128; i++) { u8g2.drawPixel(i, j); } } SEND_BUFFER_DISPLAY_MS(t); } ``` 效果如下面的右图: ![](https://cf05.ickimg.com/bbsimages/202203/7815d2d155a92ce0642e40d197e106a4.png) **注意测试程序中,我定义了一个宏定义,用于延时显示每一次的画图**,方便观察OLED的显示过程: ```c #define SEND_BUFFER_DISPLAY_MS(ms)\ do {\ u8g2.sendBuffer(); \ delay(ms);\ }while(0); ``` 可以指定延时时间,如500毫秒或1000毫秒等。 ## 4.3 画直线 - drawLine(x0,y0,x1,y1) 画一条线 - `x0,y0`线的起点 - `x1,y1`线的终点 - drawHLine(x,y,w) 画一条水平线 - `x,y`线的起点 - `w`水平线的长度(宽度) - drawVLine(x,y,h) 画一条竖直线 - `x,y`线的起点 - `h`竖直线的长度(高度) 测试函数: ```c //画直线 void testDrawLine() { int t = 500; u8g2.clearBuffer(); u8g2.drawStr(33, 14, "drawLine"); u8g2.drawLine(0, 0, 127, 63); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawLine(0, 0, 127, 0); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawLine(32, 15, 127, 15); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawLine(33, 16, 127, 16); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawLine(127, 0, 127, 15); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawLine(127, 16, 127, 63); SEND_BUFFER_DISPLAY_MS(t); } ``` 显示效果如下面的左上图: ![](https://cf05.ickimg.com/bbsimages/202203/aa908fdcf518dddff37aa3407af43d59.png) ## 4.4 画空心/实心(圆角)矩形 - drawFrame(x,y,w,h) 绘制一个空心框 - drawBox(x,y,w,h) 绘制一个实心矩形 - drawRFrame(x,y,w,h,r) 绘制一个空心框(圆角) - drawRBox(x,y,w,h,r) 绘制一个实心矩形 (圆角) - `x,y`起点坐标 - `w,h`框的宽度和高度 - `r`圆角的半径 测试函数: ```c //画空心圆角矩形 void testDrawRFrame() { int t = 500; int x = 16; int y = 32; int w = 50; int h = 20; int r = 3; u8g2.clearBuffer(); u8g2.drawStr(0, 15, "drawRFrame"); u8g2.drawRFrame(x, y, w, h, r); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawRFrame(x+w+5, y-10, w-20, h+20, r); SEND_BUFFER_DISPLAY_MS(t); } ``` 显示效果如下面的右下图: ![](https://cf05.ickimg.com/bbsimages/202203/930787663233405edb60324911df68f3.png) ## 4.5 画空心/实心圆 - drawCircle(x,y,rad,opt) 绘制一个空心圆 - drawDisc(x,y,rad,opt) 绘制一个实心圆 - `x,y`为圆心坐标 - `rad`为圆的半径 - `opt`为选择画的部分,分为: - `U8G2_DRAW_UPPER_RIGHT`(右上) - `U8G2_DRAW_UPPER_LEFT`(左上) - `U8G2_DRAW_LOWER_LEFT`(左下) - `U8G2_DRAW_LOWER_RIGHT`(右下) - `U8G2_DRAW_ALL`(全部) 空心圆 ```c //画空心圆 void testDrawCircle() { int t = 500; int stx = 0; //画图起始x int sty = 16; //画图起始y int with = 16;//一个图块的间隔 int r = 15; //圆的半径 u8g2.clearBuffer(); u8g2.drawStr(0, 15, "drawCircle"); u8g2.drawCircle(stx, sty - 1 + with, r, U8G2_DRAW_UPPER_RIGHT); //右上 SEND_BUFFER_DISPLAY_MS(t); u8g2.drawCircle(stx + with, sty, r, U8G2_DRAW_LOWER_RIGHT); //右下 SEND_BUFFER_DISPLAY_MS(t); u8g2.drawCircle(stx - 1 + with * 3, sty - 1 + with, r, U8G2_DRAW_UPPER_LEFT); //左上 SEND_BUFFER_DISPLAY_MS(t); u8g2.drawCircle(stx - 1 + with * 4, sty, r, U8G2_DRAW_LOWER_LEFT); //左下 SEND_BUFFER_DISPLAY_MS(t); u8g2.drawCircle(stx - 1 + with * 2, sty - 1 + with * 2, r, U8G2_DRAW_ALL);//整个圆 SEND_BUFFER_DISPLAY_MS(t); } ``` 显示效果如下面的左图: ![](https://cf05.ickimg.com/bbsimages/202203/269fec7b4816e864ddc8b8fdb640bfe3.png) 注意,**U8g2库画出的圆,因像素点的显示原理,圆的直径占用的宽度不是半径的2倍,而是2倍再加一个像素点**。 ## 4.6 画空心/实心椭圆 - drawEllipse(x,y,rx,ry,opt) 绘制一个空心椭圆 - drawFilledEllipse(x,y,rx,ry,opt) 绘制一个实心椭圆 - `x,y`为圆心坐标 - `rx,ry`为与椭圆x和y方向的半径 - `opt`与画圆时的作用一致 椭圆的显示与圆的显示类似,只是椭圆可以分别指定x和y方向的半径 ![](https://cf05.ickimg.com/bbsimages/202203/cd0651aeea2a1b8d1b11b1652029d0f6.png) ## 4.7 字符串、汉字和变量显示 字符串的显示,可以使用drawStr函数,也可以使用通用风格的print函数。 - drawStr(x,y,string) 绘制一个字符串 - `x,y`起点坐标 - `string`字符串 如果想要使用print**显示汉字**,需要先设置如下两句: ```c u8g2.enableUTF8Print();//enable UTF8 u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集 ``` 如果想要**显示变量**,使用print函数即可: 字符串、汉字、变量的测试函数如下: ```c //字符串/文字/变量显示测试 void testDrawStr() { int t = 1000; u8g2.clearBuffer(); u8g2.drawStr(0, 14, "drawStr / print"); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawStr(0, 32, "~!@#$%^&*()_+"); SEND_BUFFER_DISPLAY_MS(t); u8g2.enableUTF8Print();//enable UTF8 u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集 u8g2.setCursor(0, 48); u8g2.print("码农爱学习"); SEND_BUFFER_DISPLAY_MS(t); int a = 234; u8g2.setCursor(0, 64); u8g2.print("int a="); u8g2.setCursor(40, 64); u8g2.print(a);//显示变量 SEND_BUFFER_DISPLAY_MS(t); } ``` 显示效果: ![](https://cf05.ickimg.com/bbsimages/202203/6a002bc3d68e25e58fc5bcfae54a5082.png) ## 4.8 画内置图标 - drawGlyph(x,y,addr) 绘制U8g2内置的图标 - `x,y`起点坐标 - `addr`内置图标的地址 U8g2库内置了需要预先定义的图形,通过**drawGlyp函数**以及指定的地址,即可看OLED上显示对应的图标: 各个图形的地址定义如下: ![](https://cf05.ickimg.com/bbsimages/202203/294eb0038b7fe62e787f83cc9830531a.png) 编写一个测试程序: ```c void testGlyph() { int t = 1000; u8g2.clearBuffer(); u8g2.drawStr(0, 14, "drawGlyph"); u8g2.drawGlyph(0, 32, 0x23f0); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawGlyph(16, 32, 0x23f3); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawGlyph(32, 32, 0x2603); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawGlyph(48, 32, 0x2615); SEND_BUFFER_DISPLAY_MS(t); u8g2.drawGlyph(64, 32, 0x2618); SEND_BUFFER_DISPLAY_MS(t); } ``` 测试效果如下: ![](https://cf05.ickimg.com/bbsimages/202203/c1e6050b36a76dee894a9869ef607740.png) ## 4.9 画自定义图片 - drawXBM(x,y,w,h,addr) 绘制一个实心矩形 (圆角) - `x,y`起点坐标 - `w,h`图片的宽度和高度` - `addr`图片(数组)的地址 **自定义图片的显示,需要先将图形转换为数组**,可以使用如下工具进行图片到数组的转换: https://tools.clz.me/image-to-bitmap-array ![](https://cf05.ickimg.com/bbsimages/202203/a419a7287a9a7baf9d46ce9e43634881.png) 编写测试程序: ```c // width: 128, height: 48 const unsigned char bilibili[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ... 省略若干行 }; void testDrawXBM() { int t = 1000; u8g2.clearBuffer(); u8g2.drawStr(0, 14, "drawXBM"); u8g2.drawXBM(0, 16, 128, 48, bilibili); SEND_BUFFER_DISPLAY_MS(t); } ``` 效果如下: ![](https://cf05.ickimg.com/bbsimages/202203/832e6bdd6b470fd2c1251ad7b8cdfd1e.png) # 5 总结 本篇介绍了ESP8266的引脚定义以及U8g2库在OLED的使用基础,并重点介绍了U8g2库的各种画图函数,这个函数总结下来如下下表所示: ![](https://cf05.ickimg.com/bbsimages/202203/bf898598e63a57555aba0fcab9723253.png) 借助U8g2库,可以十分方便的在OLED上进行图形的显示。
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
码农爱学习
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交