当前位置: 首页 > 知识库问答 >
问题:

执行其他操作时,ESP8266 UDP ParsePackage不工作

高明辉
2023-03-14

在过去的几天里,测试我情绪的问题是,尽管我的ESP8266芯片完全能够在while循环中通过parsePacket获取数据包,但当我既想监听传入的数据包,又想让我的ESP8266读取传感器并通过wifi发送这些数据包时,它完全忽略了这些。

所以我删掉了所有与传感器有关的内容,并在下面粘贴了代码,但下面是正在发生的事情。

  1. 在Setup()中,ESP设置wifi、SoftAP节点、UDP并进行配置
  2. 然后,它进入一个while循环,通过wifi监听传入的包;这会告诉ESP开始吐出数据
  3. 当ESP接收到数据包时(这是“a”。

我的问题是这一步:

我的猜测是,A.工作正常,因为'而'条件将允许parse包始终捕获传入数据包。因为B.在无效循环中,所以我不能使用“虽然”条件,而是使用“如果”语句,所以parsePket命令不会在正确的时刻请求传入的包。我一直无法实现解决这个问题的东西。相当多的搜索并没有真正有所帮助,我无法想象只有我一个人有这个问题。

我发现了一些相关的事情:

  • 不幸的是,WifiEventHandler没有列出与接收数据包相关的事件:https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-class.html
  • 我也找到了这个主题,但是我无法让它工作,这个问题的答案似乎并不完整:制作一个不阻止ESP8266/Arduino的UDP类

我非常感谢你的帮助和反馈!

这是我的代码

#include <Wire.h>
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>

String SendString;
String SendBuffer = "STR ";
boolean SendSuccessful;
char SendChar[32];

// wifi connection variables
const char* password = #########;
boolean wifiConnected = false;
String ssid_string;
char ssid[10];

// UDP variables
unsigned int localPort = 8888;
WiFiUDP UDP;
boolean udpConnected = false;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[500] = "acknowledged"; // a string to send back

void setup(void) {
  Serial.begin(115200);

  //Setup all my sensors, code not relevant

  //Connect Wifi
  ssid_string = "DRILL_" + String(chip_id);
  ssid_string.toCharArray(ssid, 500);
  SetupWifi(ssid);
}

void loop(void) {

  //B. <<<< SO THIS IS THE PART IN THE LOOP THAT IS NOT WORKING
  int packetSize = UDP.parsePacket();
  packetSize = UDP.parsePacket();  
  if (packetSize) {
    Serial.println("");
    Serial.print("Received packet");

    // read the packet into packetBufffer
    UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    int value = packetBuffer[0] * 256 + packetBuffer[1];
    Serial.println(value);
  }

  //Read out all my sensors, code not relevant, paste all sensor data in one string

  //SendString over serial
  Serial.print(SendString);

  SendIntervalUDP(1); // Send SendString over UDP every x measurements (see function below)

  //Listen to serial
  if (Serial.available() > 0) {
    String Received = Serial.readString();
    Serial.println("ESP received: " + Received);
  }
}

现在这是在设置wifi和通过wifi发送数据的一些支持功能

unsigned long previousWifiStatMillis;

//Connect wifi during setup
void SetupWifi(char my_ssid[]) {

  // WiFi init
  wifiConnected = createAP(my_ssid);

  udpConnected = connectUDP();

  // Wait for first packet
  Serial.println("Waiting for start");

  //A. <<<< SO THIS IS THE PART IN THE CODE THAT IS ACTUALLY WORKING
  int packetSize = UDP.parsePacket();
  while (packetSize < 1) {
    packetSize = UDP.parsePacket();
    yield(); // Allow the background functions to work
    //Listen to serial
    if (Serial.available() > 0) {
      String Received = Serial.readString();
      Serial.println("I received: " + Received);
      if (Received.substring(0) == "S") {
        Serial.println("Starting..");
        break;
      }
    }

    if (packetSize)
    {
      Serial.println("");
      Serial.print("Received packet");

      // read the packet into packetBufffer
      UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
      Serial.println("Contents:");
      int value = packetBuffer[0] * 256 + packetBuffer[1];
      Serial.println(value);

    }
  }
}


// connect to UDP – returns true if successful or false if not
boolean connectUDP() {
  boolean state = false;

  Serial.println("");
  Serial.println("Connecting to UDP");

  if (UDP.begin(localPort) == 1) {
    Serial.println("Connection successful");
    state = true;
  }
  else {
    Serial.println("Connection failed");
  }

  return state;
}

// connect to wifi – returns true if successful or false if not
boolean createAP(char my_ssid[]) {
  boolean state = true;
  int i = 0;
  WiFi.softAP(my_ssid, password);             // Start the access point
  WiFi.mode(WIFI_AP);
  Serial.print("Access Point \"");
  Serial.print(my_ssid);
  Serial.println("\" started");
  Serial.print("IP address:\t");
  Serial.println(WiFi.softAPIP());         // Send the IP address of the ESP8266 to the computer
  state = true;
  return state;
}


// connect to wifi – returns true if successful or false if not
boolean connectWifi(char my_ssid[]) {
  boolean state = true;
  int i = 0;
  WiFi.begin(my_ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  // Wait for connection
  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 20) {
      state = false;
      break;
    }
    i++;
  }
  if (state) {
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(my_ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("");
    Serial.println("Connection failed.");
  }
  return state;
}

void SendIntervalUDP(int interval) {
  //Send an udp packet every x packets with x the interval
  j++;
  if (j > (interval-1) ) {
    j = 0;
    //SendString over wifi
    if (wifiConnected) {
      if (udpConnected) {
        // send a reply, to predetermined hotspot
        UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
        SendBuffer.toCharArray(ReplyBuffer, 500);
        UDP.write(ReplyBuffer);
        UDP.endPacket();
      }
    }
    SendBuffer = "";
  }
}

共有1个答案

羊舌赞
2023-03-14

“通用类”中的WiFi事件是针对传输层以下的现场视察级别的。TCP和UDP是传输层。

要接收UDP数据包,必须调用UDP。parsePacket() loop()(或在从loop()调用的函数中)与其他实现ArduinoUDP基类的Arduino网络库类似。

如果数据包可用,调用parsePacket将数据包读入内部缓冲区并返回数据包的大小。下一次调用parsePacket将清除缓冲区,并在可用时用新数据包填充缓冲区。你调用parsePacket两次,第二次总是什么也不返回。

 类似资料:
  • 其他操作 执行 sudo mn -c 会进行清理配置操作,适合故障后恢复。 执行 exit 会退出 Mininet 的 CLI,同时给出运行时间统计。 py cmd 使用 Python 来执行 cmd。 测试 Mininet 启动后立刻关闭的时间可以用 sudo mn --test none。

  • 我一直在使用storm拓扑设置,以便在不出现内存错误的情况下实现最大吞吐量。 3节点storm(V1.0.1)群集。显然,一个节点也是主节点,部署到AWS M3.2xLarge实例上。有12个工作人员(每个节点4个): 每个工作者有4 GB的堆空间: 特别是我的一个bolt,让我们称之为:具有12的并行性提示。 这将创建12个执行器,每个执行器有一个任务(因为我正在使用Flux配置/部署)。的流类

  • 问题内容: 在下面的代码中,我试图一次性进行多个(大约10个)HTTP请求和RSS解析。 我在需要访问和解析结果的URI数组上使用标准构造。 码: 我了解一次调用函数时,应该使用回调。但是,在此示例中,我唯一想到使用回调的方法是调用一个函数,该函数对被调用的次数进行计数,并且仅在被调用的次数与看起来很hacky 的次数相同时才继续。 所以我的问题是, 在node.js中处理这种情况的最佳方法 是

  • 在我的程序中,我反复1收集Java8流,以将对象集合减少为单个对象。在整个执行过程中,这个集合的大小可能会有很大的变化:从3个对象到数百个对象。 在优化我的代码和搜索瓶颈的过程中,我在某个点使流并行。这在当时起了作用,因为所有的收藏都相当大。后来,在更改程序的其他部分和参数后,集合变小了。我意识到不让流平行更有效。这是有道理的:为4个对象在多个线程上分配工作的开销根本不值得。不过,对于成百上千的物

  • 问题内容: 我有一个http服务器(使用启动),我想做一些操作。 我该怎么做(在Linux上)?在ctrl-C的情况下可以进行那些操作吗? 我不熟悉Unix信号,因此答案可能很简单。 问题答案: 您可以使用信号包订购TERM和INT信号。但是请注意,只有在明确终止进程时才发送这些信号。正常退出(由流程本身启动)不涉及任何信号。我认为,对于正常退出,只需在主例程中执行某些操作即可(该例程应该生成工作

  • 我从学习Spring开始,创建基本项目,创建数据库,插入值,然后在web浏览器中打印。我的问题是,当我把RestController放在同一个包中,就像main class一样--这是可以的,但是我想把它分发到其他包中,并且当我创建新包时,移动RestController就不起作用了。让met解释: 我的项目看起来像: 我的pom.xml看起来像 它是自动生成的,我只写一个依赖项