nodemcunodemcu

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

2016-10-22  本文已影响6620人  谢mingmin

闲言碎语

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模块中的函数应该怎样用。前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语法

function 函数名(参数)
    干活,干活
return 参数,参数
end
if (条件) then
    干活,干活
end
上一篇下一篇

猜你喜欢

热点阅读