要点: 低功耗, 深度睡眠, 反复重启.

开发环境:Arduino IDE 1.8.19. 器材:Mini D1 Wi-Fi 模块, 磁簧开关(Reed Switch 干簧管).

Mini D1 Wi-Fi 模块

利用Mini D1 Wi-Fi和磁簧开关制作门窗报警器.

大门附近没有电源插座, 需要电池供电. 考虑利用深度睡眠方式解决耗电问题. 用定时唤醒深度睡眠的方式, 虽然简单, 但以定时巡检方式监视大门的状态, 显然不可取. 于是乎决定用磁簧开关连接RST端, 及时检测到开关状态, 触发RST, 达到重启, 唤醒深度睡眠的方法. 按习惯思维, 在3.3V和RST之间接了上拉电阻, RST和地之间接干簧管. 同时, 为了随时监视电池, 连线3.3V和A0, 读取电压值.

图1-1 上拉电阻方案

代码如下, 为了便于阅览, 与主题关系不大的处理全部放在subroutine里.

#include <ESP8266WiFi.h>
#include "config.h"
#include "net.h"
#include "sensor.h"#define DEV_LED 4                       //GPIO4 内置LED
#define DEV_RSW 12                      //GPIO12 RSW
#define DEV_3_3V 17                     //A0 测量3.3Vvoid setup() {uint32 time_s = system_get_time();    //计时startSerial.begin(9600);Serial.println("");ledBlink(DEV_LED);//闪亮LEDjoinWiFiAP(WIFI_STA);                 //加入WiFi APsyncNTP();                            //同步NTPfloat f3_3V;String sTime;getLocalTime(sTime);                   //取得当前时间get3_3V(17, f3_3V);                     //采样3.3VSerial.printf("Time:%s 3v3:%s\r\n", sTime.c_str(), f3_3V);Serial.println("Send message to the host...");getRequest2Host(sTime, s3_3V);      //向HOST传送数据uint32 time_e = system_get_time();  //计时stopSerial.printf("ruuning time=%0.2fS\r\n", float((time_e - time_s)/1000000));//us->sSerial.println("Zzzz...");ESP.deepSleep(0);                       //先歇了, 有事别忘了喊我啊!
}void loop() {
}

程序调试中, 掐了一下”秒表”, 测量完成全程处理所需时间是6秒.

问题来了, 就在这”漫长的”的6秒的时间内, 一不留神打了个喷嚏, 手一抖, 干簧管和磁铁又碰在一起, 系统立马重启, 程序要做的事情还没做完!

图1-2

分析如图1-2, (波形图画得很拙劣, 见笑! ) 可见RST的状态与RSW开关的开合是同步. 虽然在开关断开时由上拉电阻的作用, RST保持在高电平, 但随着开关闭合, RST端也随着变低, 也就是说, 在程序启动, 处理完毕, 进入深度睡眠之间的6秒的时间中, 只要开关再次闭合, 系统就会重启. 想象在实际应用中, 只要有人在6秒之内闪入大门, 这个报警器就武功全废啦!

如何解决反复重启的问题, 想象中应该有一个电路, 输入端输入N个负脉冲, 输出端只PASS第一个负脉冲, 答案是"可以有", 但是我是"真没有", 手头上只有区区几只电阻! 于是乎, 来了个反向思维, 把上拉电阻换成下拉电阻, 利用ESP8266的IO端口帮忙解决其他问题, 只要使A点的电位, 在容许系统重启时为低, 在禁止系统重启时为高, 就可以解决反复重启的问题. A点接到GPIO12(当然也有其他符合条件的IO口), 就可以程控A点的电平变化了, 试试看,

见图2-1.

图2-1

代码如下:

#include <ESP8266WiFi.h>
#include "config.h"
#include "net.h"
#include "sensor.h"#define DEV_LED 4                      //GPIO4 内置LED
#define DEV_RSW 12//GPIO12 RSW
#define DEV_3_3V 17                     //A0 测量3.3Vvoid setup() {uint32 time_s = system_get_time();    //计时startSerial.begin(9600);Serial.println("");//添加三条语句***********************************************************pinMode(DEV_RSW, OUTPUT);digitalWrite(DEV_RSW, HIGH);           //禁用RSWSerialprintf("Disable RSW, GPIO12 = %d\r\n", digitalRead(DEV_RSW));ledBlink(DEV_LED);                 //闪亮LEDjoinWiFiAP(WIFI_STA);                //加入WiFi APsyncNTP();                           //同步NTPfloat f3_3V;String sTime;getLocalTime(sTime);                    //取得当前时间get3_3V(17, f3_3V);                     //采样3.3VSerial.printf("Time:%s 3v3:%s\r\n", sTime.c_str(), f3_3V);Serial.println("Send message to the host...");getRequest2Host(sTime, s3_3V);      //向HOST传送数据uint32 time_e = system_get_time();  //计时stopSerial.printf("ruuning time=%0.2fS\r\n", float((time_e - time_s)/1000000)); //us->s//添加两条语句***********************************************************digitalWrite(DEV_RSW, LOW);     //使能RSWSerialprintf("Enable RSW, GPIO12 = %d\r\n", digitalRead(DEV_RSW));Serial.println("Zzzz...");ESP.deepSleep(0);                   //先歇了, 有事别忘了喊我啊!
}void loop() {
}

由于A点电位是动态变化的, 所以单纯地将图2-1中的电阻称为下拉电阻并不准确, 故名双拉. 具体应该如何称呼, 敬请高人赐教.

图2-2

请注意A点的电位, 在图2上由黑线表示, 从RST启动开始, 在尽早将其通过GPIO12置为高, 在进入深度睡眠前再将其置为低, 由于它的箝位作用, 在程序活动期间, 任凭RSW反复闭合, 也丝毫打扰不到RST了. 是否还有疑问, 一旦进入深度睡眠, 系统的各端口(或部分, 没有详细调查) 是不是都处于悬空? GPIO12所置的低电平是不是就不起作用了? 程序运行结果证明, 在进入深度睡眠状态下, 电阻在此时起了下拉作用, A点的低点位可以在RSW闭合时触发RST启动.

上述如有不妥,遗漏之处,敬请指正. 本文完.

附: 本报警器将装在类似下图的门磁报警器中, 空间正合适, 还能就地取材, 利用原本装在其中的干簧管, 电池和电源开关等器件, 电池呢, 先用这三颗纽扣电池. 由于手头没有电流表, 本装置到底用电如何也无从可知, 等电池用光了, 再做报告吧.

小试ESP8266(一) 一只电阻, 几条语句, 摆脱深度睡眠反复重启的困扰相关推荐

  1. python两数交换 函数_Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?...

    从接触 Python 时起,我就觉得 Python 的元组解包(unpacking)挺有意思,非常简洁好用. 最显而易见的例子就是多重赋值,即在一条语句中同时给多个变量赋值: >>> ...

  2. setnx和expire合成一条指令_Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?...

    从接触 Python 时起,我就觉得 Python 的元组解包(unpacking)挺有意思,非常简洁好用. 最显而易见的例子就是多重赋值,即在一条语句中同时给多个变量赋值: >>> ...

  3. Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 从接触 Python 时起,我就觉得 Python 的元组解包(u ...

  4. 规则 2.7:不允许把多个语句写在一行中,即一行只写一条语句。

    declare begin     -- 初始化局部变量     i_l_variable1 := 1;     i_l_variable2 := i_variable1;     i_l_varia ...

  5. 一条语句完成微信、支付宝支付,生成支付二维码

    PayApiFun.dll这个动态库中包含了:微信付款码支付.生成微信支付二维码扫码支付.按商户单号查询微信支付状态.关闭未支付的微信订单.支付宝付款码支付.生成支付宝支付二维码扫码支付.按商户单号查 ...

  6. CAN总线详解 整车的控制只需要一条线(怪不得那些汽车厂商的嵌入式岗位基本都是要求会CAN的)

    怪不得那些汽车厂商的嵌入式岗位基本都是要求会CAN的 转载自:https://mp.weixin.qq.com/s/qbN0-BtQ_q2GYEV7V_o5WA 干货分享:CAN总线详解 整车的控制只 ...

  7. sql 只取一条记录_后端程序员必备:书写高质量SQL的30条建议

    前言 本文将结合实例demo,阐述30条有关于优化SQL的建议,多数是实际开发中总结出来的,希望对大家有帮助. 1.查询SQL尽量不要使用select *,而是select具体字段. 反例子: sel ...

  8. 面试:如何实现 MySQL 删除重复记录并且只保留一条

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | blog.csdn.net/n950814ab ...

  9. mysql相同姓名只显示第一条_SQL中遇到多条相同内容只取一条的最简单实现方法...

    SQL中经常遇到如下情况,在一张表中有两条记录基本完全一样,某个或某几个字段有些许差别, 这时候可能需要我们踢出这些有差别的数据,即两条或多条记录中只保留一项. 如下:表timeand 针对time字 ...

最新文章

  1. 纯CSS3制作的圆角效果按钮菜单
  2. Winform中DataGridView绑定IList数据源后的排序
  3. dva 中的响应编程
  4. Asp.net在线统计人数
  5. 防止入侵者嗅探web密码
  6. hexo博客修改博文中日期的颜色
  7. java机试_java机试要点
  8. 【原】PSD图标素材的全自动切图方法,适用于IOS、安卓、web前端等领域
  9. android fastboot驱动,fastboot驱动
  10. Android 系统蓝牙 控制手机端音乐暂停 (AVRCP)
  11. sodp软件如何导入多个工作面信息_平方英尺和面积计算软件:Metes and Bounds for Mac...
  12. numpy tolist()
  13. 计算机视觉行业博客和代码汇总
  14. AssertionError: View function mapping is overwriting an existing endpoint function: inner
  15. Android ImageView 四个角自定义角度,以及角度的变换
  16. windows设置java项目jar包开机自启
  17. Nuget的使用说明
  18. EXCEL2010数据挖掘插件 下载地址
  19. LED模拟与数字调光
  20. Leetcode刷题 ——— (1)仅仅反转字母

热门文章

  1. 替换mysql数据库_mysql数据库的替换
  2. Linux基础(2)---系统基础
  3. java工具类-java仿微信九宫格头像
  4. Linux文件管理 | Liunx 常用命令
  5. 七十七、java版商城之直播短视频带货Spring Cloud+SpringBoot+mybatis+uniapp b2b2c o2o 多商家入驻商城 直播带货商城 电子商务
  6. Devoxx法国2012天3
  7. html画布动漫人物,canvas画布画卡通人物--哆啦A梦
  8. 山东省计算机技能大赛通报,比赛成绩通报
  9. 几何分布期望与方差推导
  10. 参考平面及其高度_海图基准面、深度基准、标高等常用参考标准