How to save HEX array to String?

Hello everybody,

I am receiving a HEX command from the UART, and debuging with softwareSerial and PC, the teraterm terminal output it looks like this:
image

This is the piece of code that I am using to receive data and to send to the softwareSerial for debuging:

void loop() { // run over and over
uint8_t bufer[16];
int i;
i=0;

  if ( Serial.available() ) {
   bufer[i]=Serial.read();
   int incomingByte = bufer[i];
   if (incomingByte<10) mySerial.print ("0");
   mySerial.print(incomingByte,HEX);
   mySerial.print(' ');
   i++;
  }

}

My question is, how can I save the received data into a String in the same way that the teraterm terminal shows in the screen?
I'll like to put ... " mySerial.print(string);" ... and get:
image

Thanks in advance!

What can you do with the string that you can not do with the buffer contents? Apart from printing, which you can already do?

Are you sure you need the overhead and the fragility of the String class? What is this application about? What is the big picture?

Probably does not even need a C string.

@anon57585045 , @330R
I want to read the string with "char.at", and compare with some results, in this way:

void readSerialPort(){ 

   if (SerialInputString.charAt (0) == '0' && SerialInputString.charAt(1) == '1' && SerialInputString.charAt(2) == ...'){
    //...Do Something
      }
    

Ouch, that is a really pedestrian and inefficient way to do it.

Instead, compare the input buffer with a constant array, using strcmp(). No conversion to hex necessary...
If the buffers are fixed length with no terminating null, use memcmp().

@anon57585045 please could you give me an example?

Before we go down that road, how does your program know when the received message is complete?

c has a good set of functions for operating on char arrays. strtok() (not such a great page) is especially interesting

Your program is broken. The buffer is not being filled. You increment the index 'i' and then immediately reset it to zero every time through loop().

The only reason it has the appearance of working, is that it can just print any incoming characters.

To compare the input string with anything, it has to have a defined start and end. That is the case, no matter if you use Strings, C strings or any other kind of data representation.

It´s master-slave comunication over uart in one wire configuration. My arduino is the master, so I send a modbus request, in this case are the first 8 bytes of the received frame. Because in this configuration the Rx and Tx are together with a little circuitery attached, when you transmit data, you receive this data first and then the response data from the slave component.

If I send:
0x01 (ID)
0x03 (read)
0x88 and 0xB8 (coil)
0x00 and 0x01 (1 register request)
0x2F and 8F (CRC16 RTU checksum)

I get this response:

First, i receive the same that I sent: 0x01 0x03 0x88 0xB8 0x01 0x2F 0x8F
and then I receive the answer from the slave:
0x01 (ID)
0x03(read)
0x02(number of bytes of the answer)
0x04 and 0xE2 (answer)
0x3A and 0xCD (checksum, CRC16)

Then you need to decode the received packet to obtain the length, read only read that number of bytes. Or, if you want to dumb it down a lot, you can just read a fixed number of bytes.

Consult Technical Manual of your remote UART device (from which you are receiving data) to see the format in which the device is putting a data frame on its UART Port.

You can post a link to that device/manual so that we can also check.

is in reply #11. I agree that more info would be nice. It would answer the question, "are the same number of bytes always sent?". But the problem here is more related to serial receive code.

Another big mystery... What is the usefulness of comparing an entire frame? Usually the payload ('answer') is the only data that really means anything.

Maybe this, then. Same thing as the output of

$ man 3 strtok

No improvements in parsing can help a program that can't assemble an input string correctly.

Store received characters as hex in a String. Timeout: 1000 milliseconds.

void loop()   // run over and over
{
  static String inputString;
  static unsigned long lastCharArrivalTime = 0;

  if (Serial.available())
  {
    byte incomingByte = Serial.read();
    inputString += "0123456789ABCDEF"[incomingByte / 16];
    inputString += "0123456789ABCDEF"[incomingByte % 16];
    inputString += ' ';
    lastCharArrivalTime = millis();
  }

  if (lastCharArrivalTime != 0
      && millis() - lastCharArrivalTime >= 1000)
  {
    // Timeout.  One second since last character arrived.
    // PROCESS inputString NOW
    Serial.println(inputString);

    // Done with inputString. Reset for next message.
    inputString = "";
    lastCharArrivalTime = 0;
  }
}
2 Likes

Right answer, wrong problem. IMHO.

@johnwasser Thanks a lot, it worked as expected!.
Please, could you explain me what is the purpose of these two lines in your code:

 inputString += "0123456789ABCDEF"[incomingByte / 16];
 inputString += "0123456789ABCDEF"[incomingByte % 16];

Each line converts half of a byte into a character and appends that character to the input string.