Trouble recieving UDP packets wt32-eth01 microcontroller

Wrote a program in rust that sends UDP packets containing int arrays for an led strip connected to an esp32 via wifi and it works ok. Getting some dropped packets at range because wifi. I am now trying to implement the same process on a wt32-eth01 with the hopes of having less dropped packets because ethernet. I am using a modified version of:
khoih-prog / WebServer_WT32_ETH01

Here is the code:

/****************************************************************************************************************************
  UDPSendReceive.ino - Simple Arduino web server sample for ESP8266/ESP32 AT-command shield
  For Ethernet shields using WT32_ETH01 (ESP32 + LAN8720)
  WebServer_WT32_ETH01 is a library for the Ethernet LAN8720 in WT32_ETH01 to run WebServer
  Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
  Built by Khoi Hoang https://github.com/khoih-prog/WebServer_WT32_ETH01
  Licensed under MIT license
 *****************************************************************************************************************************/

#define DEBUG_ETHERNET_WEBSERVER_PORT       Serial

// Debug Level from 0 to 4
#define _ETHERNET_WEBSERVER_LOGLEVEL_       3

#include <FastLED.h>
#include <string>
#include <vector>
#include <sstream>

#define PIN 2
#define CL_PIN 4

#include <WebServer_WT32_ETH01.h>

// Select the IP address according to your local network
IPAddress myIP(192, 168, 4, 78);
IPAddress myGW(192, 168, 4, 1);
IPAddress mySN(255, 255, 255, 0);

// Google DNS Server IP
IPAddress myDNS(8, 8, 8, 8);

int const num_pixels = 60;

unsigned int localPort = 8080;    //10002;  // local port to listen on

char packetBuffer[450];          // buffer to hold incoming packet

int loop_count = 0;
// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;

CRGB ledstrip[num_pixels];


void setup()
{
  Serial.begin(115200);

  while (!Serial);

  // Using this if Serial debugging is not necessary or not using Serial port
  //while (!Serial && (millis() < 3000));

  Serial.print("\nStarting UDPSendReceive on " + String(ARDUINO_BOARD));
  Serial.println(" with " + String(SHIELD_TYPE));
  Serial.println(WEBSERVER_WT32_ETH01_VERSION);

  // To be called before ETH.begin()
  WT32_ETH01_onEvent();

  //bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO,
  //           eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE);
  //ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_TYPE, ETH_CLK_MODE);
  ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER);

  // Static IP, leave without this line to get IP via DHCP
  //bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = 0, IPAddress dns2 = 0);
  ETH.config(myIP, myGW, mySN, myDNS);

  WT32_ETH01_waitForConnect();

  Serial.println(F("\nStarting connection to server..."));
  // if you get a connection, report back via serial:
  Udp.begin(localPort);

  Serial.print(F("Listening on port "));
  Serial.println(localPort);

  Serial.println("");
  Serial.println("Ethernet connected");
  Serial.println("IP address: ");
  Serial.println(ETH.localIP());
}

void loop()
{
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    loop_count = 0;

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 450);
    //Serial.printf("\npacketBuffer:");
    //Serial.println(packetBuffer);
    //Serial.printf("\nlen=");
    //Serial.println(len);
    if (len > 0)
    {
      packetBuffer[len] = 0;
    }
    //Serial.printf("d%", packetBuffer);
    Serial.printf("UDP packet contents: %s\n", packetBuffer);
    //Serial.printf(packetBuffer);
    //Serial.println(packetBuffer);
    int k=0;
    int strip[num_pixels][3];
       
    for (int i = 0; i < num_pixels; i++) {
      for (int j = 0; j < 3; j++) {
                  
        strip[i][j] = packetBuffer[k];
        //Serial.printf("packetBuffer[k]:");
        //Serial.println(packetBuffer[k]);
        k++;
      }
    }
    //Serial.printf("Strip:");
    //Serial.printf("%d",strip);
    for (int l = 0; l < (num_pixels); l++) {
      ledstrip[l].setRGB(strip[l][0], strip[l][1], strip[l][2]);
      //int R = strip[l][0];
      //int G = strip[l][1];
      //int B = strip[l][2];
      //Serial.printf("%d, %d, %d\n",R, G, B);
    }
    FastLED.show();
  }
  loop_count++;
  //if (loop_count >= 1000) {
  //  for (int i = 0; i < num_pixels; i++) {
  //    ledstrip[i] = CRGB(0, 0, 0);
  //  }
  //FastLED.show();
  //}
    //Serial.println(F("Contents:"));
    //Serial.println(packetBuffer);
}

The result is that when I serial print packetBuffer it apprears to be empty. This is from serial monitor:
12:48:52.580 -> Received packet of size 450
12:48:52.580 -> From 192.168.4.79, port 8080
12:48:52.580 -> Contents:
12:48:52.580 ->

And when I print each element of packetBuffer individually I get:
12:48:52.580 ->
2:48:52.580 -> -
12:48:52.580 -> >
12:48:52.580 -> o
12:48:52.580 -> <
12:48:52.580 -> '
12:48:52.580 -> [
12:48:52.580 -> Q
12:48:52.580 ->
12:48:52.580 -> ]
12:48:52.580 -> o
12:48:52.580 ->
12:48:52.613 -> i
12:48:52.613 -> ⸮
ect......

So it appears to connect and to receive packets of the correct size, but I'm not seeing my data. The functions that handle it, don't, as it appears they are receiving junk.
I have also tried just running the example without my modifications with the same result.

As my rust code works with the esp32 I don't think there's a problem there but for good measure here's my rust code. All of the socket code is in main.rs.
rust code

I am relatively new to this and I am not a pro C++ programmer. Have googled this for days and have tried everything I can think of and am out of ideas. Can anyone help?

what does the original data which forms the packet size 450bytes look like? e.g. array of two byte integers, four byte integers, etc.
could be that you are printing the bytes which make up the integers??

12:48:52.580 ->
2:48:52.580 -> -

suggest you simplify the program to just read the packet and receive the data, e.g. remove fastLED, vector, etc etc
when it is receiving the data OK start adding in the complexity

Thanks for the reply!

what does the original data which forms the packet size 450bytes look like? e.g. array of two byte integers, four byte integers, etc.

The data that makes up the 450 byte message is an array of 450 8bit integers, representing 150 (R,G,B) led values. One frame of animation.

could be that you are printing the bytes which make up the integers??

Possibly, but wouldn't I be seeing hex values? The output looks like nonsense to me. I'll look into it though. Perhaps its trying to read empty memory addresses?

suggest you simplify the program to just read the packet and receive the data, e.g. remove fastLED, vector, etc etc
when it is receiving the data OK start adding in the complexity

I have already. I commented out everything except the socket and ethernet connection and Serial.print tested with same results. I added some more verbose print statements. Here is a cleaner version with only relevant code:

#define DEBUG_ETHERNET_WEBSERVER_PORT       Serial

#define _ETHERNET_WEBSERVER_LOGLEVEL_       3

#include <WebServer_WT32_ETH01.h>

// Select the IP address according to your local network
IPAddress myIP(192, 168, 4, 78);
IPAddress myGW(192, 168, 4, 1);
IPAddress mySN(255, 255, 255, 0);

// Google DNS Server IP
IPAddress myDNS(8, 8, 8, 8);

unsigned int localPort = 4210;    //10002;  // local port to listen on

char packetBuffer[450];          // buffer to hold incoming packet 

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

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  // Using this if Serial debugging is not necessary or not using Serial port
  //while (!Serial && (millis() < 3000));

  Serial.print("\nStarting UDPSendReceive on " + String(ARDUINO_BOARD));
  Serial.println(" with " + String(SHIELD_TYPE));
  Serial.println(WEBSERVER_WT32_ETH01_VERSION);

  // To be called before ETH.begin()
  WT32_ETH01_onEvent();

  //bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, 
  //           eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE);
  //ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_TYPE, ETH_CLK_MODE);
  ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER);

  // Static IP, leave without this line to get IP via DHCP
  //bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = 0, IPAddress dns2 = 0);
  ETH.config(myIP, myGW, mySN, myDNS);

  WT32_ETH01_waitForConnect();

  Serial.println(F("\nStarting connection to server..."));
  // if you get a connection, report back via serial:
  Udp.begin(localPort);

  Serial.print(F("Listening on port "));
  Serial.println(localPort);
}

void loop()
{
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();

  if (packetSize)
  {
    Serial.print(F("Received packet of size "));
    Serial.println(packetSize);
    Serial.print(F("From "));
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(F(", port "));
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 450);
    
    if (len > 0)
    {
      packetBuffer[len] = 0;
    }

    Serial.println(F("Contents:"));
    Serial.println(packetBuffer);

  }
}

Here is the result from serial monitor:

11:37:18.951 -> Received packet of size 450
11:37:18.951 -> From 192.168.4.79, port 8080
11:37:18.951 -> Contents:
11:37:18.951 ->
11:37:18.960 -> Received packet of size 450
11:37:18.960 -> From 192.168.4.79, port 8080
11:37:18.960 -> Contents:
11:37:18.960 ->
11:37:18.993 -> Received packet of size 450
11:37:18.993 -> From 192.168.4.79, port 8080
11:37:18.993 -> Contents:
11:37:18.993 ->
11:37:19.026 -> Received packet of size 450
11:37:19.026 -> From 192.168.4.79, port 8080
11:37:19.026 -> Contents:
11:37:19.026 ->
11:37:19.059 -> Received packet of size 450
11:37:19.059 -> From 192.168.4.79, port 8080
11:37:19.093 -> Contents:
11:37:19.093 ->
ect...

It appears despite getting a connection, recieving packets of the correct size, and seeing the lan lights on the rj45 jack blink a lot during transmission, I'm not receiving any data. I feel like the nonsense I was seeing before was maybe just empty memory? Still not sure what to try next.

Thanks again for the suggestions.

this is example of a UDP client receiving a {150]*[3] element array
it runs on a UNO with a Ethernet 5100 shield
may give you some ideas

// UDP_client_array - receive array from remote UDP client

#include <SPI.h>  // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>  // UDP library from: bjoern@cs.stanford.edu 12/30/2008

// Enter a MAC address and IP address for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);  // IP address of this Arduino to match current network
unsigned int localPort = 999;    //  UDP port number being used
EthernetUDP Udp;                 // An EthernetUDP instance to let us send and receive packets over UDP

uint8_t packet[150][3] = { 0 };

void setup() {
  Ethernet.begin(mac, ip);  // start the Ethernet and UDP:
  Udp.begin(localPort);
  Serial.begin(115200);
  Serial.println("Ethernet UDP server IP ");
  Serial.print(Ethernet.localIP());
  Serial.print(" local port ");
  Serial.println(localPort);
  Serial.print("UDP_TX_PACKET_MAX_SIZE ");
  Serial.println(UDP_TX_PACKET_MAX_SIZE);
}

void loop() {
  int inByte;
  // if there's data available, read acknowledgement packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.print(packetSize);
    Serial.print(" From ");
    IPAddress remote = Udp.remoteIP();  // display IP of remote PC
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());  // display remote port
      // read the packet and display contents
    Udp.read((char *)packet, packetSize);
    Serial.print("Contents: ");
    for (int i = 0; i < 150; i++) {
      for (int j = 0; j < 3; j++) {
        Serial.print(packet[i][j]);
        Serial.print(' ');
      }
      Serial.println();
    }
  }
}

the UNO serial monitor displays the results

Ethernet UDP server IP 
192.168.1.177 local port 999
UDP_TX_PACKET_MAX_SIZE 24
Received packet of size 450 From 192.168.1.68, port 55875
Contents: 0 1 2 
1 2 3 
2 3 4 
3 4 5 
4 5 6 
5 6 7 
6 7 8 
7 8 9 
8 9 10 
9 10 11 
10 11 12 
11 12 13 
12 13 14 
13 14 15 
14 15 16 
15 16 17 
16 17 18 
17 18 19 
18 19 20 
19 20 21 
20 21 22 
21 22 23 
22 23 24 
23 24 25 
24 25 26 
25 26 27 
26 27 28 
27 28 29 
28 29 30 
29 30 31 
30 31 32 
31 32 33 
32 33 34 
33 34 35 
34 35 36 
35 36 37 
36 37 38 
37 38 39 
38 39 40 
39 40 41 
40 41 42 
41 42 43 
42 43 44 
43 44 45 
44 45 46 
45 46 47 
46 47 48 
47 48 49 
48 49 50 
49 50 51 
50 51 52 
51 52 53 
52 53 54 
53 54 55 
54 55 56 
55 56 57 
56 57 58 
57 58 59 
58 59 60 
59 60 61 
60 61 62 
61 62 63 
62 63 64 
63 64 65 
64 65 66 
65 66 67 
66 67 68 
67 68 69 
68 69 70 
69 70 71 
70 71 72 
71 72 73 
72 73 74 
73 74 75 
74 75 76 
75 76 77 
76 77 78 
77 78 79 
78 79 80 
79 80 81 
80 81 82 
81 82 83 
82 83 84 
83 84 85 
84 85 86 
85 86 87 
86 87 88 
87 88 89 
88 89 90 
89 90 91 
90 91 92 
91 92 93 
92 93 94 
93 94 95 
94 95 96 
95 96 97 
96 97 98 
97 98 99 
98 99 100 
99 100 101 
100 101 102 
101 102 103 
102 103 104 
103 104 105 
104 105 106 
105 106 107 
106 107 108 
107 108 109 
108 109 110 
109 110 111 
110 111 112 
111 112 113 
112 113 114 
113 114 115 
114 115 116 
115 116 117 
116 117 118 
117 118 119 
118 119 120 
119 120 121 
120 121 122 
121 122 123 
122 123 124 
123 124 125 
124 125 126 
125 126 127 
126 127 128 
127 128 129 
128 129 130 
129 130 131 
130 131 132 
131 132 133 
132 133 134 
133 134 135 
134 135 136 
135 136 137 
136 137 138 
137 138 139 
138 139 140 
139 140 141 
140 141 142 
141 142 143 
142 143 144 
143 144 145 
144 145 146 
145 146 147 
146 147 148 
147 148 149 
148 149 150 
149 150 151 

the UDP server on the PC displays

Enter server host name or IP address: 192.168.1.177
Enter server port number: 999
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
11 12 13
12 13 14
13 14 15
14 15 16
15 16 17
16 17 18
17 18 19
18 19 20
19 20 21
20 21 22
21 22 23
22 23 24
23 24 25
24 25 26
25 26 27
26 27 28
27 28 29
28 29 30
29 30 31
30 31 32
31 32 33
32 33 34
33 34 35
34 35 36
35 36 37
36 37 38
37 38 39
38 39 40
39 40 41
40 41 42
41 42 43
42 43 44
43 44 45
44 45 46
45 46 47
46 47 48
47 48 49
48 49 50
49 50 51
50 51 52
51 52 53
52 53 54
53 54 55
54 55 56
55 56 57
56 57 58
57 58 59
58 59 60
59 60 61
60 61 62
61 62 63
62 63 64
63 64 65
64 65 66
65 66 67
66 67 68
67 68 69
68 69 70
69 70 71
70 71 72
71 72 73
72 73 74
73 74 75
74 75 76
75 76 77
76 77 78
77 78 79
78 79 80
79 80 81
80 81 82
81 82 83
82 83 84
83 84 85
84 85 86
85 86 87
86 87 88
87 88 89
88 89 90
89 90 91
90 91 92
91 92 93
92 93 94
93 94 95
94 95 96
95 96 97
96 97 98
97 98 99
98 99 100
99 100 101
100 101 102
101 102 103
102 103 104
103 104 105
104 105 106
105 106 107
106 107 108
107 108 109
108 109 110
109 110 111
110 111 112
111 112 113
112 113 114
113 114 115
114 115 116
115 116 117
116 117 118
117 118 119
118 119 120
119 120 121
120 121 122
121 122 123
122 123 124
123 124 125
124 125 126
125 126 127
126 127 128
127 128 129
128 129 130
129 130 131
130 131 132
131 132 133
132 133 134
133 134 135
134 135 136
135 136 137
136 137 138
137 138 139
138 139 140
139 140 141
140 141 142
141 142 143
142 143 144
143 144 145
144 145 146
145 146 147
146 147 148
147 148 149
148 149 150
149 150 151
** Server did not respond in 1 second.

Process returned 0 (0x0)   execution time : 17.405 s
Press any key to continue.

To be honest the only reason I'm using this library is that it supports the microcontroller I'm using. I'll look into the libraries your using and see if they will work, or at least try to find something comparable that will. I would really like to make this board work as it's cost per unit is lower than an Uno with a shield and I'll need a fair amount of them.

Thank you for taking the time to show me an example of how to code this properly. I'm new to this and it helps a lot. I'll start working on this and be sure to post a solution if and when I find one in case anyone else has this issue.

I don't have a wt32-eth01 so cannot comment on it

what about using a enc28j60 with the ESP32? see esp32-ethernet-enc28j60-with-plain-http-and-ssl-https

I have used the enc28j60 with an ESP32 using the EthernetENC library

Edit: copy of program from post 4 but using an ESP32 with a enc28j60

//  ENC28J60 tested with ESP32 - UDP_client_array - receive array from remote UDP client

// connections ENC28J60 to ESP32
//  SI to pin GPIO23 MOSI
//  SO to pin GPIO19 MISO
// SCK to pin GPIO18 CLK
//  CS to PIN GPIO5 - note call to Ethernet.init(5); below
// VCC to 3V3

#include <SPI.h>  // needed for Arduino versions later than 0018
#include <EthernetENC.h>
//#include <EthernetUdp.h>  // UDP library from: bjoern@cs.stanford.edu 12/30/2008

// Enter a MAC address and IP address for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);  // IP address of this Arduino to match current network
unsigned int localPort = 999;    //  UDP port number being used
EthernetUDP Udp;                 // An EthernetUDP instance to let us send and receive packets over UDP

uint8_t packet[150][3] = { 0 };

void setup() {
  Ethernet.begin(mac, ip);  // start the Ethernet and UDP:
  Udp.begin(localPort);
  Serial.begin(115200);
  Serial.println("Ethernet UDP server IP ");
  Serial.print(Ethernet.localIP());
  Serial.print(" local port ");
  Serial.println(localPort);

}

void loop() {
  int inByte;
  // if there's data available, read acknowledgement packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.print(packetSize);
    Serial.print(" From ");
    IPAddress remote = Udp.remoteIP();  // display IP of remote PC
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());  // display remote port
      // read the packet and display contents
    Udp.read((char *)packet, packetSize);
    Serial.print("Contents: ");
    for (int i = 0; i < 150; i++) {
      for (int j = 0; j < 3; j++) {
        Serial.print(packet[i][j]);
        Serial.print(' ');
      }
      Serial.println();
    }
  }
}

works OK receiving the 450 element array - results same as post 4

Ordered a few of the enc28j60's, should be here next week. I'll try them out with the esp32 and the EthernetENC library. Thank you again for the suggestions.

So i have hooked up the enc28j60 to the esp32 as instructed and uploaded the provided code. It doesn't appear to receive any packets. For that matter I don't see it come up as a device on the network and the yellow lan light on the rj45 port occasionally blinks but doesn't seem to react to data being sent. I would guess that it's not properly connecting to the network.

I double checked the code sending the udp packets and it works fine with my esp32 wifi code so that would seem to indicate that sending udp is working fine.

Any guess as to why this is or any other tests i can perform? I'm not sure where to go from here.

this is a test program I used

//  ENC28J60 tested with ESP32 - UDP_client_array - receive array from remote UDP client

// connections ENC28J60 to ESP32
//  SI to pin GPIO23 MOSI
//  SO to pin GPIO19 MISO
// SCK to pin GPIO18 CLK
//  CS to PIN GPIO5 - note call to Ethernet.init(5); below
// VCC to 3V3

#include <SPI.h>  // needed for Arduino versions later than 0018
#include <EthernetENC.h>
//#include <EthernetUdp.h>  // UDP library from: bjoern@cs.stanford.edu 12/30/2008

// Enter a MAC address and IP address for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);  // IP address of this Arduino to match current network
unsigned int localPort = 999;    //  UDP port number being used
EthernetUDP Udp;                 // An EthernetUDP instance to let us send and receive packets over UDP

uint8_t packet[150][3] = { 0 };

void setup() {
  Ethernet.begin(mac, ip);  // start the Ethernet and UDP:
  Udp.begin(localPort);
  Serial.begin(115200);
  Serial.println("Ethernet UDP server IP ");
  Serial.print(Ethernet.localIP());
  Serial.print(" local port ");
  Serial.println(localPort);

}

void loop() {
  int inByte;
  // if there's data available, read acknowledgement packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.print(packetSize);
    Serial.print(" From ");
    IPAddress remote = Udp.remoteIP();  // display IP of remote PC
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());  // display remote port
      // read the packet and display contents
    Udp.read((char *)packet, packetSize);
    Serial.print("Contents: ");
    for (int i = 0; i < 150; i++) {
      for (int j = 0; j < 3; j++) {
        Serial.print(packet[i][j]);
        Serial.print(' ');
      }
      Serial.println();
    }
  }
}

and the PC C++ Pclient code (compiled using GNU C/C++)

// udp-client.cpp - simple UDP datagram client
//   send datagram to server

#ifdef __WIN32
  #include <winsock.h>          // for windows
  #define socklen_t int
#else
  #include <arpa/inet.h>        // for UNIX
  #include <netdb.h>
  #define errno h_errno
#endif
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>

// extra 3 for cr, lf and \0
#define MAX_LINE 100
#define LINE_ARRAY_SIZE (MAX_LINE+3)
#define NEWLINE "\n"

using namespace std;

// test structure to transmit
uint8_t data[150][3];


int main()
{
  int socketDescriptor;
  int numRead;
  unsigned short int serverPort;
  struct sockaddr_in serverAddress;
  struct hostent *hostInfo;
  struct timeval timeVal;
  fd_set readSet;
  char buf[LINE_ARRAY_SIZE], c;
    // ** added for windows
    WSAData wsaData;
    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
      { perror("WSAStartup()"); system("pause"); return 255; }

  cout << "Enter server host name or IP address: ";

  memset(buf, 0x0, LINE_ARRAY_SIZE);  // Zero out the buffer.
  cin.get(buf, MAX_LINE, '\n');

  // gethostbyname() takes a host name or ip address in "numbers and
  // dots" notation, and returns a pointer to a hostent structure,
  // which we'll need later.  It's not important for us what this
  // structure is actually composed of.
  hostInfo = gethostbyname(buf);
  if (hostInfo == NULL)
    { cout << "problem interpreting host: " << buf; perror("gethostbyname() ");  system("pause");  exit(1); }

  cout << "Enter server port number: ";
  cin >> serverPort;
  cin.get(c); // dispose of the newline

  // Create a socket.  "AF_INET" means it will use the IPv4 protocol.
  // "SOCK_STREAM" means it will be a reliable connection (i.e., TCP,
  // for UDP use SOCK_DGRAM), and I'm not sure what the 0 for the last
  // parameter means, but it seems to work.
  socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
  if (socketDescriptor < 0)
    { perror("cannot create socket ");  system("pause");  exit(1); }

    for(int i=0;i<150;i++) {
        for (int j=0;j<3;j++)
          printf("%d ", data[i][j]=i+j);
          printf("\n");
    }
  // Set some fields in the serverAddress structure.
  serverAddress.sin_family = hostInfo->h_addrtype;
  memcpy((char *) &serverAddress.sin_addr.s_addr,
         hostInfo->h_addr_list[0], hostInfo->h_length);
  serverAddress.sin_port = htons(serverPort);

  {
    // Send the line to the server.
    if (sendto(socketDescriptor, (const char *) &data, sizeof(data), 0,
               (struct sockaddr *) &serverAddress,
               sizeof(serverAddress)) < 0) {
      close(socketDescriptor);
      perror("sendto()  ");  system("pause");  exit(1);
    }

    // wait until answer comes back, for up to 1 second
    FD_ZERO(&readSet);
    FD_SET(socketDescriptor, &readSet);
    timeVal.tv_sec = 1;
    timeVal.tv_usec = 0;

    if (select(socketDescriptor+1, &readSet, NULL, NULL, &timeVal)) {
      // Read the modified line back from the server.
      memset(buf, 0x0, LINE_ARRAY_SIZE);  // Zero out the buffer.
      numRead = recv(socketDescriptor, buf, MAX_LINE, 0);
      if (numRead < 0) {
        cerr << "didn't get response from server?\n";
        close(socketDescriptor);
        perror("recv()  ");  system("pause");  exit(1);
        }

      cout << "Modified: " << buf << "\n";
    }
    else {
      cout << "** Server did not respond in 1 second.\n";
    }

  }

  close(socketDescriptor);
  return 0;
}

when run the ESP322 dispays

Ethernet UDP server IP 
192.168.1.177 local port 999
UDP_TX_PACKET_MAX_SIZE 24
Received packet of size 450 From 192.168.1.68, port 55875
Contents: 0 1 2 
1 2 3 
2 3 4 
3 4 5 
4 5 6 
5 6 7 
6 7 8 
7 8 9 
8 9 10 
9 10 11 
10 11 12 
11 12 13 
12 13 14 
13 14 15 
14 15 16 
15 16 17 
16 17 18 
17 18 19 
18 19 20 
19 20 21 
20 21 22 
21 22 23 
22 23 24 
23 24 25 
24 25 26 
25 26 27 
26 27 28 
27 28 29 
28 29 30 
29 30 31 

and the PC displays

Enter server host name or IP address: 192.168.1.177
Enter server port number: 999
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
11 12 13
12 13 14
13 14 15
14 15 16
15 16 17
16 17 18
17 18 19
18 19 20

photo of setup

upload your serial monitor output as text (not an image)
also the client output if you have access to it
what is the IP address of the ESP32 server and the client PC? are they on the same subnet?
can you ping the ESP32 from your PC?
is the ESP32 connected to a router? and the client?

upload your serial monitor output as text (not an image)

Here is the serial monitor output. It only displays the print statements from setup:

14:41:39.661 -> ets Jun 8 2016 00:22:57
14:41:39.661 ->
14:41:39.661 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
14:41:39.661 -> configsip: 0, SPIWP:0xee
14:41:39.661 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
14:41:39.661 -> mode:DIO, clock div:1
14:41:39.661 -> load:0x3fff0030,len:1344
14:41:39.661 -> load:0x40078000,len:13516
14:41:39.694 -> load:0x40080400,len:3604
14:41:39.694 -> entry 0x400805f0
14:41:39.860 -> Ethernet UDP server IP
14:41:39.860 -> 192.168.4.77 local port 4210

It doesn't seem to print the package contents or acknowledge in any way it's receiving data.

also the client output if you have access to it

I assume you mean the output from the program that's sending the data. Here is a print of the payload data (one frame) immediately before being sent(I forgot that the code sends an array of 450 8 bit integers rather than the 2d array. I can't remember why I did it this way, I think the rust crate I'm using for udp doesn't like to send 2d arrays (rust is very particular this way)):

[0, 0, 0, 0, 3, 10, 2, 10, 22, 6, 16, 33, 25, 22, 47, 55, 19, 49, 102, 11, 46, 143, 4, 34, 190, 0, 24, 224, 0, 11, 224, 0, 10, 204, 0, 20, 159, 6, 41, 109, 24, 68, 65, 44, 96, 39, 53, 110, 20, 61, 120, 12, 59, 116, 11, 52, 100, 6, 39, 76, 4, 24, 47, 12, 10, 25, 26, 1, 8, 52, 0, 4, 97, 0, 4, 147, 0, 4, 190, 0, 9, 223, 0, 9, 224, 0, 9, 195, 0, 15, 158, 0, 19, 109, 9, 40, 65, 28, 73, 45, 47, 96, 69, 26, 68, 113, 8, 33, 166, 0, 18, 209, 0, 9, 228, 0, 9, 217, 0, 8, 183, 0, 10, 130, 0, 6, 86, 0, 3, 45, 0, 3, 16, 4, 10, 4, 13, 31, 5, 25, 51, 8, 38, 76, 10, 51, 101, 12, 56, 112, 23, 56, 113, 46, 49, 103, 84, 34, 81, 122, 19, 60, 172, 0, 34, 212, 0, 17, 230, 0, 10, 217, 0, 12, 179, 0, 26, 127, 9, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

I altered your code to accommodate the array as follows:

Line 20:

uint8_t packet[450] = { 0 };

And lines 51 through 59:

Udp.read((char *)packet, packetSize);
    Serial.print("Contents: ");
    for (int i = 0; i < 450; i++) {
      //for (int j = 0; j < 3; j++) {
        Serial.print(packet[i]);
        Serial.print(' ');
      //}
      Serial.println();
    }

what is the IP address of the ESP32 server and the client PC? are they on the same subnet?

I would define the server to be the pc and the client to be the ESP32. Am I wrong in this assumption? In any case the pc IP is 192.168.4.79 and the ESP32 IP is 192.168.4.77.

can you ping the ESP32 from your PC?

Surprisingly, yes. Here is the result:

➜ ~ ping 192.168.4.77
PING 192.168.4.77 (192.168.4.77) 56(84) bytes of data.
64 bytes from 192.168.4.77: icmp_seq=1 ttl=64 time=1.04 ms
64 bytes from 192.168.4.77: icmp_seq=2 ttl=64 time=0.603 ms
64 bytes from 192.168.4.77: icmp_seq=3 ttl=64 time=0.637 ms
64 bytes from 192.168.4.77: icmp_seq=4 ttl=64 time=0.628 ms
64 bytes from 192.168.4.77: icmp_seq=5 ttl=64 time=0.602 ms
64 bytes from 192.168.4.77: icmp_seq=6 ttl=64 time=0.626 ms
64 bytes from 192.168.4.77: icmp_seq=7 ttl=64 time=0.606 ms
64 bytes from 192.168.4.77: icmp_seq=8 ttl=64 time=0.623 ms
64 bytes from 192.168.4.77: icmp_seq=9 ttl=64 time=0.614 ms
64 bytes from 192.168.4.77: icmp_seq=10 ttl=64 time=0.626 ms
64 bytes from 192.168.4.77: icmp_seq=11 ttl=64 time=0.616 ms
64 bytes from 192.168.4.77: icmp_seq=12 ttl=64 time=0.620 ms
64 bytes from 192.168.4.77: icmp_seq=13 ttl=64 time=0.630 ms
64 bytes from 192.168.4.77: icmp_seq=14 ttl=64 time=0.613 ms
64 bytes from 192.168.4.77: icmp_seq=15 ttl=64 time=0.629 ms
64 bytes from 192.168.4.77: icmp_seq=16 ttl=64 time=0.623 ms
64 bytes from 192.168.4.77: icmp_seq=17 ttl=64 time=0.592 ms
64 bytes from 192.168.4.77: icmp_seq=18 ttl=64 time=0.628 ms
64 bytes from 192.168.4.77: icmp_seq=19 ttl=64 time=0.617 ms
64 bytes from 192.168.4.77: icmp_seq=20 ttl=64 time=0.628 ms
64 bytes from 192.168.4.77: icmp_seq=21 ttl=64 time=0.617 ms

is the ESP32 connected to a router? and the client?

Yes and yes.

Also, here is a pic of my hookup. I have a slightly different version of esp, but the connections look correct.

it all looks OK but the server is not receiving packets - I assume the client is sending UDP packets to

192.168.4.77 local port 4210

port 4210 seems a strange choice be should be OK
can you run wireshark and look for UDP pakets addressed to 192.168.4.177?
is it your own network? e.g. not a corporate network with various restrictions?

So In prepping these photos I must have jiggled a loose wire because it seems to work as intended now without having made any other changes. Thank you for the help. If you don't mind I have a few followup questions in the interest of learning:

Udp.read((char *)packet, packetSize);

My c++ is a bit rusty but as I understand it, this is defining packet to be an array of char's. Is this so? if so, why is that? Is there some reason we don't want it to be int's?

With regards to port numbers, why is 4210 so unusual and what would be a better alternative?

On line 34 the code defines:

int inByte;

But never seems to use it. What is the purpose of doing this?

I realize that this is an example and that you probably(maybe) didn't write it all but I would love to know the answers if possible. Thank you so much again for your help, you are an absolute legend.

the array is defined as

uint8_t packet[150][3] = { 0 };

the function prototype of EthernetUDP::read() is

int   read(unsigned char* buffer, size_t len);

its first parameter is a pointer to unsigned char, i.e. an address in memory
so to call it with the array packet as the first parameters we have to cast the address of packet (an array name is a pointer to the first element) to unsigned char*

Udp.read((char *)packet, packetSize);

should be (unsigned char *) but the compiler accepts (char *)

if we don't cast it and just give the address of packet

   Udp.read(packet, packetSize);

your get an error

 no known conversion for argument 1 from 'uint8_t [150][3] {aka unsigned char [150][3]}' to 'char*'

you have to be careful with casts as getting it wrong can cause problems - see Do not cast away a const qualification - C assumes you know what you are doing!

I just tend to use 10000, 20000, etc 4210 seemed a random choice and I thought it worth checking

it was left over from when I was doing other things in the code

Awesome thank you. Appreciate all the help and the answers.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.