授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。
1.玩转u8g2 OLED库,一篇就够
2.玩转u8g2 OLED库,一篇就够(字数太多 要分篇)
3.玩转u8g2 OLED库 + MAX7219_32X8点阵模块 (绝对被拒绝的表白神器)
4.玩转 RTC时钟库 + DS1302
5.玩转 RTC时钟库 + DS3231
6.玩转ArduinoJson库 V5版本
7.玩转ArduinoJson库 V6版本
8.玩转PubSubClient MQTT库
最近博主听到QQ群里面问得比较多的问题:
“博哥,有玩过OLED吗?”
“博哥,有试过在ESP8266上调成功过SSD1306吗?”
“博哥,OLED上显示天气信息怎么弄?”
…
诸如此类的问题,在博主看来,无非都是对OLED库用法的不熟悉甚至不了解。Arduino OLED库众多,博主也曾经介绍过一款 《博哥OLED系列》- 玩转SSD1306-12864 OLED Adafruit_GFX 和 Adafruit_SSD1306库。但是,博主今天要介绍的是目前Arduino平台上使用最广泛的OLED库 —— U8G2库,也是很多初学者容易懵逼的一个第三方库。目前在github上超过1K star,1800次commit,可以说维护热度很高,读者大可放心使用。
至于这个库为什么这么火爆,请读者认真看完本博文自行评价,博主只能说功能真的很好很强大!!!!
那么,博主首先立个flag,阅读完本篇博文的最终效果——读者以后在Arduino平台上开发OLED项目的时候,可以考虑U8G2库,并且知道U8G2库的具体用法,甚至可以能够当做工具书来翻阅。
进入正文之前,博主要给读者灌输两个个非常重要的知识点:
OLED其实就是一个M x n 的像素点阵,想显示什么就得把具体位置的像素点亮起来。对于每一个像素点,有可能是1点亮,也有可能是0点亮;
在坐标系中,左上角是原点,向右是X轴,向下是Y轴。
希望读者能仔细理解这两个知识点。
U8g2是嵌入式设备的单色图形库,一句话简单明了。主要应用于嵌入式设备,包括我们常见的单片机;
U8g2支持单色OLED和LCD,包括以下控制器:SSD1305,SSD1306,SSD1309,SSD1322,SSD1325,SSD1327,SSD1329,SSD1606,SSD1607,SH1106,SH1107,SH1108,SH1122,T6963,RA8835,LC7981,PCD8544,PCF8812,HX1230 ,UC1601,UC1604,UC1608,UC1610,UC1611,UC1701,ST7565,ST7567,ST7588,ST75256,NT7534,IST3020,ST7920,LD7032,KS0108,SED1520,SBN1661,IL3820,MAX7219(有关完整列表,请参见 此处)。
可以说,基本上主流的显示控制器都支持,比如我们常见的SSD1306 12864,读者在使用该库之前请查阅自己的OLED显示控制器是否处于支持列表中。
可以说基本上所有Arduino API的主板都得到U8g2的支持。包括:
所以说,读者完全不用担心兼容性问题,放心使用。
Arduino库U8g2可以从Arduino IDE的库管理器安装,读者在库管理器搜索“U8g2”关键字就可以下载安装:
下载完毕,测试一下库是否安装成功:
#include
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
编译成功,证明你本地已经加载了U8G2库。
为什么要运用U8g2库?也就是说U8g2库能带给我们什么样的开发便利。在博主看来,主要考虑几个方面:
以下是官方提供的一些U8G2库测试图,博主挑选了几张常见的以及附上U8G2库的配置(读者可以先不用理会配置,等看完博文再次阅读就会了解含义):
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R2, /* clock=*/ 16, /* data=*/ 17, /* reset=*/ U8X8_PIN_NONE); // ESP32 Thing, pure SW emulated I2C
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17); // ESP32 Thing, HW I2C with pin remapping
U8G2_MAX7219_32X8_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE);
U8G2_SSD1305_128X32_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(/* clock=A5*/ 19, /* data=A4*/ 18);
U8G2_PCD8544_84X48_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display
U8G2_ST7920_128X64_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18 /* A4 */, /*cs=*/ U8X8_PIN_NONE, /*dc/rs=*/ 17 /* A3 */, /*reset=*/ 15 /* A1 */); // Remember to set R/W to 0
这只是一些常见的显示器,可以说,已经足够覆盖到我们常见的范围了。
方法可以分为四大类:
函数说明:
/**
* 初始化U8g2库
* @Note 关联方法 initDisplay clearDisplay setPowerSave
*/
bool U8G2::begin(void)
源码说明:
bool begin(void) {
/* note: call to u8x8_utf8_init is not required here, this is done in the setup procedures before */
initDisplay(); //初始化显示器
clearDisplay(); // 重置清屏
setPowerSave(0); //唤醒屏幕
return 1;
}
函数说明:
/**
* 简单初始化U8g2库
* @Note 关联方法 beginSimple
*/
void U8G2::beginSimple(void);
源码说明:
void beginSimple(void) {
/* does not clear the display and does not wake up the display */
/* user is responsible for calling clearDisplay() and setPowerSave(0) */
initDisplay();//初始化显示器
}
注意点:
函数说明:
/**
* 初始化显示控制器
*/
void U8G2::initDisplay(void)
注意点:
函数说明:
/**
* 清除屏幕
*/
void U8G2::clearDisplay(void)
注意点:
函数说明:
/**
* 清除显示缓冲区
* @param is_enable
* 1 表示启用显示器的省电模式,屏幕上看不到任何东西
* 0 表示禁用省电模式
*/
void U8G2::setPowerSave(uint8_t is_enable)
注意点:
函数说明:
/**
* 清除屏幕显示,清除缓冲区,光标回到左上角原点位置(0,0)
* @Note 关联方法 home clearDisplay clearBuffer
*/
void U8G2::clear(void)
源码说明:
void clear(void) {
home(); //回到原点
clearDisplay(); //清除屏幕上的显示
clearBuffer(); //清除缓冲区
}
函数说明:
/**
* 清除内存中数据缓冲区
*/
void U8G2::clearBuffer(void)
注意点:
void loop(void) {
u8g2.clearBuffer();
// ... write something to the buffer
u8g2.sendBuffer();
delay(1000);
}
函数说明:
/**
* 禁用Arduino平台下支持输出UTF8字符集,默认是开启
*/
void U8G2::disableUTF8Print(void)
函数说明:
/**
* 开启Arduino平台下支持输出UTF8字符集
*/
void U8G2::enableUTF8Print(void)
注意点:
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);
}
函数说明:
/**
* 重置显示光标的位置,回到原点(0,0)
* @Note 关联方法 print clear
*/
void U8G2::home(void)
函数说明:
/**
* 画实心方形,左上角坐标为(x,y),宽度为w,高度为h
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @param w 方形的宽度
* @param h 方形的高度
* @Note 关联方法 drawFrame setDrawColor
*/
void U8G2::drawBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
注意点:
示例:
u8g2.drawBox(3,7,25,15);
函数说明:
/**
* 画空心圆,圆心坐标为(x0,y0),半径为rad
* @param x0 圆点的x坐标
* @param y0 圆点的y坐标
* @param rad 圆形的半径
* @param opt 圆形选项
* U8G_DRAW_ALL 整个圆
* U8G2_DRAW_UPPER_RIGHT 右上部分的圆弧
* U8G2_DRAW_UPPER_LEFT 左上部分的圆弧
* U8G2_DRAW_LOWER_LEFT 左下部分的圆弧
* U8G2_DRAW_LOWER_RIGHT 右下部分的圆弧
* 选项可以通过 | 操作符来组合
* @Note 关联方法 drawDisc setDrawColor
*/
void U8G2::drawCircle(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G2_DRAW_ALL)
注意点:
示例:
u8g2.drawCircle(20, 25, 10, U8G2_DRAW_ALL);
函数说明:
/**
* 画实心圆,圆心坐标为(x0,y0),半径为rad
* @param x0 圆点的x坐标
* @param y0 圆点的y坐标
* @param rad 圆形的半径
* @param opt 圆形选项
* U8G_DRAW_ALL 整个圆
* U8G2_DRAW_UPPER_RIGHT 右上部分的圆弧
* U8G2_DRAW_UPPER_LEFT 左上部分的圆弧
* U8G2_DRAW_LOWER_LEFT 左下部分的圆弧
* U8G2_DRAW_LOWER_RIGHT 右下部分的圆弧
* 选项可以通过 | 操作符来组合
* @Note 关联方法 drawCircle setDrawColor
*/
void U8G2::drawDisc(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G_DRAW_ALL)
注意点:
函数说明:
/**
* 画空心椭圆,圆心坐标为(x0,y0),半径为rad
* @param x0 圆点的x坐标
* @param y0 圆点的y坐标
* @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 关联方法 drawCircle
*/
void U8G2::drawEllipse(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t opt)
注意点:
示例:
u8g2.drawEllipse(20, 25, 15, 10, U8G2_DRAW_ALL);
函数说明:
/**
* 画实心椭圆,圆心坐标为(x0,y0),半径为rad
* @param x0 圆点的x坐标
* @param y0 圆点的y坐标
* @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 关联方法 drawCircle
*/
void U8G2::drawFilledEllipse(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t opt)
注意点:
函数说明:
/**
* 画空心方形,左上角坐标为(x,y),宽度为w,高度为h
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @param w 方形的宽度
* @param h 方形的高度
* @Note 关联方法 setDrawColor
*/
void U8G2::drawFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
注意点:
示例:
u8g2.drawFrame(3,7,25,15);
函数说明:
/**
* 绘制字体字集里面定义的符号
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @param encoding 字符的unicode值
* @Note 关联方法 setFont
*/
void U8G2::drawGlyph(u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
注意点:
函数说明:
/**
* 绘制水平线
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @param w 水平线的长度
* @Note 关联方法 setDrawColor
*/
void U8G2::drawHLine(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)
注意点:
函数说明:
/**
* 绘制线,从坐标(x0,y0) 到(x1,y1)
* @param x0 端点0的x坐标
* @param y0 端点0的y坐标
* @param x1 端点1的x坐标
* @param y1 端点1的y坐标
* @Note 关联方法 setDrawColor
*/
void U8G2::drawLine(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1)
注意点:
示例:
u8g2.drawLine(20, 5, 5, 32);
函数说明:
/**
* 绘制像素点,坐标(x,y)
* @param x 像素点的x坐标
* @param y 像素点的y坐标
* @Note 关联方法 setDrawColor
*/
void U8G2::drawPixel(u8g2_uint_t x, u8g2_uint_t y)
注意点:
函数说明:
/**
* 绘制圆角实心方形,左上角坐标为(x,y),宽度为w,高度为h,圆角半径为r
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @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)
注意点:
函数说明:
/**
* 绘制圆角空心方形,左上角坐标为(x,y),宽度为w,高度为h,圆角半径为r
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @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)
注意点:
示例:
u8g2.drawRFrame(20,15,30,22,7);
函数说明:
/**
* 绘制字符串
* @param x 左上角的x坐标
* @param y 左上角的y坐标
* @param s 绘制字符串内容
* @return 字符串的长度
*/
u8g2_uint_t U8g2::drawStr(u8g2_uint_t x, u8g2_uint_t y, const char *s)
注意点:
示例:
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0,15,"Hello World!");
函数说明:
/**
* 绘制实心三角形,定点坐标分别为(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)
示例:
u8g2.drawTriangle(20,5, 27,50, 5,32);
函数说明:
/**
* 绘制UTF8编码的字符串
* @param x 字符串在屏幕上的左下角x坐标
* @param y 字符串在屏幕上的左下角y坐标
* @param s 需要绘制的UTF-8编码字符串
* @return 返回字符串的长度
*/
u8g2_uint_t U8g2::drawUTF8(u8g2_uint_t x, u8g2_uint_t y, const char *s)
注意点:
示例:
u8g2.setFont(u8g2_font_unifont_t_symbols);
u8g2.drawUTF8(5, 20, "Snowman: ☃");
函数说明:
/**
* 绘制竖直线
* @param x 左上角坐标x
* @param y 左上角坐标y
* @param h 高度
*/
void U8G2::drawVLine(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t h)
函数说明:
/**
* 绘制图像
* @param x 左上角坐标x
* @param y 左上角坐标y
* @param w 图形宽度
* @param h 图形高度
* @param bitmap 图形内容
* @Note 关联方法 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)
注意点:
函数说明:
/**
* 绘制图像
*/
void U8G2::firstPage(void)
uint8_t U8G2::nextPage(void)
注意点:
优势点:
示例:
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() );
库源码解析:
void u8g2_FirstPage(u8g2_t *u8g2)
{
if ( u8g2->is_auto_page_clear )
{
//清除缓冲区
u8g2_ClearBuffer(u8g2);
}
//设置当前缓冲区的Tile Row 一个Tile等于8个像素点的高度
u8g2_SetBufferCurrTileRow(u8g2, 0);
}
uint8_t u8g2_NextPage(u8g2_t *u8g2)
{
uint8_t row;
u8g2_send_buffer(u8g2);
row = u8g2->tile_curr_row;
row += u8g2->tile_buf_height;
if ( row >= u8g2_GetU8x8(u8g2)->display_info->tile_height )
{
//如果row已经到达最后一行,触发refreshDisplay调用,表示整个页面已经刷完了
u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );
return 0;
}
if ( u8g2->is_auto_page_clear )
{
//清除缓冲区
u8g2_ClearBuffer(u8g2);
}
//不断更新TileRow 这是非常关键的一步
u8g2_SetBufferCurrTileRow(u8g2, row);
return 1;
}
函数说明:
/**
* 绘制内容
* @Note 关联方法 setFont setCursor enableUTF8Print
*/
void U8G2::print(...)
示例:
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 15);
u8g2.print("Hello World!");
函数说明:
/**
* 绘制缓冲区的内容
* @Note 关联方法 clearBuffer
*/
void U8G2::sendBuffer(void)
注意点:
库源码解析:
void u8g2_SendBuffer(u8g2_t *u8g2)
{
u8g2_send_buffer(u8g2);
u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );
}
static void u8g2_send_tile_row(u8g2_t *u8g2, uint8_t src_tile_row, uint8_t dest_tile_row)
{
uint8_t *ptr;
uint16_t offset;
uint8_t w;
w = u8g2_GetU8x8(u8g2)->display_info->tile_width;
offset = src_tile_row;
ptr = u8g2->tile_buf_ptr;
offset *= w;
offset *= 8;
ptr += offset;
u8x8_DrawTile(u8g2_GetU8x8(u8g2), 0, dest_tile_row, w, ptr);
}
/*
write the buffer to the display RAM.
For most displays, this will make the content visible to the user.
Some displays (like the SSD1606) require a u8x8_RefreshDisplay()
*/
static void u8g2_send_buffer(u8g2_t *u8g2) U8X8_NOINLINE;
static void u8g2_send_buffer(u8g2_t *u8g2)
{
uint8_t src_row;
uint8_t src_max;
uint8_t dest_row;
uint8_t dest_max;
src_row = 0;
src_max = u8g2->tile_buf_height;
dest_row = u8g2->tile_curr_row;
dest_max = u8g2_GetU8x8(u8g2)->display_info->tile_height;
do
{
u8g2_send_tile_row(u8g2, src_row, dest_row);
src_row++;
dest_row++;
} while( src_row < src_max && dest_row < dest_max );
}
示例:
void loop(void) {
u8g2.clearBuffer();
// ... write something to the buffer
u8g2.sendBuffer();
delay(1000);
函数说明:
/**
* 获取基准线以上的高度
* @return 返回高度值
* @Note 关联方法 setFont getDescent setFontRefHeightAll
*/
int8_t U8G2::getAscent(void)
注意点:
函数说明:
/**
* 获取基准线以下的高度
* @return 返回高度值
* @Note 关联方法 setFont setFontRefHeightAll
*/
int8_t U8G2::getDescent(void)
注意点:
示例:
下面例子,descent是-5
函数说明:
/**
* 获取显示器的高度
* @return 返回高度值
*/
u8g2_uint_t getDisplayHeight(void)
函数说明:
/**
* 获取显示器的宽度
* @return 返回宽度值
*/
u8g2_uint_t getDisplayWidth(void)
函数说明:
/**
* 获取当前字体里的最大字符的高度
* @return 返回高度值
* @Note 关联方法 setFont
*/
u8g2_uint_t getMaxCharHeight(void)
注意点:
函数说明:
/**
* 获取当前字体里的最大字符的宽度
* @return 返回宽度值
* @Note 关联方法 setFont
*/
u8g2_uint_t getMaxCharWidth(void)
注意点:
函数说明:
/**
* 获取字符串的像素宽度
* @param s 绘制字符串
* @return 返回字符串的像素宽度值
* @Note 关联方法 setFont drawStr
*/
u8g2_uint_t U8G2::getStrWidth(const char *s)
注意点:
函数说明:
/**
* 获取UTF-8字符串的像素宽度
* @param s 绘制字符串
* @return 返回字符串的像素宽度值
* @Note 关联方法 setFont drawStr
*/
u8g2_uint_t U8G2::getUTF8Width(const char *s)
注意点:
函数说明:
/**
* 是否自动清除缓冲区
* @param mode 0 表示关闭
* 1 表示开启,默认是开启
*/
void U8G2::setAutoPageClear(uint8_t mode)
注意点:
函数说明:
/**
* 设置位图模式(定义drawXBM方法是否绘制背景颜色)
* @param is_transparent
* 0 绘制背景颜色,不透明,默认是该值
* 1 不绘制背景颜色,透明
* @Note 关联方法 drawXBM
*/
void U8G2::setBitmapMode(uint8_t is_transparent)
示例:
u8g2.setDrawColor(1);
u8g2.setBitmapMode(0);
u8g2.drawXBM(4,3, u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
u8g2.drawXBM(12,11, u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
u8g2.setDrawColor(1);
u8g2.setBitmapMode(1);
u8g2.drawXBM(4,3, u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
u8g2.drawXBM(12,11, u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
函数说明:
/**
* 设置总线时钟(I2C SPI)
* @param mode clock_speed 总线时钟频率(Hz)
* @Note 关联方法 begin
*/
void U8G2::setBusClock(uint32_t clock_speed);
注意点:
函数说明:
/**
* 设置采集窗口,窗口范围从左上角(x0,y0)到右下角(x1,y1)
* 也就是我们绘制的内容只能在规范范围内显示
* @param x0 左上角x坐标
* @param y0 左上角y坐标
* @param x1 右上角x坐标
* @param y1 右上角y坐标
* @Note 关联方法 begin
*/
void U8G2::setClipWindow(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1 );
注意点:
void U8G2::setMaxClipWindow(void)
示例:
u8g2.setClipWindow(10, 10, 85, 30);
u8g2.setDrawColor(1);
u8g2.drawStr(3, 32, "U8g2");
函数说明:
/**
* 设置绘制光标位置(x,y)
* @Note 关联方法 print
*/
void U8G2::setCursor(u8g2_uint_t x, u8g2_uint_t y)
示例:
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 15);
u8g2.print("Hello World!");
函数说明:
/**
* 设置显示器的旋转角度
* @param u8g2_cb 旋转选项
* U8G2_R0 不做旋转 水平
* U8G2_R1 旋转90度
* U8G2_R2 旋转180度
* U8G2_R3 旋转270度
* U8G2_MIRROR 不做旋转 水平,显示内容是镜像的,暂时不理解
*/
void setDisplayRotation(const u8g2_cb_t *u8g2_cb)
函数说明:
/**
* 设置绘制颜色(暂时还没有具体去了解用法)
*/
void U8G2::setDrawColor(uint8_t color)
这是一个非常重要的方法,非常重要!!!
函数说明:
/**
* 设置字体集(字体集用于字符串绘制方法或者glyph绘制方法)
* @param font 具体的字体集
* @Note 关联方法 drawUTF8 drawStr drawGlyph print
*/
void U8G2::setFont(const uint8_t *font)
Font会根据像素点高度做了很多区分,具体font请参考 wiki。
如果我们需要用到中文字符,可以在wiki里面搜索一下chinese,你就会发现很多中文font,比如:
//支持UTF-8或者GB2312编码
u8g2_font_wqy15_t_chinese1
u8g2_font_wqy15_t_chinese2
u8g2_font_wqy15_t_chinese3
u8g2_font_wqy12_t_gb2312
u8g2_font_wqy12_t_gb2312a
......
注意点:
至于用哪一个,看自己的需求了。
我们看看Font的命名规则:
<prefix> '_' <name> '_' <purpose> <char set>
其中:
描述 | |
---|---|
t | Transparent font, Do not use a background color. |
h | All glyphs have common height(所有的图形有通用的高度). |
m | All glyphs have common height and width (monospace). |
8 | All glyphs fit into a 8x8 pixel box. |
描述 | |
---|---|
f | The font includes up to 256 glyphs. |
r | Only glyphs on the range of the ASCII codes 32 to 127 are included in the font. |
u | Only glyphs on the range of the ASCII codes 32 to 95 (uppercase chars) are included in the font. |
n | Only numbers and extra glyphs for writing date and time strings are included in the font. |
… | Other custom character list. |
注意点:
示例:Fonts u8g2_font_5x7_tr and u8g2_font_pressstart2p_8u
函数说明:
/**
* 定义字符串绘制或者图形绘制的方向
* @param dir 方向
* @param 关联方法 drawStr
*/
void U8G2::setFontDirection(uint8_t dir)
注意点:
Argument | String Rotation | Description |
---|---|---|
0 | 0 degree | Left to right |
1 | 90 degree | Top to down |
2 | 180 degree | Right to left |
3 | 270 degree | Down to top |
示例:
u8g2.setFont(u8g2_font_ncenB14_tf);
u8g2.setFontDirection(0);
u8g2.drawStr(15, 20, "Abc");
u8g2.setFontDirection(1);
u8g2.drawStr(15, 20, "Abc");
缓存相关函数,一般不会去操作,了解即可;
函数说明
/**
* 获取缓存空间的地址
* @return 返回缓存空间起始地址
* @Note 关联方法 getBufferTileHeight, getBufferTileWidth, clearBuffer
*/
uint8_t *U8G2::getBufferPtr(void)
注意点:
函数说明
/**
* 获取缓冲区的Tile高度
* @return 返回高度值
*/
uint8_t U8G2::getBufferTileHeight(void)
注意点:
函数说明
/**
* 获取缓冲区的Tile宽度
* @return 返回宽度值
*/
uint8_t U8G2::getBufferTileWidth(void)
注意点:
函数说明
/**
* 获取缓冲区的当前Tile row行数
* @return 返回当前的tilerow
*/
uint8_t U8G2::getBufferCurrTileRow(void)
注意点:
函数说明
/**
* 设置缓冲区的当前Tile row
* @param 当前的tilerow
*/
void U8G2::setBufferCurrTileRow(uint8_t row)
注意点:
示例:
u8g2.setBufferCurrTileRow(0); // let y=0 be the topmost row of the buffer
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(2, 8, "abcdefg");
u8g2.setBufferCurrTileRow(2); // write the buffer to tile row 2 (y=16) on the display
u8g2.sendBuffer();
u8g2.setBufferCurrTileRow(4); // write the same buffer to tile row 4 (y=32) on the display
u8g2.sendBuffer();
利用好该方法,我们可以实现部分更新;
前面博主介绍到U8G2适配了绝大部分的OLED,那么我们如何构建具体的OLED驱动呢?可分为以下几个顺序步骤:
首先,你需要知道OLED显示器的控制器型号以及屏幕大小。举个例子,博主手上有一块SSD1306 128X64的OLED,那么它的控制器就是SSD1306,屏幕大小是128X64。
其次,你所选择的OLED必须在U8g2库所支持的OLED列表中,具体可参考 链接地址。
图像信息是通过物理总线方式发给OLED显示器。通常,我们的总线包括:
具体的OLED使用什么物理总线,我们需要查阅各自的数据手册。比如,博主的SSD1306就是IIC。
知道了物理连线模式之后,我们一般都是把OLED连接到Arduino Board的输出引脚,也就是软件模拟具体总线协议。当然,如果有现成的物理总线端口那就更好了。
经历以上三步之后,我们就可以开始初始化出具体的OLED驱动了。比如,博主的IIC SSD1306 128X64 的OLED,就可以用以下初始化构造器(Builder设计模式,有空可以去了解一下):
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
当然SSD1306还有其他构造器(具体可以参考 wiki):
Controller “ssd1306”, Display “128x64_noname” | Descirption |
---|---|
U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI(rotation, clock, data, cs, dc [, reset]) | page buffer, size = 128 bytes |
U8G2_SSD1306_128X64_NONAME_2_4W_SW_SPI(rotation, clock, data, cs, dc [, reset]) | page buffer, size = 256 bytes |
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI(rotation, clock, data, cs, dc [, reset]) | full framebuffer, size = 1024 bytes |
U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI(rotation, cs, dc [, reset]) | page buffer, size = 128 bytes |
那么,我们这里就需要重点讲述一下构造器的规则。
构造器的名字包括以下几方面:
No | Description | Example |
---|---|---|
1 | Prefix | U8G2 |
2 | Display Controller | SSD1306 |
3 | Display Name | 128X64_NONAME |
4 | Buffer Size | 1, 2 or F (full frame buffer) |
5 | Communication | 4W_SW_SPI |
它们之间使用"_"连接起来。其中:
BufferSize | Description |
---|---|
1 | 保持一页的缓冲区,用于firstPage/nextPage的PageMode. |
2 | 保持两页的缓冲区,用于firstPage/nextPage的PageMode… |
F | 获取整个屏幕的缓冲区,ram消耗大,一般用在ram空间比较大的arduino板子. |
Communication | Description |
---|---|
4W_SW_SPI | 4-wire (clock, data, cs and dc) software emulated SPI |
4W_HW_SPI | 4-wire (clock, data, cs and dc) hardware SPI (based on Arduino SPI library) |
2ND_4W_HW_SPI | If supported, second 4-wire hardware SPI (based on Arduino SPI library) |
3W_SW_SPI | 3-wire (clock, data and cs) software emulated SPI |
SW_I2C | Software emulated I2C/TWI |
HW_I2C | Hardware I2C based on the Arduino Wire library |
2ND_HW_I2C | If supported, use second hardware I2C (Arduino Wire lib) |
6800 | 8-bit parallel interface, 6800 protocol |
8080 | 8-bit parallel interface, 8080 protocol |
Rotation/Mirror | Description |
---|---|
U8G2_R0 | No rotation, landscape |
U8G2_R1 | 90 degree clockwise rotation |
U8G2_R2 | 180 degree clockwise rotation |
U8G2_R3 | 270 degree clockwise rotation |
U8G2_MIRROR | No rotation, landscape, display content is mirrored (v2.6.x) |
所以,一个完整的例子为:
#include
#include
#include
#include
U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, 13, 11, 10, 8);
void setup(void) {
u8g2.begin();
}
void loop(void) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0,24,"Hello World!");
} while ( u8g2.nextPage() );
}
那么,我们来看看到底构造器里面做了什么操作?还是以博主使用的SSD1306 128X64为例子:
/**
* SSD1306 4线软件模拟SPI
*/
U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI(.....)
类定义:
/**
* SSD1306构造器,继承U8G2
*/
class U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI : public U8G2 {
public: U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset = U8X8_PIN_NONE) : U8G2() {
//配置SSD1306
u8g2_Setup_ssd1306_128x64_noname_1(&u8g2, rotation, u8x8_byte_arduino_4wire_sw_spi, u8x8_gpio_and_delay_arduino);
//设置通信协议
u8x8_SetPin_4Wire_SW_SPI(getU8x8(), clock, data, cs, dc, reset);
}
};
从上面代码看出,默认调用了父类U8G2的构造函数,我们看看它里面做了什么:
class U8G2 : public Print
{
protected:
u8g2_t u8g2;
u8x8_char_cb cpp_next_cb; /* the cpp interface has its own decoding function for the Arduino print command */
public:
u8g2_uint_t tx, ty;
U8G2(void) {
//设置Arduino print函数的解码方法,这里是ASCII,当然也有UTF-8
cpp_next_cb = u8x8_ascii_next;
//屏幕初始化
home();
}
.......
然后我们看看,u8g2_Setup_ssd1306_128x64_noname_1做了什么:
void u8g2_Setup_ssd1306_128x64_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{
uint8_t tile_buf_height;
//定义好缓存空间 记住 这里是 1 page mode
uint8_t *buf;
//配置屏幕
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb);
//生成buf 这里是128 bytes
buf = u8g2_m_16_8_1(&tile_buf_height);
//初始化buf
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
}
/*============================================*/
/*
This procedure is called after setting up the display (u8x8 structure).
--> This is the central init procedure for u8g2 object
*/
void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_draw_ll_hvline_cb ll_hvline_cb, const u8g2_cb_t *u8g2_cb)
{
u8g2->font = NULL;
//u8g2->kerning = NULL;
//u8g2->get_kerning_cb = u8g2_GetNullKerning;
//u8g2->ll_hvline = u8g2_ll_hvline_vertical_top_lsb;
u8g2->ll_hvline = ll_hvline_cb;
u8g2->tile_buf_ptr = buf;
u8g2->tile_buf_height = tile_buf_height;
u8g2->tile_curr_row = 0;//页码 这是一个很重要的参数
u8g2->font_decode.is_transparent = 0; /* issue 443 */
u8g2->bitmap_transparency = 0;
u8g2->draw_color = 1;
u8g2->is_auto_page_clear = 1;//自动清除
u8g2->cb = u8g2_cb;
u8g2->cb->update_dimension(u8g2);
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_SetMaxClipWindow(u8g2); /* assign a clip window and call the update() procedure */
#else
u8g2->cb->update_page_win(u8g2);
#endif
u8g2_SetFontPosBaseline(u8g2); /* issue 195 */
#ifdef U8G2_WITH_FONT_ROTATION
u8g2->font_decode.dir = 0;
#endif
}
可以总结几点:
注意点:
U8g2支持三种绘制模式:
特点:
构造器:
U8G2_ST7920_128X64_F_SW_SPI(rotation, clock, data, cs [, reset])
用法:
示例代码:
void setup(void) {
u8g2.begin();
}
void loop(void) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0,20,"Hello World!");
u8g2.sendBuffer();
}
特点:
构造器:
U8G2_ST7920_128X64_ 1 _SW_SPI(rotation, clock, data, cs [, reset])
用法:
示例代码:
void setup(void) {
u8g2.begin();
}
void loop(void) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0,24,"Hello World!");
} while ( u8g2.nextPage() );
}
特点:
构造器:
U8X8_ST7565_EA_DOGM128_4W_SW_SPI(clock, data, cs, dc [, reset])
用法:
示例代码:
void setup(void) {
u8x8.begin();
}
void loop(void) {
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.drawString(0,1,"Hello World!");
}
上面讲解了那么多理论知识,是时候去实际运用。博主在这里选用了Arduino Mega2560 以及 NodeMcu ESP8266开发板,结合手上的SSD1306 OLED去讲解例子。
实验内容:
实验器材:
实验代码:
/*
HelloWorld.ino
*/
#include
#include
#ifdef U8X8_HAVE_HW_SPI
#include
#endif
#ifdef U8X8_HAVE_HW_I2C
#include
#endif
/*
U8g2lib Example Overview:
Frame Buffer Examples: clearBuffer/sendBuffer. Fast, but may not work with all Arduino boards because of RAM consumption
Page Buffer Examples: firstPage/nextPage. Less RAM usage, should work with all Arduino boards.
U8x8 Text Only Example: No RAM usage, direct communication with display controller. No graphics, 8x8 Text only.
*/
// Please UNCOMMENT one of the contructor lines below
// U8g2 Contructor List (Frame Buffer)
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
// Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
//U8G2_NULL u8g2(U8G2_R0); // null device, a 8x8 pixel display which does nothing
//U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6); // Arduboy (Production, Kickstarter Edition)
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 16, /* data=*/ 17, /* reset=*/ U8X8_PIN_NONE); // ESP32 Thing, pure SW emulated I2C
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17); // ESP32 Thing, HW I2C with pin remapping
//U8G2_SSD1306_128X64_NONAME_F_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
//U8G2_SSD1306_128X64_VCOMH0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range
//U8G2_SSD1306_128X64_ALT0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
//U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1106_128X64_VCOMH0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range
//U8G2_SH1106_128X64_WINSTAR_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but uses updated SH1106 init sequence
//U8G2_SH1106_72X40_WISE_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SH1107_64X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SH1107_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SH1107_128X128_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
//U8G2_SH1107_PIMORONI_128X128_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8);
//U8G2_SH1107_SEEED_128X128_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1107_SEEED_128X128_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1107_SEEED_96X96_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SH1108_160X160_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SH1122_256X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
//U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 21, /* data=*/ 20, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather M0 Basic Proto + FeatherWing OLED
//U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED
//U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Adafruit ESP8266/32u4/ARM Boards + FeatherWing OLED
//U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA); // pin remapping with ESP8266 HW I2C
//U8G2_SSD1306_128X32_WINSTAR_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA); // pin remapping with ESP8266 HW I2C
//U8G2_SSD1306_64X48_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.66" OLED breakout board, Uno: A4=SDA, A5=SCL, 5V powered
//U8G2_SSD1306_48X64_WINSTAR_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_64X32_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_96X16_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // EastRising 0.69" OLED
//U8G2_SSD1322_NHD_256X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
//U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8G2_16BIT in u8g2.h
//U8G2_SSD1322_NHD_128X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1322_NHD_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1325_NHD_128X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD0323_OS128064_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD0323_OS128064_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1326_ER_256X32_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // experimental driver for ER-OLED018-1
//U8G2_SSD1327_SEEED_96X96_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96
//U8G2_SSD1327_SEEED_96X96_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96
//U8G2_SSD1327_EA_W128128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1327_EA_W128128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1327_EA_W128128_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 4, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1327_EA_W128128_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1327_MIDAS_128X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1327_MIDAS_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1327_WS_128X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1327_WS_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1329_128X96_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1329_128X96_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1305_128X32_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1305_128X32_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1305_128X32_ADAFRUIT_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1305_128X32_ADAFRUIT_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1305_128X64_ADAFRUIT_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1305_128X64_ADAFRUIT_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1309_128X64_NONAME0_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1309_128X64_NONAME0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1309_128X64_NONAME2_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1309_128X64_NONAME2_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1317_96X96_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // not tested, not confirmed
//U8G2_SSD1317_96X96_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // not tested, not confirmed
//U8G2_SSD1318_128X96_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1318_128X96_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_LD7032_60X32_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 9, /* dc=*/ 10, /* reset=*/ 8); // SW SPI Nano Board
//U8G2_LD7032_60X32_F_4W_SW_I2C u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* reset=*/ U8X8_PIN_NONE); // NOT TESTED!
//U8G2_UC1701_EA_DOGS102_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_UC1701_EA_DOGS102_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display
//U8G2_PCD8544_84X48_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Nokia 5110 Display
//U8G2_PCF8812_96X65_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814
//U8G2_PCF8812_96X65_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Could be also PCF8814
//U8G2_HX1230_96X68_F_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
//U8G2_HX1230_96X68_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_KS0108_128X64_F u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low!
//U8G2_KS0108_ERM19264_F u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ 16, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low!
//U8G2_ST7920_192X32_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE);
//U8G2_ST7920_192X32_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
//U8G2_ST7920_128X64_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18 /* A4 */, /*cs=*/ U8X8_PIN_NONE, /*dc/rs=*/ 17 /* A3 */, /*reset=*/ 15 /* A1 */); // Remember to set R/W to 0
//U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE);
//U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);
//U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 14, /* data=*/ 13, /* CS=*/ 15, /* reset=*/ 16); // Feather HUZZAH ESP8266, E=clock=14, RW=data=13, RS=CS
//U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);
//U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS=*/ 15, /* reset=*/ 16); // Feather HUZZAH ESP8266, E=clock=14, RW=data=13, RS=CS
//U8G2_ST7565_EA_DOGM128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_EA_DOGM128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_64128N_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_64128N_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_EA_DOGM132_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); // DOGM132 Shield
//U8G2_ST7565_EA_DOGM132_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE); // DOGM132 Shield
//U8G2_ST7565_ZOLEN_128X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_ZOLEN_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_LM6059_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Adafruit ST7565 GLCD
//U8G2_ST7565_LM6059_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Adafruit ST7565 GLCD
//U8G2_ST7565_LX12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_LX12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_ERC12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_ERC12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_ERC12864_ALT_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // contrast improved version for ERC12864
//U8G2_ST7565_ERC12864_ALT_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // contrast improved version for ERC12864
//U8G2_ST7565_NHD_C12832_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_NHD_C12832_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_NHD_C12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_NHD_C12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_JLX12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7565_JLX12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_PI_132X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6
//U8G2_ST7567_PI_132X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8); // Pax Instruments Shield, LCD_BL=6
//U8G2_ST7567_JLX12864_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_JLX12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_ENH_DG128064_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_ENH_DG128064_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_ENH_DG128064I_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_ENH_DG128064I_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7567_64X32_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_ST75256_JLX172104_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST75256_JLX172104_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST75256_JLX19296_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST75256_JLX19296_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST75256_JLX256128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16 bit mode for this display
//U8G2_ST75256_JLX256128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16 bit mode for this display
//U8G2_ST75256_WO256X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16 bit mode for this display
//U8G2_ST75256_WO256X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16 bit mode for this display
//U8G2_ST75256_JLX256128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 9, /* data=*/ 8, /* cs=*/ 7, /* dc=*/ 6, /* reset=*/ 5); // MKR Zero, Enable U8g2 16 bit mode for this display
//U8G2_ST75256_JLX256128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 6, /* reset=*/ 5); // MKR Zero, Enable U8g2 16 bit mode for this display
//U8G2_ST75256_JLX256160_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16 bit mode for this display
//U8G2_ST75256_JLX256160_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Enable U8g2 16 bit mode for this display
//U8G2_ST75256_JLX240160_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST75256_JLX240160_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST75256_JLX25664_F_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, enable U8g2 16 bit mode for this display
//U8G2_NT7534_TG12864R_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_NT7534_TG12864R_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_ST7588_JLX12864_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ 5);
//U8G2_ST7588_JLX12864_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 5);
//U8G2_IST3020_ERC19264_F_6800 u8g2(U8G2_R0, 44, 43, 42, 41, 40, 39, 38, 37, /*enable=*/ 28, /*cs=*/ 32, /*dc=*/ 30, /*reset=*/ 31); // Connect WR pin with GND
//U8G2_IST3020_ERC19264_F_8080 u8g2(U8G2_R0, 44, 43, 42, 41, 40, 39, 38, 37, /*enable=*/ 29, /*cs=*/ 32, /*dc=*/ 30, /*reset=*/ 31); // Connect RD pin with 3.3V
//U8G2_IST3020_ERC19264_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_LC7981_160X80_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
//U8G2_LC7981_160X160_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
//U8G2_LC7981_240X128_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
//U8G2_LC7981_240X64_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RW with GND
//U8G2_SED1520_122X32_F u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*dc=*/ A0, /*e1=*/ A3, /*e2=*/ A2, /* reset=*/ A4); // Set R/W to low!
//U8G2_T6963_240X128_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
//U8G2_T6963_256X64_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
//U8G2_T6963_160X80_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
//U8G2_T6963_128X64_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
//U8G2_T6963_128X64_ALT_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable/wr=*/ 17, /*cs/ce=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FS0 and FS1 with GND
//U8G2_SED1330_240X128_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect RD with +5V, FG with GND
//U8G2_SED1330_240X128_F_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); // A0 is dc pin!
//U8G2_RA8835_NHD_240X128_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // Connect /RD = E with +5V, enable is /WR = RW, FG with GND, 14=Uno Pin A0
//U8G2_RA8835_NHD_240X128_F_6800 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 17, /*cs=*/ 14, /*dc=*/ 15, /*reset=*/ 16); // A0 is dc pin, /WR = RW = GND, enable is /RD = E
//U8G2_UC1604_JLX19264_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_UC1604_JLX19264_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_UC1608_ERC24064_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup
//U8G2_UC1608_ERC240120_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_UC1608_240X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // SW SPI, Due ERC24064-1 Test Setup
//U8G2_UC1610_EA_DOGXL160_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE);
//U8G2_UC1610_EA_DOGXL160_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ U8X8_PIN_NONE);
//U8G2_UC1611_EA_DOGM240_F_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, DOGM240 Test Board
//U8G2_UC1611_EA_DOGM240_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Due, SW SPI, DOGXL240 Test Board
//U8G2_UC1611_EA_DOGXL240_F_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ 8); // Due, 2nd I2C, DOGXL240 Test Board
//U8G2_UC1611_EA_DOGXL240_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Due, SW SPI, DOGXL240 Test Board
//U8G2_UC1611_EW50850_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 3, /*dc=*/ 16, /*reset=*/ 17); // 240x160, Connect RD/WR1 pin with 3.3V, CS is aktive high
//U8G2_UC1611_CG160160_F_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ 3, /*dc=*/ 16, /*reset=*/ 17); // Connect WR1 and CD1 pin with 3.3V, connect CS0 with cs, WR0 with enable, CD with dc
//U8G2_UC1638_160X128_F_4W_HW_SPI u8g2(U8G2_R2, /* cs=*/ 2, /* dc=*/ 3, /* reset=*/ 4); // Not tested
//U8G2_SSD1606_172X72_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // eInk/ePaper Display
//U8G2_SSD1607_200X200_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // eInk/ePaper Display, original LUT from embedded artists
//U8G2_SSD1607_GD_200X200_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Good Display
//U8G2_SSD1607_WS_200X200_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // Waveshare
//U8G2_IL3820_296X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // WaveShare 2.9 inch eInk/ePaper Display, enable 16 bit mode for this display!
//U8G2_IL3820_V2_296X128_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // ePaper Display, lesser flickering and faster speed, enable 16 bit mode for this display!
//U8G2_MAX7219_64X8_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE);
//U8G2_MAX7219_32X8_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE);
//U8G2_MAX7219_8X8_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE);
//U8G2_LS013B7DH03_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display
//U8G2_LS027B7DH01_400X240_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display
//U8G2_LS013B7DH05_144X168_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ 8); // there is no DC line for this display
//U8G2_ST7511_AVD_320X240_F_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable/WR=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); // Enable U8g2 16Bit Mode and connect RD pin with 3.3V/5V
// End of constructor list
void setup(void) {
u8g2.begin();
}
void loop(void) {
u8g2.clearBuffer(); // 清除内部缓冲区
u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
u8g2.drawStr(0,10,"Hello World!"); // write something to the internal memory
u8g2.drawStr(0,20,"This is bro cainiao!"); // write something to the internal memory
u8g2.drawStr(0,30,"Welcome to U8G2!"); // write something to the internal memory
u8g2.sendBuffer(); // transfer internal memory to the display
delay(1000);
}
实验结果: