美文网首页nodemcunodemcu
2、nodeMCU学习笔记--tmr模块

2、nodeMCU学习笔记--tmr模块

作者: 谢mingmin | 来源:发表于2016-10-22 22:47 被阅读6620次

    闲言碎语

    nodeMCU是基于esp8266的开源项目,项目组让这个小玩意可以使用Lua脚本语言来开发一些有趣的东西。这里有nodeMCU最新的英文文档。当然,也有中文文档,但不是最新的。从这篇文章起,会花几篇文章来讲讲笔者构建的固件中的模块。从简单的开始说起,今天的主角是tmr模块。这里是英文的API文档,以及对应的C文件

    模块函数

    提供API的翻译,只会针对性的说一些文档里面的内容 -.-

    模块提供7个静态timer,编号0~6(很快将移除)。也可以使用 .create函数动态创建。tmr模块总共有13的函数。

    序号 函数名 参数 返回值
    1 tmr.alarm() id / ref, interval_ms, mode, func true / false
    2 tmr.create() object
    3 tmr.delay() us nil
    4 tmr.interval() id / ref, interval_ms nil
    5 tmr.now() us
    6 tmr.register() id / ref, interval_ms, mode, func nil
    7 tmr.softwd() timeout_s nil
    8 tmr.start() id / ref true / false
    9 tmr.state() id / ref bool, int / nil
    10 tmr.stop() id / ref true / false
    11 tmr.time() s
    12 tmr.unregister() id / ref nil
    13 tmr.wdclr() nil

    先从简单的函数开始说起,

    1. .softwd 设置一个软件看门狗,时间参数单位为秒。使用任何负数可以失能。
    2. .wdclr 喂狗。但是,文档说使用这个功能是错误的。没明白tmr这个看门狗干嘛用的。
    3. .delay 顾名思义,就是最传统的死循环延时,文档中明确指出不推荐使用!
    4. tmr.now & tmr.time 都是用来获取系统时间,只是单位不一样。前者是微秒,后者是秒。31位计数器,计满后清零。
    5. .alarm 就是调用 .register.start 两个函数。
    6. .interval 修改一个定时器的终止时间,单位ms
    7. .start 启动或者重启定时器.
    8. .stop 暂停一个正在运行的定时器,可以使用.start重启。
    9. .state 返回一个定时器的运行状态(启动or暂停)和模式或者nil。注意,该函数返回的是两个参数。Lua的神奇之处在于,返回值可以是多个。
    10. .register & .unregister 前者用于注册一个定时器。后者注销一个定时器,如果定时器还在运行会先暂停。
    11. .create 动态创建一个定时器。

    还有,就是mode参数有三种选择。分别是:

    1. tmr.ALARM_SINGLE 单触发模式,会自动注销定时器;
    • tmr.ALARM_SEMI 手动重置模式,可以使用.start重启定时器;
    • tmr.ALARM_AUTO 自动重置模式。

    接下来,会用几个例子来说tmr模块中的函数应该怎样用。前3个函数忽略掉!首先来看看.alarm是什么效果。

    count = 0
    function print_count() 
        count = count + 1
        print("count = ", count)
        end
    tmr.alarm(0, 1000, tmr.ALARM_SINGLE, print_count)
    
    单触发模式

    保存上面的代码,会自动把文件传到nodeMCU并执行。可以看到只是输出了一次就停下来了。可以在右边的输入框里面输入

    =dofile("tmr_1.lua")       
    

    重新执行,引号里面是你刚才保存的文件名。接着,把mode换成

    tmr.alarm(0, 1000, tmr.ALARM_SEMI, print_count)
    
    手动重置模式
    效果如上图所示,也是输出一次就停了。不过,使用.start(0)可以重启该定时器,并输出累计值。如果在单触发模式使用.start(0)则会返回false,不会有输出累计值。对于,自动重置模式,就不用给例子了,我知道你懂的。不过,你使用自动重置模式后,会发现那累计值的输出根本停不下来。这时候,别忘了,还有.stop可以用哈。一不小心,就说了3个函数了。再来试试看.interval,在右边输入
    =tmr.interval(0, 10000)
    

    把自动重置时间调整到10s,如果先前你暂停了定时器,那麻烦先启动一下。

    =tmr.state(0)
    

    我们还可以用.state来查询一下定时器的状态。我不会告诉你返回了true跟1的。可能你会有疑问,这样子输指令,哪里是编程。这样做只是要看看效果,Lua是异步的,在接收到一条指令后就会执行。这里把手动输入指令当作一个外部中断就可以了。
    接下来用另外一个例子介绍剩下的几个函数

    count = 0
    timer = tmr.create()
    runTime = tmr.time()
    tmr.register(timer, 1000, tmr.ALARM_AUTO, function()
        local temp = 0
        count = count + 1
        temp = tmr.time()
        print("count&runTime=", count, temp - runTime)
        runTime = temp
        if(count == 10) then
            tmr.interval(timer, 3000)
        end
        if(count == 20) then
            tmr.stop(timer)
            print(tmr.state(timer))
            print(tmr.unregister(timer))
            print(tmr.state(timer))
        end
    end)
    tmr.start(timer)
    

    先使用.create动态创建一个定时器,然后使用.register注册这个定时器,在其回调函数里面使用了.interval调整时间间隔。最后使用.stop和** .unregister**停止、注销这个定时器。这里使用print函数打印查询状态、暂停、注销的返回值。

    一点问题

    第二个例子中,由于定时器是动态创建的。如果你在这个例子中的定时器没有停下来之前,又send了一次文件,那么恭喜你,你会看到一直有输出。每send一次就动态创建一个定时器。因为count是一个全局变量,一直在+1,count = 20只有一次,也就只有一个定时器会被暂停,其他的定时器则不会。

    补充一下Lua语法

    • Lua中没有像C语言那样的自增运算符,比如++
    • 函数是这样声明的
    function 函数名(参数)
        干活,干活
    return 参数,参数
    end
    
    • if 语句是这样子的
    if (条件) then
        干活,干活
    end
    

    相关文章

      网友评论

      • 世華:你好!楼主。我把定时设置了自动模式count+1,然后我把你下一篇文章的LED灯程序下进去,为什么count还是会继续+1 我在窗口发送tmr.stop(0),就可以停止。我很好奇,我不是已经把LED程序下进去了么?为什么还有之前的程序
        谢mingmin:@世華 重启啊😂,默认会执行 init.lua文件。不要往里面写就好了
        世華:@谢mingmin 那怎么把之前的程序删掉,重新下载新的程序?新手刚接触LUA和nodemcu,之前一直玩51和stm32,望楼主能多多指教
        谢mingmin:@世華 这个是脚本语言,之前执行的依然还会执行
      • f248cec1a22a:请问楼主除了tmr.delay()这个函数有延时功能,还有没有其他延迟函数?tmr.delay()官方不建议使用,而且调用该函数期间cpu不会执行任何其他操作包括定时器。我想在主函数中实现两条命令间隔1s执行,但是不影响定时器工作应该如何执行?
        比如:
        tmr.alarm(0, 1000, tmr.ALARM_SINGLE, function)
        -- 这里想要延迟一段时间然后执行后面的代码
        gpio.write(0, gpio.LOW)
        谢mingmin:@zhanlej 定时器可以开很多个啊,他们的独立的
      • 逐梦ing_09cd:楼主 拷贝最后一个例子后 报错啊 是怎么回事

        dofile("tmr.lua")
        tmr.lua:2: attempt to call field 'create' (a nil value)
        stack traceback:
        tmr.lua:2: in main chunk
        [C]: in function 'dofile'
        stdin:1: in main chunk
        >
        谢mingmin: @猪鼻插葱装大象 看软件左下方,应该有一堆按钮
        6153fa6a53f9:@谢mingmin 对,我也遇到同样的问题,楼主说 save到nodemcu是什么意思?貌似在ESPlorer里没看到这个选项,新手刚上手nodemcu好多不明白,望楼主指教。
        谢mingmin: @逐梦ing_09cd save到nodemcu看看会不会
      • Zszen:模块提供7个静态timer,编号0~6(很快将移除)。也可以使用 .create函数动态创建。tmr模块总共有13的函数。

        很快将移除? 官方api将移除还是内部系统自动回收?
        谢mingmin: @Zszen 静态的后面会移除。。。
      • wangli675:你好,我尝试着把时间间隔改为1ms,然后我就再也写不了东西了,他就那么一直运行,什么代码都没有作用
        谢mingmin:@wangli675 可能是定时器速度太快了,影响了性能。要不试试看stop掉这个定时器,或者调整一下时间间隔
        wangli675:@谢mingmin
        count = 0
        function print_count()
        count = count + 1
        print("count = ", count)
        end
        tmr.alarm(0, 1, tmr.ALARM_AUTO, print_count)
        谢mingmin: @wangli675 给个代码看看

      本文标题:2、nodeMCU学习笔记--tmr模块

      本文链接:https://www.haomeiwen.com/subject/gbkhuttx.html