美文网首页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