基于Lua框架下Air103使用U8g2库驱动I2C OLED图像显示

基于Lua框架下Air103使用U8g2库驱动I2C OLED屏幕图像演示


  • 本案例来源于:https://gitee.com/openLuat/LuatOS/tree/master/demo/u8g2
  • 关于Lua u8g2图形处理库介绍:https://wiki.luatos.com/api/u8g2.html
  • 在1.3寸sh1106 OLED 演示效果:

支持I2C 0.96寸屏幕以及1.3寸屏幕

  • 0.96寸屏幕为ssd1306
u8g2.begin({ic = "ssd1106",direction = 0,mode="i2c_hw",i2c_id=0,i2c_speed = i2c.FAST}) -- direction 可选0 90 180 270
-- 初始化软件i2c的ssd1306
-- u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_sw", i2c_scl=1, i2c_sda=4}) -- 通过PA1 SCL / PA4 SDA模拟
  • 1.3寸屏幕为sh1106
u8g2.begin({ic = "sh1106",direction = 0,mode="i2c_hw",i2c_id=0,i2c_speed = i2c.FAST}) -- direction 可选0 90 180 270
-- 初始化软件i2c的sh1106
-- u8g2.begin({ic = "sh1106",direction = 0,mode="i2c_sw", i2c_scl=1, i2c_sda=4}) -- 通过PA1 SCL / PA4 SDA模拟

  • ⚡注意:如果1.3寸sh1106 OLED屏幕刷ssd1306屏幕的程序,会有白边。注意ic变量参数都是小写,大写会识别不到默认为是ssd1306.

汉字取模显示内容说明

  • 该部分内容参考了《合宙Air103|DISP|OLED|u8g2|I2C|SSD1306|PCtoLCD2002|取模|正则|三目运算符|二维码|QRCode|JSON函数|官方demo|学习(6):DISP-OLED》
  • 由于U8g2库本身就集成了中文汉字库,所以你也可以直接使用汉字字体,汉字取模,调用图像函数显示。
  • 取模软件:PCtoLCD2002
  • 取模参数设置:
    基于Lua框架下Air103使用U8g2库驱动I2C OLED图像显示_第1张图片
  • 在生成字模前,设置好,避免拷贝到程序中再进行二次加工。
  • ⚡需要注意的是:字模点阵必须是8的整倍:16 x16 、 24x24、32x32 。
-- 以下是汉字取模显示内容:
    u8g2.ClearBuffer()
    u8g2.SetBitmapMode(1)   --定义位图函数是否将写入背景色,mode字体模式,启用(1)或禁用(0)透明模式
 
    t={

       --(0)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)(15)

        string.char(0x40,0x04,0x40,0x08,0x40,0x10,0xFC,0x07,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x04),
        string.char(0xFF,0x3F,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x14,0x40,0x08,0x40,0x00),--/*"书",0*/
        
        string.char(0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x10),
        string.char(0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,0x00,0x10,0x00,0x00),--/*"山",1*/
        
        string.char(0x40,0x00,0x40,0x00,0xFF,0x7F,0x20,0x00,0x20,0x00,0xF0,0x0F,0x10,0x08,0x18,0x08),
        string.char(0xF4,0x0F,0x12,0x08,0x11,0x08,0xF0,0x0F,0x10,0x08,0x10,0x08,0x10,0x0A,0x10,0x04),--/*"有",2*/
        
        string.char(0x00,0x02,0x3E,0x02,0x22,0x1E,0x22,0x11,0xA2,0x0A,0x3E,0x04,0x08,0x0A,0x08,0x11),
        string.char(0x88,0x60,0x3A,0x1F,0x0A,0x11,0x0A,0x11,0x0A,0x11,0x3A,0x11,0x07,0x1F,0x00,0x11),--/*"路",3*/
        
        string.char(0x44,0x04,0x44,0x04,0xFF,0x05,0x44,0x04,0x7C,0x3F,0x10,0x24,0xFE,0x24,0x92,0x24),
        string.char(0xFE,0x24,0x10,0x24,0xFE,0x24,0x10,0x22,0xFE,0x22,0x10,0x21,0xF0,0x14,0x4F,0x08),--/*"勤",4*/
        
        string.char(0x80,0x00,0x84,0x00,0x88,0x00,0x88,0x00,0x80,0x00,0xFE,0x1F,0x40,0x10,0x40,0x10),
        string.char(0x40,0x11,0x20,0x12,0x20,0x12,0x10,0x10,0x08,0x10,0x04,0x10,0x02,0x0A,0x01,0x04),--/*"为",5*/
        
        string.char(0x10,0x00,0xD0,0x1F,0x08,0x08,0x04,0x04,0x12,0x06,0x10,0x19,0x88,0x20,0x6C,0x40),
        string.char(0x0A,0x00,0xC9,0x3F,0x08,0x02,0x08,0x02,0x08,0x02,0x08,0x02,0xE8,0x7F,0x08,0x00),--/*"径",6*/
        
        string.char(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
        string.char(0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x08,0x00,0x04,0x00,0x00,0x00),--/*",",7*/
        
        string.char(0x44,0x10,0x88,0x10,0x88,0x08,0x00,0x04,0xFE,0x7F,0x02,0x40,0x01,0x20,0xF8,0x07),
        string.char(0x00,0x02,0x80,0x01,0xFF,0x7F,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00),--/*"学",8*/
        
        string.char(0x80,0x00,0x84,0x00,0x88,0x3F,0x48,0x00,0xA1,0x1F,0x82,0x10,0x92,0x12,0x90,0x14),
        string.char(0xE8,0x7F,0x88,0x10,0x47,0x12,0x44,0x14,0xC4,0x3F,0x04,0x10,0x04,0x0A,0x00,0x04),--/*"海",9*/
        
        string.char(0x00,0x00,0xFC,0x0F,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xFE,0x3F,0x20,0x01),
        string.char(0x20,0x01,0x20,0x01,0x10,0x01,0x10,0x01,0x08,0x21,0x04,0x21,0x02,0x3E,0x01,0x00),--/*"无",10*/
        
        string.char(0x00,0x00,0xE4,0x7F,0x28,0x04,0x28,0x04,0xA1,0x3F,0x22,0x04,0x22,0x04,0xE8,0x7F),
        string.char(0x28,0x00,0x24,0x04,0x27,0x04,0xA4,0x3F,0x24,0x04,0x14,0x04,0xD4,0x7F,0x08,0x00),--/*"涯",11*/
        
        string.char(0x10,0x04,0x10,0x04,0xFF,0x7F,0x10,0x04,0x90,0x04,0x80,0x00,0x80,0x00,0xFF,0x7F),
        string.char(0x80,0x00,0x80,0x00,0xF8,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x0F,0x08,0x08),--/*"苦",12*/
        
        string.char(0x90,0x00,0x90,0x00,0x90,0x00,0x88,0x7F,0x48,0x01,0x4C,0x01,0x2C,0x01,0x0A,0x1F),
        string.char(0x09,0x01,0x08,0x01,0x08,0x01,0x08,0x3F,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01),--/*"作",13*/
        
        string.char(0x40,0x00,0x20,0x00,0xF8,0x0F,0x08,0x08,0x48,0x08,0x88,0x08,0x88,0x08,0xFF,0x7F),
        string.char(0x08,0x08,0x48,0x08,0x88,0x08,0x88,0x08,0x04,0x08,0x04,0x08,0x02,0x0A,0x01,0x04),--/*"舟",14*/
        
        string.char(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
        string.char(0x00,0x00,0x00,0x00,0x18,0x00,0x24,0x00,0x24,0x00,0x18,0x00,0x00,0x00,0x00,0x00) --/*"。",15*/
 
 
    }
    for i = 1, #t/2 do
        row=(math.ceil(2*i/#t[1])-1)   --取整数部分,得到需显示的行数
        col=i%(128/#t[1])
        --col= (col==0) and 8 or col --等同于 if col==0 then col=8 end
        col=(col==0 and {8} or {col})[1]  --通用三目运算符
        u8g2.DrawXBM((col-1)*#t[1],row*#t[2],#t[1],#t[2], t[i*2-1]..t[i*2])   --行数增加后,从0,0重新输出
        -- u8g2.SendBuffer()  --逐字输出,间隔100ms
        -- sys.wait(100)
    end
    -- u8g2.DrawXBM(0, 0, 16,16, t[1]..t[2])
    -- u8g2.DrawXBM(16, 0, 16,16, t[3]..t[4])
    u8g2.SendBuffer()   --一次性输出
    sys.wait(2000)

Demo代码

✨文件位置:/demo/u8g2/Air101_Air103,在原来代码基础上正价了一个while循环显示,原代码只执行一遍就不显示了,注释掉了后面的qrcode测试内容。

--- 模块功能:u8g2demo
-- @module u8g2
-- @author Dozingfiretruck
-- @release 2021.01.25

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "u8g2demo"
VERSION = "1.0.1"

log.info("main", PROJECT, VERSION)

-- sys库是标配
_G.sys = require("sys")

--[[
I2C0
I2C0_SCL               (PA1)
I2C0_SDA               (PA4)
]]

--添加硬狗防止程序卡死
wdt.init(9000)--初始化watchdog设置为9s
sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗

-- 日志TAG, 非必须
local TAG = "main"

-- 初始化显示屏
log.info(TAG, "init ssd1306")

-- 初始化硬件i2c的ssd1306
u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_hw",i2c_id=0,i2c_speed = i2c.FAST}) -- direction 可选0 90 180 270
-- 初始化软件i2c的ssd1306
-- u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_sw", i2c_scl=1, i2c_sda=4}) -- 通过PA1 SCL / PA4 SDA模拟

u8g2.SetFontMode(1)
u8g2.ClearBuffer()
u8g2.SetFont(u8g2.font_opposansm8)
u8g2.DrawUTF8("U8g2+LuatOS", 32, 12)

if u8g2.font_opposansm12_chinese then
    u8g2.SetFont(u8g2.font_opposansm12_chinese)
else
    u8g2.SetFont(u8g2.font_opposansm10_chinese)
end
u8g2.SetFont(u8g2.font_opposansm12_chinese)
u8g2.DrawUTF8("中文测试", 40, 30) -- 若中文不显示或乱码,代表所刷固件不带这个字号的字体数据, 可自行云编译一份. wiki.luatos.com 有文档.
u8g2.SendBuffer()

--主流程
sys.taskInit(function()
  while true do
    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("屏幕宽度", 0, 12)
    u8g2.DrawUTF8("屏幕高度", 0, 30)
    u8g2.DrawUTF8(":"..u8g2.GetDisplayWidth(), 54, 12)
    u8g2.DrawUTF8(":"..u8g2.GetDisplayHeight(), 54, 30)
    u8g2.SendBuffer()

    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("画线测试:", 30, 12)
    for i = 0, 128, 8 do
        u8g2.DrawLine(0,40,i,40)
        u8g2.DrawLine(0,60,i,60)
        u8g2.SendBuffer()
        sys.wait(100)
    end

    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("画圆测试:", 30, 12)
    u8g2.DrawCircle(30,50,10,15)
    u8g2.DrawDisc(90,50,10,15)
    u8g2.SendBuffer()

    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("椭圆测试:", 30, 12)
    u8g2.DrawEllipse(30,50,6,10,15)
    u8g2.DrawFilledEllipse(90,50,6,10,15)
    u8g2.SendBuffer()

    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("方框测试:", 30, 12)
    u8g2.DrawBox(30,40,30,24)
    u8g2.DrawFrame(90,40,30,24)
    u8g2.SendBuffer()

    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("圆角方框:", 30, 12)
    u8g2.DrawRBox(30,40,30,24,8)
    u8g2.DrawRFrame(90,40,30,24,8)
    u8g2.SendBuffer()

    sys.wait(1000)
    u8g2.ClearBuffer()
    u8g2.DrawUTF8("三角测试:", 30, 12)
    u8g2.DrawTriangle(30,60, 60,30, 90,60)
    u8g2.SendBuffer()
-- 以下是汉字取模显示内容:
    u8g2.ClearBuffer()
    u8g2.SetBitmapMode(1)   --定义位图函数是否将写入背景色,mode字体模式,启用(1)或禁用(0)透明模式
 
    t={

       --(0)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)(15)

        string.char(0x40,0x04,0x40,0x08,0x40,0x10,0xFC,0x07,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x04),
        string.char(0xFF,0x3F,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x14,0x40,0x08,0x40,0x00),--/*"书",0*/
        
        string.char(0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x10),
        string.char(0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,0x00,0x10,0x00,0x00),--/*"山",1*/
        
        string.char(0x40,0x00,0x40,0x00,0xFF,0x7F,0x20,0x00,0x20,0x00,0xF0,0x0F,0x10,0x08,0x18,0x08),
        string.char(0xF4,0x0F,0x12,0x08,0x11,0x08,0xF0,0x0F,0x10,0x08,0x10,0x08,0x10,0x0A,0x10,0x04),--/*"有",2*/
        
        string.char(0x00,0x02,0x3E,0x02,0x22,0x1E,0x22,0x11,0xA2,0x0A,0x3E,0x04,0x08,0x0A,0x08,0x11),
        string.char(0x88,0x60,0x3A,0x1F,0x0A,0x11,0x0A,0x11,0x0A,0x11,0x3A,0x11,0x07,0x1F,0x00,0x11),--/*"路",3*/
        
        string.char(0x44,0x04,0x44,0x04,0xFF,0x05,0x44,0x04,0x7C,0x3F,0x10,0x24,0xFE,0x24,0x92,0x24),
        string.char(0xFE,0x24,0x10,0x24,0xFE,0x24,0x10,0x22,0xFE,0x22,0x10,0x21,0xF0,0x14,0x4F,0x08),--/*"勤",4*/
        
        string.char(0x80,0x00,0x84,0x00,0x88,0x00,0x88,0x00,0x80,0x00,0xFE,0x1F,0x40,0x10,0x40,0x10),
        string.char(0x40,0x11,0x20,0x12,0x20,0x12,0x10,0x10,0x08,0x10,0x04,0x10,0x02,0x0A,0x01,0x04),--/*"为",5*/
        
        string.char(0x10,0x00,0xD0,0x1F,0x08,0x08,0x04,0x04,0x12,0x06,0x10,0x19,0x88,0x20,0x6C,0x40),
        string.char(0x0A,0x00,0xC9,0x3F,0x08,0x02,0x08,0x02,0x08,0x02,0x08,0x02,0xE8,0x7F,0x08,0x00),--/*"径",6*/
        
        string.char(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
        string.char(0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x08,0x00,0x04,0x00,0x00,0x00),--/*",",7*/
        
        string.char(0x44,0x10,0x88,0x10,0x88,0x08,0x00,0x04,0xFE,0x7F,0x02,0x40,0x01,0x20,0xF8,0x07),
        string.char(0x00,0x02,0x80,0x01,0xFF,0x7F,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00),--/*"学",8*/
        
        string.char(0x80,0x00,0x84,0x00,0x88,0x3F,0x48,0x00,0xA1,0x1F,0x82,0x10,0x92,0x12,0x90,0x14),
        string.char(0xE8,0x7F,0x88,0x10,0x47,0x12,0x44,0x14,0xC4,0x3F,0x04,0x10,0x04,0x0A,0x00,0x04),--/*"海",9*/
        
        string.char(0x00,0x00,0xFC,0x0F,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xFE,0x3F,0x20,0x01),
        string.char(0x20,0x01,0x20,0x01,0x10,0x01,0x10,0x01,0x08,0x21,0x04,0x21,0x02,0x3E,0x01,0x00),--/*"无",10*/
        
        string.char(0x00,0x00,0xE4,0x7F,0x28,0x04,0x28,0x04,0xA1,0x3F,0x22,0x04,0x22,0x04,0xE8,0x7F),
        string.char(0x28,0x00,0x24,0x04,0x27,0x04,0xA4,0x3F,0x24,0x04,0x14,0x04,0xD4,0x7F,0x08,0x00),--/*"涯",11*/
        
        string.char(0x10,0x04,0x10,0x04,0xFF,0x7F,0x10,0x04,0x90,0x04,0x80,0x00,0x80,0x00,0xFF,0x7F),
        string.char(0x80,0x00,0x80,0x00,0xF8,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x0F,0x08,0x08),--/*"苦",12*/
        
        string.char(0x90,0x00,0x90,0x00,0x90,0x00,0x88,0x7F,0x48,0x01,0x4C,0x01,0x2C,0x01,0x0A,0x1F),
        string.char(0x09,0x01,0x08,0x01,0x08,0x01,0x08,0x3F,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01),--/*"作",13*/
        
        string.char(0x40,0x00,0x20,0x00,0xF8,0x0F,0x08,0x08,0x48,0x08,0x88,0x08,0x88,0x08,0xFF,0x7F),
        string.char(0x08,0x08,0x48,0x08,0x88,0x08,0x88,0x08,0x04,0x08,0x04,0x08,0x02,0x0A,0x01,0x04),--/*"舟",14*/
        
        string.char(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
        string.char(0x00,0x00,0x00,0x00,0x18,0x00,0x24,0x00,0x24,0x00,0x18,0x00,0x00,0x00,0x00,0x00) --/*"。",15*/
 
 
    }
    for i = 1, #t/2 do
        row=(math.ceil(2*i/#t[1])-1)   --取整数部分,得到需显示的行数
        col=i%(128/#t[1])
        --col= (col==0) and 8 or col --等同于 if col==0 then col=8 end
        col=(col==0 and {8} or {col})[1]  --通用三目运算符
        u8g2.DrawXBM((col-1)*#t[1],row*#t[2],#t[1],#t[2], t[i*2-1]..t[i*2])   --行数增加后,从0,0重新输出
        -- u8g2.SendBuffer()  --逐字输出,间隔100ms
        -- sys.wait(100)
    end
    -- u8g2.DrawXBM(0, 0, 16,16, t[1]..t[2])
    -- u8g2.DrawXBM(16, 0, 16,16, t[3]..t[4])
    u8g2.SendBuffer()   --将存储器帧缓冲区的内容发送到显示器
    sys.wait(1000)
     u8g2.ClearBuffer()
    u8g2.SetBitmapMode(1)   --定义位图函数是否将写入背景色,mode字体模式,启用(1)或禁用(0)透明模式
    u8g2.DrawXBM(0,0,16,16, string.char(
        0x1F,0xF8,0x0F,0xF0,0x8F,0xF1,0xC7,0xE3,0xA7,0xE5,0xE7,0xE7,0xE7,0xE7,0x6F,0xF6,
        0xCF,0xF3,0x8F,0xF1,0x03,0xC0,0xC0,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00
        )) 
    u8g2.SendBuffer()   --将存储器帧缓冲区的内容发送到显示器
    sys.wait(1000)
    u8g2.ClearBuffer()
  end
    -- qrcode测试
    -- sys.wait(1000)
    -- u8g2.ClearBuffer()
    -- u8g2.DrawDrcode(4, 4, "https://wiki.luatos.com/chips/air101/mcu.html", 10);

    -- u8g2.SendBuffer()

    --sys.wait(1000)
    -- log.info("main", "u8g2 demo done")
end)

-- 主循环, 必须加
sys.run()

你可能感兴趣的:(Lua嵌入式开发,Lua,U8g2,Air103)