Arduino库之U8g2lib
某些图片、表格在手机竖屏状态下会显示不全,横屏显示即可。最好是用平板或电脑看。大部分内容摘自官网。
简介

U8g2
U8glib是用于单色显示屏的图形库,它可以用于51、Arduino、ARM控制显示屏,目前作者olikraus已经更新到version2了,也就是U8g2lib(下面简称U8g2)。U8g2这个库实际上包含两个库(api):U8g2和U8x8,它们有如下特点:
- U8g2
- 可处理所有图形
- 支持很多字体(。(几乎)对字体大小没限制
- 微控制器需要一定的存储空间来传递显示
- U8x8
- 只能输出文字
- 只能输出固定像素的字体
- 直接输出到显示屏,微控制器无需缓冲区
这两个库还包含一个特殊的类(也能看作一个子库):U8log,它能模拟一个输出终端,功能如下:
- U8log
- Output of boot/startup information 输出初始化信息
- Error logging 载入错误
- Debugging logging 载入debug
- Output of sensor values 输出传感器值(我看上的是这一点)
我在这里只给出Arduino相关的部分,51和ARM大同小异。下面我们结合实际操作来学习。
安装U8g2
进入Arduino IDE,点击上方“工具”-“管理库”,搜索U8g2,选择U8g2 by oliver那个,点击安装即可。

Hello World!
按照惯例,我们先输出一个Hello World!。点击上方“文件”-“示例”-“U8g2”-“full_buffer”-“HelloWorld”,先不要急着上传到Arduino,要先根据你的屏幕控制器、像素,删掉其中一个注释的//。我的型号是淘宝上常见的0.96 OLED(下图),所以我用的是这句:U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);。

上传,接好线,上电,就可以看到屏幕上出现”Hello World!“(位置可能和上图不一样)。
配置
虽然上面的”HelloWorld“看起来很长,但实际上只有以下几句:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
开头第一句是引用U8g2,我们着重看第二句,它就是配置”Setup“,具体分成以下几部分:
| Description | Example |
|---|---|
| 前缀 | U8G2 |
| 控制器(驱动器) | SSD1306 |
| 显示屏 | 128x64_NONAME |
| 缓冲区大小 | 1、2、或F(full) |
| 通信协议 | HW_I2C |
| 参数 | (U8G2_R0, U8x8_PIN_NONE) |
控制器/显示屏名字
这个没什么好讲的,一般淘宝上都会标出来,实在不知道就问商家,再不行就挨个试一下符合像素的那几句。
缓冲区大小
1表示RAM中只会储存一页画面的缓冲。你需要用一个firstPage()/nextPage()循环来显示。
2和1类似,但会储存两页。官网还说2是1的两倍快,但我实在不知道”快“指的是什么。
F表示“full frame buffer”,储存所有页面,用clearBuffer()来清除缓冲,用sendBuffer()来把缓冲发送到显示屏。
这一部分还没完全弄懂,貌似就是F相当于一本书,你可以预先在书上画很多页,然后要显示哪一页就翻到那里。1就相当于一块黑板,你只能画一页东西,要显示新的东西就要重新擦掉重画。2就是两块黑板。
通信协议
支持常见的SPI、I2C、6800和8080,支持硬件HW和软件SW,具体有下面几种:
| 通信协议 | 描述 |
|---|---|
4W_SW_SPI | 4线(clock, data, cs and dc)软件模拟SPI |
4W_HW_SPI | 4线(clock, data, cs and dc)硬件SPI(基于SPI库) |
2ND_4W_HW_SPI | 如果板子支持,第二个 4线硬件SPI |
3W_SW_SPI | 3线(clock, data and cs)软件模拟SPI |
SW_I2C | 软件模拟 I2C/TWI |
HW_I2C | 硬件 I2C (基于Wire库) |
2ND_HW_I2C | 如果板子支持,第二个 硬件 I2C (基于Wire库) |
| 6800 | 8-bit并行接口,6800协议 |
| 8080 | 8-bit并行接口,8080协议 |
软件模拟 I2C 需要设置SCL,SDA对应管脚:..._SW_I2C(clock, data [, reset])。
旋转
这是配置语句的第一个参数,有如下几种选择:
| 旋转/镜像 | 描述 |
|---|---|
U8G2_R0 | 不旋转 |
U8G2_R1 | 顺时针旋转90度 |
U8G2_R2 | 顺时针旋转180度 |
U8G2_R3 | 顺时针旋转270度 |
U8G2_MIRROR | 不旋转,镜像翻转 |
接线
官网上的表格:
| Pin Argument | Description | Datasheet Names |
|---|---|---|
| clock | SPI or I2C clock line | SCL, SCLK, … |
| data | SPI or I2C data line | SDA, MOSI, SDIN, … |
| d0 … d7 | Data lines of the parallel interface | D0 … D7 |
| cs | Chip select line | CS |
| dc | Data/command selection line (register select) | D/C, A0, RS, … |
| enable | “Write” for the 8080 interface, “enable” for the 6800 interface | 8080: WR, 6800: E |
| reset | Reset line |
如果你不需要用某个引脚但又需要一个参数,可以用U8X8_PIN_NONE
16 Bit模式
U8g2默认是8 Bit Mode,如果你的设备支持 256或以上的像素宽,你可以在u8g2.h文件中取消注释//#define U8G2_16BIT。
SSD1306 128X64_NONAME
由于这个模块比较常用,所以我把它的详细介绍搬了过来。其他模块请去官网。(显示不全的话请横屏查看)
| Controller “ssd1306”, Display “128x64_noname” | Descirption |
|---|---|
| U8G2_SSD1306_128X64_NONAME_1_SW_I2C(rotation, clock, data [, reset]) | page buffer, size = 128 bytes |
| U8G2_SSD1306_128X64_NONAME_2_SW_I2C(rotation, clock, data [, reset]) | page buffer, size = 256 bytes |
| U8G2_SSD1306_128X64_NONAME_F_SW_I2C(rotation, clock, data [, reset]) | full framebuffer, size = 1024 bytes |
| U8G2_SSD1306_128X64_NONAME_1_HW_I2C(rotation, [reset [, clock, data]]) | page buffer, size = 128 bytes |
| U8G2_SSD1306_128X64_NONAME_2_HW_I2C(rotation, [reset [, clock, data]]) | page buffer, size = 256 bytes |
| U8G2_SSD1306_128X64_NONAME_F_HW_I2C(rotation, [reset [, clock, data]]) | full framebuffer, size = 1024 bytes |
| U8G2_SSD1306_128X64_NONAME_1_2ND_HW_I2C(rotation, [reset]) | page buffer, size = 128 bytes |
| U8G2_SSD1306_128X64_NONAME_2_2ND_HW_I2C(rotation, [reset]) | page buffer, size = 256 bytes |
| U8G2_SSD1306_128X64_NONAME_F_2ND_HW_I2C(rotation, [reset]) | full framebuffer, size = 1024 bytes |
控制函数
下面一些控制函数,能对全局进行操作。写得有点乱。
begin
-
函数原型:
1 2
bool U8G2::begin(void) bool U8G2::begin(uint8_t menu_select_pin, uint8_t menu_next_pin, uint8_t menu_prev_pin, uint8_t menu_up_pin = U8X8_PIN_NONE, uint8_t menu_down_pin = U8X8_PIN_NONE, uint8_t menu_home_pin = U8X8_PIN_NONE) -
描述:用上面的配置设置显示屏,并且会清空显示屏,退出显示屏的省电模式。还可以设置按键:将按键的对应引脚传递到对应参数(按键要求低有效),用getMenuEvent来检查按键事件,从而构建用户交互界面。
-
这个函数会调用:
- initDisplay
- clearDisplay
- setPowerSave
-
返回值:永远是1/true
-
相关:initDisplay, setPowerSave, clearDisplay, U8X8::begin
-
例子:这个函数一般放在
void setup(void)里面:1 2 3
void setup(void) {u8g2.begin(); }
initDisplay
-
函数原型:
1
void U8G2::initDisplay(void) - 描述:重新设置显示屏。显示前一定要先调用这个函数。它会让屏幕处在省电模式。要让屏幕显示,先取消省电模式(setPowerSave)
- 相关:setPowerSave, begin
setPowerSave
-
原型:
1
1
void U8G2::setPowerSave(uint8_t is_enable) -
描述:开启(is_enable=1)或关闭(is_enable=0)显示屏的省电模式。当省电模式开启时,屏幕上的内容不可见,屏幕RAM的内容未更改。这个函数在begin被调用。
-
参数:
- is_enable:开启(1)或关闭(0)显示屏的省电模式。
-
相关:begin
clear
-
函数原型:
1
void U8G2::clear(void) - 描述:清空屏幕(display)和缓冲区(buffer)的所有像素(说实话我分不清这俩)。将print的指针(cursor)归位到左上角。
- 这个函数会调用:
- home
- clearDisplay
- clearBuffer
- 相关:home, clearDisplay, clearBuffer
home
-
函数原型:
1
void U8G2::home(void) -
描述:将print函数的指针(游标cursor)重置到左上角。如果字体的参考点不在上方的话,字体的一部分会看不见。
-
相关:print, clear, setCursor
clearDisplay
-
函数原型:
1
void U8G2::clearDisplay(void) -
描述:清空内部和显示屏的缓冲区的像素。这个函数在begin函数内被调用,因此除了初始化时之外,无需再调用这个函数。其他函数,如 sendBuffer 和 nextPage) ,也能覆盖/清空显示。
-
注:
- 这个命令可以对
_F_、_1_、_2_三种缓冲区大小都有效 - 不要在单页的循环内使用这个命令(在firstPage和nextPage)
- 这个命令可以对
-
相关:begin
clearBuffer
-
函数原型:
1
void U8G2::clearBuffer(void) -
描述:清空内部缓冲区的所有像素。清楚后,用 sendBuffer 来将新的页面传递给显示屏。这个函数只对
_F_(储存所有页面)的情况有效(见上面的缓冲器大小)。它还会发送一个刷新信号(refreshDisplay)给墨水屏。 -
相关:sendBuffer
-
示例:
1 2 3 4 5
void loop(void) {u8g2.clearBuffer();// ... write something to the buffer u8g2.sendBuffer();delay(1000);
sendBuffer
-
函数原型:
1
void U8G2::sendBuffer(void) -
描述:将内存缓冲区中的内容发送给显示。用 clearBuffer清空缓冲区,用绘画函数向缓冲区添加内容。这个函数只对
_F_(储存所有页面)的情况有效(见上面的缓冲器大小)。它还会发送一个刷新信号(refreshDisplay)给墨水屏。 -
注:有点复杂,把英文抄下来:
Actually this procedure will send the current page to the display. This means, the content of the internal pixel buffer will be placed in the tile row given by the current page position. This means, that this procedure could be used for partial updates on paged devices (constructor with buffer option “1” or “2”). However, this will only work for LCDs. It will not work with most e-Paper/e-Ink devices because of the buffer switch in the display controller. Conclusion: Use this command only together with full buffer constructors. It will then work with all LCDs and e-Paper/e-Ink devices.
-
相关:clearBuffer, updateDisplay
firstPage
-
函数原型
1
void U8G2::firstPage(void) -
描述:这个和nextPage一起构成图像循环,将内容发送到显示屏。有一些限制:不要在执行循环时更改显示内容。循环时总是重新绘制所有内容,而非一部分。这样能节约ram,参考sendBuffer。
-
相关:nextPage
-
示例:
1 2 3 4 5 6 7
1 2 3 4 5 6 7
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() );
nextPage
-
函数原型:
1
uint8_t U8G2::nextPage(void) -
描述:这个和firstPage一起构成图像循环,将内容发送到显示屏。有一些限制:不要在执行循环时更改显示内容。循环时总是重新绘制所有内容,而非一部分。这样能节约ram,参考sendBuffer。完成循环后,这个函数会发送一个刷新命令(refreshDisplay)给墨水屏(在返回0之前)。
-
返回值:0,在循环完成后(所有数据都传送给屏幕)。
-
相关:firstPage
-
示例:
1 2 3 4 5 6 7
1 2 3 4 5 6 7
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() );
disableUTF8Print
-
函数原型:
1
void U8G2::disableUTF8Print(void) -
描述:禁止
print函数用UTF8。这是默认设置。 -
相关:print, enableUTF8Print
enableUTF8Print
-
函数原型:
1
void U8G2::enableUTF8Print(void) -
描述:允许
print函数用UTF8。当其有效时,可以传递unicode符号的字符串给print函数。通常这个函数在begin后被调用:1 2 3 4
void setup(void) {u8g2.begin();u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() } -
相关:print, disableUTF8Print
-
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
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 for all the glyphs of "你好世界"u8g2.firstPage();do {u8g2.setCursor(0, 40);u8g2.print("你好世界"); // Chinese "Hello World" } while ( u8g2.nextPage() );delay(1000); }
setI2CAddress
-
函数原型
1
void U8G2::setI2CAddress(uint8_t adr) -
描述:默认情况,U8g2假设显示屏为最不可能的地址(原文为:By default, U8g2 assumes the lowest possible I2C address of the display.)。如果需要设置一个不同的地址,请在begin()之前调用这个函数。
-
参数:I2C地址乘以2(我也不知道为什么,我用I2C_scan程序扫描到的地址为0x3C,但只有输入0x78(0x3C*2=0x78)才有效),并且最低位必须为0(才能写)
-
相关:begin
-
注:U8g2 v2.6.x才可用。
绘图函数
这类函数有一个特点,就是都以draw开头,可以画各种点、线、形。需要注意的是,下面的所有坐标都是以左上角为(0, 0),正方向为向右和向下。测试时可用如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
drawPixel
-
函数原型:
1
void U8G2::drawPixel(u8g2_uint_t x, u8g2_uint_t y) -
描述:在特定的x/y位置画一个点。(0, 0)为左上角。可能会超出屏幕边界。这个程序会用当前颜色(setDrawColor)来画,颜色0会清除一个像素,颜色1会设置一个像素。
-
参数:
x:x坐标y:y坐标
-
相关:setDrawColor
drawBitmap
-
函数原型:
1
void U8G2::drawBitmap(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap) -
描述:在特定的x/y处画一个位图(x/y对应位图的左上角)。位图的一部分可能会超出屏幕边界。位图由
bitmap数组给定。 -
参数:
x:x坐标(位图的左上角)y:y坐标(位图的左上角)cnt:水平方向上位图的字数。位图的宽度=cnt*8。h:位图的高度
-
注:不要再用这个函数,用drawXBM代替。
-
相关:drawXBM
drawXBM
-
函数原型:
1 2
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) -
描述:画一个X BitMap (一种单色点阵图),x/y对应点阵图的左上角。颜色由setColorIndex给定。在U8g2 Version 2.15.x中,引进了实/虚模式(solid/transparent),默认是实模式。这个函数的XBMP版本(即drawXBMP)要求点阵图储存在PROGMEM中(ROM内)。有很多工具可以将普通图片转换到XBM,比如开源软件GIMP,在线网站onlineconvertfree。实在不知道,可以参考教程Interfacing & displaying a custom graphic on an 0.96″ I2C OLED with Arduino
-
参数:
x/y:点阵图左上角的位置w/h:点阵图的宽/高bitmap:指向点阵图开头的指针
-
相关:setBitmapMode
-
注:XBMP版本要求点阵图数组按下面方式定义:
1
static const unsigned char u8g_logo_bits[] U8X8_PROGMEM = { ...另外,由于Arduino普遍内存小,尽量
-
示例:
1 2 3 4 5 6
#define u8g_logo_width 38 #define u8g_logo_height 24 static const unsigned char u8g_logo_bits[] PROGMEN= {//使用PROGMEN储存,不然可能会提示错误0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0xe0, ...0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f };这个可以直接粘贴到你的代码里。
1
u8g2.drawXBM( 0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);
drawLine
-
函数原型:
1
void U8G2::drawLine(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1) -
描述:在两点之间画一条直线,这个函数会用当前颜色(setDrawColor)来画。
-
参数:
x0、y0:起始点的坐标x1、y1:终点的坐标
-
相关:drawPixel, setDrawColor
-
示例:
1
u8g2.drawLine(20, 5, 5, 32);drawLine示例
drawHLine
-
函数原型:
1
void U8G2::drawHLine(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w) -
描述:以x/y为左边起点,w为长度向右画水平线。线的一部分可能超出屏幕边界。这个函数会用当前颜色(setDrawColor)来画,颜色0为清除像素,颜色1为设置像素。
-
参数:
x/y:左边起点的x/y坐标w:水平线的长度
-
相关:setDrawColor, drawVLine
drawVLine
-
函数原型:
1
void U8G2::drawVLine(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t h) -
描述:以x/y为上面起点,h为长度向下画竖直线。线的一部分可能超出屏幕边界。这个函数会用当前颜色(setDrawColor)来画,颜色0为清除像素,颜色1为设置像素。
-
参数:
x/y:上面起点的x/y坐标h:竖直线的长度
-
相关:setDrawColor, drawHLine
drawTriangle
-
函数原型:
1
void U8G2::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) -
描述:画一个实心的三角形。参数为16bit。图形会根据显示屏尺寸裁剪。后面一段看不懂……
Multiple polygons are drawn so that they exactly match without overlap:The left side of a polygon is drawn, the right side is not draw. The upper side is only draw if it is flat.
-
参数:
x0/y0:点0的位置x1/y1:点1的位置x2/y2:点2的位置
-
示例:
1
u8g2.drawTriangle(20,5, 27,50, 5,32);
drawBox
-
函数原型:
1
void U8G2::drawBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) -
描述:画一个实心矩形,左上角的位置对应
x/y,宽为w,高为h。矩形的一部分可能会超出屏幕边界。这个函数会用当前颜色(setDrawColor)来画,对于单色显示屏,颜色0表示清除像素,颜色1表示显示像素。 -
参数:
x:x坐标(框的左上角)y:y坐标(框的左上角)w:矩形的宽度h:矩形的长度
-
相关:drawFrame, setDrawColor
-
示例:
1
u8g2.drawBox(3,7,25,15);drawBox示例
drawFrame
-
函数原型:
1
void U8G2::drawFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) -
描述:画一个空心框,左上角的位置对应
x/y,宽为w,高为h。矩形的一部分可能会超出屏幕边界。这个函数会用当前颜色(setDrawColor)来画,对于单色显示屏,颜色0表示清除像素,颜色1表示显示像素。 -
参数:
x:x坐标(框的左上角)y:y坐标(框的左上角)w:框的宽度h:框的长度
-
相关:drawBox, setDrawColor
-
示例:
1
u8g2.drawFrame(3,7,25,15);drawFrame示例
drawRBox
见drawRFrame
drawRFrame
-
函数原型:
1 2
void U8G2::drawRBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) void U8G2::drawRFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) -
描述:画一个有圆角的框/矩形,以
x/y为左上角的坐标,以w/h为宽/长。部分可能会超出屏幕边界。圆角半径为r,要求w >= 2*(r+1)且h >= 2*(r+1),函数不会检查是否满足这个关系,如果w或h小于2*(r+1),会发生未定义的行为(就是出错…)这个函数会用当前颜色(setDrawColor)来画,对于单色显示屏,颜色0表示清除像素,颜色1表示显示像素。 -
参数
-
x/y:左上角的坐标 -
w:框/矩形的宽度 -
h:框/矩形的长度 -
r:圆角的半径
-
-
相关:[setDrawColor]{#setDrawColor}, [drawFrame]{#drawFrame}, [drawBox]{#drawBox}
-
示例:
1
u8g2.drawRFrame(20,15,30,22,7);drawRFrame示例
drawCircle
-
函数原型:
1
void U8G2::drawCircle(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G_DRAW_ALL) -
描述:以
(x0, y0)为圆心,rad为半径,画空心圆。圆的直径为2*rad+1。不同opt参数可以设置画圆的不同部分,可选的参数有:U8G2_DRAW_UPPER_RIGHT、U8G2_DRAW_UPPER_LEFT、U8G2_DRAW_LOWER_LEFT、U8G2_DRAW_LOWER_RIGHT、U8G2_DRAW_ALL,并且这些参数可以用|结合。这个函数会用当前颜色(setDrawColor)来画。 -
参数:
x0、y0:圆心的位置rad:圆的半径opt:选择画圆的哪部分。U8G2_DRAW_UPPER_RIGHTU8G2_DRAW_UPPER_LEFTU8G2_DRAW_LOWER_LEFTU8G2_DRAW_LOWER_RIGHTU8G2_DRAW_ALL
-
注:不支持Draw color 2(XOR Mode)
-
相关:drawDisc, setDrawColor
-
示例:
1
u8g2.drawCircle(20, 25, 10, U8G2_DRAW_ALL);drawCircle示例
drawDisc
-
函数原型:
1
void U8G2::drawDisc(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G_DRAW_ALL) -
描述:以
(x0, y0)为圆心,rad为半径,画实心圆。圆的直径为2*rad+1。不同opt参数可以设置画圆的不同部分,可选的参数有:U8G2_DRAW_UPPER_RIGHT、U8G2_DRAW_UPPER_LEFT、U8G2_DRAW_LOWER_LEFT、U8G2_DRAW_LOWER_RIGHT、U8G2_DRAW_ALL,并且这些参数可以用|结合。这个函数会用当前颜色(setDrawColor)来画。 -
参数:
x0、y0:圆心的位置rad:圆的半径opt:选择画圆的哪部分。U8G2_DRAW_UPPER_RIGHTU8G2_DRAW_UPPER_LEFTU8G2_DRAW_LOWER_LEFTU8G2_DRAW_LOWER_RIGHTU8G2_DRAW_ALL
-
注:不支持Draw color 2(XOR Mode)
-
相关:drawDisc, setDrawColor
-
示例:(见drawCircle)
drawGlyph
-
函数原型:
1
void U8G2::drawGlyph(u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding) -
描述:画一个Unicode象形文字。文字放在
x/y像素上方。U8g2只支持Unicode低16位编码的字符(BMP):encoding的值为0~65535。只有当字体中有对应编码时才能画出来。 -
参数:
x/y:字符在屏幕上的位置encoding:字符的Unicode值
-
注:这个绘画函数受setDrawColor和setFontMode控制
-
相关:setFont
-
示例:“雪人”是Unicode中的天气符号之一,其Unicode编码为9731(十进制)/2603(2进制):⛄。“雪人”也是U8g2字体:u8g2_font_unifont_t_symbol中的一个字。
1 2
u8g2.setFont(u8g2_font_unifont_t_symbols);u8g2.drawGlyph(5, 20, 0x2603); /* dec 9731/hex 2603 Snowman */drawGlyph示例
drawStr
-
函数原型:
1
u8g2_uint_t U8g2::drawStr(u8g2_uint_t x, u8g2_uint_t y, const char *s) -
描述:画一个字符串。第一个字符的位置为
x/y。调用这个函数前用setFont来指定一种字体。要输入编码为127~255的字符的话,用C/C++/Arduino的转义字符 “\xab”(16进制)或“\xyz”(8进制)。这个函数不能画编码大于等于256的字符,请用drawUTF8或drawGlyph来这种字符。 -
参数:
x/y:第一个字符的位置s:文本
-
返回值:字符串的长度
-
注:
- 这个绘画函数受setDrawColor和setFontMode控制
- 用print来显示出数值型变量
-
相关:setFont, drawUTF8, drawGlyph, print
-
示例:
1 2
u8g2.setFont(u8g2_font_ncenB14_tr);u8g2.drawStr(0,15,"Hello World!");drawStr示例
drawUTF8
-
函数原型:
1
u8g2_uint_t U8g2::drawUTF8(u8g2_uint_t x, u8g2_uint_t y, const char *s) -
描述:画一个以UTF-8编码的字符串。使用该函数的前提条件有两个:
- C/C++/Arduino编译器必须支持UTF-8(这是GNU编译器的默认设置,而大多数Arduino用的正是GNU)
- 代码编辑器必须支持UTF-8(Arduino IDE支持)
如果满足上两条件,你可以使用编码大于127的字符(当然,这个字符要在字体文件中存在,见setFont)。
好处:代码的可读性更好;可直接”复制“-”粘贴“象形文字到代码里。
坏处:代码的移植性差;
strLen函数无法返回字符长度,要用getUTF8Len来代替strLen -
参数:
x/y:首字符的位置s:UTF-8编码的文本
-
返回值:字符串的长度
-
注:
- 这个绘画函数受setDrawColor和setFontMode控制
- 用print来显示出数值型变量
-
相关:setFont, drawStr, print
-
示例:
1 2
u8g2.setFont(u8g2_font_unifont_t_symbols);u8g2.drawUTF8(5, 20, "Snowman: ☃");drawUTF8示例
-
函数原型:
1
void U8G2::print(...) -
描述:相当书Arduino的 print() 函数,见Arduino官网上的LiquidCrystalPrint和Serial.print()。这个函数会在当前指针处(setCursor),用当前字体(setFont)打印文本(或数字)。要想支持UTF-8,可以用enableUTF8Print
-
参数:见上面的Arduino官网后俩链接
-
相关:enableUTF8Print, setCursor, setFont
-
示例:
1 2 3
u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.setCursor(0, 15); u8g2.print("Hello World!");print示例
设置函数
setAutoPageClear
-
函数原型:
1
uint8_t U8G2::setAutoPageClear(uint8_t mode) -
描述:开启(mode=1)或关闭(mode=0)自动清除像素缓冲,通过
setFont
-
函数原型:
1
void U8G2::setFont(const uint8_t *font) -
描述:设置u8g2字体。注意u8x8的字体无法使用。字体的最后两个字母决定字体的种类或字符集:
字体名 字体种类 u8g2_xxx_tx 字体透明,宽度可变 u8g2_xxx_mx 等宽字体 u8g2_xxx_hx 宽度可变,普通高度 u8g2_xxx_8x 等宽字体,宽度限制在8x8的格子中 字体名 字符集 u8g2_xxx_xe Extended:unicode 32~701 u8g2_xxx_xf Full:unicode 32~255 u8g2_xxx_xr Restricted:unicode 32~127 u8g2_xxx_xu Uppercase:数字和大写字母 u8g2_xxx_xn 数字和与日期时间相关的字符 u8g2_xxx_x_something 特殊的字符集,看具体的字体图列 -
参数:
font:u8g2字体,具体见这里
-
相关:drawUTF8, drawStr, drawGlyph, u8g2字体集
-
示例:字体:
u8g2_font_5x7_tr
setFontDirection
-
函数原型:
1
void U8G2::setFontDirection(uint8_t dir) -
描述:决定字体显示的方向:
参数 旋转 描述 0 0 度 从左到右 1 90 度 从上到下 2 180 度 从右到左 3 270 度 从下到上 -
参数
dir:方向
-
相关:drawStr
-
示例:
1 2 3 4 5
u8g2.setFont(u8g2_font_ncenB14_tf); u8g2.setFontDirection(0); u8g2.drawStr(15, 20, "Abc"); u8g2.setFontDirection(1); u8g2.drawStr(15, 20, "Abc");setFontDirection示例
setFontMode
-
函数原型:
1
void U8G2::setFontMode(uint8_t is_transparent) -
描述:决定背景是否有颜色(
is_transparent = 0无颜色,is_transparent = 1有颜色),默认为0 -
参数:
is_transparent:开启(1)或关闭(0)透明模式
-
注:要选择一个合适的字体:
字体名 字体种类 适用于 u8g2_xxx_tx 透明字体,宽度可变 is_transparent = 1, XOR Modeu8g2_xxx_mx 等宽字体 is_transparent = 0u8g2_xxx_hx 宽度可变,普通高度 is_transparent = 0u8g2_xxx_8x 等宽字体,宽度限制在8x8的格子中 is_transparent = 0 -
示例:展示字体与背景的四种组合(setFontColor)
1 2 3 4 5 6 7 8 9 10 11
/* write background pattern, then: */ u8g2.setFontMode(0); u8g2.setDrawColor(1); u8g2.drawStr(3, 15, "Color=1, Mode 0"); u8g2.setDrawColor(0); u8g2.drawStr(3, 30, "Color=0, Mode 0"); u8g2.setFontMode(1); u8g2.setDrawColor(1); u8g2.drawStr(3, 45, "Color=1, Mode 1"); u8g2.setDrawColor(0); u8g2.drawStr(3, 60, "Color=0, Mode 1");setFontMode示例
setPowerSave
-
函数原型:
1
1
void U8G2::setPowerSave(uint8_t is_enable) -
描述:开启(
is_enable = 1)或关闭(is_enable = 0)显示屏的省电模式。开启省电模式时,显示屏上无显示,但不改变RAM。这个函数被begin调用。 -
参数:
is_enable:开启(1)或关闭(0)省电模式
相关文章:
Arduino库之U8g2lib
某些图片、表格在手机竖屏状态下会显示不全,横屏显示即可。最好是用平板或电脑看。大部分内容摘自官网。 简介 U8g2 U8glib是用于单色显示屏的图形库,它可以用于51、Arduino、ARM控制显示屏,目前作者olikraus已经更新到version2了࿰…...
fiddler 手机抓包
前置步骤参考:手把手教你如何配置fiddler、并开启手机代理抓包、最详细_fiddler抓socks5_赴梦、的博客-CSDN博客 后续: 问:fiddler 证书已安装 在 iphone, 访问网站,报错, 此链接非私人链接 gpt: 如果你在使用 Fiddl…...
基于知识问答的上下文学习中的代码风格11.20
基于知识问答的上下文学习中的代码风格 摘要1 引言2 相关工作3 方法3.1 概述3.2 元函数设计3.3 推理 4 实验4.1 实验设置4.2 实施细节4.3 主要结果 摘要 现有的基于知识的问题分类方法通常依赖于复杂的训练技术和模型框架,在实际应用中存在诸多局限性。最近&#x…...
opencv-形态学处理
通过阈值化分割可以得到二值图,但往往会出现图像中物体形态不完整,变的残缺,可以通过形态学处理,使其变得丰满,或者去除掉多余的像素。常用的形态学处理算法包括:腐蚀,膨胀,开运算&a…...
手把手设计C语言版循环队列(力扣622:设计循环队列)
文章目录 前言描述分析力扣AC代码 力扣: 622.设计循环队列 前言 队列会出现“假溢出”现象,即队列的空间有限,队列是在头和尾进行操作的,当元素个数已经达到最大个数时,队尾已经在空间的最后面了,但是对头…...
数据仓库及ETL的理论基础
数据仓库(Data Warehouse)是一个用于存储和管理大量结构化数据的系统,旨在支持企业的决策制定过程。它是一个集成的、主题导向的、时间变化的、非易失性的数据集合,用于支持企业的决策制定过程。数据仓库的设计目标是提供高性能的…...
5-4计算一串字符的空格数字字符其他
#include<stdio.h> int main(){char c;int space0;//空格int letters0;//英文字母int numbers0;//数字int others0;//其他字符printf("请输入一行字符:");while((cgetchar())!\n)//获取字符的内容,到\n停止{if(c>a&&c<z|…...
leetcode面试经典150题——30 长度最小的子数组
题目:长度最小的子数组 描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组&a…...
学习计划计划执行记录
11.21--写下学习目标 游戏行业通识学习: 求知鱼游戏学院的个人空间-求知鱼游戏学院个人主页-哔哩哔哩视频 (bilibili.com) (28 封私信 / 80 条消息) 游鲨游戏圈 - 知乎 (zhihu.com) 书籍学习: 软技能2:软件开发者职业生涯指南 面经学习…...
【紫光同创PCIE教程】——使用WinDriver驱动紫光PCIE
本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注www.meyesemi.com) 紫光的logos系列的PGL50H/PGL100H、logos-2全系列都集成gen24的PCIE硬核,且官方也提供了例程。 紫光的PCIE用起来还是挺方便的…...
MT8735/MTK8735安卓核心板规格参数介绍
MT8735核心板是一款高性能的64位Cortex-A53四核处理器,设计用于在4G智能设备上运行安卓操作系统。这款多功能核心板支持LTE-FDD/LTE-TDD/WCDMA/TD-SCDMA/EVDO/CDMA/GSM等多种网络标准,同时还具备WiFi 802.11a/b/g/n和BT4.0LE等无线通信功能。此外&#x…...
NSSCTF web刷题记录6
文章目录 [HZNUCTF 2023 final]eznode[MoeCTF 2021]地狱通讯-改[红明谷CTF 2022] Smarty Calculator方法一 CVE-2021-26120方法二 CVE-2021-29454方法三 写马蚁剑连接 [HZNUCTF 2023 final]eznode 考点:vm2沙箱逃逸、原型链污染 打开题目,提示找找源码 …...
米哈游大数据云原生实践
云布道师 近年来,容器、微服务、Kubernetes 等各项云原生技术的日渐成熟,越来越多的公司开始选择拥抱云原生,并将企业应用部署运行在云原生之上。随着米哈游业务的高速发展,大数据离线数据存储量和计算任务量增长迅速,…...
移动端适配-(postcss-pxtorem)
基于vuevant的移动端适配(rem) 1.下载lib-flexible --save npm i lib-flexible --save2.在main.js中引入lib-flexible main.js import lib-flexible/flexible3.设置meta标签 <meta name"viewport" content"widthdevice-width, initial-scale1, maximum-s…...
【PostgreSQL】解决PostgreSQL时区(TimeZone)问题
问题描述 最近在使用PostgreSQL中,对行记录进行设置创建时间(created_time)时,出现了设置了now()时间而数据库中写入的数据是不一致的数据。 eg: insert into dept ( created_at, updated_at) VALUES (now(),now())…...
Vue Router的使用
Vue.js是一个流行的JavaScript框架,用于开发单页面应用程序。Vue提供了一个强大的路由系统,可以帮助我们管理应用程序中的不同页面。在本文中,我们将详细讲解Vue路由的使用方法。 目录 1. 安装Vue Router2. 创建路由实例3. 配置路由4. 在模板…...
海外IP代理科普——API代理
随着互联网的不断发展,越来越多的企业开始使用API(应用程序接口)来实现数据的共享和交流。而在API使用中,海外代理IP也逐渐普及。那么,什么是API代理IP呢?它有什么作用?API接口有何用处…...
详解Python安装requests库的实例代码
文章目录 前言基本用法基本的get请求带参数的GET请求解析json关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前…...
Flutter 使用 device_info_plus 遇到的问题
问题:引用device_info_plus 插件出现了异常,不知道为啥打开项目的时候就不能用了。 解决:改了版本解决 Target of URI doesnt exist: package:device_info_plus/device_info_plus.dart. (Documentation) Try creating the file reference…...
论文阅读:“基于特征检测与深度特征描述的点云粗对齐算法”
文章目录 摘要简介相关工作粗对齐传统的粗对齐算法基于深度学习的粗对齐算法 特征检测及描述符构建 本文算法ISS 特征检测RANSAC 算法3DMatch 算法 实验结果参考文献 摘要 点云对齐是点云数据处理的重要步骤之一,粗对齐则是其中的难点。近年来,基于深度…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
