Skip to content

WIFI UDP no longer receives data after data is sent #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
robert-nash opened this issue Apr 5, 2015 · 7 comments
Closed

WIFI UDP no longer receives data after data is sent #53

robert-nash opened this issue Apr 5, 2015 · 7 comments

Comments

@robert-nash
Copy link

Alse posted on ESP8266.com forumn.

I'm not entirely sure that this is a bug but I can't see any other explanation for the behavior. I am using the following code on which is connected to a python script which essentially acts as a terminal-esque way of sending and receiving data to the ESP. The code below works and I can have the light set on or off. The problem is that, after a message has been sent using sendMessage, the ESP will no longer receive packets. I can see from the serial output that the loop is still running and if I remove the call to sendMessage, it will continue turning the light on and off merrily. I wonder if I'm just missing something?

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

WiFiClient client;
WiFiUDP port;

char packetBuffer[255];
unsigned int localPort = 9999;
IPAddress serverIP(192, 168, 1, 117);


void setup() {
  Serial.begin(9600);
  WiFi.begin("******", "********");
  port.begin(9999);
  pinMode(2, OUTPUT);
  digitalWrite(2,LOW);
}

void loop() {
  int packetSize = port.parsePacket();
  Serial.println(packetSize);
  if (packetSize) {
    int len = port.read(packetBuffer, 255);
    if (len > 0) packetBuffer[len] = 0;
    Serial.println(packetBuffer);
    handleMessage(String(packetBuffer));
  }
  delay(500);
}

void handleMessage(String data) {
  if(data=="on"){
    digitalWrite(2,HIGH);
    Serial.println("ON");
    sendMessage("light on");
  }
  if(data=="off"){
    digitalWrite(2,LOW);
    Serial.write("OFF");
    sendMessage("light off");
  }
}

void sendMessage(char data[]) {
  port.beginPacket(serverIP,localPort);
  port.write(data);
  port.endPacket();
}

From what I can see, it looks like the call to beginPacket in WiFiUDP.cpp resets everything when it calls: _ctx->unref();
In order to try and get around this I have tried calling stop and then begin again after a transmission to restart the listening but to no avail.

int WiFiUDP::beginPacket(IPAddress ip, uint16_t port)
{
    ip_addr_t addr;
    addr.addr = ip;

    if (_ctx)
        _ctx->unref();
    _ctx = new UdpContext;
    return (_ctx->connect(addr, port)) ? 1 : 0;
}
@ghost
Copy link

ghost commented Apr 6, 2015

Guess this is not the right way to solve the issue, but this workaround works for me:

void sendMessage(char data[]) {
WiFiUDP port2;
port2.beginPacket(serverIP,localPort);
port2.write(data);
port2.endPacket();
}

@igrr
Copy link
Member

igrr commented Apr 6, 2015

Yes, i think this is the right way — just create two WiFiUDP instances, one listening, one transmitting.

@robert-nash
Copy link
Author

Thank you, that makes sense. It would be helpful if things like this were documented. Is there somewhere where people are able to contribute to documentation as I would be willing to add to it if there were.

@tim-in-oakton
Copy link

This does seem related to #64, if the beginpacket does whack all info. That said, it is important to be able to send a UDP packet and receive the response - which seems like a different use case than above-

@igrr
Copy link
Member

igrr commented Apr 11, 2015

Mhm, i guess I need to read through the original WiFiShield library source code again — perhaps I messed up UdpClient's semantics.

@igrr igrr reopened this Apr 11, 2015
@igrr igrr closed this as completed in 00247bb Apr 11, 2015
@pRoFlT
Copy link

pRoFlT commented May 21, 2015

Arduinos site shows that you can send data back to the sender through a single UDP connection. But I had the same issue as roberttang30. I wanted to receive from a UDP port and respond using a know port. Once i sent data i could no longer receive data. I think this must only work when you respond to the senders port. Using two UDP objects the way mvdbro said works for me. I'm using TouchOSC to send receive to the ESP and having two UDP objects work. One for send and the other for receive. Thanks.

igrr added a commit that referenced this issue Oct 29, 2015
UdpClient used to create a new socket for each begin/beginPacket call. This made bidirectional communication impossible.
Fix #64, fix #53.
@moebiussurfing
Copy link

here is working send and receive with only one (WiFiUDP Udp;) instance. sending and receiving OSC
could be a problem?
should I use two instantes one for each port?

ascillato pushed a commit to ascillato/Arduino that referenced this issue Nov 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants