Convert struct into char *

Hi!

I have some problems with serialization. I'd like to send a message that must be a char * to be passed to the send() function, and that could be a serialized struct or just data (mainly numbers) put into a char *.

I tried many things, and I can't get anything with Serial.print() on my final char *.
The two main solutions I tried :

char * sendbuf;
float flat = 51.508131;
float flon = -0.128002;  

void setup() {
  Serial.begin(9600);  
}

void loop() {
  sendbuf = (char*)malloc(sizeof(byte) + 2*sizeof(long));
  byte id = 1;
  short lon = (short)(flon*100);
  short lat = (short)(flat*100);
  memcpy(sendbuf, &id, sizeof(byte));
  memcpy(sendbuf + sizeof(byte), &lon, sizeof(long));
  memcpy(sendbuf + sizeof(byte) + sizeof(long), &lat, sizeof(long));
  
  Serial.print("buf is ");     
  Serial.print(sendbuf);
  
  delay(10000);
}

This solution doesnt work, I suspect it could be related to the memcpy ?

struct mes_t {
  byte id;
  short lon;
  short lat;
};

void * buf;
float flat = 51.508131;
float flon = -0.128002;  

void setup() {
  Serial.begin(9600);  
}

void loop() {
  struct mes_t *mes = (struct mes_t *)buf;
  mes->id = 1;
  mes->lon = (short)(flon*100);
  mes->lat = (short)(flat*100);
  
  Serial.print("buf is ");     
  Serial.println((char *)buf);     
  delay(10000);
}

I cant serialize my struct either.

Could someone tell me how to get this data into a char * ?
Thx a lot ! :slight_smile:

roopse:
I have some problems with serialization.

Where did you find serialization in C++?

If you want it, you have to write it yourself (as a member function of your struct?).

If you want to send data you could just cast it

struct mes_t {
  byte id;
  short lon;
  short lat;
} message;

BlaBla.send((char*)&message, sizeof(message));

Thanks for your reply!

I use this word (serialization) to tell that I wanted to convert a struct into a char *, but it's not the best word talking about C++, you're right.

I've tried cast it, but I must do it wrong...

struct message_t {
  byte id;
  short lon;
  short lat;
};

float flat = 51.508131;
float flon = -0.128002;  

void setup() {
  Serial.begin(9600);  
}

void loop() {

  struct message_t message ;
  message.id = 1;
  message.lon = (short)(flon*100);
  message.lat = (short)(flat*100);

  Serial.print("message is ");     
  Serial.println((char*)&message);
       
  delay(10000);
}

The result is :

message is ôÿ

Or maybe it's just that I can't print it using Serial.print ? (It is the only way I can check what I send)

Just write a function to print each member in turn.

Or maybe it's just that I can't print it using Serial.print ?

You could make the structure print and you could dump the memory of the struct.

struct message_t {
  byte id;
  short lon;
  short lat;
  void printIt() {
    Serial.print(F("id "));
    Serial.print(id);
    Serial.print(F(", lon "));
    Serial.print(lon);
    Serial.print(F(", lat "));
    Serial.println(lat);
  }
};

float flat = 51.508131;
float flon = -0.128002;

void setup() {
  Serial.begin(250000);
  struct message_t message = { 1, (short)(flon * 100), (short)(flat * 100) };
  message.printIt();
  Serial.print(F("message is"));
  dump(&message, sizeof(message));
}
void loop() {}

void dump(const void* adr, int len) {
  char* ptr = (char*) adr;
  for (; len > 0; len -= 0x10, ptr += 0x10) {
    byte i;
    for (i = 0; i < 16; i++) {
      if (i < len) {
        Serial.write(' ');
        pHex(ptr[i]);
      }
    }
    Serial.print(F(" '"));
    for (i = 0; i < 16; i++) {
      if (i < len) {
        Serial.write(ptr[i] < 0x20 ? '.' : ptr[i]);
      } else {
        break;
      }
    }
    Serial.println('\'');
  }
}
void pHex(byte val) {
  if (val < 16) {
    Serial.write('0');
  }
  Serial.print(val, HEX);
}
id 1, lon -12, lat 5150
message is 01 F4 FF 1E 14 '.....'

Thank you both!
Why have'nt I thought about that sooner..........?

I checked by remaking the struct, and it works, I shouldn't have used Serial.print.

Thank u :smiley:

  message.lon = (short)(flon*100);
  message.lat = (short)(flat*100);

why are you losing all the accuracy in your coordinates?
If you send them as longs or floats or strings you'll get a much better resolution of distance.

Quilkin, because I need to send the lowest amount of data and I dont need a good precision, so 2 decimals are good for me :slight_smile:

roopse:
Quilkin, because I need to send the lowest amount of data and I dont need a good precision, so 2 decimals are good for me :slight_smile:

The lowest volume of data would be to write the 4 bytes of the float as binary data.

Converting 51.508131 or -0.128002 to ints gives 5150 and -128. Each is 4 characters, with a huge loss of accuracy. Sending the data in binary would require 4 bytes each, and NO loss of accuracy.

Actually I made two modes, depending on the precision I need.

I use short (2 bytes) if no precision needed (~ 1.1 kms) and float (4 bytes) for very precise localization.

In my post I only published the first case since it wasn't the purpose of my question.
But thanks for your advice :slight_smile: