-->
Page 1 of 2

ESP stops receiving UDP but loop is still executing

PostPosted: Sat Oct 22, 2016 7:10 pm
by Shadow351
I have decided to try another ESP8266 project. I have a couple lamps in my living room I would like to have controlled by an application on my server. The application will send UDP commands to Turn the light on or off as well as request the status of the light. The Visual Basic Program works and The ESP Acts accordingly for a while then stops responding to UDP "commands". I added some code to the ESP to make sure it is still executing the loop, and it is but after some time (18 min on my last test) the UDP just seems to stop. I was having trouble with the ESP8266-03 Modules so I am doing my prototyping with an Adafruit Huzzah ESP-12 Breakout board. I did a bunch of testing and the code works great shortly after a reset, so In my most recent test I first let the ESP sit and loop for a couple hours and then passed some UDP commands to it, it didn't react to the commands so I tried pinging the module and I did get a response so I reset the module and after it connected to the wifi again, I passed the same UDP command to it and it worked properly. Why would the module stop processing UDP packets and is there a way to catch such a scenario and maybe Reset the module? thanks
-Brad

ESP8266 Arduino Code
Code: Select all#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <Time.h> 

const char* ssid = XXXX;
const char* password = XXXX;

IPAddress ip(192, 168, 1, 158);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int port = 2000;
int replyWait = 5000;
// buffers for receiving and sending data
char packetBuffer[32]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back

bool lightStatus = 0;
WiFiUDP Udp;
IPAddress ham(192,168,1,10);
int lastMinUpdate = 0;
bool replyExpected = false;
int lastCycleMin = 0;
int triac = 14;
int greenLED = 12;
int redLED = 13;
int overrideSw = 16;

void setup() {
  pinMode(triac,OUTPUT);
  pinMode(greenLED,OUTPUT);
  pinMode(redLED,OUTPUT);
  pinMode(overrideSw,INPUT);
  digitalWrite(triac,LOW);
  digitalWrite(greenLED,LOW);
  digitalWrite(redLED,LOW);
  Serial.begin(115200);
  delay(10);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  bool ledToggle = true;

  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(redLED,ledToggle);
    ledToggle = !ledToggle;
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  digitalWrite(redLED,HIGH);

  // Print the IP address
  Serial.print("Using IP: ");
  Serial.println(WiFi.localIP());
  Serial.println("Initializing UDP Interface...");
  Udp.begin(port);
  Serial.print("Done, Listening on port ");
  Serial.println(port,DEC);
  Serial.println("Syncing Clock with HAM...");
  sprintf(packetBuffer,"TIME?");
  Udp.beginPacket(ham, port);
  Udp.write(packetBuffer);
  Udp.endPacket();
  replyExpected = true;
  int replyTimeout = millis() + replyWait;
  while (replyExpected && (millis() < replyTimeout))
  {
    checkUDP();
  }
  if (replyExpected)
  {
    replyExpected = false;
    replyTimeout = 0;
  }
}

void parseClock()
{
  int mth = atoi(&packetBuffer[5]);
  Serial.print(mth,DEC);
  Serial.print("/");
  int da = atoi(&packetBuffer[8]);
  Serial.print(da,DEC);
  Serial.print("/");
  int yr = atoi(&packetBuffer[11]);
  Serial.print(yr,DEC);
  Serial.print(" ");
  int hr = atoi(&packetBuffer[16]);
  Serial.print(hr,DEC);
  Serial.print(":");
  int mi = atoi(&packetBuffer[19]);
  Serial.print(mi,DEC);
  Serial.print(":");
  int se = atoi(&packetBuffer[22]);
  Serial.print(se,DEC);

  setTime(hr,mi,se,da,mth,yr);
   Serial.println(" Time is Set");
}

/*
 * Reads and parses data in UDP buffer
 */
void udpRead(int packetSize)
{
    bool ack = true;
    clearArray();
    Serial.print("Received packet of size ");
    Serial.print(packetSize,DEC);                                                                                   
    Serial.print(" from ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, 32);
    Udp.flush();
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    /*
     * parse UDP data
     */
     char *ptr;
     ptr = strstr(packetBuffer,"TIME");
     if (ptr != NULL)
     {
      replyExpected = false;
      parseClock();
     }
     else if (strcmp(packetBuffer, "LIGHT_OFF")==0)
     {
      lightStatus = 0;
      Serial.println("Light Off");
     }
     else if (strcmp(packetBuffer, "LIGHT_ON")==0)
     {
      lightStatus = 1;
      Serial.println("Light On");
     }
     else if (strcmp(packetBuffer, "STATUS?")==0)
     {
        Serial.println("Sending Status");
        ack = false;
        clearArray();
        if (lightStatus)
        {
          sprintf(packetBuffer,"LIGHT_ON");
        }
        else
        {
          sprintf(packetBuffer,"LIGHT_OFF");
        }
        Udp.beginPacket(Udp.remoteIP(), port);
        Udp.write(packetBuffer);
        Udp.endPacket();
     }
     
   
    if (ack && (strcmp(packetBuffer,"acknowledged") != 0))
    {
      // send a reply, to the IP address and port that sent us the packet we received
      Udp.beginPacket(Udp.remoteIP(), port);
      Udp.write(ReplyBuffer);
      Udp.endPacket();
    }
}

/*
 * Clears the buffer from previous UDP read
 */
void clearArray(){
  for( int i = 0; i < 30;  ++i ){
    packetBuffer[i] = (char)0;
  }
  packetBuffer[31] = '/0';
}

void checkUDP()
{
  /*
     * Check for udp data
     */
    int packetSize = Udp.parsePacket();
    //Serial.println(packetSize,DEC);
    if (packetSize)
    {
      Serial.print("Packet Size: ");
      Serial.println(packetSize,DEC);
      if (packetSize > 0 && packetSize < 33)
      {
        Serial.println("Reading Packet");
        udpRead(packetSize);
      }
      else
      {
        Serial.print("Flushing Packet... ");
        Udp.flush();
        Serial.println(" Packet Flushed");
      }
    }
}

void loop()
{
  if (WiFi.status() == WL_CONNECTED)
  {
    digitalWrite(redLED,HIGH);
  }
  else
  {
    digitalWrite(redLED,LOW);
    //esp.restart()
  }
  checkUDP();

  if (lightStatus)
  {
    digitalWrite(triac,HIGH);
    digitalWrite(greenLED,HIGH);
  }
  else
  {
    digitalWrite(triac,LOW);
    digitalWrite(greenLED,LOW);
  }
//code added to verify loop is still running
  int minNow = minute();
  if (abs(minNow - lastCycleMin) >= 1)
  {
    Serial.print(".");
    Serial.print(minNow);
    lastCycleMin = minNow;
  }
  if (minNow % 15 == 0 && minNow != lastMinUpdate)
  {
    char clockBuffer[20];
    if (isAM())
    {
      sprintf(clockBuffer,"%02u/%02u/%02u %u:%02u AM   ",month(),day(),year(),hourFormat12(),minute());
    }
    else
    {
      sprintf(clockBuffer,"%02u/%02u/%02u %u:%02u PM   ",month(),day(),year(),hourFormat12(),minute());
    }
    Serial.println("...");
    Serial.print("Running ");
    Serial.println(clockBuffer);
    lastMinUpdate = minNow;
  }
}


Serial Output From my last test run:
Code: Select allConnecting to NachoWifi
...
WiFi connected
Using IP: 192.168.1.158
Initializing UDP Interface...
Done, Listening on port 2000
Syncing Clock with HAM...
Packet Size: 24
Reading Packet
Received packet of size 24 from 192.168.1.10, port 58712
Contents:
TIME 10/22/2016 15:55:31
10/22/2016 15:55:31 Time is Set
.55.56.57.58.59.0.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15...
Running 10/22/2016 4:15 PM   
.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30...
Running 10/22/2016 4:30 PM   
.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45...
Running 10/22/2016 4:45 PM   
.46.47.48.49.50.51.52.53.54.55.56.57.58.59.0...
Running 10/22/2016 5:00 PM   
.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15...
Running 10/22/2016 5:15 PM   
.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30...
Running 10/22/2016 5:30 PM   
.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45...
Running 10/22/2016 5:45 PM   
.46.47.48.49.50.51.52.53.54.55.56.57.58.59.0...
Running 10/22/2016 6:00 PM   
.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15...
Running 10/22/2016 6:15 PM   
.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30...
Running 10/22/2016 6:30 PM   
.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45...
Running 10/22/2016 6:45 PM   
.46.47.48.49.50.51.52.53.54.55.56.57.58.59.0...
Running 10/22/2016 7:00 PM   
.1.2.3.4

<At 76800 BAUD>
ets Jan  8 2013,rst cause:2, boot mode:(3,6)
load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
<Back to 115200 BAUD>

Connecting to NachoWifi
..
WiFi connected
Using IP: 192.168.1.158
Initializing UDP Interface...
Done, Listening on port 2000
Syncing Clock with HAM...
Packet Size: 24
Reading Packet
Received packet of size 24 from 192.168.1.10, port 58712
Contents:
TIME 10/22/2016 19:05:01
10/22/2016 19:5:1 Time is Set
.5Packet Size: 8
Reading Packet
Received packet of size 8 from 192.168.1.55, port 61877
Contents:
LIGHT_ON
Light On
Packet Size: 7
Reading Packet
Received packet of size 7 from 192.168.1.55, port 61877
Contents:
STATUS?
Sending Status
Packet Size: 9
Reading Packet
Received packet of size 9 from 192.168.1.55, port 61877
Contents:
LIGHT_OFF
Light Off
Packet Size: 7
Reading Packet
Received packet of size 7 from 192.168.1.55, port 61877
Contents:
STATUS?
Sending Status
Packet Size: 8
Reading Packet
Received packet of size 8 from 192.168.1.55, port 61877
Contents:
LIGHT_ON
Light On
Packet Size: 7
Reading Packet
Received packet of size 7 from 192.168.1.55, port 61877
Contents:
STATUS?
Sending Status
Packet Size: 7
Reading Packet
Received packet of size 7 from 192.168.1.55, port 61877
Contents:
STATUS?
Sending Status
Packet Size: 9
Reading Packet
Received packet of size 9 from 192.168.1.55, port 61877
Contents:
LIGHT_OFF
Light Off
Packet Size: 7
Reading Packet
Received packet of size 7 from 192.168.1.55, port 61877
Contents:
STATUS?
Sending Status

Re: ESP stops receiving UDP but loop is still executing

PostPosted: Sun Oct 23, 2016 6:42 am
by Barnabybear
Hi, I had the same problem earlier this year, ensuring you connect to the AP that hosts the DHCP is one way to fix this issue. It appears that because the ESP doesn't resopnd to the packet the APs stop passing them, this however doesn't happen if connected to the DHCP AP. The time out seems to be about 4 mins, if the ESP uses the network within 4 mins of the last packet, then packets are still passed, if you go over that the packets are not passed. I don't really understand it, but if you send a packet every minute or get the ESP to use the network every minute it works.

Re: ESP stops receiving UDP but loop is still executing

PostPosted: Sun Oct 23, 2016 12:30 pm
by Shadow351
Interesting. I am connected to the DHCP AP as I only have the AP that is built into my ASUS router. I added
Code: Select all    sprintf(packetBuffer,"PING");
    Udp.beginPacket(ham, port);
    Udp.write(packetBuffer);
    Udp.endPacket();

to the "every minute" code and it has been running for almost 2.5 hours and is still responding to UDP commands. This seems really messy on the part of the router. Other than sending a UDP packet every couple minutes, is there a way to ensure this doesn't happen? Like a keep connection alive command? Or should I direct this question to my router manufacturers forums?
Thanks
-Brad

Re: ESP stops receiving UDP but loop is still executing

PostPosted: Sun Oct 23, 2016 2:26 pm
by Barnabybear
Hi, sorry I spent quite a bit of time on this but TBH the AP suff was all over my head and I ended up with a messy fix like you. My project is for sesonal lighting and the ESP recieves a packet every 50mS and every thing works well, but during any breaks in the display I have to ensure that something happens every 4 minuets maximum to ensure the AP / router keeps passing the packets, as you've found. Doing this I had everything working for a months. I ended up of the view that it was some AP measure to cut down on network traffic, glad to have helped a bit and if you get a fix for this please post it up so I can tidy my code aswell.