Arduino ESP8266编程深入要点
Arduino for ESP8266的话,如果不修改代码,默认没有办法进入轻睡眠的省电模式,只能进入Modem Sleep,也就是说Wifi可以暂时睡眠但是CPU没法睡,Modem Sleep最低功耗在15mA-16mA,轻睡眠的最低功耗在1mA-2mA左右
如果要在Arduino中再腾出几KB内存的话,我这晨还有一个方法,就是去到esp8266 arduino的开发包中,找到一个叫"cont.h"的头文件,里边有一个栈大小的宏定义常量叫“CONT_STACKSIZE",他的值默认是4096,我试着将他改成1024,这样就省了3KB内存,具体稳定的话,我用一个程序目前测试了一下,还是可以顺利腾出3KB的内存的,因为刚好我应要用把这将近50K的内存用完,所以特此贡献这个方法
我先看看他的调度的汇编来确定一下是否有其他的隐患,目前是测得可以正常工作的
如果你用过SDK就会发现,有将近50K的内存,你用Arduino会少了几K,不好奇是去了哪里吗?有4K至少,是被用来做保存是上下文用的,什么是上下文?就是内核调度器的一个概念,你可以理解为,一个MCU要实现不同的线程,他就要为单个线程保存单独的现场环境,而这个现场环境就用掉了4K多一点的内存了
如果有空可以将试着去官网下载一个最新版的SDK文件夹,然后将"lib"中的文件替换至现在的2.0.0版的"lib"文件夹中,这样的话,可以使用一些SDK1.5.0的一些最新的特性(不知道的可以暂时不升级),记得替换前要进行好备份原来的文件夹,如果替换后编译时出错,则可以在这个旧的文件夹中找至具体出错的文件进行找旧版的覆盖上去用,目前我大部份测试Arduino 2.0.0将SDK 1.3.0替换成SDK1.5.0(最新版的)也是可以正常工作的
另外发现Arduino的一个问题就是在使用TCP(注意仅是TCP)发送一个内存缓冲区(大小是1450左右)函数的时候速度很慢(表现为TCP这个write函数执行时间较久),暂时我还没有办法找到内部的原因,但是使用SDK就没有这个问题,但是为了使用Arduino良好的编译环境,以及一堆的函数库(比如SD卡库),我在Ardiuno中使用了SDK的代码(可以直接编译成功,改动不大)
我查看过这个write函数内部的源代码,发现里边有进行调度的迹象,因此有可能是因为这个Arduino内部的调度所产生的问题,这样的话比如你要做一个实时性要求很高的串口透传就会有受影响
但如果对这个实时性要求不高的话,暂时Arduino也可以满足要求,我的话,是在Arduino上采用SDK编程的方法,使用异步回调的接口(而不是像Arduino一样必须在一个大循环里执行所有的逻辑)
同时也要注意,由于esp8266的省电模式中,有三种,其中有一种是叫Modem Sleep,这种是默认开启的(你可能在一买回来就ping这个esp8266会觉得慢,其实不是他慢,根据我的测试,只要关掉这个默认的省电模式,esp8266的响应非常快,可以达到小于1毫秒的时间)理论分析也是可以做到小于1毫秒的,实测也可以。这种模式对于Arduino来讲是可以轻易进入的,他的功耗大概是省电模式进入后是15mA左右,但是对于第二种比较好用的更省电的模式,大概是1mA左右,是15分之一
但是这种模式,你首先要理解为什么省电能再省14mA?原因是这个CPU可以被暂停!但由于是由系统自己判断如何进入省电模式的,其中有一个重要的条件,则是,CPU要保持空闲,才会被检测到,这是系统内部的逻辑来实现的,其中有一点重要的条件就是,CPU上的程序不能有一个循环定时,它的间隔是不能小于路由器上的两个DITM Beacon帧中设定的间隔的,通常我们家用的一般是100毫秒,你可以抓包看看便知具体数值,一般是这个
如果有一个定时他总是小于100毫秒去执行的
那么CPU便不能被判定为空闲状态,换言之,他省电也只能做到15mA了,即使你调用了API将系统设定为轻睡眠模式
用Arduino的结论就是默认不能进入轻睡眠模式,那就是说默认情况下你用Arduino做的东西的最低的功耗可能只能到15mA了,一个1500mAh的电池,可以跑80个小时,因为中间还会醒来接收一下是否有数据要发给自己的,所以不会跑足100个小时的,而接收时的平均电流一般是60-70mA左右,这是比15mA还要大几倍的
好了,那是不是就彻底没办法了?
有的
那就是想办法将这个阻碍系统判定Arduino进入省电模式的东西去掉
core_esp8266_main.cpp
在这个核心的文件中,你打开就会发现刚才我讲的,那个“Arduino利用SDK的函数来创建一个SDK上的任务(注意不是RTOS)”的函数
我现在的推测就是可能是这个创建的任务导致Arduino不能进入轻睡模式的,因为他这个任务的时间片可能就是15mS左右,15mS当然是小了100mS的了!所以这又怎么会能进入轻睡眠模式呢?CPU怎么可能知道他啥时候要睡呢?一睡要是影响了你的15mS的时间片,人家罪就大了不是?
15mS这个时间值是经详细研读乐鑫的esp8266手册推测得出的,官方特么的没有任何说法给出来这些重要的数值
所以啊,要让Arduino不要被阻碍进入轻睡眠模式,从而让CPU可以顺利被暂停的关键就在于要去掉这个创建的任务了
着重来看这个函数
core_esp8266_main.cpp中的"loop_wraper()"
static void loop_wrapper() {
static bool setup_done = false;
if(!setup_done) {
setup();
setup_done = true;
}
preloop_update_frequency();
loop();
esp_schedule();
}
他就是Arduino中的loop函数那个大循环的“包在外边”的代码了
一者是setup(),一者是loop(),setup使用了一个静态变量来判断为只执行一次
loop()则是你实际的loop函数的代码,在编译时,这个函数会和在ino文件中的loop函数对应链接起来
所以有了这个不断在执行的循环啊
系统不能让它睡这个也完全可以理解了吧?
那么问题来了,是不是只要简单的不要创建这几个任务就行了呢?
是的,如果你不使用Serial等内部封装了Arduino本身的这套调度系统的话,是没有大问题的
但是啊,问题是这些平时用得很爽的封装过的类啊,他内部或多或少都是使用了Arduino的这套调度系统的
你不相信可以自己使用VS的跳转功能来查看这些函数的源代码,就知道了
所以啊,换言之啊,可以总结为
如果你想在Arduino中找到一些不使用这些调度系统的函数的话, 那用之,则没问题
但是很可惜很多都不行
要用轻睡眠省电模式就最好不要用Arduino
不要觉得奇怪,看起来低效的东西,逻辑上往往很好理解!
这就是Arduino的封装者为什么一定要强行加一个setup和loop的原因,内部的逻辑就是为了简化入门者的门槛,同时引导你快速形成一种编程的思想习惯,也就是西乡一样所强调的“编程框架”
虽然它不是异步的,但显然是简单而又可以让你动脑筋去实现复杂的结构的一种好的切入点
只要我们不满足于这种编程的方式,我们总能找到更有效的异步回调的方式的,但,那时的你也不是一个新手级别的人了
自然而言掌握回调这样的方法来解决业务逻辑,这是轻而易举的事
所以Arduino他并不是低效(虽然我本人也比较喜欢用异步的方式,看起来比较“高效”)
好了,只要注重几个重要的点,其实Arduino也没啥的,他的执行速度就是SDK的执行速度,C++和C语言之间的这点点执行差别,我们根本就很难体现得出来的!
Arduino ESP8266编程深入要点的更多相关文章
- 【Arduino】、Arduino+ESP8266上传至oneNet云
一.硬件简介 1. Arudino 是一种开源的电子平台,该平台最初主要基于AVR单片机的微控制器和相应的开发软件,包含硬件(各种型号的Arduino板)和软件(Arduino IDE). 2. ES ...
- ArduinoYun教程之通过网络为Arduino Yun编程
ArduinoYun教程之通过网络为Arduino Yun编程 Arduino Yun的软件部分 通过第一章的介绍后读者就明白了Arduino Yun除了是一个类似其他Arduino的单片机之外,它的 ...
- Mac Arduino ESP8266 ESP32 搭建开发环境
目录 1.安装Arduino 2.搭建开发板管理器 3.可能出现的错误 1.安装Arduino Arduino下载. 官方下载地址:Arduino官方网站 Arduino中文社区:下载地址 安装方式: ...
- blinker语音控制Arduino/esp8266开关灯-滑动条使用-文本框交互
总链接: https://www.arduino.cn/thread-78393-1-1.html 语音控制:https://doc.blinker.app/?file=005-App%E4%BD% ...
- esp8266(1) 手机+Arduino+esp8266通信
ESP8266 Android与Arduino通信 功能描述: 1 Arduino上电,它通过软串口(Arduino的 2号和3号脚)发送命令,配置espson8266为 AP模式,wifi名 DDD ...
- PHP面向对象编程知识要点
1.基本概念 1.1.面向对象的阶段概念 OOA:面向对象分析 OOD:面向对象设计 OOP:面向对象编程 1.2.类的概念 面向对象中的类,实质上就是现实世界中一类有着相似属性事物抽象的概括,像鸟类 ...
- 基于Air800+Arduino+ESP8266的混合物联网开发
流程图如下:
- keil 使用C++编程主要要点
1.中断处理,添加一下宏定义.如果不添加,中断服务函数不会链接到下载文件中:发生中断后,会停留在xxx.s文件的 "B ."语句. #ifdef __cplusplus exter ...
- socket网络编程实践要点
1.创建udp的socket句柄 // 当host_port为0时,则表示让操作系统自动分配 bool createUdpSocket(string host_ip,unsigned short ho ...
随机推荐
- zk 10之:Curator之三:服务的注册及发现
Service Discovery 我们通常在调用服务的时候,需要知道服务的地址,端口,或者其他一些信息,通常情况下,我们是把他们写到程序里面,但是随着服务越来越多,维护起来也越来越费劲,更重要的是, ...
- Spring boot 学习八 Springboot的filter
一: 传统的javaEE增加Filter是在web.xml中配置,如以下代码: <filter> <filter-name>TestFilter</filter-nam ...
- java代码优化(1)---
代码的优化,需要考虑的维度很多.但是代码的优化并不是减少代码量,有的时候我们需要增加代码来提高代码的可读性. 1.正确标记变量 2.封装某个动作 3.注意函数的写法 4.不容易理解的东西,加注释
- Repeater 和 GridView 添加序列号
<tr><asp:Repeater ID="rptOfBrowerInfo" runat="server" > <Heade ...
- 2、CDH组件安装
一.zookeeper 1.安装 继续->完成: 二.HDFS 1.安装 继续->完成: 三.yarn.hive 1.安装yarn 继续->完成: 2.安装hive 继续->完 ...
- 51Nod - 1092 回文字符串(添加删除字符LCS变形)
回文字符串 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串.每个字符串都可以通过向中间添加一些字符,使之变为回文字符串. 例如:abbc 添加2个字符可以变为 acbbca, ...
- Guid.NewGuid().ToString()的几种格式 (转)
1.Guid.NewGuid().ToString("N") 结果为: 38bddf48f43c48588e0d78761eaa1ce6 2.Guid.NewGuid() ...
- JAVA企业级开发-sql入门(07)
一. 数据库 什么是数据库? 就是一个文件系统,通过标准SQL语言操作文件系统中数据 ---- 用来存放软件系统的数据 我们今天学习的数据库是mysql.关系型数据库. 什么是关系化数据库 ? 保存关 ...
- MVC动态生成的表单:表单元素比较多 你就这样写
MVC动态生成的表单:表单元素比较多 你就这样写: public ActionResult ShoudaanActionResult(FormCollection from,T_UserM user) ...
- 使用Maven构建Spring Security应用
1.概述 本文将解释如何使用Maven构建Spring Security应用程序.将讨论使用Spring Security依赖项的特定用例.最新的Spring Security版本可以在Maven C ...