UDP packet reception begins to decrease after 24hrs

I am not sure why, but I have a the LED set to flash each packet it receives. Another node sends “ping” packets 2x a second. The weird thing is, when I see it’s flashing less than twice a second, I reset the receiver and boom we’re back in business. It is powered through the USB cable current connected to PC. Why does resetting the receiver “fix” the problem?

I can only think of it possibly being a memory issue. Please review the code for sender and receiver.

While I know UDP is no guaranteed delivery, the protocol suits my needs. I also want to have some advice on UDP data integrity, clearly if packets don’t get through, I could multiply the sends and add -01 -02 for each iteration. That way it ignores subsequent packets of same event multiplied. I could also add an unique code as an acknowledgment that notes the original packet sent. If sender doesn’t get a reply back, it will re-transmit, up to a reasonable number.

Sender

// ** Node 5 ***
int code, i, x;

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

IPAddress ip(192, 168, 1, 135);
IPAddress ipTarget(192, 168, 1, 139);
const char* ssid = "JMR";
const char* password = "crystal2965";

// buffers for receiving and sending data
char packetBuffer[32]; //buffer to hold incoming packet,

// An EthernetUDP instance to let us send and receive packets over UDP
WiFiUDP Udp;

const byte numChars = 8;
char receivedChars[numChars];   // an array to store the received data
char codeChar[numChars];
boolean newData = false;

int bo5 = D1;
int dr5 = D2;
int bo5Last, dr5Last, dr5Now, bo5Now;

void setup() {
  // start the Ethernet and UDP:
  Serial.begin(115200);
  Serial.print("Node 5 Starting...");
  WiFi.mode(WIFI_STA);
  pinMode(bo5, INPUT_PULLUP);
  pinMode(dr5, INPUT_PULLUP);

  IPAddress gw(192, 168, 1, 254);
  IPAddress dns(192, 168, 1, 254);
  IPAddress sn(255, 255, 255, 0);
  WiFi.config(ip, gw, sn,  dns);

  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Node5: Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  x = Udp.begin(8888);
  if (x == 0) {
    Serial.print("UDP.Begin: No sockets availible");
  }
}

void loop() {
  dr5Now = digitalRead(dr5);
  bo5Now = digitalRead(bo5);

  if (dr5Now != dr5Last) { //If door state changes
    if (dr5Now == HIGH) {
      if (bo5Now == HIGH) {
        sendUDP("5005");  //bolt break
      }
      sendUDP("5001"); //door open
    }
    if (dr5Now == LOW) {
      sendUDP("5002"); //door closed
    }
  }

  if (bo5Now != bo5Last) { //if bolt state changes
    if (bo5Now == HIGH) { sendUDP("5009"); }
    if (bo5Now == LOW) { sendUDP("5010"); }
  }

  dr5Last = dr5Now;
  bo5Last = bo5Now;

  recvWithEndMarker();
  showNewData();

  delay(100);
  i++;
  if (i == 10) {
    //Send ping!
    sendUDP("5102");
    i = 0;
  }
  udpRead();
}
void sendUDP(char* udpDataOut) {
  //Inital Clearance Period
  if (millis() < 5000) return;
  
  x = Udp.beginPacket(ipTarget, 8888);
  if (x == 1) {
  }
  else {
    Serial.print("beginPacket status: FAILURE ");
  }
  Serial.printf("Sending UDP: %s", udpDataOut);
  x = Udp.write(udpDataOut);
  x = Udp.endPacket();
  if (x == 1) {
  }
  else {
    Serial.print("Packet Send status: FAILURE ");
  }
}
void udpRead() {
  int packetSize = Udp.parsePacket();
  if (packetSize > 3) {
    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("From B->A: ");
    Serial.println(packetBuffer);
  }
}
void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  //Serial.print("recvWithEndMarker");

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    sendUDP(receivedChars);
    Serial.println("A->B: ");
    Serial.println(receivedChars);
    newData = false;
  }
}/code]

My reciever sketch is too large to display in-line. Please download using link to review it.

node5-0.ino (3.41 KB)

I am not sure why, but I have a the LED set to flash each packet it receives. Another node sends "ping" packets 2x a second. The weird thing is, when I see it's flashing less than twice a second, I reset the receiver and boom we're back in business. It is powered through the USB cable current connected to PC. Why does resetting the receiver "fix" the problem?

Sounds like a Google translation, unfortunately the translation isn't very good.

Try to formulate with simple sentences as machine translators are much better with these. It's also possible that you simply expect us to know everything about your project you know about it. This isn't the case as we know exactly as much as you told us.

I understood that you have a receiver that blinks an LED for every packet received. If it doesn't receive two packets a second you manually reset it.

While I know UDP is no guaranteed delivery, the protocol suits my needs. I also want to have some advice on UDP data integrity, clearly if packets don't get through, I could multiply the sends and add -01 -02 for each iteration. That way it ignores subsequent packets of same event multiplied. I could also add an unique code as an acknowledgment that notes the original packet sent. If sender doesn't get a reply back, it will re-transmit, up to a reasonable number.

if an information must be delivered to the recipient, UDP might be the wrong choice. And based on above paragraph I reason that the protocol doesn't suit your needs.
Why don't you tell us your needs, as complete as possible?

I am making a security system. Its supplemental to a surveillance network. I have a couple of "nodes" which are ESP12s and they are hooked up for the sake of simplicity to reed switches on door, bolt throw, windows, etc. If one of these states change, it sends a four character code such as "5002" or "A055" to the Nexus, an ESP32S, which in turn will activate the house alarm system by making requests via HTTP to Blue Iris. Blue Iris is a IP camera program and I have horns attached to an Amp running from a particular camera. Also, i'm not ESL :stuck_out_tongue:

That makes your alarm system very easy to deactivate: use a 2.4GHz sender with a few Watts power and none of your nodes can send anything to the nexus node. You should also include an alive information that each node has to send periodically to tell the nexus it's still there and active. And the nexus must be wired to the alarm system, so an ESP32S is a bad choice. If you replace it by a Raspberry Pi (or something similar) you're able to keep TCP connections with all nodes, so the signal is guaranteed to be received by the nexus and if the connection dies (no alive signal every other second) you can send the alarm signal too.

If you want to do the same with UDP you have to implement most of the TCP stuff yourself (packet queue, keep the packets there until you got an acknowledgement for the reception, resend lost packets, etc.). You just have more work to do and gain nothing (the performance overhead is not relevant).

Hi. I think rather than "please review code" to help find a memory leak in your code, it's better to look for it and post specific questions. Not so many people like to dig through other people's code. In your case, if you find that the performance starts to drop, then you can do various things to start detecting if a memory leak starts happening. Start monitoring memory allocation and see if they get de-allocated, etc. The larger issue is you may only be able to run one test a day if it takes a full day for the memory leak to degrade performance to something that is noticeable.

You should also include an alive information that each node has to send periodically to tell the nexus it's still there and active.

Codes x102 do just that. An alert is activated if one doesn't send a ping for n seconds.

And the nexus must be wired to the alarm system, so an ESP32S is a bad choice. If you replace it by a Raspberry Pi (or something similar) you're able to keep TCP connections with all nodes, so the signal is guaranteed to be received by the nexus and if the connection dies (no alive signal every other second) you can send the alarm signal too.

Can't I use the ESP12 or 32 for TCP connections? You made it sound like I needed a RaspPi. It is wired to alarm "system", that being a PC running BlueIris. Well, TWO PCs as one will check the other is alive.

Can't I use the ESP12 or 32 for TCP connections?

You know how easy it is to disturb a WiFi network, don't you? I don't expect that BlueIris system to check periodically that your ESP is still sending keepalive packets.

No. BlueIris is closed-source. I certainly am checking if ITs alive.

Overall, I am no fan of wifi, but the boards are dirt-cheap, so it's a starting point and prototyping platform.

In fact I'm trying to get it to text me if it detects loss of a node. Can't get through to the damned IFTTT server on the ESP... I posted that elsewhere though.