玩轉(zhuǎn) ESP32 + Arduino (八) U8G2驅(qū)動OLED

OLED驅(qū)動芯片:SSD1306
開發(fā)平臺: vscode+platformIO
開發(fā)板:ESP32 Divkit v1

目前Arduino平臺上使用最廣泛的OLED庫: U8G2
github地址: https://github.com/olikraus/u8g2/

設(shè)置和參考手冊:https://github.com/olikraus/u8g2/wiki

U8g2:單色顯示器庫,版本2

U8g2是用于嵌入式設(shè)備的單色圖形庫。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(完整列表請參見此處)。

為什么要運(yùn)用U8g2庫?

  • U8g2庫平臺支持性好,基本上支持絕大部分Arduino開發(fā)板;
  • U8g2庫顯示控制器支持性好,基本上市面上的OLED都完美支持;
  • U8g2庫 API眾多,特別支持了中文,支持了不同字體,這是一個對于開發(fā)者倆說不小的福利。

支持單片機(jī)平臺:

一. u8g2的安裝

再platformIO.ini中配置庫

lib_deps =
  # Using a library name
  U8g2

二. u8g2函數(shù)庫

方法可以分為四大類:

  • 基本函數(shù)
  • 繪制相關(guān)函數(shù)
  • 顯示配置相關(guān)函數(shù)
  • 緩存相關(guān)函數(shù)

U8g2庫函數(shù)詳解

三. 基本函數(shù)

?1. u8g2.begin() —— 構(gòu)造U8G2

初始化顯示器, 清屏, 喚醒屏幕

/**
 * 初始化U8g2庫
 * @Note 關(guān)聯(lián)方法 initDisplay clearDisplay setPowerSave
 */
bool U8G2::begin(void)

2. u8g2.beginSimple() —— 構(gòu)造U8G2

只是初始化顯示器, 并不清屏, 也不喚醒屏幕

3. u8g2.initDisplay() —— 初始化顯示控制器

/**
 * 初始化顯示控制器
 */
void U8G2::initDisplay(void)

4. u8g2.clearDisplay() —— 清除屏幕內(nèi)容

/**
 * 清除屏幕
 */
void U8G2::clearDisplay(void)

?5. u8g2.setPowerSave() —— 是否開啟省電模式

/**
 * 清除顯示緩沖區(qū)
 * @param is_enable
 *        1 表示啟用顯示器的省電模式,屏幕上看不到任何東西
 *        0 表示禁用省電模式
 */
void U8G2::setPowerSave(uint8_t is_enable)

?6. u8g2.clear() —— 清除操作

/**
 * 清除屏幕顯示,清除緩沖區(qū),光標(biāo)回到左上角原點(diǎn)位置(0,0)
 * @Note 關(guān)聯(lián)方法 home clearDisplay clearBuffer
 */
void U8G2::clear(void)

?7. u8g2.clearBuffer() —— 清除緩沖區(qū)

/**
 * 清除內(nèi)存中數(shù)據(jù)緩沖區(qū)
 */
void U8G2::clearBuffer(void)

8. u8g2.disableUTF8Print() —— 禁用 UTF8打印

/**
 * 禁用Arduino平臺下支持輸出UTF8字符集,默認(rèn)是開啟
 */
void U8G2::disableUTF8Print(void)

9. u8g2.enableUTF8Print() —— 啟用 UTF8打印

/**
 * 開啟Arduino平臺下支持輸出UTF8字符集
 */
void U8G2::enableUTF8Print(void)

開啟UTF-8后,我們可以使用其UTF-8字庫

#include <Arduino.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping

void setup(void)
{
  u8g2.begin();
  u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
}
void loop(void)
{
  u8g2.setFont(u8g2_font_unifont_t_chinese2); // use chinese2
  u8g2.firstPage();
  do
  {
    u8g2.setCursor(0, 20);
    u8g2.print("helloworld"); // Chinese "Hello World"
    u8g2.setCursor(0, 40);
    u8g2.print("你好世界"); // Chinese "Hello World"
  } while (u8g2.nextPage());
  delay(1000);
}

10. u8g2.home() —— 重置顯示光標(biāo)的位置

/**
 * 重置顯示光標(biāo)的位置,回到原點(diǎn)(0,0)
 * @Note 關(guān)聯(lián)方法 print clear
 */
void U8G2::home(void)

四. 繪制相關(guān)函數(shù)

1. u8g2.drawBox() —— 畫實(shí)心方形

/**
 * 畫實(shí)心方形,左上角坐標(biāo)為(x,y),寬度為w,高度為h
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param w 方形的寬度
 * @param h 方形的高度
 * @Note 關(guān)聯(lián)方法 drawFrame setDrawColor
 */
void U8G2::drawBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)

如果支持繪制顏色(也就是不是單色顯示器),那么由setDrawColor設(shè)置;

#include <Arduino.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping

void setup(void)
{
  u8g2.begin();
}
void loop(void)
{
  u8g2.drawBox(3,7,25,15);
  u8g2.sendBuffer();
  delay(1000);
}

2. u8g2.drawCircle() —— 畫空心圓

/**
 * 畫空心圓,圓心坐標(biāo)為(x0,y0),半徑為rad
 * @param x0 圓點(diǎn)的x坐標(biāo)
 * @param y0 圓點(diǎn)的y坐標(biāo)
 * @param rad 圓形的半徑
 * @param opt 圓形選項
 *        U8G_DRAW_ALL 整個圓
 *        U8G2_DRAW_UPPER_RIGHT 右上部分的圓弧
 *        U8G2_DRAW_UPPER_LEFT  左上部分的圓弧
 *        U8G2_DRAW_LOWER_LEFT  左下部分的圓弧
 *        U8G2_DRAW_LOWER_RIGHT 右下部分的圓弧
 *        選項可以通過 | 操作符來組合
 * @Note 關(guān)聯(lián)方法 drawDisc setDrawColor
 */
void U8G2::drawCircle(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G2_DRAW_ALL)
  • 如果支持繪制顏色(也就是不是單色顯示器),那么由setDrawColor設(shè)置;
  • 直徑等于2rad + 1;

例: 畫圓動畫 (4幀????????)

#include <Arduino.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping

void setup(void)
{
  u8g2.begin();
}
void loop(void)
{
  u8g2.clear();
  u8g2.drawCircle(64, 32, 25, U8G2_DRAW_UPPER_RIGHT);
  u8g2.sendBuffer();
  delay(1000);
  u8g2.drawCircle(64, 32, 25, U8G2_DRAW_LOWER_RIGHT);
  u8g2.sendBuffer();
  delay(1000);
  u8g2.drawCircle(64, 32, 25, U8G2_DRAW_LOWER_LEFT);
  u8g2.sendBuffer();
  delay(1000);
  u8g2.drawCircle(64, 32, 25, U8G2_DRAW_UPPER_LEFT);
  u8g2.sendBuffer();
  delay(1000);
}

3. u8g2.drawDisc() —— 畫實(shí)心圓

/**
 * 畫實(shí)心圓,圓心坐標(biāo)為(x0,y0),半徑為rad
 * @param x0 圓點(diǎn)的x坐標(biāo)
 * @param y0 圓點(diǎn)的y坐標(biāo)
 * @param rad 圓形的半徑
 * @param opt 圓形選項
 *        U8G_DRAW_ALL 整個圓
 *        U8G2_DRAW_UPPER_RIGHT 右上部分的圓弧
 *        U8G2_DRAW_UPPER_LEFT  左上部分的圓弧
 *        U8G2_DRAW_LOWER_LEFT  左下部分的圓弧
 *        U8G2_DRAW_LOWER_RIGHT 右下部分的圓弧
 *       選項可以通過 | 操作符來組合
 * @Note 關(guān)聯(lián)方法 drawCircle setDrawColor
 */
void U8G2::drawDisc(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G_DRAW_ALL)
  • 如果支持繪制顏色(也就是不是單色顯示器),那么由setDrawColor設(shè)置;
  • 直徑等于2rad + 1;

4. u8g2.drawEllipse() —— 畫空心橢圓

/**
 * 畫空心橢圓,圓心坐標(biāo)為(x0,y0),半徑為rad
 * @param x0 圓點(diǎn)的x坐標(biāo)
 * @param y0 圓點(diǎn)的y坐標(biāo)
 * @param rx 橢圓形水平x方向的半徑
 * @param ry 橢圓形豎直y方向的半徑
 * @param opt 圓形選項
 *        U8G_DRAW_ALL 整個橢圓
 *        U8G2_DRAW_UPPER_RIGHT 右上部分的圓弧
 *        U8G2_DRAW_UPPER_LEFT  左上部分的圓弧
 *        U8G2_DRAW_LOWER_LEFT  左下部分的圓弧
 *        U8G2_DRAW_LOWER_RIGHT 右下部分的圓弧
 *        選項可以通過 | 操作符來組合
 * @Note 關(guān)聯(lián)方法 drawCircle
 */
void U8G2::drawEllipse(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t opt)

5. u8g2.drawFilledEllipse() —— 畫實(shí)心橢圓

/**
 * 畫實(shí)心橢圓,圓心坐標(biāo)為(x0,y0),半徑為rad
 * @param x0 圓點(diǎn)的x坐標(biāo)
 * @param y0 圓點(diǎn)的y坐標(biāo)
 * @param rx 橢圓形水平x方向的半徑
 * @param ry 橢圓形豎直y方向的半徑
 * @param opt 圓形選項
 *        U8G_DRAW_ALL 整個橢圓
 *        U8G2_DRAW_UPPER_RIGHT 右上部分的圓弧
 *        U8G2_DRAW_UPPER_LEFT  左上部分的圓弧
 *        U8G2_DRAW_LOWER_LEFT  左下部分的圓弧
 *        U8G2_DRAW_LOWER_RIGHT 右下部分的圓弧
 *        選項可以通過 | 操作符來組合
 * @Note 關(guān)聯(lián)方法 drawCircle
 */
void U8G2::drawFilledEllipse(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t opt)

6. u8g2.drawFrame() —— 畫空心方形

/**
 * 畫空心方形,左上角坐標(biāo)為(x,y),寬度為w,高度為h
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param w 方形的寬度
 * @param h 方形的高度
 * @Note 關(guān)聯(lián)方法 setDrawColor
 */
void U8G2::drawFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)

7. u8g2.drawGlyph() —— 繪制字體字集的符號

/**
 * 繪制字體字集里面定義的符號
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param encoding 字符的unicode值
 * @Note 關(guān)聯(lián)方法 setFont
 */
void U8G2::drawGlyph(u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)

8. u8g2.drawHLine() —— 繪制水平線

/**
 * 繪制水平線
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param w 水平線的長度
 * @Note 關(guān)聯(lián)方法 setDrawColor
 */
 void U8G2::drawHLine(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)

9. u8g2.drawLine() —— 兩點(diǎn)之間繪制線

/**
 * 繪制線,從坐標(biāo)(x0,y0) 到(x1,y1)
 * @param x0 端點(diǎn)0的x坐標(biāo)
 * @param y0 端點(diǎn)0的y坐標(biāo)
 * @param x1 端點(diǎn)1的x坐標(biāo)
 * @param y1 端點(diǎn)1的y坐標(biāo)
 * @Note 關(guān)聯(lián)方法 setDrawColor
 */
 void U8G2::drawLine(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1)

10. u8g2.drawPixel() —— 繪制像素點(diǎn)

/**
 * 繪制像素點(diǎn),坐標(biāo)(x,y)
 * @param x 像素點(diǎn)的x坐標(biāo)
 * @param y 像素點(diǎn)的y坐標(biāo)
 * @Note 關(guān)聯(lián)方法 setDrawColor
 */
void U8G2::drawPixel(u8g2_uint_t x, u8g2_uint_t y)
  • 我們可以利用這個繪制方法自定義自己的圖形顯示

11. u8g2.drawRBox() —— 繪制圓角實(shí)心方形

/**
 * 繪制圓角實(shí)心方形,左上角坐標(biāo)為(x,y),寬度為w,高度為h,圓角半徑為r
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param w 方形的寬度
 * @param h 方形的高度
 * @param r 圓角半徑
 */
void U8G2::drawRBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)

12. u8g2.drawRFrame() —— 繪制圓角空心方形

/**
 * 繪制圓角空心方形,左上角坐標(biāo)為(x,y),寬度為w,高度為h,圓角半徑為r
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param w 方形的寬度
 * @param h 方形的高度
 * @param r 圓角半徑
 */
void U8G2::drawRFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)

13. u8g2.drawStr() —— 繪制字符串

/**
 * 繪制字符串
 * @param x 左上角的x坐標(biāo)
 * @param y 左上角的y坐標(biāo)
 * @param s 繪制字符串內(nèi)容
 * @return 字符串的長度
 */
u8g2_uint_t U8g2::drawStr(u8g2_uint_t x, u8g2_uint_t y, const char *s)
  • 需要先設(shè)置字體,調(diào)用setFont方法;
  • 這個方法不能繪制encoding超過256的,超過256需要用drawUTF8或者drawGlyph;說白了就是一般用來顯示英文字符;
  • x,y屬于字符串左下角的坐標(biāo);

14. u8g2.drawTriangle() —— 繪制實(shí)心三角形

/**
 * 繪制實(shí)心三角形,定點(diǎn)坐標(biāo)分別為(x0,y0),(x1,y1),(x2,y2)
 */
void U8G2::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) 

15. u8g2.drawUTF8() —— 繪制UTF8編碼的字符

/**
 * 繪制UTF8編碼的字符串
 * @param x 字符串在屏幕上的左下角x坐標(biāo)
 * @param y 字符串在屏幕上的左下角y坐標(biāo)
 * @param s 需要繪制的UTF-8編碼字符串
 * @return 返回字符串的長度
 */
u8g2_uint_t U8g2::drawUTF8(u8g2_uint_t x, u8g2_uint_t y, const char *s)

16. u8g2.drawVLine() —— 繪制豎直線

/**
 * 繪制豎直線
 * @param x 左上角坐標(biāo)x
 * @param y 左上角坐標(biāo)y
 * @param h 高度
 */
void U8G2::drawVLine(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t h) 

?17. u8g2.drawXBM()/drawXBMP() —— 繪制圖像

/**
 * 繪制圖像
 * @param x 左上角坐標(biāo)x
 * @param y 左上角坐標(biāo)y
 * @param w 圖形寬度
 * @param h 圖形高度
 * @param bitmap 圖形內(nèi)容
 * @Note 關(guān)聯(lián)方法 setBitmapMode
 */
void U8G2::drawXBM(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
void U8G2::drawXBMP(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
  • drawXBM和drawXBMP區(qū)別在于 XBMP支持PROGMEM;

18. u8g2.firstPage()/nextPage() —— 繪制命令

/**
 * 繪制圖像
 */
void U8G2::firstPage(void)
uint8_t U8G2::nextPage(void)
  • firstPage方法會把當(dāng)前頁碼位置變成0;
  • 修改內(nèi)容處于firstPage和nextPage之間,每次都是重新渲染所有內(nèi)容;
  • 優(yōu)勢點(diǎn):該方法消耗的ram空間,比sendBuffer消耗的ram空間要少;

實(shí)例:

  u8g2.firstPage();
  do {
    /* all graphics commands have to appear within the loop body. */    
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0,20,"Hello World!");
  } while ( u8g2.nextPage() );

?19. u8g2.print() —— 繪制內(nèi)容

/**
 * 繪制內(nèi)容
 * @Note 關(guān)聯(lián)方法  setFont setCursor enableUTF8Print
 */
void U8G2::print(...)

?20. u8g2.sendBuffer() —— 繪制緩沖區(qū)的內(nèi)容

/**
 * 繪制緩沖區(qū)的內(nèi)容
 * @Note 關(guān)聯(lián)方法  clearBuffer
 */
void U8G2::sendBuffer(void)
  • sendBuffer的RAM占用空間大,需要結(jié)合構(gòu)造器的buffer選項(請繼續(xù)往下看,先有個概念)使用;
  • 不管是fistPage、nextPage還是sendBuffer,都涉及到一個叫做 current page position的概念;

五. 顯示配置相關(guān)函數(shù)

1. u8g2.getAscent()

/**
 * 獲取基準(zhǔn)線以上的高度
 * @return 返回高度值
 * @Note 關(guān)聯(lián)方法  setFont getDescent setFontRefHeightAll
 */
int8_t U8G2::getAscent(void)
  • 跟字體有關(guān)(setFont)

示例:下面例子,ascent是18

2. u8g2.getDescent() —— 獲取基準(zhǔn)線以下的高度

/**
 * 獲取基準(zhǔn)線以下的高度
 * @return 返回高度值
 * @Note 關(guān)聯(lián)方法  setFont setFontRefHeightAll
 */
int8_t U8G2::getDescent(void)
  • 跟字體有關(guān)(setFont);

示例:下面例子,descent是-5

3. u8g2.getDisplayHeight() —— 獲取顯示器的高度

/**
 * 獲取顯示器的高度
 * @return 返回高度值
 */
u8g2_uint_t getDisplayHeight(void)

4. u8g2.getDisplayWidth() —— 獲取顯示器的寬度

/**
 * 獲取顯示器的寬度
 * @return 返回寬度值
 */
u8g2_uint_t getDisplayWidth(void)

5. u8g2.getMaxCharHeight() —— 獲取當(dāng)前字體里的最大字符的高度

/**
 * 獲取當(dāng)前字體里的最大字符的高度
 * @return 返回高度值
 * @Note 關(guān)聯(lián)方法 setFont
 */
u8g2_uint_t getMaxCharHeight(void)

6. u8g2.getMaxCharWidth() —— 獲取當(dāng)前字體里的最大字符的寬度

/**
 * 獲取當(dāng)前字體里的最大字符的寬度
 * @return 返回寬度值
 * @Note 關(guān)聯(lián)方法 setFont
 */
u8g2_uint_t getMaxCharWidth(void)

7. u8g2.getStrWidth() —— 獲取字符串的像素寬度

/**
 * 獲取字符串的像素寬度
 * @param s 繪制字符串
 * @return 返回字符串的像素寬度值
 * @Note 關(guān)聯(lián)方法 setFont drawStr
 */
u8g2_uint_t U8G2::getStrWidth(const char *s)

?8. u8g2.getUTF8Width() —— 獲取UTF-8字符串的像素寬度

/**
 * 獲取UTF-8字符串的像素寬度
 * @param s 繪制字符串
 * @return 返回字符串的像素寬度值
 * @Note 關(guān)聯(lián)方法 setFont drawStr
 */
u8g2_uint_t U8G2::getUTF8Width(const char *s)

9. u8g2.setAutoPageClear() —— 設(shè)置自動清除緩沖區(qū)

/**
 * 是否自動清除緩沖區(qū)
 * @param mode 0 表示關(guān)閉
 *             1 表示開啟,默認(rèn)是開啟
 */
void U8G2::setAutoPageClear(uint8_t mode)
  • 建議該方法保持默認(rèn)就好,如果用戶禁止了,那么需要自己維護(hù)緩沖區(qū)的狀態(tài)或者手動調(diào)用clearBuffer;

10. u8g2.setBitmapMode() —— 設(shè)置位圖模式

/**
 * 設(shè)置位圖模式(定義drawXBM方法是否繪制背景顏色)
 * @param is_transparent
 *         0 繪制背景顏色,不透明,默認(rèn)是該值
 *         1 不繪制背景顏色,透明
 * @Note 關(guān)聯(lián)方法 drawXBM
 */
void U8G2::setBitmapMode(uint8_t is_transparent)

11. u8g2.setBusClock() —— 設(shè)置總線時鐘

/**
 * 設(shè)置總線時鐘(I2C SPI)
 * @param mode clock_speed 總線時鐘頻率(Hz)
 * @Note 關(guān)聯(lián)方法 begin
 */
void U8G2::setBusClock(uint32_t clock_speed);
  • 僅僅Arduino平臺支持;
  • 必須在u8g2.begin() 或者 u8g2.initDisplay()之前調(diào)用;

12. u8g2.setClipWindow() —— 限制繪圖區(qū)域大小

/**
 * 設(shè)置采集窗口,窗口范圍從左上角(x0,y0)到右下角(x1,y1)
 * 也就是我們繪制的內(nèi)容只能在規(guī)范范圍內(nèi)顯示
 * @param x0 左上角x坐標(biāo)
 * @param y0 左上角y坐標(biāo)
 * @param x1 右下角x坐標(biāo)
 * @param y1 右下角y坐標(biāo)
 * @Note 關(guān)聯(lián)方法 begin
 */
void U8G2::setClipWindow(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1 );
  • 可以通過 setMaxClipWindow 去掉該限制

?13. u8g2.setCursor() —— 設(shè)置光標(biāo)位置

/**
 * 設(shè)置繪制光標(biāo)位置(x,y)
 * @Note 關(guān)聯(lián)方法 print
 */
void U8G2::setCursor(u8g2_uint_t x, u8g2_uint_t y)

14. u8g2.setDisplayRotation() —— 設(shè)置顯示器的旋轉(zhuǎn)角度

/**
 * 設(shè)置顯示器的旋轉(zhuǎn)角度
 * @param u8g2_cb 旋轉(zhuǎn)選項
 *        U8G2_R0 不做旋轉(zhuǎn) 水平
 *        U8G2_R1 旋轉(zhuǎn)90度
 *        U8G2_R2 旋轉(zhuǎn)180度
 *        U8G2_R3 旋轉(zhuǎn)270度
 *        U8G2_MIRROR 不做旋轉(zhuǎn) 水平,顯示內(nèi)容是鏡像的,暫時不理解
 */
void setDisplayRotation(const u8g2_cb_t *u8g2_cb)

15. u8g2.setDrawColor() —— 設(shè)置繪制顏色

/**
 * 設(shè)置繪制顏色(暫時還沒有具體去了解用法)
 */
void U8G2::setDrawColor(uint8_t color)

?16. u8g2.setFont() —— 設(shè)置字體集

/**
 * 設(shè)置字體集(字體集用于字符串繪制方法或者glyph繪制方法)
 * @param font 具體的字體集
 * @Note 關(guān)聯(lián)方法  drawUTF8 drawStr drawGlyph print
 */
void U8G2::setFont(const uint8_t *font)
請看第九章獲取字庫更多信息

17. u8g2.setFontMode() 設(shè)置顯示模式

啟用(1)或禁用(0)透明模式

18. u8g2.setFontDirection() —— 設(shè)置字體方向

/**
 * 定義字符串繪制或者圖形繪制的方向
 * @param dir 方向
 * @param 關(guān)聯(lián)方法 drawStr
 */
void U8G2::setFontDirection(uint8_t dir)

六. 緩存相關(guān)函數(shù)

1. u8g2.getBufferPtr() —— 獲取緩存空間的地址

/**
 * 獲取緩存空間的地址
 * @return 返回緩存空間起始地址
 * @Note 關(guān)聯(lián)方法 getBufferTileHeight, getBufferTileWidth, clearBuffer
 */
uint8_t *U8G2::getBufferPtr(void)

2. u8g2.getBufferTileHeight() —— 獲取緩沖區(qū)的Tile高度

/**
 * 獲取緩沖區(qū)的Tile高度
 * @return 返回高度值
 */
uint8_t U8G2::getBufferTileHeight(void)
  • 一個tile等于8個像素點(diǎn).

3. u8g2.getBufferTileWidth() —— 獲取緩沖區(qū)的Tile寬度

/**
 * 獲取緩沖區(qū)的Tile寬度
 * @return 返回寬度值
 */
uint8_t U8G2::getBufferTileWidth(void)

4. u8g2.getBufferCurrTileRow() —— 獲取緩沖區(qū)的當(dāng)前Tile row

/**
 * 獲取緩沖區(qū)的當(dāng)前Tile row行數(shù)
 * @return 返回當(dāng)前的tilerow
 */
uint8_t U8G2::getBufferCurrTileRow(void)

5. u8g2.setBufferCurrTileRow() —— 設(shè)置緩沖區(qū)的當(dāng)前Tile row

/**
 * 設(shè)置緩沖區(qū)的當(dāng)前Tile row
 * @param 當(dāng)前的tilerow
 */
void U8G2::setBufferCurrTileRow(uint8_t  row)
  • 在 firstPage/nextPage 循環(huán)時,由于底層調(diào)用了setBufferCurrTileRow,所以盡量不要自己手動調(diào)用該方法

七. U8g2繪制模式

U8g2支持三種繪制模式:

  • Full screen buffer mode,全屏緩存模式
  • Page mode (This is the U8glib picture loop) 分頁模式
  • U8x8, character only mode 僅僅支持普通字符

1. Full screen buffer mode

特點(diǎn):

  • 繪制速度快
  • 所有的繪制方法都可以使用
  • 需要大量的ram空間

用法:

  1. 清除緩沖區(qū) u8g2.clearBuffer()
  2. 操作一些繪制方法
  3. 發(fā)送緩沖區(qū)的內(nèi)容到顯示器 u8g2.sendBuffer().

2. Page mode

特點(diǎn):

  • 繪制速度慢
  • 所有的繪制方法都可以使用
  • 需要少量的ram空間

3. U8x8 character mode

特點(diǎn):

  • 繪制速度快
  • 并不是對所有的顯示器都有效
  • 圖形繪制不可用
  • 不需要ram空間
    使用U8X8構(gòu)造器,比如:
U8X8_ST7565_EA_DOGM128_4W_SW_SPI(clock, data, cs, dc [, reset])

八. 用法

  1. 包含頭文件
#include <U8g2lib.h>
  1. U8g2對象初始化

看例程里有無數(shù)條代表著各種屏幕的寫好的U8g2初始化語句,選擇適合的一條解除注釋即可

我的ESP32 DEVKIT V1+SSD1306(IIC)是選擇這個:

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping
  1. 初始化屏幕
u8g2.begin();
  1. 使用第六節(jié)的一種方法開始吧

九. 關(guān)于字庫

1. 命名規(guī)則

<prefix> '_' <name> '_' <purpose> <char set>
  • prefix基本上都是 u8g2;
  • name 字體名稱
  • purpose 用法
字符 描述
t 透明字體,不要使用背景色
h 所有的圖形有通用的高度
m 所有字形都有共同的高度和寬度(等寬)
8 所有圖示符都可以放入8x8像素的方框中
  • char set 字符設(shè)置
字符 描述
f 最多包含256個字體
r 字體中只包含ASCII代碼32到127范圍內(nèi)的字形.
u 字體中只包含ASCII代碼32到95(大寫字符)范圍內(nèi)的字形.
n 字體中只包含數(shù)字和用于寫入日期和時間字符串的額外字形
其他自定義字符列表.

2. 所有字庫

https://github.com/olikraus/u8g2/wiki/fntlistall

3. 符號字庫參考

https://github.com/olikraus/u8g2/wiki/fntgrpiconic

示例: 顯示所有iconic圖標(biāo)

#include <Arduino.h>
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping

void setup()
{
  u8g2.begin();
}
void loop()
{
  for (size_t i = 64; i < 288; i++)
  {
    u8g2.setFont(u8g2_font_tenstamps_mn);
    u8g2.setCursor(0, 20);
    u8g2.print("   ");//為了不全屏刷新的情況下清空局部顯示區(qū)域
    u8g2.setCursor(0, 20);
    u8g2.print(i);
    u8g2.setFont(u8g2_font_inr33_mf);
    u8g2.setCursor(64, 48);
    u8g2.print("   ");//為了不全屏刷新的情況下清空局部顯示區(qū)域
    u8g2.setFont(u8g2_font_open_iconic_all_4x_t);
    u8g2.drawGlyph(64, 48, i);
    u8g2.sendBuffer();
    delay(1500);
  }
}

4. 中文字庫

https://github.com/olikraus/u8g2/wiki/fntgrpwqy

可以看到, 最小的字高12px, 最大的字高18px,如果想要更大的字,請取XBM格式字模

十. 一個小車的動畫

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping
void setup(void)
{
  u8g2.begin();
  u8g2.setFont(u8g2_font_10x20_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void loop(void)
{
  for (int i = -31; i < 128; i++)
  {
    u8g2.clearBuffer();
    u8g2.drawStr(0, 0, "Fashional Car");
    u8g2.drawBox(0 + i, 54 - i % 2, 31, 6);
    u8g2.drawBox(7 + i, 48 - i % 2, 17, 6);
    u8g2.drawDisc(7 + i, 59, 4);
    u8g2.drawDisc(22 + i, 59, 4);
    switch (i % 6)
    {
    case 0:
      u8g2.drawDisc(-6 + i, 59, 1);
      break;
    case 1:
      u8g2.drawDisc(-12 + i, 58, 2);
      break;
    case 2:
      u8g2.drawDisc(-16 + i, 57, 3);
      break;
    default:
      break;
    }
    Serial.println(i);
    delay(50);
    u8g2.sendBuffer();
  }
}

十一. 顯示XBM圖片

我使用了在線轉(zhuǎn)換器:

https://convertio.co/zh/image-converter/?utm_source=chrome_extension

整個轉(zhuǎn)換過程很簡單, 轉(zhuǎn)換好的XBM文件用記事本打開就能看到數(shù)組了, 感覺比傳統(tǒng)的 Img2Lcd 或者 PCtoLCD2002 好用

#include <Arduino.h>
#include "U8g2lib.h"
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE, /* clock=*/22, /* data=*/21); // ESP32 Thing, HW I2C with pin remapping

static const unsigned char al_logo[] 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, 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, 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, 
  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, 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, 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, 
  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, 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, 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, 
  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, 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, 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, 0x08, 
  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x0A, 0x00, 0x00, 
  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 
  0xC0, 0x08, 0x80, 0x01, 0x07, 0x00, 0x70, 0x00, 0x00, 0x06, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x10, 0x80, 0x1D, 0xC0, 0x03, 0x0F, 0x00, 0xF8, 0x00, 
  0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xC0, 0x03, 
  0xEF, 0x00, 0xF8, 0x01, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 
  0x30, 0x18, 0xC0, 0x03, 0xE7, 0x01, 0xFC, 0x01, 0x00, 0x1F, 0x00, 0x00, 
  0x00, 0x07, 0x00, 0x00, 0x88, 0x57, 0xE0, 0x03, 0xEF, 0x03, 0xFE, 0x01, 
  0x00, 0x1F, 0x0F, 0x00, 0x80, 0x07, 0x00, 0x00, 0xCC, 0x7E, 0xE0, 0x01, 
  0xC7, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x00, 
  0x02, 0x00, 0xE0, 0x0F, 0x87, 0x83, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 
  0xC0, 0x07, 0x00, 0x00, 0x00, 0x06, 0xF0, 0x1F, 0x37, 0xC1, 0xFF, 0x0F, 
  0x80, 0x7F, 0x01, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x04, 0xF0, 0x1F, 
  0xFF, 0xC0, 0xBF, 0x0F, 0x80, 0xBF, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 
  0x00, 0x16, 0xF8, 0x1C, 0xFF, 0xC0, 0x17, 0x0F, 0x80, 0x0F, 0x00, 0x00, 
  0xF0, 0x03, 0x00, 0x00, 0x00, 0x1D, 0x78, 0x9C, 0x1F, 0xC0, 0xFD, 0x0F, 
  0x80, 0x47, 0x07, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x05, 0x30, 0xFF, 
  0x07, 0xE0, 0xFF, 0x0F, 0x80, 0xFF, 0x3F, 0x00, 0xF8, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0xE0, 0xFF, 0x07, 0xE0, 0xBF, 0x0F, 0x80, 0xFF, 0x7E, 0x00, 
  0xFC, 0x00, 0x00, 0x00, 0x80, 0x64, 0xE0, 0x3D, 0x33, 0xE0, 0x9F, 0x07, 
  0xE0, 0x0F, 0x78, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x80, 0x05, 0x60, 0x9C, 
  0x33, 0xE0, 0x8B, 0x0F, 0xF0, 0x03, 0xF0, 0x00, 0xFE, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x30, 0x9F, 0x63, 0xE0, 0x8D, 0x0F, 0x7C, 0x00, 0xF0, 0x00, 
  0xFF, 0x03, 0x00, 0x00, 0x00, 0x30, 0xE0, 0x9D, 0xE9, 0xE0, 0xBC, 0x07, 
  0x3F, 0xF0, 0xF8, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x80, 0x01, 0xE0, 0xDE, 
  0xF1, 0xE0, 0xBE, 0x0F, 0x1E, 0xFC, 0xF9, 0x80, 0xDF, 0x0F, 0x00, 0x00, 
  0x80, 0x02, 0x80, 0xDF, 0xF0, 0xE1, 0xBF, 0x07, 0x04, 0xFF, 0x79, 0xC0, 
  0x9F, 0x1F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x7F, 0xE0, 0xE0, 0x9F, 0x07, 
  0xC0, 0xBF, 0x7D, 0xC0, 0x0F, 0x7E, 0x00, 0x00, 0xC0, 0x0C, 0x08, 0x2E, 
  0x00, 0xE0, 0x8C, 0x0F, 0xF0, 0x0F, 0x7C, 0xE0, 0x07, 0xFC, 0x01, 0x00, 
  0xC0, 0x0C, 0x1E, 0x00, 0xC0, 0xE1, 0xCC, 0x07, 0xFE, 0x0B, 0x3E, 0xF0, 
  0x03, 0xF8, 0x07, 0x00, 0x80, 0x28, 0x3C, 0x00, 0xE2, 0xE3, 0xD2, 0x07, 
  0xFE, 0x38, 0x3E, 0xF0, 0x03, 0xE0, 0x1F, 0x00, 0xA0, 0x2D, 0x3C, 0xFF, 
  0xDF, 0xE7, 0xF8, 0x07, 0x00, 0xF0, 0x3F, 0xF8, 0x01, 0xC0, 0xFF, 0x02, 
  0xA0, 0x01, 0xF8, 0x71, 0x8E, 0xE7, 0xFE, 0x07, 0x00, 0xF0, 0x1F, 0xFC, 
  0x00, 0x80, 0xFF, 0x1F, 0x00, 0x0C, 0xF0, 0x60, 0x80, 0xE7, 0xFF, 0x07, 
  0x00, 0xE0, 0x0F, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 
  0xC0, 0xE3, 0xC3, 0x07, 0x00, 0xE0, 0x0F, 0x7F, 0x00, 0x00, 0xFE, 0xFF, 
  0x00, 0x08, 0x00, 0x00, 0x20, 0xE0, 0xC1, 0x03, 0x00, 0xC0, 0x03, 0x0C, 
  0x00, 0x00, 0xF0, 0x1F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x80, 0x03, 
  0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x03, 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, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x02, 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, 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, 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, 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 setup()
{
  Serial.begin(115200);
  u8g2.begin();
}
void loop()
{
  u8g2.firstPage();
  do
  {
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawXBMP(0, 0, 128, 64, al_logo);
  } while (u8g2.nextPage());
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。