在 arduino ESP8226 中作为服务器定期向我的客户端发送数据

Send data periodically as a server to my client in arduino ESP8226

我正在使用 NodeMCU 板通过 WiFi 与笔记本电脑通信。使用这样的代码可以进行基本通信:

void loop (){
WiFiClient client = server.available();

  if (client) {
    while (client.connected()){
       client.println(Data_mem[0]); 
       delay(2000);
    }
    client.stop();  // tarminates the connection with the client
   }
}

但是当我想发送一个 Timer Tick 数据时,客户端似乎无法连接到我。

void setup(){
....
  //Initialize Ticker every 40ms
  Data_Rec.attach_ms(40, 40ms_Data );
}

void 40ms_Data (){
WiFiClient client = server.available();

  Serial.println("40ms_Data A");
  if (client) {
      Serial.println("40ms_Data B");
    if (client .connected()){
       Serial.println("40ms_Data C");    
       client.println(40ms_Data [0]); 
    }
    else{
       client.stop(); 
    }
   }
}

我是arduino串口监视器,我只看到这个: 40ms_Data一个\r\n 40ms_Data一个\r\n .... 那么,有人可以帮助我吗?可能是非永久循环中 WiFiClient 减速的问题(如示例 1)。但是我不知道要修复它。

根据M.R.的想法,这是我的全新代码:

#include <ESP8266WiFi.h>
#include <Ticker.h>

/* Put your SSID & Password */
const char* ssid = "NodeMCU";  // Enter SSID here
const char* password = "12345678";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

WiFiServer server(80);                    
const int CLIENT_TIMEOUT = 2000;
Ticker Data_Rec;
bool Sending_40ms_Start_Flag = false;

void setup() {
  Serial.begin(115200);
  pinMode(D0, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);

  server.begin();
  Serial.println("HTTP server started");
    Data_Rec.attach_ms(500, flag_enable);//500ms is for test
}

void flag_enable(){
    //Read FPGA Data from SPI
    //...
    Sending_40ms_Start_Flag = true;
}


void loop(){
    WiFiClient client = server.available();
    if (client) {
        while(client.connected()){
        Serial.println("40ms_Data B");
            if (Sending_40ms_Start_Flag){          
              client.println("Server listening.\r"); 
              Sending_40ms_Start_Flag = false;                            
            }
            delay(1);//without this delay, ESP would be reset(because it cannot handle background processes)
         }
//         else{
//           client.stop();
//         }
      }
}

此代码有效。但是服务器在发送一个、两个或树 "Server listening." 后 RST TCP 连接,如 Wireshark 所示:Wireshark Capture

从 ESP 重置 TCP 的可能原因是什么?

此外,您的代码中存在一些语法错误: 一个好的解决方案是从 client 创建一个静态指针对象并将其作为参数传递给 ms40_Data 函数:

void ms40_Data(WiFiClient *client)
{
    Serial.println("40ms_Data A");
    if (*client)
    {
        Serial.println("40ms_Data B");
        if (client->connected())
        {
            Serial.println("40ms_Data C");
            //client.println(40ms_Data [0]);
        }
        else
        {
            client->stop();
        }
    }
}

void setup()
{
    ...
    // create a static object from WiFiClient
    static WiFiClient client = server.available();
    //Initialize Ticker every 40ms
    Data_Rec.attach_ms(40, ms40_Data, &client);
}

void loop()
{
}

另一个解决方案是,您可以在代码中设置一个标志,然后调用您的 ms40_Data 函数:

bool start_40ms_Data = false;

void ms40_Data()
{
    static WiFiClient client = server.available();

    Serial.println("40ms_Data A");
    if (client)
    {
        Serial.println("40ms_Data B");
        if (client.connected())
        {
            Serial.println("40ms_Data C");
            //client.println(40ms_Data [0]);
        }
        else
        {
            client.stop();
        }
    }
}

void flag_enable()
{
    start_40ms_Data = true;
}

void setup()
{
    ...
    //Initialize Ticker every 40ms
    Data_Rec.attach_ms(40, flag_enable);
}

void loop()
{
    if (start_40ms_Data)
    {
        ms40_Data();
        start_40ms_Data = false;
    }
}

重点是将其添加到设置函数中: WiFi.mode(WIFI_AP); 完整解释:Here 谢谢,