从零开始的ESP8266探索(07)-使用Arduino for esp8266出现的问题小结

2023-11-19

问题一

现象描述

  • 使用 WiFi.softAP 方法建立网络,有时候很难连接上;
  • 改用 WiFi.begin 切换为STA模式后用其他设备扫描网络发现竟然前次设置的AP模式网络还在;

原因分析

阅读Arduino for esp8266库文档可以知道用该方式来开发除了我们写的代码外还有很多功能在运作,比如使用 WiFi.begin 连接过的网络默认情况下会被存储,并在下次上电时自动连接。
是不是在使用 WiFi.softAP 模式的时候我前次实验用过的 WiFi.begin 功能的网络还存在,并且上电就去尝试连接了?而在使用 WiFi.begin 模式下存在之前的AP模式网络是不是也因为这个原因?是不是因为这些原因导致了上面的问题?

解决方法

虽然没在库中找到完整的相关描述,但是解决方法倒是有(实测可行),在开启STA或AP功能前强制设定工作模式,使用下面方法:

WiFi.mode(m) :set mode to WIFI_AP , WIFI_STA , WIFI_AP_STA or WIFI_OFF .

从上面方法的参数中也可以知道ESP8266其实是可能会同时工作在AP和STA模式下的,要是该模式不是你想要的,最好强制设置下。

问题二

现象描述

网络运行不稳定,有时候会断开或失去连接,特别是在工作较频繁时该现象更严重。

原因分析

阅读Arduino for esp8266库文档可以看到下面描述:

Remember that there is a lot of code that needs to run on the chip besides the sketch when WiFi is connected. WiFi and TCP/IP libraries get a chance to handle any pending events each time the loop() function completes, OR when delay is called. If you have a loop somewhere in your sketch that takes a lot of time (>50ms) without calling delay, you might consider adding a call to delay function to keep the WiFi stack running smoothly.


There is also a yield() function which is equivalent to delay(0). The delayMicroseconds function, on the other hand, does not yield to other tasks, so using it for delays more than 20 milliseconds is not recommended.

上文的意思就是说使用Arduino for esp8266来开发时除了你自己的代码外还有很多TCP/IP的工作需要运行,这些工作在 loop() 或是 delay 亦或是 yield() 过程中执行。如果你的程序耗时(>50ms),请调用一下 delay 函数 或是 yield() (等价于 delay(0) )。

解决方法

解决方法就按上文所述。

问题三

现象描述

使用Web Server功能时,在客户端连接后长时间无响应。

原因分析

分析程序可看到 while (client.connected()){……} 这里用了 while 但是可能因为某些原因在这内部并没有执行到跳出的动作,导致一直在此处循环。

解决方法

while 里面加入超时处理。

实例应用

针对上述的几个问题这里用前一篇文章中的代码进行修改作为示范:

#include <ESP8266WiFi.h>

/*** 该工程可以在2.4.0版本esp8266库中运行,没在更高版本库中进行测试 ***/

const char *ssid = "********";
const char *password = "********";

WiFiServer server(80);

String readString = ""; //建立一个字符串对象用来接收存放来自客户的数据

//响应头
String responseHeaders =
    String("") +
    "HTTP/1.1 200 OK\r\n" +
    "Content-Type: text/html\r\n" +
    "Connection: close\r\n" +
    "\r\n";

//网页
String myhtmlPage =
    String("") +
    "<html>" +
    "<head>" +
    "    <title>ESP8266 Web Server Test</title>" +
    "    <script defer=\"defer\">" +
    "        function ledSwitch() {" +
    "            var xmlhttp;" +
    "            if (window.XMLHttpRequest) {" +
    "                xmlhttp = new XMLHttpRequest();" +
    "            } else {" +
    "                xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");" +
    "            }" +
    "            xmlhttp.onreadystatechange = function () {" +
    "                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {" +
    "                    document.getElementById(\"txtState\").innerHTML = xmlhttp.responseText;" +
    "                }" +
    "            }," +
    "            xmlhttp.open(\"GET\", \"Switch\", true);" +
    "            xmlhttp.send(); " +
    "        }" +
    "    </script>" +
    "</head>" +
    "<body>" +
    "    <div id=\"txtState\">Unkwon</div>" +
    "    <input type=\"button\" value=\"Switch\" onclick=\"ledSwitch()\">" +
    "</body>" +
    "</html>";

bool isLedTurnOn = false; // 记录LED状态

void setup()
{
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH); // 熄灭LED

    Serial.begin(115200);
    Serial.println();

    Serial.printf("Connecting to %s ", ssid);
    
    WiFi.mode(WIFI_STA); //******设置为STA模式******
    WiFi.setAutoConnect(false); //关闭上电时自动连接到已保存网络
    
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println(" connected");

    server.begin();
    Serial.printf("Web server started, open %s in a web browser\n", WiFi.localIP().toString().c_str());
}

void loop()
{
    WiFiClient client = server.available(); //尝试建立客户对象
    if (client)                             //如果当前有客户可用
    {
        boolean currentLineIsBlank = true;
        Serial.println("[Client connected]");

        unsigned long previousMillis = millis(); //******获取当前时间******
        while (client.connected()) //如果客户端建立连接
        {
            if(millis() - previousMillis >= 50)yield(); //******如果50ms未处理完则调用延时处理网络事务******
            if(millis() - previousMillis >= 5000)break; //******如果5000ms则认定超时,立即跳出******
          
            if (client.available()) //等待有可读数据
            {
                char c = client.read(); //读取一字节数据
                readString += c;        //拼接数据
                /************************************************/
                if (c == '\n' && currentLineIsBlank) //等待请求头接收完成(接收到空行)
                {
                    //比较接收到的请求数据
                    if (readString.startsWith("GET / HTTP/1.1")) //如果是网页请求
                    {
                        client.print(responseHeaders); //向客户端输出网页响应
                        client.print(myhtmlPage);      //向客户端输出网页内容
                        client.print("\r\n");
                    }
                    else if (readString.startsWith("GET /Switch")) //如果是改变LED状态请求
                    {
                        if (isLedTurnOn == false)
                        {
                            digitalWrite(2, LOW); // 点亮LED
                            client.print("LED has been turn on");
                            isLedTurnOn = true;
                        }
                        else
                        {
                            digitalWrite(2, HIGH); // 熄灭LED
                            client.print("LED has been turn off");
                            isLedTurnOn = false;
                        }
                    }
                    else
                    {
                        client.print("\r\n");
                    }
                    break;
                }

                if (c == '\n')
                {
                    currentLineIsBlank = true; //开始新行
                }
                else if (c != '\r')
                {
                    currentLineIsBlank = false; //正在接收某行中
                }
                /************************************************/
            }
        }
        delay(1);      //等待客户完成接收
        client.stop(); //结束当前连接:
        Serial.println("[Client disconnected]");

        Serial.println(readString); //打印输出来自客户的数据
        readString = "";
    }
}

上文中带 //******XXXXXX****** 注释的那几行就是针对上述几个问题所添加的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从零开始的ESP8266探索(07)-使用Arduino for esp8266出现的问题小结 的相关文章

  • Arduino 支持线程吗?

    我有几个任务需要用arduino来做 但其中一个需要很长时间 所以我想使用线程来同时运行它们 我有一个 Arduino Mega 更新 四年后 我终于可以在我的 arduino mega 上安装 FreeRTOS 这里有一个link htt
  • 如何返回变量?

    我正在编写一个程序 将字母翻译成摩尔斯电码 然后将它们传输到 LED 并闪烁 我无法返回值 include
  • GSM SM5100B C M E E R R O R:4 错误

    我正在使用 Arduino 来控制 SM5100B GSM 设备 除了当我想在收到另一条短信后发送短信时 一切正常 我明白了 错误代码 确定 gt C M G S 2 5 确定 C M E E R O R 4 我处理上述收到的短信的代码 i
  • android BluetoothChat 使用来自另一个类的发送接收方法

    您好 我使用 BluetoothChat 示例来与 arduino 进行通信 到目前为止 一切正常 现在我想访问 sendMessage 方法 以便能够不从主类发送数据 而是从我创建的另一个类发送数据 这是BluetoothChat jav
  • Arduino“SerialEvent”示例代码无法在我的 Arduino Nano 上运行。我无法接收串行数据。为什么?

    我正在按照教程进行操作串行事件 https www arduino cc en Tutorial BuiltInExamples SerialEvent我正在尝试这段代码 然而 当我发送我的Arduino 纳米 https en wikip
  • 如何在Arduino上将int转换为字符串?

    如何转换 int n 到一个字符串 以便当我通过串行发送它时 它作为字符串发送 这是我到目前为止所拥有的 int ledPin 13 int testerPin 8 int n 1 char buf 10 void setup pinMod
  • Fedora 中的 Arduino 上传错误“stk500_recv(): 程序员没有响应”

    我正在尝试上传库存Blink在 Fedora Core 15 Linux 中使用 Arduino IDE 绘制草图 我收到此错误 avrdude stk500 recv 程序员没有响应 要重现该问题 通过 USB 线插入 Arduino U
  • 蓝牙 HC-05 发送错误 1F 仅适用于 INQ 命令

    我的新蓝牙 HC 05 模块有问题 在 AT 模式下 它可以与我需要的所有命令完美配合 除了 INQ 我已经尝试事先发送一大堆其他命令 AT INIT OK AT ORGL OK AT ROLE 1 OK AT CLASS 0 OK 他们都
  • Arduino I2S 正弦波

    我正在开发一个项目 我想通过组合不同的正弦波来生成 简单 声音 我使用的是 arduino mkrZero 因为它内置了 I2S 接口 并且似乎有足够的处理能力来满足我的需求 I have wired my system exactly l
  • Android 和 Arduino 都通过蓝牙接收奇怪的值

    我正在 Android 端使用 BluetoothChat 代码使用聊天框向 Arduino UNO 发送开 关信号 我发送 110 119 或下面定义的其他情况 但是当我显示接收到的值时 它显示奇怪的Arduino 串行监视器中的值 即
  • DCF77 解码器与噪声信号

    我几乎完成了我的开源 DCF77 解码器项目 当我注意到标准 Arduino DCF77 库在噪声信号上表现非常差时 这一切就开始了 特别是当天线靠近计算机或洗衣机正在运行时 我永远无法从解码器中获取时间 我的第一个方法是向输入信号添加 数
  • 同时使用 GPRS 和 GSM

    我正在尝试使用 GSM GPRS 调制解调器的 GPRS 功能将数据发送到远程服务器 但我无法这样做 我在 Arduino 论坛上发布了一个问题 但没有得到任何回复 这是问题的链接 https robotics stackexchange
  • C++ Linux (Ubuntu) 正确写入串行(对于 Arduino)

    我想知道是否有一种标准方法可以与高效的串行设备进行通信 我应该使用标准库吗 如果有 是哪一个 现在我正在摆弄让 LED 根据输入的数字以给定的量亮起 Arduino 代码如下 只是练习一些东西 看我过于简单且低效的测试 include
  • Arduino - 高效地迭代 C 数组

    我有以下数组 PROGMEM prog uint16 t show hide info 4216 8900 4380 580 500 600 500 580 1620 580 500 600 500 580 500 600 480 600
  • pySerial 与 python 2.7 和 3.4 的差异

    我正在开发一个项目 需要通过串口将一些数字从 Windows 10 中的 python 发送到 arduino uno 作为一个简单的测试 我只想通过发送 2 来打开 LED 并通过从命令提示符发送 4 来关闭 LED 尽管我希望最终能够将
  • Arduino 上的 Serial 和 Stream 有什么区别,Serial.write 是如何实现的?

    我很难理解串行和流这两个术语之间的区别 串行不是流的一种吗 我对作业有一些我不明白的问题 计算机通过使用 流或串行 读取 彼此发送的数据来确定每个字节的含义 Also Serial write 我也很困惑 它返回一个字节的数据 对吗 一个字
  • 使用 Java 控制 Arduino

    我正在寻找一个LED http en wikipedia org wiki Light emitting diode用Java程序打开和关闭 我用 C 完成了这个项目大约 5 分钟 但用 Java 似乎更具挑战性 我让 Arduino 等待
  • 如何在 Windows 上获取 Arduino 草图的汇编语言列表?

    我希望能够看到我的 Arduino 草图的汇编语言列表 我怎样才能实现这个目标 Update 我正在 Windows 机器上运行 Arduino 软件 一种方法是使用avr objdump on the elf构建创建的文件 例如 在 OS
  • 使用 Ardulink 命令 Arduino Uno

    我试图在我的 JAVA 应用程序中使用 Ardulink 库来命令我的 Arduino Uno 但没有成功 我不知道我错过了什么 这是我的代码 Link link Link getDefaultInstance boolean connec
  • Arduino串口数据解析

    我正在编写一个应用程序 通过蓝牙用我的 Android 手机控制我的机器人 一切都很顺利 数据得到回显和验证 但我在协议方面遇到了一些问题 特别是我希望我的机器人的轮子在我发送时转动一个命令 例如s 10 100 or s 30 10 数值

随机推荐

  • [C++基础]-stack和queue

    前言 作者 小蜗牛向前冲 名言 我可以接受失败 但我不能接受放弃 如果觉的博主的文章还不错的话 还请点赞 收藏 关注 支持博主 如果发现有问题的地方欢迎 大家在评论区指正 目录 一 stack的基本知识 1 什么是栈 2 栈的基本使用 3
  • Python 使用execjs调用网页js 进行数据加密

    最近做一个数据采集项目的时候需要自动采集网站的招投标数据 随便打开一个网站 打开开发者模式 输入关键词 点击搜索 获得以下内容 可以看到请求链接和请求类型 请求类型Content Type 是application x www form u
  • maven 项目导入junit问题

    maven项目无法导入 import org junit Test import org junit runner RunWith 问题 1 检查 Maven Dependencies中Junit的jar中是否有此类 如果没有 说明pom
  • 判断一个IP地址是不是单播地址

    1 组播地址 2 单播地址 1 2
  • C++_生成随机字符串

    include
  • Vite配置跨域代理

    Vite 配置跨域代理 修改vite config js文件 import defineConfig from vite import react from vitejs plugin react https vitejs dev conf
  • Xilinx AXI-memory接口 转 AXI-stream 接口(含源码)

    AXI memory接口 转 AXI stream 接口 AXI memory接口介绍 具体详情可以查看源码 AXI memory接口介绍 从图中我们可以看出memory接口有5个通道 分别是读地址通道 写地址通道 写响应通道 读数据通道
  • 华为OD两轮技术面试

    华为OD面试 1性格测试 选积极向上的选项 注意 性格测试也会挂人 我一个朋友性格测试就没过 2机试 一道变成题目 1h 用例60 通过即可 任给一个数组 元素有20M 1T 300G之类的 其中1T 1000G 1G 1000M 按从小到
  • 数据库事务锁详解

    前言 上篇说到数据库事务中的特性ACID和4个隔离级别 今儿就来看一下事务中的锁 MySQL中的锁 锁是MySQL在服务器层和存储引擎层的并发控制 锁可以保证数据并发访问的一致性 有效性 锁冲突也是影响数据库并发访问性能的一个重要因素 My
  • 并发编程4 - 线程状态、死锁及ReentrantLock

    文章目录 一 再述线程状态转换 二 多把锁与线程活跃性问题 1 多把锁 2 活跃性 三 ReEntrantLock 1 基本用法 2 可重入 3 可打断 4 锁超时 5 公平锁 6 条件变量 一 再述线程状态转换 情况1 New RUNNA
  • JAVA数据结构——利用图的广度优先遍历搜索算法确定无向连通图的连通分量

    分析 如果这个无向图是非连通图的时候 从图的一个顶点没法访问这个图的所有顶点 只能访问包含该顶点的连通分量中的所有顶点 所以从无向图的每个连通分量中的一个顶点开始遍历图 则可求得无向图的所有连同分量 如图则是非连通的无向图 我们只需要从第一
  • (Python笔记)使用Python解析HEX文件的内容

    需要用到binascii库 binascii库中包含了很多在二进制和二进制表示的各种ASCII码之间转换的方法 Code import binascii HEX path r 1 HEX with open HEX path rb as f
  • Python 实现列队

    1 列队定义 队列是项的有序结合 其中添加新项的一端称为队尾 移除项的一端称为队首 当一个元素从队尾进入队列时 一直向队首移动 直到它成为下一个需要移除的元素为止 最近添加的元素必须在队尾等待 集合中存活时间最长的元素在队首 这种排序成为
  • Flutter个推推送Android端,退出应用后收到消息报错

    场景 Android手机 iOS没有测试 1 集成getuiflut 2 返回退出APP 3 发送推送透传消息 报错 Tried to send a platform message to Flutter but FlutterJNI wa
  • (八)nginx反向代理功能

    nginx反向代理概念 反向代理也称reverse proxy 指的就是代理外网用户请求到内部指定web服务器 并将数据返回给用户的一种方式 nginx除了可以在企业提供高性能的web服务之外 另外还可以将本身不具备的请求通过某种预定的协议
  • centos7安装配置fdfs时service fdfs_storaged start启动不成功

    service fdfs storaged start 命令启动后 提示是启动失败 ps ajx grep fdfs 查看不到 fdfs storaged启动信息 解决方法 当时解压缩时 fdfs storaged解压失败 自己当时没注意
  • ERROR:105: Unable to locate a modulefile for 'xxx'

    查看可用的 module module avail 将xxx替换为屏幕输出中已有的模块 转载于 https www cnblogs com zhyantao p 10462141 html
  • cunit单元测试

    一 安装cunit 1 1下载cunit https sourceforge NET projects cunit 下载最新安装包 1 2解压缩安装包 root Ubuntu1610 tar jxvf CUnit 2 1 3 tar bz2
  • HJ103 Redraiment的走法

    Redraiment是走梅花桩的高手 Redraiment可以选择任意一个起点 从前到后 但只能从低处往高处的桩子走 他希望走的步数最多 你能替Redraiment研究他最多走的步数吗 示例 2 5 1 5 4 5 输出 3 说明 6个点的
  • 从零开始的ESP8266探索(07)-使用Arduino for esp8266出现的问题小结

    文章目录 问题一 现象描述 原因分析 解决方法 问题二 现象描述 原因分析 解决方法 问题三 现象描述 原因分析 解决方法 实例应用 问题一 现象描述 使用 WiFi softAP 方法建立网络 有时候很难连接上 改用 WiFi begin