【实例演示】ESP8266+U8g2库,玩转OLED显示

上篇文章,介绍了esp8266在arduino ide中的基础使用方法,本篇,来继续学习oled显示屏如何使用esp8266来控制。
1 esp8266引脚 首先来看一下esp8266的引脚定义,因为本篇需要外接oled,就要先看看esp8266具有哪些功能的引脚。
esp8266的引脚定义如下:
可以看出,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线接线更方便。
本篇使用最为常用的0.96寸的oled,分辨率128x64,黄蓝双色。
注意这里的双色,不是值一个像素点可以显示两种颜色,而是屏幕的上部1/4只能显示黄色,下部的3/4只能显示蓝色,并且黄色和蓝色之间,不是紧密靠在一起的,而是有约一个像素点的间隙。
3 u8g2库简介与安装 3.1 u8g2库简介 u8g2 是一个用于嵌入式设备的单色图形库。u8g2支持单色oled和lcd,并支持如ssd1306等多种类型的oled驱动。
u8g2源码的开源库地址:https://github.com/olikraus/u8g2
u8g2专为arduino提供的方便安装的库地址:https://github.com/olikraus/u8g2_arduino
想要研究u8g2源码的可以看看这里的源代码,c和c++写的。
比如画直线这个函数和具体实现如下:
3.2 u8g2库安装 和上篇介绍esp8266库的安装类似, u8g2库的安装也有两种方式:
在线安装
在线安装,在arduino ide的菜单的“项目->加载库->管理库”中搜索u8g2后安装即可,对网络环境要求较高
源码安装
将u8g2专为arduino提供的库(https://github.com/olikraus/u8g2_arduino)整个下载下来,然后还是在arduino ide的菜单的“项目->加载库”中选择“添加.zip库...”,然后选到你刚下载的u8g2_arduino源码文件夹后即可安装,也十分的方便。
3.3 u8g2库的基础使用 使用u8g2库进行oled的显示十分简单,首先要包含两个库,u8g2lib和wire,后者是iic通信需要用。
对于iic接口的oled,需要在程序中指定一下引脚的接口定义,如果是spi接口,可以参考u8g2库自带例程中spi接口是使用方法。
然后在ardunio的setup中进行u8g2的初始化。
最后在ardunio的loop中就可以编写自己的逻辑了。
另外,u8g2库在loop中的通用写法是使用do{}while()的形式:
u8g2.firstpage(); do { //自己的的逻辑 } while (u8g2.nextpage()); delay(1000); 一个简单的helloword在oled中的显示如下:
#include #include #define scl 5#define sda 4u8g2_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),字符串实际是到屏幕外面了,不会显示!
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)
只有指定位置即可显示像素点,比如把所有的点都显示出来:
//画像素点-填充屏幕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);} 效果如下面的右图:
注意测试程序中,我定义了一个宏定义,用于延时显示每一次的画图,方便观察oled的显示过程:
#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竖直线的长度(高度)
测试函数:
//画直线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);} 显示效果如下面的左上图:
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圆角的半径
测试函数:
//画空心圆角矩形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);} 显示效果如下面的右下图:
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(全部)
空心圆
//画空心圆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);} 显示效果如下面的左图:
注意,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方向的半径
4.7 字符串、汉字和变量显示 字符串的显示,可以使用drawstr函数,也可以使用通用风格的print函数。
drawstr(x,y,string) 绘制一个字符串
x,y起点坐标
string字符串
如果想要使用print显示汉字,需要先设置如下两句:
如果想要显示变量,使用print函数即可:
字符串、汉字、变量的测试函数如下:
//字符串/文字/变量显示测试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);} 显示效果:
4.8 画内置图标 drawglyph(x,y,addr) 绘制u8g2内置的图标
x,y起点坐标
addr内置图标的地址
u8g2库内置了需要预先定义的图形,通过drawglyp函数以及指定的地址,即可看oled上显示对应的图标:
各个图形的地址定义如下:
编写一个测试程序:
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);} 测试效果如下:
4.9 画自定义图片 drawxbm(x,y,w,h,addr) 绘制一个实心矩形 (圆角)
x,y起点坐标
w,h图片的宽度和高度`
addr图片(数组)的地址
自定义图片的显示,需要先将图形转换为数组,可以使用如下工具进行图片到数组的转换:
https://tools.clz.me/image-to-bitmap-array
编写测试程序:
// width: 128, height: 48const 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);} 效果如下:
5 总结 本篇介绍了esp8266的引脚定义以及u8g2库在oled的使用基础,并重点介绍了u8g2库的各种画图函数,这个函数总结下来如下下表所示:
借助u8g2库,可以十分方便的在oled上进行图形的显示。

区块链是一条失信的不归路吗
如何才能找到一个有潜力和才能的区块链开发人员
数字化地理信息的电磁环境信号发生技术的思想、方法和发展现状介绍
芯片销售基本流程
高端电力电子器件弥补差距仍需创新突破
【实例演示】ESP8266+U8g2库,玩转OLED显示
Xilinx FPGA解决方案的优势在哪里
隔离型Cuk变换器电路
虹科教您派固定工业树莓派Modbus RTU设备编号
如何对PNET 模拟器进行初始化安装
车规MCU选型的9大注意事项
浅谈2019年全球TV面板产业的机遇和挑战
iPhone11系列暗夜绿受欢迎程度最高
蓝牙耳机哪个品牌比较好,哪款蓝牙耳机2023年值得买,排行榜推荐
直接存储器存取(DMA)简介及程序设计
默克看好中国半导体发展,考虑进行更深度布局
SMIT率先推出CI Plus 2.0 CAM
MathWorks网络研讨会:使用MATLAB及Simulink启动软件定义无线电的开发
HSDPA基站部署及容量分析
土壤紧实度测定仪的功能是什么