EthernetENC icon indicating copy to clipboard operation
EthernetENC copied to clipboard

Library doesn't read UDP packages!

Open ruiseixasm opened this issue 6 months ago • 12 comments

I'm trying to make this sketch work, the sent part of the loop works fine, but the receive part never picks anything! The ping on the device works just fine, so, it's not a problem of the network.

#include <EthernetENC.h>
#include <EthernetUdp.h>

// // Linux testing commands:
// echo "BROADCAST 255" | nc -ubv 255.255.255.255 5005
// echo "BROADCAST 192" | nc -ubv 192.168.31.255 5005
// echo "UNICAST" | nc -ubv 192.168.31.100 5005


// Network Settings
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 31, 100);       // Arduino IP
IPAddress subnet(255, 255, 255, 0);   // Network mask
IPAddress gateway(192, 168, 31, 77);    // Router IP (if needed)
const unsigned int UDP_PORT = 5005;
IPAddress target(192, 168, 31, 22);                // Target PC IP
IPAddress broadcast(255, 255, 255, 255); // Broadcast address

EthernetUDP udp;
unsigned long lastSendTime = 0;
const unsigned long INTERVAL = 5000; // 5 seconds

void setup() {
    Serial.begin(9600);
    
    // Initialize Ethernet with static IP
    Ethernet.begin(mac, ip, gateway, subnet);

    // Start UDP
    if (udp.begin(UDP_PORT)) {
        Serial.print("\n\nUDP active on ");
        Serial.println(Ethernet.localIP());
    } else {
        Serial.println("UDP failed!");
    }
}

void loop() {

    // Send "Hello" every 5 seconds
    if (millis() - lastSendTime >= INTERVAL) {
        if (random(2) % 2 == 0) {
            Serial.println("Direct hello");
            udp.beginPacket(target, UDP_PORT);
            udp.write("Direct hello");
        } else {
            Serial.println("Broadcasted hello");
            udp.beginPacket(broadcast, UDP_PORT);
            udp.write("Broadcasted hello");
        }
        udp.endPacket();
        lastSendTime = millis();
    }

    
    // Check for incoming packets
    int packetSize = udp.parsePacket();
    if (packetSize > 0) {
        char packet[128];
        udp.read(packet, sizeof(packet));
        Serial.print("From ");
        Serial.print(udp.remoteIP());
        Serial.print(": ");
        Serial.println(packet);
    }
}

However, the received packages in the other machine are these:

b'Direct helloBroadca'
b'Broadcasted hello'
b'Direct helloBroadca'
b'Direct helloBroadca'
b'Broadcasted hello'
b'Broadcasted hello'
b'Direct helloDirect Direct Direct Direct Direct Direct Broadca'
b'Direct helloDirect Broadca'
b'Direct helloBroadca'
b'Broadcasted hello'
b'Broadcasted hello'
b'Direct helloDirect Broadca'
b'Direct helloBroadca'
b'Broadcasted hello'

And the Arduino nano never receives any package I send to it, regardless from the Python script or from these commands:

echo "BROADCAST 255" | nc -ubv 255.255.255.255 5005
echo "BROADCAST 192" | nc -ubv 192.168.31.255 5005
echo "UNICAST" | nc -ubv 192.168.31.100 5005

Ping works just fine, so it must be a problem with UDP implementation!

Pinging 192.168.31.100 with 32 bytes of data:
Reply from 192.168.31.100: bytes=32 time=1ms TTL=128
Reply from 192.168.31.100: bytes=32 time=1ms TTL=128
Reply from 192.168.31.100: bytes=32 time=1ms TTL=128
Reply from 192.168.31.100: bytes=32 time=1ms TTL=128

Ping statistics for 192.168.31.100:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 1ms, Maximum = 1ms, Average = 1ms

Can you help me in make the script work, these is the compiling output.

Sketch uses 16456 bytes (53%) of program storage space. Maximum is 30720 bytes.
Global variables use 1054 bytes (51%) of dynamic memory, leaving 994 bytes for local variables. Maximum is 2048 bytes.

Thanks

ruiseixasm avatar May 19 '25 15:05 ruiseixasm

https://github.com/Networking-for-Arduino/EthernetENC/wiki/Limitations

JAndrassy avatar May 19 '25 15:05 JAndrassy

By limitations does that means that contrary to the EtherCard the EthernetENC doesn't capture UDP packages?

ruiseixasm avatar May 19 '25 15:05 ruiseixasm

To reduce the load, ENC28J60 can filter out packets with very simple rules and don't store them for processing. This way the library filters out broadcast packets and allows only packets with the given MAC address.

broadcast UDP is filtered here:

https://github.com/Networking-for-Arduino/EthernetENC/blob/19664f609b9b864bd772b048f992afff4f75c214/src/utility/Enc28J60Network.cpp#L98

JAndrassy avatar May 20 '25 05:05 JAndrassy

So, that means I should use the UIPEthernet library instead, like this:

#include <UIPEthernet.h>
#include <UIPUdp.h>  // If using UDP

ruiseixasm avatar May 21 '25 12:05 ruiseixasm

what is the source of the UDP broadcast? does it really have to be a broadcast?

JAndrassy avatar May 21 '25 17:05 JAndrassy

Yes, it has, the Devices start to interact by broadcasting messages and only then they switch to Unicast once responding to them. It uses JSON as encoded communication with checksum included.

ruiseixasm avatar May 23 '25 03:05 ruiseixasm

I'm in the same need. I have to read WoL Broadcast on port 9 Can I just comment these lines in [EthernetENC/src/utility/Enc28J60Network.cpp] ?

writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
writeRegPair(EPMM0, 0x303f);
writeRegPair(EPMCSL, 0xf7f9);

CoyoteProd avatar May 23 '25 06:05 CoyoteProd

  writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);

BCEN: Broadcast Filter Enable bit 1 = Packets which have a destination address of FF-FF-FF-FF-FF-FF will be accepted

JAndrassy avatar May 23 '25 17:05 JAndrassy

Can you write a concrete example where that is done in a .ino sketch? Thanks.

ruiseixasm avatar May 24 '25 02:05 ruiseixasm

https://github.com/Networking-for-Arduino/EthernetENC/issues/72#issuecomment-2892993098

JAndrassy avatar May 24 '25 05:05 JAndrassy

It's a defined bit to use in a bitwise operation accordingly to these bit definitions for each one best guess:

// ENC28J60 ERXFCON Register Bit Definitions
#define ERXFCON_UCEN     0x80
#define ERXFCON_ANDOR    0x40
#define ERXFCON_CRCEN    0x20
#define ERXFCON_PMEN     0x10
#define ERXFCON_MPEN     0x08
#define ERXFCON_HTEN     0x04
#define ERXFCON_MCEN     0x02
#define ERXFCON_BCEN     0x01

My guess is that those are chip ENC28J60 direct configurations despite not finding any mention of ERXFCON_BCEN in the datasheet. For instance, what PMEN really means is still unknown.

ruiseixasm avatar May 24 '25 20:05 ruiseixasm

Ok, I found it in the datasheet:

UCEN: Unicast Filter Enable bit
CRCEN: Post-Filter CRC Check Enable bit
PMEN: Pattern Match Filter Enable bit
MPEN: Magic Packet Filter Enable bit
HTEN: Hash Table Filter Enable bit
MCEN: Multicast Filter Enable bit
BCEN: Broadcast Filter Enable bit

ruiseixasm avatar May 24 '25 20:05 ruiseixasm