2.做个迷你气象站·二

模块化

在继续推进我们这个迷你气象站之前,我们需要了解一下lua的模块与包。具体的概念这里不赘述。

引入模块和包的一个主要原因是,后面我们要涉及的功能模块比较多。按照模块化编程的思想是,让不同的功能代码分散在不同的文件中,以减少代码的耦合性。

先来看一个简单的例子

module = { }

module.value = 1

function  module.func()
  print(module.value)
end

return module

首先,定义一个module的table。然后往这个table写入一堆东西。最后返回这个module。实现一个模块就是这么简单。

而引用这个模块也是相当的简单,在另外一个文件里面使用require "module"即可。引号里是module的名字。一般来说把模块名与文件名保持一致即可。

第一个模块

既然是第一个lua模块,那就要拿最最最简单的功能模块来练手了。我想最简单的非gpio莫属了。

不知道你忘记没有,nodemcu上面有2个IO外设。没错,一个flash按键和一个蓝色的led。我们先把这两个外设封装起来成为我们第一个模块,命名为myIO。模块包含了以下几个功能:

  • IO初始化
  • 写IO
  • 读IO

让我们一点一点来实现,

--1
myIO = { }

local key, led = 3, 0
local keymode, ledmode = gpio.INPUT, gpio.OUTPUT
local keyCnt = 0

这里我们先定义一个myIO的table,和一些局部变量。局部变量只可以被模块内部访问。另外,local key, led = 3, 0是lua里面一个有趣的语法,和下面的写法是等效的。

local key = 3
local led = 0

接下来是初始化IO

--3
function myIO.gpioInit()
    gpio.mode(key, keymode)
    gpio.mode(led, ledmode)
    return true
end

这是模块的一个函数,初始化key和led,是可以被模块外的其他函数调用的。下面这个函数是用来控制led状态的,我想不需要我多说了。

--4
function myIO.setLED(s) 
    if s == true then
        gpio.write(led, gpio.LOW)
    else
        gpio.write(led, gpio.HIGH)
    end
end

弄完led的,接着来写一个按键的。

--2
local function keyScan()
    local v = gpio.read(key)

    if v == 0 then 
        keyCnt = keyCnt + 1
        if keyCnt > 50 then 
            v = 2 
            keyCnt = 0
        end
    else
        if keyCnt > 5 then 
            v = 1 
            keyCnt = 0
        else 
            v = 0 
            keyCnt = 0
        end
    end

    return v
end

你可能发现了,这个函数和前面不一样。恩,没错。这个多了个local,少了个myIO。这其实是个局部函数,或者说模块内部函数。

这个用来做按键扫描,可以判断按键是长按还是短按(短按在松手后判断)。为啥这个函数要做出local的呢?后面在说明原因。

接着来看最后一个函数

--5
function myIO.setKey(short, long)
    local s = 0

    if myIO.ktimer == nil then
        myIO.ktimer = tmr.create()
    end
    
    tmr.stop(myIO.ktimer)

    --20ms
    tmr.register(myIO.ktimer, 20, tmr.ALARM_AUTO, function()
        
        local k = keyScan()
        --调整扫描频率
        if s == 1 then 
            tmr.interval(myIO.ktimer, 20)
            s = 0
        end

        if k == 1 then
            short()
        elseif k == 2 then
            long()
            tmr.interval(myIO.ktimer, 500)
            s = 1
        end
    end)

    tmr.start(myIO.ktimer)

end

函数有点长。不过,你应该看出来了。这里面其实就是创建了一个定时器,并注册了回调事件来处理键盘。

不知道你有没有注意到这里,

    if myIO.ktimer == nil then
        myIO.ktimer = tmr.create()
    end

是的,这个定义了一个模块变量。以为着你可以在其他模块里面使用myIO.ktimer来操作键盘扫描这个定时器。

也许,你还留意到了short, long。这两个参数在函数内部被当做函数使用了。

这种做的好处是,我们在模块内部对按键的行为做好封装,外部代码不用知道键盘的具体逻辑,这需要把长按和短按的两个函数传进来即可,类似于回调。这样更符合模块化编程。

这也是为什么keyScan()是一个局部函数。因为外面的世界不需要知道里面的世界是什么样子的!

最后,别忘记了

--6
return myIO

测试模块

模块写好了,能不能用还要测试才知道。建议先按--1 ~ --6拷贝代码到文件,并命名为myIO.lua。然后使用我们平时用的那个软件的upload功能把文件上传到nodemcu上。

重新写个测试文件test.lua。代码如下。

local myIO = require "myIO"
myIO.gpioInit()

function a()
    print("short")
end

function b()
    print("long")
end

myIO.setKey(a, b)

使用local myIO = require "myIO"来引入包,并给这个包重新起个名字,方便后面使用。

初始化IO,并定义2个函数,在设置按键事件回调。

最后,按一下nodemcu上面的flash来看效果吧。长按和短按是不一样的!

效果出来了!

关于模块化,暂且先到这。后面我们都会讲用的的功能封装成一个一个模块!

点完赞再走啊!

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

推荐阅读更多精彩内容