0

I have to send a jpeg by serial from a uart to an esp8266, the jpeg has 0 values in some places, if I send the zeros as is, the received frame contains the chars before the zeros, so what I do is that I send a '0' (0x30 ascii code) instead of a zero,

as you can see on the picture of the merge, on the right the jpeg I receive, on the left the normal jpeg, look at the fifth byte of the top, you will see the difference !

I can't work like that I really want to send char[i]= 0 and receive it

i also give you my code of sending :

for (i=0;i<244;i++){
                if (Storage_ReadWrite_Buffer[i]!=0)
                    sprintf(Storage_ReadWrite_Buffer[i],"%c", Storage_ReadWrite_Buffer[i]);
                else
                    Storage_ReadWrite_Buffer[i] = '0';
                    //sprintf(Storage_ReadWrite_Buffer[i],"%d", Storage_ReadWrite_Buffer[i]);
            }
            RS485_Send_CHAN_A("<",1);
            RS485_Send_CHAN_A(Storage_ReadWrite_Buffer,244);
          //  RS485_Send_CHAN_A(">",1);
            RS485_Send_CHAN_A("\0",1);

that is the code in the esp to get data :

void loop() {
  
   recvWithStartEndMarkers();
   showNewData();
  
   
}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static int ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
   
    
 
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();
        //delay(5);
  
        if (recvInProgress == true) {
            if (rc != endMarker) {
            
                receivedChars[ndx] = rc;
                compteur++;
                ndx++;
                if (ndx >= numChars-1) {
                    ndx = 0;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                //Serial.println(ndx,DEC);
                recvInProgress = false;
                ndx = 0;
                
                //publish_image();
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
            for(int comp;comp<6000;comp++){
              receivedChars[comp] = 0;
            }
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        //Serial.println(receivedChars[4],HEX);
        newData = false;
        publish_image();
    }
}

merge

Jonas
  • 121,568
  • 97
  • 310
  • 388
Hicham
  • 5
  • 1
  • 4
  • I cannot follow you. If you send a 0 you receive a 0. Why on earth would you turn it into 0x30? What do you mean with "contains the chars before the zeros"? – Piglet Oct 06 '21 at 11:40
  • i d'ont receive 0 if i send ttt0ppp , i put it in char tab[] ans then when i print(tab) in esp i see just "ttt" – Hicham Oct 06 '21 at 11:43
  • i have to send ttt0x30ppp to receive ttt0ppp – Hicham Oct 06 '21 at 11:56

1 Answers1

0

i d'ont receive 0 if i send ttt0ppp , i put it in char tab[] ans then when i print(tab) in esp i see just "ttt"

You send 0 and you receive 0. That's not the problem.

The problem is that you cannot print it.

Your idea to send '0' is not good because how do you know if your data actually contained a 0x00 or 0x30? You will see a '0' in both cases.

Not every number represents a printable character. See https://www.asciitable.com/

Also C strings are zero terminated. That means if you print a string given by a char pointer, it will print every character until the first 0x00. That way you don't have to provide a length.

The actual solution to this problem is to print a human-readable form. There are many ways. Just google char array to hex

How do you convert a byte array to a hexadecimal string in C?

And make sure that you send the actual values. Not some string representation.

Piglet
  • 27,501
  • 3
  • 20
  • 43
  • thank's a lot for your answer, it's really helpfull, but really i don't care about printing what i want is , send the frame by mqtt receive it by pyhton script and write the picture ! – Hicham Oct 06 '21 at 12:42
  • ok, i change sprintf to : sprintf(Storage_ReadWrite_Buffer[i],"%02X", Storage_ReadWrite_Buffer[i]); but its still don't work, it print character untill the first 0x00 – Hicham Oct 06 '21 at 12:47
  • this is not how you use sprintf... sprinft(str, format, ...) will put the formatted string into buffer str. you cannot do this in-place. also why do you need sprinft in the first place? if you want to send an image through serial, send it's bytes. not some string representation. – Piglet Oct 06 '21 at 12:58
  • i don't understand how to send it "bytes" the storage_read_Write_buffer" is char type so it's also byte . – Hicham Oct 06 '21 at 13:12
  • when i send just the storage_buffer it's don't work too , it print until the 0x00 – Hicham Oct 06 '21 at 13:13
  • what I mean is that you do not have to use sprinf to format Storage_ReadWrite_Buffer befor you send it via rs485. if you want to print it on the esp, format it there. you cannot print it as is because a string is terminated with a 0. So whatever comes after the first 0 is ignored. that's why you have to format it it so 0 is printed as '0' or '0x00', you don't do this on the sending side. – Piglet Oct 06 '21 at 13:28
  • ok thank you so much, i will try – Hicham Oct 06 '21 at 13:42
  • i edit my question to add the esp code, what can i apply to "rc" value to format the data – Hicham Oct 06 '21 at 13:54
  • why do you think I link stuff in my answer? please read it. it shows how to convert a byte array into a printable hex string. run a loop over rc and concatenate a string. Usually it won't make sense to print a whole jpeg file as a hex string though :) – Piglet Oct 06 '21 at 14:08
  • ok, I give up I'll rather encode my bytes in base64 and send them ! it's easier – Hicham Oct 07 '21 at 10:00