技术经验 • dingxiao • 阅读数:6569 • 2019年5月18日 12:29
u8g2是一个非常优秀的开源GUI库,现简单的将她的API梳理遍,详细API可以访问https://github.com/olikraus/u8g2/wiki/u8g2reference#begin学习。
测试中ESP32和0.91寸OLED连接关系如图,使用ESP32的I2C接口。
创建u8g2显示设备:
U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather M0 Basic Proto + FeatherWing OLED
其中管脚分配是GPIO22(SCL),GPIO21(SDA)。
u8g2初始化:
u8g2.begin(/* menu_select_pin= */ 13, /* menu_next_pin= */ U8X8_PIN_NONE, /* menu_prev_pin= */ U8X8_PIN_NONE, /* menu_up_pin= */ 4, /* menu_down_pin= */ 15, /* menu_home_pin= */ U8X8_PIN_NONE);
其中u8g2.begin是初始化接口,她还可以分配GUI显示过程中采用的按键管脚分配。按键数值的采集功能可以用户自定义修改。本初始化中使用了3个ESP32自带的电容Touch功能的GPIO分别作为按键输入。
其中T0(GPIO4-UP),T3(GPIO15-DOWN)和T4(GPIO13-SELECT)。
按键采集:
自定义覆盖原有按键采集操作,自定义函数uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8) 。
ESP32中具备Touch功能的管教为:GPIO4/0/2/15/13/12/14/27/33/32,分别对应T0-T9,目前测试发现T2存在bug,暂未使用,ESP32中的Touch功能参考:http://www.esp32learning.com/code/esp32-capacitive-touch-example.php。
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
{
touch_t0 = touchRead(T0);
if((touch_t0 < 12)&&(touch_t0 > 0))
touch_pan0 = true;
else
touch_pan0 = false;
touch_t3 = touchRead(T3);
if((touch_t3 < 12)&&(touch_t3 > 0))
touch_pan3 = true;
else
touch_pan3 = false;
touch_t4 = touchRead(T4);
if((touch_t4 < 12)&&(touch_t4 > 0))
touch_pan4 = true;
else
touch_pan4 = false;
if (touch_pan0) { return U8X8_MSG_GPIO_MENU_UP; }
if (touch_pan3) { return U8X8_MSG_GPIO_MENU_DOWN; }
if (touch_pan4) { return U8X8_MSG_GPIO_MENU_SELECT; }
}
典型的绘图模式为:
u8g2.firstPage();
do {
drawSometing...
} while ( u8g2.nextPage() );
使用u8g2.userInterfaceSelectionList创建应用菜单时,需要注意的是该API在创建List后将在创建的List中无线循环,对用户后台应用程序有影响。
// If Timer has fired
if (Timer_flag1 != 0)
{
Timer_flag1 = 0;
Serial.println("Going to sleep now");
}
Serial.println(String(Timer_flag));
delay(10);
//=================NAVEGACÃO===========类是一个while-始
if ( menu_inicial == 1 ) //
{
current_selection = u8g2.userInterfaceSelectionList(
"Menu Principal",
current_selection,
string_list
);
}
//=================NAVEGACÃO===========类是一个while-终
if ( current_selection == 0) {
u8g2.userInterfaceMessage(
"Nada Selecionado.",
"",
"",
" ok ");
}
上述代码在List创建后,Serial.println("Going to sleep now")不能被执行,必须要等List选择菜单后才能被执行。创建List后类似于一个while(1)的无限循环。current_selection = u8g2.userInterfaceSelectionList。
在应用中可以通过u8g2.getMenuEvent()来获得注册按键的键值,键值的获取方法函数可以自定义,与0x02中u8x8_GetMenuEvent描述的一致。
void loop(void) {
uint8_t e;
e = u8g2.getMenuEvent();
if ( e != 0 )
{
last_event = e;
}
draw();
}
在u8g2中使用中文需要有中文字库的支持,通过使用u8g2自带的中文示例可以掌握中文显示应用。
在应用中采用了开源的一个中文字库,地址为:https://github.com/larryli/u8g2_wqy。该开源字库包含5中规格的中文字库,可以根据需要进行裁剪,当然也可以通过其他方法生成需要使用的中文汉字的字库,方法见:https://github.com/larryli/u8g2_wqy/wiki/CustomFont。
我使用的了当中的一个尺寸的所有汉字的字库,并将其更名为:dx_gb2312。
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include "u8g2_wqy.h"
U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather M0 Basic Proto + FeatherWing OLED
void setup(void) {
u8g2.begin();
u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
}
void loop(void) {
// u8g2.setFont(u8g2_font_unifont_t_chinese3); // use chinese2 for all the glyphs of "你好世界"
u8g2.setFont(dx_gb2312); // use chinese2 for all the glyphs of "你好世界"
//u8g2.setFont(u8g2_font_b10_t_japanese1); // all the glyphs of "こんにちは世界" are already included in japanese1: Lerning Level 1-6
u8g2.setFontDirection(0);
u8g2.firstPage();
do {
u8g2.setCursor(0, 15);
u8g2.print("貂蝉-西施-杨贵妃");
u8g2.setCursor(0, 31);
u8g2.print("王昭君");
// u8g2.setCursor(0, 40);
// u8g2.print("你好世界"); // Chinese "Hello World"
//u8g2.print("こんにちは世界"); // Japanese "Hello World"
} while ( u8g2.nextPage() );
delay(1000);
}
其中#include "u8g2_wqy.h"是包含的字库头文件。
/**
* https://github.com/larryli/u8g2_wqy
*/
#ifndef _U8G2_WQY_H
#define _U8G2_WQY_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef U8G2_USE_LARGE_FONTS
#define U8G2_USE_LARGE_FONTS
#endif
#ifndef U8X8_FONT_SECTION
#ifdef __GNUC__
# define U8X8_SECTION(name) __attribute__ ((section (name)))
#else
# define U8X8_SECTION(name)
#endif
#if defined(__GNUC__) && defined(__AVR__)
# define U8X8_FONT_SECTION(name) U8X8_SECTION(".progmem." name)
#endif
#if defined(ESP8266)
# define U8X8_FONT_SECTION(name) __attribute__((section(".text." name)))
#endif
#ifndef U8X8_FONT_SECTION
# define U8X8_FONT_SECTION(name)
#endif
#endif
#ifndef U8G2_FONT_SECTION
#define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name)
#endif
//extern const uint8_t u8g2_font_wqy12_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_wqy12_t_chinese1");
//extern const uint8_t u8g2_font_wqy12_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_wqy12_t_chinese2");
//extern const uint8_t u8g2_font_wqy12_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_wqy12_t_chinese3");
extern const uint8_t dx_gb2312[] U8G2_FONT_SECTION("dx_gb2312");
//extern const uint8_t u8g2_font_wqy12_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_wqy12_t_gb2312a");
//extern const uint8_t u8g2_font_wqy12_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_wqy12_t_gb2312b");
//extern const uint8_t u8g2_font_wqy13_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_wqy13_t_chinese1");
//extern const uint8_t u8g2_font_wqy13_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_wqy13_t_chinese2");
//extern const uint8_t u8g2_font_wqy13_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_wqy13_t_chinese3");
//extern const uint8_t u8g2_font_wqy13_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_wqy13_t_gb2312");
//extern const uint8_t u8g2_font_wqy13_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_wqy13_t_gb2312a");
//extern const uint8_t u8g2_font_wqy13_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_wqy13_t_gb2312b");
//extern const uint8_t u8g2_font_wqy14_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_wqy14_t_chinese1");
//extern const uint8_t u8g2_font_wqy14_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_wqy14_t_chinese2");
//extern const uint8_t u8g2_font_wqy14_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_wqy14_t_chinese3");
//extern const uint8_t u8g2_font_wqy14_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_wqy14_t_gb2312");
//extern const uint8_t u8g2_font_wqy14_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_wqy14_t_gb2312a");
//extern const uint8_t u8g2_font_wqy14_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_wqy14_t_gb2312b");
//extern const uint8_t u8g2_font_wqy15_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_chinese1");
//extern const uint8_t u8g2_font_wqy15_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_chinese2");
//extern const uint8_t u8g2_font_wqy15_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_chinese3");
//extern const uint8_t u8g2_font_wqy15_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_gb2312");
//extern const uint8_t u8g2_font_wqy15_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_gb2312a");
//extern const uint8_t u8g2_font_wqy15_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_gb2312b");
//extern const uint8_t u8g2_font_wqy16_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_chinese1");
//extern const uint8_t u8g2_font_wqy16_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_chinese2");
//extern const uint8_t u8g2_font_wqy16_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_chinese3");
//extern const uint8_t u8g2_font_wqy16_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_gb2312");
//extern const uint8_t u8g2_font_wqy16_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_gb2312a");
//extern const uint8_t u8g2_font_wqy16_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_gb2312b");
#ifdef __cplusplus
}
#endif
#endif
项目的代码结构:
u8g2_font_wqy.c是字库文件,目前该字库文件包含了所有中文常用汉字。
u8g2自带很多字库形式,不同字符高度中又有很多种不同字体的字库,详情请参考:https://github.com/olikraus/u8g2/wiki/fntlistall。
u8g2中显示变量数值,需要采用的方法为:
u8x8.setFont(u8x8_font_amstrad_cpc_extended_r);
u8x8.setCursor(0, 0);
u8x8.print(VariableInUse);
u8g2库提高了三种显示模式。网址:https://github.com/olikraus/u8g2/wiki/setup_tutorial。
u8g2 full buffer,page buffer and u8x8 mode
page buffer mode(Picture Loop)
U8x8 character mode