So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By Pluckerpluck
#91175 So disclaimer. I half have no idea what I'm doing... So I'll start by saying that a while back I bought the following off Amazon UK:
MakerHawk 3pcs ESP8266 NodeMCU LUA CP2102 ESP-12E WiFi Internet Development Board Serial Wireless Module for Arduino IDE/Micropython New Version


Anyway. I want to use this to trigger a relay wirelessly over my WiFi. I want this response to be as near instant as possible, and the first time I used these chips I ran into issues with delays using TCP, so I thought "I'll use UDP". The idea being that we're within network, so packet loss should be extremely low, and I can just handle resending data if I don't get responses within X amount of time as a backup.

Anyway, I wrote this (using Platform.IO in VSCode):

Code: Select all#include <Arduino.h>
#include <ESP8266WiFi.h>  // Include the Wi-Fi library
#include <WiFiUdp.h>

// Save the WIFI settings
const char* ssid     = "REDACTED";
const char* password = "REDACTED";

// WIFI Setup
WiFiUDP Udp;
unsigned int localUdpPort = 4210;
char incomingPacket[256];

void setup() {
    // Start the Serial communication to send messages to the computer
    Serial.begin(9600);
    delay(10);

    // Connect to the WiFi
    WiFi.begin(ssid, password);

    // Wait for the WiFi signal
    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
    }

    // Listen
    Udp.begin(localUdpPort);
}

void loop() {

    // Try reading the next packet
    int packetSize = Udp.parsePacket();
    if (packetSize)
    {
        int len = Udp.read(incomingPacket, 255);
        if (len > 0) incomingPacket[len] = 0;


        Serial.printf(
            "Received %d bytes from %s, port %d: %s\n",
            packetSize,
            Udp.remoteIP().toString().c_str(),
            Udp.remotePort(),
            incomingPacket
        );
    }
}


That's the simplest code I can think of to print useful information from a UDP packet.

Anyway I then used the following Python code:

Code: Select allimport socket
import time

UDP_IP = "REDACTED (Even if it's internal...)"
UDP_PORT = 4210

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP

i = 1
while True:
    print("Sent", i)
    sock.sendto(bytes(str(i), "utf-8"), (UDP_IP, UDP_PORT))
    sock.sendto(bytes(str(i), "utf-8"), (UDP_IP, UDP_PORT))
    sock.sendto(bytes(str(i), "utf-8"), (UDP_IP, UDP_PORT))
    i += 1
    time.sleep(4)



So just sending triple bursts of messages every 4 seconds. I have tested this with my phone. Every single message makes it through the router, every single time. When sending to my phone (on the same WiFi), it literally never fails. But from my ESP8266 I get the following:

Code: Select allReceived 1 bytes from <REDACTED>, port 63661: 2
Received 1 bytes from <REDACTED>, port 63661: 2
Received 1 bytes from <REDACTED>, port 63661: 2
Received 1 bytes from <REDACTED>, port 63661: 4
Received 1 bytes from <REDACTED>, port 63661: 4
Received 1 bytes from <REDACTED>, port 63661: 4
Received 1 bytes from <REDACTED>, port 63661: 6
Received 1 bytes from <REDACTED>, port 63661: 6
Received 1 bytes from <REDACTED>, port 63661: 6
Received 1 bytes from <REDACTED>, port 63661: 8
Received 1 bytes from <REDACTED>, port 63661: 8
Received 1 bytes from <REDACTED>, port 63661: 8
Received 1 bytes from <REDACTED>, port 63661: 9
Received 1 bytes from <REDACTED>, port 63661: 9
Received 1 bytes from <REDACTED>, port 63661: 9
Received 2 bytes from <REDACTED>, port 63661: 11
Received 2 bytes from <REDACTED>, port 63661: 11
Received 2 bytes from <REDACTED>, port 63661: 11
Received 2 bytes from <REDACTED>, port 63661: 13
Received 2 bytes from <REDACTED>, port 63661: 13
Received 2 bytes from <REDACTED>, port 63661: 13
Received 2 bytes from <REDACTED>, port 63661: 14
Received 2 bytes from <REDACTED>, port 63661: 14
Received 2 bytes from <REDACTED>, port 63661: 14
Received 2 bytes from <REDACTED>, port 63661: 15
Received 2 bytes from <REDACTED>, port 63661: 15
Received 2 bytes from <REDACTED>, port 63661: 15
Received 2 bytes from <REDACTED>, port 63661: 16
Received 2 bytes from <REDACTED>, port 63661: 16
Received 2 bytes from <REDACTED>, port 63661: 16
Received 2 bytes from <REDACTED>, port 63661: 18
Received 2 bytes from <REDACTED>, port 63661: 18
Received 2 bytes from <REDACTED>, port 63661: 18


The first packet is pretty much guaranteed to fail. And then it's hit and miss wether any given batch will make it through (it does tend to alternate passing and failng). But do note, it NEVER fails just 1 of the packets in a block of 3. It's always an all or nothing type thing.

I would appreciate any help here... A near 50% packet loss is a little to high for me to sustain. Something I have noticed. The longer I leave it between sending packets, the more likely it is to fail. It's basically completely unusable like this though.

Am I doing something horribly wrong? I'd appreciate any and all help!

Regards,
Pluckerpluck
User avatar
By Pluckerpluck
#91237 On the off chance that someone else comes across this. I just gave up and tried to use ESPAsyncUDP instead.

It seems a lot better, no longer dropping 50% of all packets, but it still drops way more packets than I'd like. The main difference is it no longer drops them in giant batches, which means I can keep latency low by resending if I don't get a response after X milliseconds and chances are the next packet will succeed.

Honestly though, the number of dropped packets is completely unacceptable. I know UDP is meant to be "unreliable", but I still expect packet loss to be <1%. Hell, on a local network I expect it to be <0.01%.
User avatar
By QuickFix
#92558
sa1324123413241 wrote:20-70% loss when esp-01s connected to pc via usb programmer
almost no loss when used as a stand alone module with its own power supply

Is this a question or a statement?

Try a shielded USB cable connected directly to the motherboard of the PC with the ESP as far as possible from the PC.
Also make sure your PC case is closed (it is enclosed, or originally was, inside metal for a reason).