【NodeMCU】NodeMCU编程手记.part2

之前写到自己组装了一个黑群,由于黑群的硬件限制,无法实现自动开机,必须借助外部干预,因此购置了一个nodeMCU继电器实现定时开关机。
硬件电路搭完了,准备着手写nodeMCU的软件了

本方案采用的继电器电路如图,GPIO0控制继电器通断。
在这里插入图片描述
而GPIO在ESP8266里index为3
ESP8266的GPIO定义

在写软件之前,有一个血泪经验需要分享,通过ESPlorer或LuaLoader给nodeMCU上传代码,无法中断代码的执行,并且也没有在线调试的功能,上传的代码如果有BUG,就很容易进入死循环或者无限重启,这时候只需要在ESPlorer或LuaLoader的命令行里执行如下代码就可及时中断程序执行,拼手速的时候到了。要是实在拼不过,或者系统宕了,只能重新下载固件了。

file.remove("init.lua")
file.rename("init.lua","init_bad.lua")

ESPlorer
LuaLoader

正式代码开始:

为了实现定时开关机,首先要知道自己的时间,上一次编译nodeMCU固件,忘记选择sntp了,重新编译并下载后,支持获取ntp时间。

以下代码是每5秒钟同步一下时间服务器,并打印当前时间,当然也没必要这么快,每小时甚至一天同步一次足矣。另外, 通过rtc.get()获取的时间单位是秒,并且要加上8小时才是北京时间,也就是东8区的时间,所以sec+8*60*60。

tmr.create():alarm(5000, tmr.ALARM_AUTO, function()
    sec,usec,rate = rtctime.get()
    time2 = rtctime.epoch2cal((sec+8*60*60),usec,rate)
    print(string.format("nowtime=,%04d/%02d/%02d %02d:%02d:%02d", 
                        time2["year"], 
                        time2["mon"], 
                        time2["day"], 
                        time2["hour"], 
                        time2["min"], 
                        time2["sec"]))    
end)

获取ntp时间后,就按ntp时间来控制开关机。
本方案中,考虑最简单的情况,每天0点关机,7点开机,也就是说time[“hour”]大于等于0,小于等于6(也就是最晚6点59)保持断电状态,其他时间保持开合状态。
另外,为了保护主机硬盘,不能直接关电,会等主机完全关闭后才关闭电源。拟通过ping来判断主机是否已经关机,连续ping不通60次(周期是5秒,也就是300秒)则认为主机已经关机了,则关掉电源。

这里需要用到net.ping,代码如下:

ping_lose = 0
tmr.create():alarm(5000, tmr.ALARM_AUTO, function()
    sec,usec,rate = rtctime.get()
    time2 = rtctime.epoch2cal((sec+8*60*60),usec,rate)
    print(string.format("nowtime=,%04d/%02d/%02d %02d:%02d:%02d", 
                        time2["year"], 
                        time2["mon"], 
                        time2["day"], 
                        time2["hour"], 
                        time2["min"], 
                        time2["sec"]))    
    --在这里实现定时关机
    --如果大于11点到第二天7点,如果连续ping不通nas,就关电,在其他时间,就开电
    if ( time2["hour"] >= 0 and time2["hour"]<=6 )then
       net.ping(host_ip, 1, function (b, ip, sq, tm) 
         if ip then print(("%d bytes from %s, icm p_seq=%d time=%dms"):format(b, ip, sq, tm)) else print("Invalid IP address") end 
         if b > 0 then ping_lose=0 else ping_lose=ping_lose + 1 end
         if ping_lose > 60 then
			gpio.mode(3,gpio.OUTPUT)
            gpio.write(3,gpio.HIGH)
		 end
       end) 
    else
      ping_lose = 0 
			gpio.mode(3,gpio.OUTPUT)
            gpio.write(3,gpio.Low) 
    end
end)

其中

	gpio.mode(3,gpio.OUTPUT)
	gpio.write(3,gpio.HIGH)

就是用来关闭继电器,gpio.write(3,gpio.LOW)就是用来打开电源。

主要程序就这么点,虽然有点简单粗暴,但是实用效果还是不错的。
如果要临时取消关电,只需要关闭黑群的自动开关机功能,保持主机开机,继电器就不会断电的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值