Bootstrap

Arduino ESP8266 使用u8g2图形库 IIC驱动 SSD1306_0.96寸 OLED

一:安装Arduino

二:安装ESP8266开发包

三:u8g2库的简介与安装

u8g2简介:

U8g2 是一个用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,并支持如SSD1306等多种类型的OLED驱动。

u8g2的安装:

我们可以直接在Arduino的库管理中搜索和安装:(对网络环境要求较高)

 我们也可以直接去下载源码然后导入:

四: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);

接下来是一个简单的显示示例:

#include <U8g2lib.h>
#include <Wire.h>

#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),字符串实际是到屏幕外面了,不会显示!

五:U8g2常用API函数  

5.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(异或模式)   

5.2: 画像素点

  • drawPixel(x,y) 

可以设置指定坐标显示画点,例如我们可以显示所有的点:

#include <U8g2lib.h>
#include <Wire.h>

#define SCL 5
#define SDA 4
//定义了一个宏定义,用于延时显示每一次的画图,方便观察OLED的显示过程:
#define SEND_BUFFER_DISPLAY_MS(ms)\
  do {\
    u8g2.sendBuffer(); \
    delay(ms);\
  }while(0);

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 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);
}
void loop()
{
  testDrawPixelToFillScreen();

}


5.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);
}

 5.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);
}

5.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倍再加一个像素点

5.6:画空心/实心椭圆

  • drawEllipse(x,y,rx,ry,opt) 绘制一个空心椭圆
  • drawFilledEllipse(x,y,rx,ry,opt) 绘制一个实心椭圆
    • x,y为圆心坐标
    • rx,ry为与椭圆x和y方向的半径
    • opt与画圆时的作用一致

椭圆的显示与圆的显示类似,只是椭圆可以分别指定x和y方向的半径 

 5.7:字符串、汉字和变量显示:

字符串的显示,可以使用drawStr函数,也可以使用通用风格的print函数。

  • drawStr(x,y,string) 绘制一个字符串
    • x,y起点坐标
    • string字符串

 如果想要使用print显示汉字,需要先设置如下两句:

u8g2.enableUTF8Print();//enable UTF8
u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集

如果想要显示变量,使用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);
}

5.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);
}

 5.9:画自定义图片

  • drawXBM(x,y,w,h,addr) 绘制一个实心矩形 (圆角)
    • x,y起点坐标
    • w,h图片的宽度和高度`
    • addr图片(数组)的地址

自定义图片的显示,需要先将图形转换为数组

测试程序:

// 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);
}

总结: 

 

;