TCP/IP sending unsigned long array

Hi there!

My first post, so I take occasion to present myself: I am not a developer, neither an engineer, just an economist passionate about programming and, since a couple of weeks, microelectronics (thanks to arduino!), with a bunch of spare time to develop some project!

I am trying to send an unsigned long array from a “Client” microcontroller (in my case an ESP32 Dev Board, not important just for info, Wifi embedded) to a “Server” microcontroller (ARDUINO MEGA 2560 + Ethernet Shield 2) through TCP protocol.

I am able to send a single value, but I don’t have idea how to send in a smart way the entire array.

Basically, on the client side, I came up with an unsigned long array made up from different sensors output.

Here is the portion of the code of interest from the client sketch (I omit library, setup, just to be coincise, all the code is working properly, I just need help with handling an entire long unsigned array with client.write()):

connecting stuff, sensor testing and so on, all working well

void loop() {

//.... sensor output all fine

//collecting outputs 

unsigned long sensordataset[] ={Out1, Out2, Out3, Out4}; 

if (client.connected()){
    client.write((uint8_t*) &sensordataset,sizeof(sensordataset));//print
    delay(10);    
  }
delay(5000); // I have a timer with millis(), just putting delay to be more coincise in this example
}

on the server side instead:

void loop() {

//.... sensor output all fine

// array for collecting data from client:
unsigned long sensordataset[] ={Out1, Out2, Out3, Out4}; 

EthernetClient client = server.available(); // wait and assing client
   int size;
   unsigned long * clientdata = (unsigned long *)malloc(size);
   if (client) { 
    Serial.println("new client");
    if (size=client.available()){
        size = client.read((uint8_t *)clientdata , size);
        String str = String("") + (*clientdata );
        Serial.println(str);
        Out1=str.toInt(); //     <----- here i find the first value but I would like the entire array
    }
   }

// do calculation & other stuff with sensordataset array elements

delay(10000);

So I give an unsigned long array to client.write, and I receive just the first value in client.read on the server side.

How can I solve the issue?

Thanks in advance!

PS: given my little experience, I decided to use TCP because I read it is reliable instead of UDP, that could not ensure all data are sent in the desidered order. Anyway what I need is just to receive on the ARDUINO MEGA with Ethernet shield the data collected from the ESP32WiFi (12 unsigned long every minute is the maximum rate, so not so much and complex data), so if you have other suggestion I will be more pleased to receive them! (of course not I2C wired connection :stuck_out_tongue: neither BLE)

It looks as though you are getting all the values you want. The issue is that you haven't added them into your printed String. Try this:

String str = String("") + clientdata[0]+" "+clientdata[1];

Not compiled or tested.

@wildbill: Thanks so much for your prompt reply, Sir!

And moreover THANKS FOR SAVING MY DAY!!!

It is working properly! I attach the Server part in the case other guys will need!

 if (client) { 
    Serial.println("new client");
    if (size=client.available()){
        size = client.read((uint8_t *)sensordata, size);
        for (int i=0;i<=11;i++){
        String str = String("") + sensordata[i];
        sensorboxdata[i]=str.toInt();
        }
    }
   }

Now I have just to check the variable type assignation between the two sketch cause I found some value are not taken correctly! (if you can confirm me for example that if I gave to the client.write() a float instead of a long it will go on error on the server side, right?)

Thanks so much again!

I am not clear what you are asking. Client.write (as you are using it) will send any kind of data you like as a stream of bytes. It's up to you to interpret those bytes appropriately. In your example, you're successfully sending an array of long. You can do the exact same thing with an array of floats.

Of course, if you send a float and interpret it as a long, you will get garbage.

Perfect! This is just what is happening lol

Do I have just to cast to long all the input on the client.write() side, right?

Because I have some float and other long output from sensors

If you cast a float to a long, you will lose the precision after the decimal place. You could point a float* to the place in the array where the floats are to go and write them that way.

Take a look at structs - easier than all that pointer and casting stuff.

Ok… still in the troubles… I tried to make it work until now without success…

Please test it and try to be kind explaining me what is going on… I am honestly not understanding well what (uint8_t*), same for stand for, but I cannot find a logic in the output of this code…

Client:

#include <WiFi.h>
///////////////////////////////////////////////////////////////////////////////////
// Wifi configuration
// Replace with your network credentials
const char* ssid = "netwroksssssfds";
const char* password = "passsssssss";
byte server[] = {xxx, xxx,xxx,xxx};  // web server IP (CORE) 
WiFiClient client;

/**********  Setup    **********/
void setup(){
  // Serial port for debugging purposes
  Serial.begin(9600);
    WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("Connecting to WiFi..");
    delay(1000);
  }
  // connecting to server
  if (client.connect(server,1235)){
  Serial.print("Connected to Server: ");
  }
}

 
void loop(){
  
  // Sensors Output
  unsigned long Out0= 0;
  unsigned long Out1= 1;
  unsigned long Out2= 2;
  unsigned long Out3= 3;
  unsigned long Out4= 4;
  unsigned long Out5= 5;
  unsigned long Out6= 6;
  unsigned long Out7= 7;
  unsigned long Out8= 8;
  unsigned long Out9= 9;
  unsigned long Out10= 10;
  unsigned long Out11= 11;
  unsigned long Out12= 12;
  unsigned long sensorboxdata[] ={Out0, Out1, Out2, Out3, Out4, Out5,Out6,Out7,Out8,Out9,Out10,Out11,Out12};

  for (int i=0;i<=10;i++){
    Serial.print("Sensore numero ");
    Serial.println(i);
    Serial.println(sensorboxdata[i]);  // they are correct there
  }
  // Send data to Server
  if (client.connected()){
    Serial.println("sensorboxdatabyte to Server");
    client.write((uint8_t*) &sensorboxdata,sizeof(sensorboxdata));
    delay(10);    
  } else {
    Serial.println("Connection to Server lost, trying to reconnect...");
    if (client.connect(server,1234)){
      Serial.println("Connected to Server");
    }
    else {
      Serial.println("Unable to connect to Server!");
    
    }
  }  
 delay(3000);    
}

I receive the correct data from serial.print on the client side (Sorry for some italian in the way lol):

19:34:33.563 → Sensore numero 0
19:34:33.563 → 0
19:34:33.563 → Sensore numero 1
19:34:33.609 → 1
19:34:33.609 → Sensore numero 2
19:34:33.609 → 2
19:34:33.609 → Sensore numero 3
19:34:33.643 → 3
19:34:33.643 → Sensore numero 4
19:34:33.690 → 4
19:34:33.690 → Sensore numero 5
19:34:33.690 → 5
19:34:33.690 → Sensore numero 6
19:34:33.728 → 6
19:34:33.728 → Sensore numero 7
19:34:33.728 → 7
19:34:33.728 → Sensore numero 8
19:34:33.764 → 8
19:34:33.764 → Sensore numero 9
19:34:33.764 → 9
19:34:33.764 → Sensore numero 10
19:34:33.811 → 10
19:34:33.811 → sensorboxdatabyte to Server

… but when I read them on the Server side:

#include <SPI.h>               // SPI: for screen & ethernet
#include <Ethernet.h>
byte mac[] = {xxxxxxxx};  
byte ip[] = { xxxxxxxx };
EthernetServer server(1234); 
////////////////////////           SETUP                   /////////////////////////
void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac); // Start Ethernet Connection _   Ethernet.begin(mac, ip); 
  server.begin(); // start server 
}
////////////////////////           LOOP                    /////////////////////////
void loop() {
  unsigned long sensorboxdata[13]; 
  // request data from sensor box
   Serial.print("Request data from sensor box"); 
   EthernetClient client = server.available(); // wait and assign client
   int size;
   unsigned long * sensordata = (unsigned long*)malloc(size);
   if (client) { 
    Serial.println("client ready");
    if (size=client.available()){
        size = client.read((uint8_t *) sensordata, size);
        for (int i=0;i<=12;i++){
        sensorboxdata[i]=0;
        String str = String("") + sensordata[i];
        sensorboxdata[i]=str.toInt();
        Serial.print("Output #");
        Serial.println(i);
        Serial.println(str);
        Serial.println(String(sensorboxdata[i]));
        }
    }
   }
   else {
   Serial.println("No client available"); 
   }
      delay(5000);
}
////////////////////////////////////// loop end

… I got something that for me is just madness:

19:35:58.390 → Request data from sensor boxclient ready
19:35:58.424 → Output #0
19:35:58.458 → 0
19:35:58.458 → 0
19:35:58.458 → Output #1
19:35:58.458 → 131072
19:35:58.458 → 131072
19:35:58.458 → Output #2
19:35:58.492 → 808517632
19:35:58.492 → 808517632
19:35:58.543 → Output #3
19:35:58.543 → 859191089
19:35:58.543 → 859191089
19:35:58.543 → Output #4
19:35:58.543 → 655417
19:35:58.590 → 655417
19:35:58.590 → Output #5
19:35:58.590 → 3617076
19:35:58.590 → 3617076
19:35:58.590 → Output #6
19:35:58.643 → 942669878
19:35:58.643 → 942669878
19:35:58.643 → Output #7
19:35:58.643 → 56
19:35:58.643 → 56
19:35:58.643 → Output #8
19:35:58.690 → 8
19:35:58.690 → 8
19:35:58.690 → Output #9
19:35:58.690 → 9
19:35:58.690 → 9
19:35:58.690 → Output #10
19:35:58.690 → 10
19:35:58.744 → 10
19:35:58.744 → Output #11
19:35:58.744 → 11
19:35:58.744 → 11
19:35:58.744 → Output #12
19:35:58.744 → 12
19:35:58.744 → 12

I have output from 1 to 7 completely no sense, and the other are correct!

What is happening? I cannot figure out!

Please help me with this issue, it is the cherry on the cake and I cannot imagine to getting lost on internet comunication!!!

Thanks again

Good mng all!

Got it sorted and I suspected it was a pretty stupid problem… But honestly I was floored by the fact that some values where correct!

Anyway the problem is about memory allocation of the array (sensordata). I sorted it out by assigning a big value to size, that indeed was not declared (honestly as said, I had no time to investigate properly in this part of the project and what these function were doing, my really bad). Then I used free(sensordata) to free the memory allocated and finally the server has been able to read correctly all the data!

Moreover as suggested by the good PieterP, nosense to convert the int to String and then back to int…
Sorry guys, I usually try to understand well each part of the code I am using, this time really exhausted about c stuff and misleaded from some correct values.

ANYWAY AS USUAL, THE ANSWER IS INSIDE YOU(R CODE)!!

Thanks so much for your patience!

PS: Here you are the server code in case some puppet like me will need in the future :smiley:

   int size=100; // <- before it was just declared, no value assigne
   int long * sensordata = (int long *)malloc(size);
   if (client) { 
    Serial.println("client ready");
    if (size=client.available()){
        size = client.read((uint8_t *) sensordata, size);
        for (int i=0;i<=12;i++){
        sensorboxdata[i]=sensordata[i]; // almost surely I can directly use sensordata instead of allocating 
        // a new  array... going to test it
        Serial.print("Output #");
        Serial.println(i);
        Serial.println(String(sensorboxdata[i]));
        }
        free(sensordata); // <- freeing up the memory on sensordata array
    }
   }