Skip to content

Library doesn't read UDP packages! #72

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

Open
ruiseixasm opened this issue May 19, 2025 · 12 comments
Open

Library doesn't read UDP packages! #72

ruiseixasm opened this issue May 19, 2025 · 12 comments

Comments

@ruiseixasm
Copy link

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

@JAndrassy
Copy link
Member

@ruiseixasm
Copy link
Author

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

@JAndrassy
Copy link
Member

JAndrassy commented May 20, 2025

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:

writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);

@ruiseixasm
Copy link
Author

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

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

@JAndrassy
Copy link
Member

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

@ruiseixasm
Copy link
Author

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.

@CoyoteProd
Copy link

CoyoteProd commented May 23, 2025

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);

@JAndrassy
Copy link
Member

JAndrassy commented May 23, 2025

  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

@ruiseixasm
Copy link
Author

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

@JAndrassy
Copy link
Member

#72 (comment)

@ruiseixasm
Copy link
Author

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
Copy link
Author

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

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

3 participants