15、nodeMCU学习笔记--u8glib模块·一

oled  spi  esp8266  nodeMCU

Hello NodeMCU

闲言碎语

终于知道如何调整简书的图片大小了。这回准备说说u8glib模块。这个模块我折腾了好几天才弄懂怎么用。关于这个模块,官方的文档显然没有其他模块讲的详细,在没有接触过u8glib模块的人,看nodeMCU的文档估计是点不亮屏幕的。或许想我一开始一样,只有花屏。

真正要知道如何用还要靠u8glib这个图形库的官方文档。这里有个文档说如何显示一行字符串。

如果不想看英文文档,下面这段代码可以让oled显示一段文字(当然是英文的)。效果就是文章开头的那图片所展示的。

cs  = 8 
dc  = 2 -- D2
res = 0 -- D0
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
disp:setFont(u8g.font_6x10)

str = "Hello NodeMCU!"
function draw()     
    disp:drawStr(0, 16, str)
end

disp:firstPage()
while (disp:nextPage())
do 
    draw()
end

函数模块

如果说上面的代码看起来有点难度的话。没关系,先看看nodeMCU的u8glib模块的API。模块的API看起来是有点多。但完全不需要看那么多,这里只关注几个API。

|序号|函数名|参数|返回值|
|:--|:--:|:---:|:--:|--:|
|1|i2c.setup()|id, pinSDA, pinSCL, speed|speed|
|2|spi.setup()|id, mode, cpol, cpha, databits, clock_div[, duplex_mode]|1|
|||||
|3|ssd1306_128x64_i2c()|address[, use_delay]|object|
|4|ssd1306_128x64_spi()|cs, dc[, res[, use_delay]]|object|
这里前两个API是硬件接口初始化函数,来自i2c模块和spi模块。i2c模块比较简单,还是说说spi模块把。esp8266有2个spi硬件接口,其中一个用于flash了。因此要使用spi驱动oled的话,就只能用另一个接口了。
HSCLK对应了D5, HMISO对应D6,HMOSI对应D7。

后面两个API则是u8glib的初始化函数,具体的函数名和编译的固件有关,后面还会说到。

u8glib相关的API,nodeMCU的文档并没有详细的介绍。要弄清楚各个API具体怎么用,可能还需要看u8glib的官方文档

这里简单的说一下,开头的源码。这里oled的CS直接接到GND了,所以在配置完spi后,可以把gpio配置成输入,把IO利用起来。当然不配置也OK。

spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
disp:setFont(u8g.font_6x10)

接着初始化u8glib,返回一个u8glib的object。之后都是围绕object来用,比如用setFont()来设置字体。使用drawStr()来显示字符串。但是,想要实现显示,还需要类似于下面的代码。u8glib官方称其为Picture Loop

disp:firstPage()
while (disp:nextPage())
do 
    draw()
end

因为嵌入式设备的RAM很有限,所以u8glib采用了多种内存操作方式。具体怎么操作,应用层不用理会。u8glib会循环写入显存,以实现显示。在循环开始前,需要使用firstPage(),然后等待写入结束。当nextPage()返回0,则表示写入完成。

实际上,这段代码要放在主循环里面,才能刷新屏幕的显示内容。有了这些感性认识后,我就可以开始实际了。

实践一下

开始实践之前,你可能需要重新编译一个固件!这里我们可以选择云编译

Paste_Image.png

I2C和SPI至少要选择一个。再者就是本文的主角——u8glib模块,选择这个模块后,会多一个U8G options栏目,用来选择字体和驱动IC。需要根据使用的液晶驱动IC选择对应的xxx_i2c和xxx_spi。

还有就是选择字体。点击select会弹出一个字体窗口,里面有很多字体可以选择。可以随意选择自己喜欢的字体。不过,不要选太多。同时注意字体的大小,别选择了大字体后没法正常显示。最后,千万要把字体名字记录下来千万要把字体名字记录下来千万要把字体名字记录下来

准备工作做完后,就可以开始code了。先从几个简单的画图API开始。代码有点长,这里面涉及的函数包括了:

cs  = 8 -- GPIO15, pull-down 10k to GND
dc  = 2
res = 0
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
disp:setFont(u8g.font_6x10)

local s = 0
function draw(state)     
    if state == 0 then 
        disp:drawStr(0, 15, "drawBox")
        disp:drawBox(0, 23, 10, 20)
    elseif state == 1 then
        disp:drawStr(0, 15, "drawCircle")
        disp:drawCircle(36, 36, 10)
    elseif state == 2 then
        disp:drawStr(0, 15, "drawDisc")
        disp:drawDisc(36, 36, 15)
    elseif state == 3 then
        disp:drawStr(0, 15, "drawEllipse")
        disp:drawEllipse(60, 30, 20, 10, U8G_DRAW_ALL)
    elseif state == 4 then
        disp:drawStr(0, 15, "drawFrame")
        disp:drawFrame(60, 20, 20, 30)   
    elseif state == 5 then
        disp:drawStr(0, 15, "drawLine")
        disp:drawLine(5,26, 25, 40)
    elseif state == 6 then
        disp:drawStr(0, 15, "drawStr")
        disp:drawStr90(60, 20, "drawStr90") 
    else  
        disp:drawStr(0, 15, "drawTriangle")
        disp:drawTriangle(14,20, 45,32, 9,42);    
    end
end
disp:begin() -- u8g2不需要使用这个函数了
tmr.alarm(0, 1000, tmr.ALARM_AUTO, function()
    if s == 7 then
        s = 0
    else 
        s = s + 1
    end
    disp:firstPage()
    while (disp:nextPage())
    do 
        draw(s)
    end
end)

draw函数中切换的使用u8glib中的几种画图函数。然后使用一个定时器来执行Picture Loop以刷新屏幕。

把上面的代码save到nodeMCU中就可以看到屏幕不断的变化了。更多的内容可以查看U8glib Reference Manual。当然了,nodeMCU的u8g模块并没有完全实现u8glib库的全部API,具体可以看Unimplemented Functions

这回就先到这里吧,回头我继续研究一下u8glib。看看有没有什么高级点应用。

一点问题

使用drawStr()函数,这样写disp:drawStr(0, 0, "drawFrame")是看不到屏幕显示字符串的。只有调整一下Y坐标到16左右才可以正常显示。

更多内容

↑ 点击上面的标题可用查看同文集的其它文章。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,568评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 儿茶酚胺敏感性室速(CPVT)是一种遗传性心律失常疾病,以运动或情绪诱发的双向性或多形性室性心动过速为特征,好发于...
    黑猫格鲁宾阅读 6,429评论 0 0
  • 今天,汤老师让我们在作文课上画画。我好奇地问老师:“老师今天为什么要画画?”老师说:“以后你就知道了。”我开心得很...
    江上归舟阅读 188评论 0 0
  • 穿上曾经的旧鞋 踏上了以往的路 两边已长大的树 早已换上了新枝 脑海中回放的记忆 剩下嘴边说不完的往事 树说你在感...
    温觉阅读 682评论 5 0