UDP Send mit ENC28J60

Guten Tag zusammen,
irgendwie habe ich immer nur Probleme mit Ethernet Themen :slight_smile:

Da der Ethernet Chip ENC28J60 zwar schwach auf der Brust ist aber dafür klein und billig ist wollte ich ihn als alternative für den W5100 einsetzen.
Da ich mein eigenes Protokoll auf UDP Basis entwickelt habe, wird auch nicht viel Leistung benötigt.
Die einzige Library die ich gefunden habe, die verlässlich funktioniert, nennt sich "ethercard" (GitHub - njh/EtherCard: EtherCard is an IPv4 driver for the ENC28J60 chip, compatible with Arduino IDE). Das Beispiel zum UDP Server funktioniert auch einwandfrei nur habe ich am Anfang kein Anzeichen gefunden UDP Pakete zu senden.
Also nicht lange nach was neuem suche und versuchen selber zu machen. Habe mir dann mal die "EtherCard.h" ein wenig genauer angeschaut und gesehen, dass es schon eine Funktion "sendUdp" gibt:

 /**   @brief  Sends a UDP packet                                            
    *     @param  data Pointer to data                                          
    *     @param  len Size of payload (maximum 220 octets / bytes)              
    *     @param  sport Source port                                             
    *     @param  dip Pointer to 4 byte destination IP address                  
    *     @param  dport Destination port                                        
    */                                                                          
    static void sendUdp (const char *data, uint8_t len, uint16_t sport,         
                         const uint8_t *dip, uint16_t dport);

Gut mal schnell das Server Beispiel angepasst, einen Server auf meinem Rechner gestartet und gehofft das es funktioniert:

#include <EtherCard.h>
#include <IPAddress.h>

#define STATIC 1  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip[] = { 192,168,178,200 };
static byte hostip[] = { 192,168,178,26 };
// gateway ip address
static byte gwip[] = { 192,168,0,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x70,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

//callback that prints received packets to the serial port
void udpSerialPrint(word port, byte ip[4], const char *data, word len) {
  IPAddress src(ip[0], ip[1], ip[2], ip[3]);
  Serial.println(src);
  Serial.println(port);
  Serial.println(data);
  Serial.println(len);
}

void setup(){
  Serial.begin(57600);
  Serial.println(F("\n[backSoon]"));

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);

  //register udpSerialPrint() to port 1337
  ether.udpServerListenOnPort(&udpSerialPrint, 1337);

  //register udpSerialPrint() to port 42.
  ether.udpServerListenOnPort(&udpSerialPrint, 42);
}

void loop(){
  //this must be called for ethercard functions to work.
  //ether.packetLoop(ether.packetReceive());
  ether.sendUdp("HelloWorld", 10, 26, hostip, 8888);
}

Die Enttäuschung war groß. Es kam nichts an. Nun ja Wireshark aufgemacht und mal ein wenig rumgesucht.
Siehe da jedes Packet kommt mit richter SourceIP, DestinationIP, Source Port, Destination Port, Data Length und der Payload. Habe mal ein Screenshot abgehangen wo man alles sieht.
Der UDP Server funktioniert mit anderen Clients und er ist auch im netstat registriert.
Habt ihr eine Idee wo die Pakete abbleiben?

Morgen,

ich glaube ich hatte dein Problem schonmal so ähnlich bei einer Maschinensteuerung.
Wenn ich das Richtig sehe, beginnt dein Datagram mit ASCII 0. Ich Tippe darauf das du deine Daten als String abholst. Ein String wird ASCII 0 beendet. Na, alles klar? Anfang = Ende :smiley:
Meine Lösung sah damals so aus, das ich meine Zahlen maschinenseitig nach String gewandelt habe und damit war alles gut.

Gruß
Jago

Hallo Jago
Habe hier zu Testzwecken einen ganz einfachen Python UDP Server. Wie das Intern mit den Charactern geregelt wird weiß ich nicht. Werde, wenn ich von der Arbeit wieder komme, mal schnell was in C schreibseln um zu sehen wie viel chars denn ankommen.

Allerdings würde ich dies dann nicht verstehen. Die Nutzdaten fangen erst in der 3ten Zeile bei 0x48 an. Da 10 Bytes an Payload übertragen werden, müsste dann ja das "d" von "HelloWorld" fehlen.

Auf dem Arduino, oder bei dir auf der Maschinenseite, ist es ja schon ein String (char pointer), oder verstehe ich dein Lösungsansatz jetzt falsch?

Nachtrag 1:
Habe es eben mit einem habe nun eben ein C Server geschrieben und es kommen 0 Bytes an. Habe irgendwie das Gefühl die Verbindung wird intern nicht weitergegeben.
Mir ist gerade noch "netcat" eingefallen und es einfach mal mit "nc -u -l 8888" probiert. Auch hier keine Reaktion und netcat sollte nun alles ausgeben, auch wenn es nur Müll ist.

Nachtrag 2:
Habe jetzt nochmal ein ankommendes Paket (rechts) mit einem Paket vom Arduino (links) verglichen. Sie sind beide identisch (Sourceip/Port und Checksum jetzt mal ausgenommen.)
Um ehrlich zu sein verstehe ich das nicht.

So da ich nun die Lösung gefunden habe mache ich mal ein neuen Post.

Wenn man den Arduino sich per DHCP anmelden lässt funktioniert es.
Verstehe allerdings den Unterschied nicht. Bei beiden Fällen registriert er sich bei der Fritz Box und wird auch angezeigt.
Also sehe ich als einzige Fehlerquelle die Variable "gwip" (Gateway IP). Da die Fritz Box (192.168.178.1) aber das Gateway ist verstehe ich dies nicht.