UDP Everything after zero byte in packet becomes zero

Hello guys,

I am trying to send GPS-Data from one ESP8266 to another ESP8266 via UDP. I am using the WiFiUdp library. But I have noticed something weird. The packet gets sent from one device to the other, but whenever there is a zero byte in the packet, all the data in this packet after the zero byte becomes zero.

Example:
Sent packet: 2E BE 00 4D 21
Received packet: 2E BE 00 00 00

Sent packet: 2E BE FF 4D 21
Received packet: 2E BE FF 4D 21

If I send a packet without a zero byte everything is fine. Can somebody explain to me why this happens? And what would be a way to handle this?
Thanks!

Show your code (with code tags)

Are you sending with .print ?
That’ll do it.

Or even write for a char buffer would assume a cString and stop at 0.

A write with a byte pointer and size of the payload would be required

Seeing the code would clear that up but seems OP is MIA….

Sorry it was nighttime in my country.

This is basically the code that sends the packet. Examples of the print:
Example 1: "Sensor Answer: 12 34 56 78 9A BC DE F6"
Example 1: "Sensor Answer: 12 34 56 78 00 BC DE F6"

Serial.printf("Sensor Answer: %02X %02X %02X %02X %02X %02X %02X %02X\n\r", answerPacketData[0], answerPacketData[1],answerPacketData[2],answerPacketData[3],answerPacketData[4],answerPacketData[5],answerPacketData[6],answerPacketData[7]);
c_UDP.beginPacket(g_ip_APlocalIP, c_UDP.remotePort());
c_UDP.write(answerPacketData);
c_UDP.endPacket();

And this is the code that receives the packet. Examples of the print with the packets sent by the examples above:
Example 1: "ListenClient::2 Bytes read: 10 Sensor Answer: 12 34 56 78 9A BC DE F6"
Example 2: "ListenClient::2 Bytes read: 10 Sensor Answer: 12 34 56 00 00 00 00 00"

char	 incomingPacket[10]	= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  if ( c_UDP.parsePacket() )
  {
    int n = c_UDP.read(incomingPacket, 10);
    Serial.printf("ListenClient::2\tBytes read: %d\tSensor Answer: %02X %02X %02X %02X %02X %02X %02X %02X\n\r",(sizeof(incomingPacket)/sizeof(incomingPacket[0])),incomingPacket[0], incomingPacket[1],incomingPacket[2],incomingPacket[3],incomingPacket[4],incomingPacket[5],incomingPacket[6],incomingPacket[7]);

You need to pass the size if it’s a binary payload

I tried it with:

c_UDP.write(answerPacketData, 10);

But it is still doing it. The size of the packet is 10 bytes big. The first 8 bytes are the coordinates and the last two are the time.

Try something like this on the receiving end

byte incomingPacket[10];

int packetSize = c_UDP.parsePacket();
if (packetSize != 0) {
  Serial.print(F("Packet size : ")); Serial.println(packetSize);
  c_UDP.read(incomingPacket,10);
  for (int i=0; i < packetSize; i++) {
    if (incomingPacket[i] < 0x10) Serial.write('0');
    Serial.print(incomingPacket[i] , HEX);
    Serial.write(' ');
  }
  Serial.println(); 
}

I did that and the output of the print is: "12 34 56"

well you should also see the size before...

We need full code of the emitter and receiver (or working example) to make sure we understand exactly what you are doing.

Will read beyond end of array if packetSize > 10.

good point !

for (int i=0; i < min(10, packetSize); i++) {
  ...

Ok, the size is 3 according to the print.
It is quite hard to give a full example of the working code as it is quite long, because there is a lot more functions. But the only thing that is producing this error, is if there is a byte with 00.

What I am doing is basically chopping the GPS data and time data up into bytes which can be send via the packet. The receiver then puts the data back together and saves it onto a SD card. This works fine, except for when the 00 thing happens.

I have changed the send packet to: 0x12 34 50 08 9A BC DE F6, so that it should get send normally and it does. This is what the changes you advised to me printed:
Packet size: 28
12 34 50 08 9A BC DE F6 14 04 CE 17 63 53 6A 00 00 00 00 00 00 00 00 00 F0 A7 C6 4B

it's surprising that you get 28 bytes in the payload if you only sent 8...

again without the code I can't help more

Then post a Minimum Reproducible Example (MRE). That is the smallest possible code that compiles and demonstrates the problem. Leave out all the unrelated stuff from your big, messy code.

So this is the code that basically puts the GPS and time data into single bytes in hex. It is a little bit confusing but it works. I am sure that there are better ways to do it, but that is how I have done it. The array "arr" is the the array "answerPacketData", that gets send to the receiver via UDP. Nothing else is done with "answerPacketData". So as you can see there are a max of 10 Bytes in it.

Hope this helps.

void MSG_encode(char* arr, uint16_t& ip, uint64_t& data_val_64, uint16_t& time_val)
{
  uint16_t rest       = 0;
  uint16_t rest_lat       = 0;
  uint16_t rest_long       = 0;
  uint16_t quotient_data  = 0;
  uint16_t quotient_time  = 0;
  uint32_t quotient_data_lat      = 0;
  uint32_t quotient_data_long      = 0;
  quotient_data_long      = (uint32_t)data_val_64 & 0xFFFFFFFF; //this is just a conversion to the decimal value of the longitudinal value
  quotient_data_lat      = (uint32_t)(data_val_64>>32) & 0xFFFFFFFF; //this is just a conversion to the decimal value of the latidunal value
  quotient_time       = time_val;
  
  /* Sensor Data und Timevalue conversation, Slave to Master */
          uint8_t t_arr[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // Slave send Data, convert to Hex
          for (uint8_t i=0; i < 8; i++)
          {
            rest_lat      = quotient_data_lat %16;
            quotient_data_lat   = quotient_data_lat /16;
            
            rest_long       = quotient_data_long %16;
            quotient_data_long   = quotient_data_long /16;
      
            t_arr[i] = rest_lat;
            t_arr[i+8] = rest_long;
            //Serial.printf("MSG_encode::3:: t_arr[%d]:%4X\n\r",i, arr[i]);
          }
          arr[0] = (t_arr[7]<<4) | t_arr[6];
          arr[1] = (t_arr[5]<<4) | t_arr[4];
          arr[2] = (t_arr[3]<<4) | t_arr[2];
          arr[3] = (t_arr[1]<<4) | t_arr[0];
          

          arr[4] = (t_arr[15]<<4) | t_arr[14];
          arr[5] = (t_arr[13]<<4) | t_arr[12];
          arr[6] = (t_arr[11]<<4) | t_arr[10];
          arr[7] = (t_arr[9]<<4) | t_arr[8];

          rest = 0;
          t_arr[0] = 0x00;
          t_arr[1] = 0x00;
          t_arr[2] = 0x00;
          t_arr[3] = 0x00;
          t_arr[4] = 0x00;
          t_arr[5] = 0x00;

          for (uint8_t i=0; i<4; i++)
          {
            rest      = quotient_time %16;
            quotient_time   = quotient_time /16;
      
            t_arr[i] = rest;
            //Serial.printf("MSG_encode::3:: t_arr[%d]:%4X\n\r",i, arr[i]);
          }
          arr[8] = (t_arr[1]<<4) | t_arr[0];
          arr[9] = (t_arr[3]<<4) | t_arr[2];
}

Ok, I can try to do that.

you probably would be better off using a structure and sending the bytes in the structure directly rather than going through all those modifications

we would need to see a code with c_UDP.write(answerPacketData, 10); to ensure you only send 10 bytes and a receiver code with what I provided above (that should see the 10 bytes coming in)

I don't really know what I have changed but I guess it had somethind to do with the c_UDP.write(answerPacketData, 10); and now it works! Thanks a lot for the patience and help!