Serial.read into unsigned char. What's the ways?

Hello guys.
I basically sending a Strings over bluetooth in this format it's all HEX. FFF001122334455667788

I do have working code but it's a bit slow. So I thing there should be other ways to get Strings into Char array and first 3 bytes of incoming data into INT. What I want is basically avoid using Strings. and get more faster in data transfer... So I need absolutely the same what my code does but do it via no String.
What can I do about? Thanks.

unsigned char writeBuf[8];

void setup() {

    Serial.begin(115200);
    Serial.setTimeout(200);
    Serial2.begin(57600);
     Serial2.setTimeout(200);
}

void loop() 
{


 if(Serial2.available()>0)
       {

            String Str = Serial2.readString();
           
      //      Serial.print(Str);
      //      Serial.println("   ");

                String GetID = Str.substring(0,3);

                byte a = digit_to_binary(GetID[0]);
                byte b = digit_to_binary(GetID[1]);
                byte c = digit_to_binary(GetID[2]);

               int SendID = a * 256 + b * 16 + c;

   //     Serial.print(SendID, HEX);
   //     Serial.print("   ");

              ///////////////////////////////////////////////////////
                int z = 0;
                for (int i = 3; i < Str.length()+3; i += 2) {
            
               String  DATA = Str.substring(i, i + 2);
            
                  byte A =  digit_to_binary(DATA[0]);
                  byte B =  digit_to_binary(DATA[1]);
            
                  // Put the two digits together into a byte
                  byte ds = A * 16 + B;
            
                  writeBuf[z++] = ds;
                }
}

byte digit_to_binary(char a){
   // Convert  digit to binary

  if ( 'A' <= a && a <= 'F') {
        return a - 'A' + 10;
      } else if ( 'a' <= a && a <= 'f') {
        return a - 'a' + 10;
      } else if ( '0' <= a && a <= '9') {
        return a - '0';
      } else {
        return a=0;  // Invalid digit
      } 
}
.....

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. The second example is probably most relevant for you.

After you have received the characters would you can convert them to whatever you want.

Note that it is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

Do you have control over the format? If you are basically sending ints, I would contemplate a complete redesign. Hex is not a bad idea, but I would use delimiters in the string to make the decoding easier. There are a number of string parsing functions in C, such as strtok() that can do that.

aarg:
Do you have control over the format?

I do but to keep it simple and not change anything on sending said it's android app. I got to keep it same.

Robin2. Good job! It has been done long time ago ah?

How do you protect against errors (junk data)?

But I would at least include a delimiter or a start so you actually KNOW where in the data you are.

aarg:
How do you protect against errors (junk data)?

ha ha! Only if Im sanding data after wait 200 milisec. That's way it makes it a bit slow. I have to redesign!

septillion:
But I would at least include a delimiter or a start so you actually KNOW where in the data you are.

That would probably be a

Slavka85:
ha ha! Only if Im sanding data after wait 200 milisec. That's way it makes it a bit slow. I have to redesign!

You lost me. I'm not familiar with that method of error detection. Anyway, it's possible to implement your method with cstrings as mentioned above. It's just not the way I would do it.

The problem of sending binary data in 7 bit ASCII is a very old one, with many solutions.

aarg:
You lost me. I'm not familiar with that method of error detection.

Basically Serail.readString() will wait 200 milliseconds from the first char. on incoming data. after it the Str become new.

Slavka85:
Basically Serail.readString() will wait 200 milliseconds from the first char. on incoming data. after it the Str become new.

That sounds weird. Are you saying that your data is not even terminated with a new line (\n)?

Actually terminated!

mmOutStream.write(income.getBytes());
mmOutStream.write(13);
mmOutStream.write(10);

But Arduino code ain't look for it! Need to add...

Ok thanks to Robin2 I come with flowing code.

Could you please check what might have I forgot. General mistakes and improvments. For me seems it works.

app sends: mmOutStream.write(income.getBytes());
mmOutStream.write('\n');

And is there any other ways?

const byte numChars = 20;
char receivedChars[numChars];   // an array to store the received data

unsigned char writeBuf[8];

boolean newData = false;

void setup() {

    Serial.begin(115200);
    Serial.setTimeout(200);
    Serial2.begin(57600);
     Serial2.setTimeout(200);
}
void loop() {


    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (Serial2.available() > 0 && newData == false) {
        rc = Serial2.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }

     if (newData == true) {

        for(int i=0; i<numChars; i++)
                {
                  /*
                  if( writeBuf[i]<=15)
                    {
                    Serial.print("0");
                    }
                    */
                  Serial.print (receivedChars[i]);
                  Serial.print(" ");
                }
                Serial.println("  ");
                newData = false;


                byte a = digit_to_binary(receivedChars[0]);
                byte b = digit_to_binary(receivedChars[1]);
                byte c = digit_to_binary(receivedChars[2]);

               int SendID = a * 256 + b * 16 + c;

               Serial.print(SendID, HEX);
               Serial.print("   ");

  ///////////////////////////////////////////////////////
                int z = 0;
                for (int i = 3; i < numChars; i += 2) {
            
          //     String  DATA = receivedChars.substring(i, i + 2);
               
            
                  byte A =  digit_to_binary(receivedChars[i]);
                  byte B =  digit_to_binary(receivedChars[i+1]);
            
                  // Put the two digits together into a byte
                  byte ds = A * 16 + B;
            
                  writeBuf[z++] = ds;
                }
 ////////////////////////////////////////////////////////////////


 
               for(int i=0; i<8; i++)
                {
                  if( writeBuf[i]<=15)
                    {
                    Serial.print("0");
                    }
                  Serial.print (writeBuf[i],HEX);
                  Serial.print(" ");
                }
                Serial.println("  ");

               
     }   
}

Slavka85:
Could you please check what might have I forgot.

Why have you removed all the functions from my example?

Just copy my example into your program and write your own function to operate when a new message arrives (newData = true)

...R