Sending characters through the serial port including zero-value bytes

Asked

Viewed 518 times

5

I am making an application in which I need to send a character array via serial to an external hardware (declared as unsigned char) containing commands and times.

With the commands I have no problem, since each command corresponds to a unsigned char ('A','B', etc.). The problem is with time.

Time is stored in a variable unsigned short int that I access byte to byte through a vector t of unsigned char, using the following union:

union tempos {
    unsigned short int tempo; //16 bits ou 2 bytes
    unsigned char t[2]; //8 bits ou 1 byte [cada posição]
}temp;

Thus, an example of the structure of array of unsigned char that I must send is the following:

[cabeçalho] [comando1] [comando2] [byte1 do tempo1 (temp.t[0])] [byte2 do tempo1 (temp.t[1])] [comando 3] 

The problem is when one of bytes time is equal to 0, since 0 corresponds to 0 NULL in the ASCII table and NULL is the character that marks the end of a vector of char. So when this condition occurs mine array is not yet formed (because there is a NULL) and consequently is not transferred correctly via serial.


Edited (added an important comment to the body of the question):

WriteFile(hComm,Buffer,strlen(Buffer),&bytesEscritos,NULL);

The shipping code is this. hComm is the serial settings variable, Buffer the array of unsigned char that I want to send, the third parameter is the size of the array, the fourth is the number of bytes written and the last is an overlapping configuration. The problem is that Buffer does not have the value that should due to the NULL corresponding to 0. For example, instead of having #ABTTCD@, where A, B, C and D are commands and T each of the bytes of time, Buffer vale #ABT or #AB depending on which of the time bytes is worth 0.

  • 1

    Can’t you configure to transfer the entire struct by size sizeof(Seustruct) instead of transferring to the NULL limiter? If you can, put the code of the section that you do the serial transfer, so we can see what you’re using and such.

  • I do not transfer until the NULL limiter, I have a variable (called Buffer) that stores what I will send by serial. Unwanted NULL placement prevents this Buffer variable from forming to the end. It is something as if the "[command3]" quoted in the question was not included due to the presence of NULL.

  • What function call of which library are you using to send bytes? What are your parameters?

  • 3

    WriteFile(hComm,Buffer,strlen(Buffer),&bytesEscritos,NULL); The shipping code is this. hComm is the serial settings variable, Buffer the unsigned char array I want to send, the third parameter is the array size, the fourth is the number of bytes written and the last is an overlapping configuration. The problem is that Buffer does not have the value it should have due to the NULL corresponding to 0. For example, instead of having #ABTTCD@, where A,B,C and D are commands and T each of the bytes of time, Buffer is worth #ABT or #AB depending on which of the bytes of time is worth 0.

  • There is the possibility to perform a check before executing the sending code and, if any parameter is null, replace its value with a valid one?

  • I thought about it, but the problem is when reading this parameter in the software that will receive this set of bytes. For example, if I identify the value 0 and replace it with 50 at the time of sending, at the time of receiving there is no way I know if this 50 was originally a 50 or a 0. I also thought of adding 1 in both bytes before sending and at the time of receiving subtract 1, which will fail if one of the bytes (or both) is equal to 255.

  • You can add one more variable in the upload function to do the control, or even implement a verification mechanism calculated on both sides based on the parameters to make sure all the information was sent and received lossless. It’s not the best solution, but it will work until you find another way.

  • @Thiagocavali I added your comment to the body of the question, changed the title and posted an answer. Take a look and say what you think.

Show 3 more comments

1 answer

1


Your problem is in the instruction you are using:

WriteFile(hComm,Buffer,strlen(Buffer),&bytesEscritos,NULL);

Note that the strlen will return the size to the first byte with zero value and that’s where your problem is. Do not use strlen to do this! You need to use another way to measure the size of what you want to send, something that can accept 0 values within your Buffer.

The way to measure the size probably consists of the sum of the size of each of the terms, where a term can be a header, a command or a Union element. It seems to me that the header and the command always has the size 1 (sizeof(unsigned char)) and Union always has size 2 (sizeof(temp)). Just add it all up.

Obviously, if what you send at this point is always in the format #ABTTCD@, where A, B, C, D and each of the T has exactly one byte, it seems trivial to me to define that the value of the third parameter should always be 8.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.