找回密码
 立即注册
搜索
0赞
赞赏
手机版
扫码打开手机版
把文字装进口袋

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

有个胖子他姓杨 2022-8-4 10:54:37
上篇文章,介绍了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()的形式:
  1.   u8g2.firstPage();
  2.   do
  3.   {
  4.     //自己的的逻辑
  5.   } while (u8g2.nextPage());
  6.   delay(1000);
复制代码
一个简单的HelloWord在OLED中的显示如下:
  1. #include
  2. #include
  3. #define SCL 5
  4. #define SDA 4
  5. U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE);   
  6. void setup()
  7. {
  8.   u8g2.begin();
  9.   u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
  10. }
  11. void loop()
  12. {
  13.   u8g2.setFont(u8g2_font_unifont_t_symbols);
  14.   u8g2.firstPage();
  15.   do
  16.   {
  17.     u8g2.setCursor(0, 15); //指定显示位置
  18.     u8g2.print("Hello World!"); //使用print来显示字符串
  19.   } while (u8g2.nextPage());
  20.   delay(1000);
  21. }
复制代码
注意,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)
        只有指定位置即可显示像素点,比如把所有的点都显示出来:
  1. //画像素点-填充屏幕
  2. void testDrawPixelToFillScreen()
  3. {
  4.   int t = 1000;
  5.   u8g2.clearBuffer();
  6.   for (int j = 0; j < 64; j++)
  7.   {
  8.     for (int i = 0; i < 128; i++)
  9.     {
  10.       u8g2.drawPixel(i, j);
  11.     }
  12.   }
  13.   SEND_BUFFER_DISPLAY_MS(t);
  14. }
复制代码
效果如下面的右图:
        注意测试程序中,我定义了一个宏定义,用于延时显示每一次的画图,方便观察OLED的显示过程:
  1. #define SEND_BUFFER_DISPLAY_MS(ms)
  2.   do {
  3.     u8g2.sendBuffer();
  4.     delay(ms);
  5.   }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竖直线的长度(高度)
        测试函数:
  1. //画直线
  2. void testDrawLine()
  3. {
  4.   int t = 500;
  5.   u8g2.clearBuffer();
  6.   u8g2.drawStr(33, 14, "drawLine");
  7.   u8g2.drawLine(0, 0, 127, 63);
  8.   SEND_BUFFER_DISPLAY_MS(t);
  9.   u8g2.drawLine(0, 0, 127, 0);
  10.   SEND_BUFFER_DISPLAY_MS(t);
  11.   u8g2.drawLine(32, 15, 127, 15);
  12.   SEND_BUFFER_DISPLAY_MS(t);
  13.   u8g2.drawLine(33, 16, 127, 16);
  14.   SEND_BUFFER_DISPLAY_MS(t);
  15.   u8g2.drawLine(127, 0, 127, 15);
  16.   SEND_BUFFER_DISPLAY_MS(t);
  17.   u8g2.drawLine(127, 16, 127, 63);
  18.   SEND_BUFFER_DISPLAY_MS(t);
  19. }
复制代码
显示效果如下面的左上图:
        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圆角的半径
        测试函数:
  1. //画空心圆角矩形
  2. void testDrawRFrame()
  3. {
  4.   int t = 500;
  5.   int x = 16;
  6.   int y = 32;
  7.   int w = 50;
  8.   int h = 20;
  9.   int r = 3;
  10.   u8g2.clearBuffer();
  11.   u8g2.drawStr(0, 15, "drawRFrame");
  12.   u8g2.drawRFrame(x, y, w, h, r);
  13.   SEND_BUFFER_DISPLAY_MS(t);
  14.   u8g2.drawRFrame(x+w+5, y-10, w-20, h+20, r);
  15.   SEND_BUFFER_DISPLAY_MS(t);
  16. }
复制代码
显示效果如下面的右下图:
       
        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(全部)
        空心圆
  1. //画空心圆
  2. void testDrawCircle()
  3. {
  4.   int t = 500;
  5.   int stx = 0;  //画图起始x
  6.   int sty = 16; //画图起始y
  7.   int with = 16;//一个图块的间隔
  8.   int r = 15;   //圆的半径
  9.   u8g2.clearBuffer();
  10.   u8g2.drawStr(0, 15, "drawCircle");
  11.   u8g2.drawCircle(stx, sty - 1 + with, r, U8G2_DRAW_UPPER_RIGHT); //右上
  12.   SEND_BUFFER_DISPLAY_MS(t);
  13.   u8g2.drawCircle(stx + with, sty, r, U8G2_DRAW_LOWER_RIGHT); //右下
  14.   SEND_BUFFER_DISPLAY_MS(t);
  15.   u8g2.drawCircle(stx - 1 + with * 3, sty - 1 + with, r, U8G2_DRAW_UPPER_LEFT); //左上
  16.   SEND_BUFFER_DISPLAY_MS(t);
  17.   u8g2.drawCircle(stx - 1 + with * 4, sty, r, U8G2_DRAW_LOWER_LEFT); //左下
  18.   SEND_BUFFER_DISPLAY_MS(t);
  19.   u8g2.drawCircle(stx - 1 + with * 2, sty - 1 + with * 2, r, U8G2_DRAW_ALL);//整个圆
  20.   SEND_BUFFER_DISPLAY_MS(t);
  21. }
复制代码
显示效果如下面的左图:
        注意,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函数即可:
        字符串、汉字、变量的测试函数如下:
  1. //字符串/文字/变量显示测试
  2. void testDrawStr()
  3. {
  4.   int t = 1000;
  5.   u8g2.clearBuffer();
  6.   u8g2.drawStr(0, 14, "drawStr / print");
  7.   SEND_BUFFER_DISPLAY_MS(t);
  8.   u8g2.drawStr(0, 32, "~!@#$%^&*()_+");
  9.   SEND_BUFFER_DISPLAY_MS(t);
  10.   u8g2.enableUTF8Print();//enable UTF8
  11.   u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集
  12.   u8g2.setCursor(0, 48);
  13.   u8g2.print("码农爱学习");
  14.   SEND_BUFFER_DISPLAY_MS(t);
  15.   int a = 234;
  16.   u8g2.setCursor(0, 64);
  17.   u8g2.print("int a = ");
  18.   u8g2.setCursor(40, 64);
  19.   u8g2.print(a);//显示变量
  20.   SEND_BUFFER_DISPLAY_MS(t);
  21. }
复制代码
显示效果:
        4.8 画内置图标

        drawGlyph(x,y,addr) 绘制U8g2内置的图标
        x,y起点坐标
        addr内置图标的地址
        U8g2库内置了需要预先定义的图形,通过drawGlyp函数以及指定的地址,即可看OLED上显示对应的图标:
        各个图形的地址定义如下:
        编写一个测试程序:
  1. void testGlyph()
  2. {
  3.   int t = 1000;
  4.   u8g2.clearBuffer();
  5.   u8g2.drawStr(0, 14, "drawGlyph");
  6.   u8g2.drawGlyph(0, 32, 0x23f0);
  7.   SEND_BUFFER_DISPLAY_MS(t);
  8.   u8g2.drawGlyph(16, 32, 0x23f3);
  9.   SEND_BUFFER_DISPLAY_MS(t);
  10.   u8g2.drawGlyph(32, 32, 0x2603);
  11.   SEND_BUFFER_DISPLAY_MS(t);
  12.   u8g2.drawGlyph(48, 32, 0x2615);
  13.   SEND_BUFFER_DISPLAY_MS(t);
  14.   u8g2.drawGlyph(64, 32, 0x2618);
  15.   SEND_BUFFER_DISPLAY_MS(t);
  16. }
复制代码
测试效果如下:
        4.9 画自定义图片

        drawXBM(x,y,w,h,addr) 绘制一个实心矩形 (圆角)
        x,y起点坐标
        w,h图片的宽度和高度`
        addr图片(数组)的地址
        自定义图片的显示,需要先将图形转换为数组,可以使用如下工具进行图片到数组的转换:
        https://tools.clz.me/image-to-bitmap-array
        编写测试程序:
  1. // width: 128, height: 48
  2. 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, ... 省略若干行 };
  3. void testDrawXBM()
  4. {
  5.   int t = 1000;
  6.   u8g2.clearBuffer();
  7.   u8g2.drawStr(0, 14, "drawXBM");
  8.   u8g2.drawXBM(0, 16, 128, 48, bilibili);
  9.   SEND_BUFFER_DISPLAY_MS(t);
  10. }
复制代码
效果如下:
       
        5 总结

        本篇介绍了ESP8266的引脚定义以及U8g2库在OLED的使用基础,并重点介绍了U8g2库的各种画图函数,这个函数总结下来如下下表所示:
        借助U8g2库,可以十分方便的在OLED上进行图形的显示。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

使用道具 举报

您需要登录后才可以回帖 立即登录
谢谢楼主,,,收藏ing
2022-8-5 02:30:27
顶起  很好的帖
2022-8-5 18:06:16
2022-8-7 10:42:18
顶一个了
2022-8-8 09:51:34
必须支持。。。。。。。
2022-8-9 09:00:49
好像还不错!
2022-8-10 14:40:49
支持你们一下下哈
2022-8-11 20:20:48
太赞了
2022-8-12 05:41:35
学习了,这就去试试
2022-8-14 10:48:40
12下一页
返回顶部