Decoding HEX data

Hi,
I’m currently trying to get an Arduino to decode HEX Data that it gets thru a serial connection.
I have 2 issues.
The first issue being that it doesn’t record all the data.

For exemple I’m sending this :

<FF735AFFFF748F6D80000000000000>

The arduino reads this with weird symbols at the end (or it could be my way of writing it to the serial monitor):

FF735AFFFF74808487000

I’m reading it with this Function :

void ReadSerial() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Wemos.available() > 0 && newData == false) {
        rc = Wemos.read();

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

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

Then i’m trying to find certain HEX codes in this hex Data

//Defining every Key hex code

#define PSB_SELECT      0x0001
#define PSB_L3          0x0002
#define PSB_R3          0x0004
#define PSB_START       0x0008
#define PSB_PAD_UP      0x0010
#define PSB_PAD_RIGHT   0x0020
#define PSB_PAD_DOWN    0x0040
#define PSB_PAD_LEFT    0x0080
#define PSB_L2          0x0100
#define PSB_R2          0x0200
#define PSB_L1          0x0400
#define PSB_R1          0x0800
#define PSB_GREEN       0x1000
#define PSB_RED         0x2000
#define PSB_BLUE        0x4000
#define PSB_PINK        0x8000
#define PSB_TRIANGLE    0x1000
#define PSB_CIRCLE      0x2000
#define PSB_CROSS       0x4000
#define PSB_SQUARE      0x8000

////These are analog buttons
//#define PSAB_PAD_RIGHT    9
//#define PSAB_PAD_UP      11
//#define PSAB_PAD_DOWN    12
//#define PSAB_PAD_LEFT    10
//#define PSAB_L2          19
//#define PSAB_R2          20
//#define PSAB_L1          17
//#define PSAB_R1          18
//#define PSAB_GREEN       13
//#define PSAB_RED         14
//#define PSAB_BLUE        15
//#define PSAB_PINK        16
//#define PSAB_TRIANGLE    13
//#define PSAB_CIRCLE      14
//#define PSAB_CROSS       15
//#define PSAB_SQUARE      16

//These are stick values
#define PSS_RX 5
#define PSS_RY 6
#define PSS_LX 7
#define PSS_LY 8

unsigned char GamePadData[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //where Hex Values are stored.

boolean Button(uint16_t button) { //IF button is pressed then Button(PSB_Key) is true.
  return ((~buttons & button) > 0);
}

buttons =  (uint16_t)(GamePadData[4] << 8) + GamePadData[3];

Is this the “right way” of doing it ?

Thanks a lot.

I’ve been struggling with this for a full week now, and don’t get it. I struggle with data types and serial.

The arduino reads this with weird symbols at the end (or it could be my way of writing it to the serial monitor):

unsigned char GamePadData[21]

Coincidence?

Please post your code

The way I write it to the monitor to debug is like this :

Serial.write(GamePadData,strlen(GamePadData));

Here is the complete code :

#include "UnoJoy.h"
#include <SoftwareSerial.h>

#define PSB_SELECT      0x0001
#define PSB_L3          0x0002
#define PSB_R3          0x0004
#define PSB_START       0x0008
#define PSB_PAD_UP      0x0010
#define PSB_PAD_RIGHT   0x0020
#define PSB_PAD_DOWN    0x0040
#define PSB_PAD_LEFT    0x0080
#define PSB_L2          0x0100
#define PSB_R2          0x0200
#define PSB_L1          0x0400
#define PSB_R1          0x0800
#define PSB_GREEN       0x1000
#define PSB_RED         0x2000
#define PSB_BLUE        0x4000
#define PSB_PINK        0x8000
#define PSB_TRIANGLE    0x1000
#define PSB_CIRCLE      0x2000
#define PSB_CROSS       0x4000
#define PSB_SQUARE      0x8000

////These are analog buttons
//#define PSAB_PAD_RIGHT    9
//#define PSAB_PAD_UP      11
//#define PSAB_PAD_DOWN    12
//#define PSAB_PAD_LEFT    10
//#define PSAB_L2          19
//#define PSAB_R2          20
//#define PSAB_L1          17
//#define PSAB_R1          18
//#define PSAB_GREEN       13
//#define PSAB_RED         14
//#define PSAB_BLUE        15
//#define PSAB_PINK        16
//#define PSAB_TRIANGLE    13
//#define PSAB_CIRCLE      14
//#define PSAB_CROSS       15
//#define PSAB_SQUARE      16

//These are stick values
#define PSS_RX 5
#define PSS_RY 6
#define PSS_LX 7
#define PSS_LY 8

SoftwareSerial Wemos (5, 6);

int error = 0;
byte type = 0;
byte vibrate = 0;
byte Packet[21];
unsigned int buttons = 0xFFFF;
boolean newData = false;
const byte numChars = 21;

unsigned char GamePadData[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

boolean Button(uint16_t button) {
  return ((~buttons & button) > 0);
}

byte GamePadAnalog(byte button) {
  return GamePadData[button];
}

void ReadSerial() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Wemos.available() > 0 && newData == false) {
        rc = Wemos.read();

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

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void setup() {
  setupUnoJoy();
  Serial.begin(9600);
  Wemos.begin(9600);
  delay(1000);
}

void loop() {
//  if (Wemos.available() > 21) {
//    for (int i = 0; i < 21; i++) {
//      Packet[i] = Wemos.read();
//    }
  //}
  ReadSerial();
  Serial.write(GamePadData,strlen(GamePadData));
  buttons =  (uint16_t)(GamePadData[4] << 8) + GamePadData[3];
  //Serial.println(buttons, HEX);

  // Always be getting fresh data
  //  dataForController_t controllerData = getControllerData();
  // setControllerData(controllerData);
  newData = false;
  //Serial.println(buttons, HEX);
}

  dataForController_t getControllerData(void){

  // Set up a place for our controller data
  //  Use the getBlankDataForController() function, since
  //  just declaring a fresh dataForController_t tends
  //  to get you one filled with junk from other, random
  //  values that were in those memory locations before
  dataForController_t controllerData = getBlankDataForController();
  // Since our buttons are all held high and
  //  pulled low when pressed, we use the "!"
  //  operator to invert the readings from the pins
  controllerData.triangleOn = !Button(PSB_TRIANGLE);
  controllerData.circleOn = !Button(PSB_CIRCLE);
  controllerData.squareOn = !Button(PSB_SQUARE);
  controllerData.crossOn = !Button(PSB_CROSS);
  controllerData.dpadUpOn = !Button(PSB_PAD_UP);
  controllerData.dpadDownOn = !Button(PSB_PAD_DOWN);
  controllerData.dpadLeftOn = !Button(PSB_PAD_LEFT);
  controllerData.dpadRightOn = !Button(PSB_PAD_RIGHT);
  controllerData.l1On = !Button(PSB_L1);
  controllerData.r1On = !Button(PSB_R1);
  controllerData.l2On = !Button(PSB_L2);
  controllerData.r2On = !Button(PSB_R2);
  controllerData.l3On = !Button(PSB_L3);
  controllerData.r3On = !Button(PSB_R3);
  controllerData.selectOn = !Button(PSB_SELECT);
  controllerData.startOn = !Button(PSB_START);

  // Set the analog sticks
  //  Since analogRead(pin) returns a 10 bit value,
  //  we need to perform a bit shift operation to
  //  lose the 2 least significant bits and get an
  //  8 bit number that we can use
  controllerData.leftStickX = GamePadAnalog (PSS_LX), DEC;
  controllerData.leftStickY = GamePadAnalog(PSS_LY), DEC;
  controllerData.rightStickX = GamePadAnalog(PSS_RX), DEC;
  controllerData.rightStickY = GamePadAnalog(PSS_RY), DEC;
  // And return the data!
  return controllerData;
  }

You're sending 30 characters to a 21 byte buffer and you've commented out the code that would have null terminated the result.

Like AWOL pointed out already, you say you are sending 30 characters and trying to receive them into an array that's only 21 characters long.

I think you made the code much too complicated. I suspect it can be much simpler.

Are 30 characters always sent, without exception? And the format/layout of that data is fixed, the same every time?

Yes, the characters are always sent, but it’s a 21 bytes array as well.

The one Printing serial is like this :

byte GamePadData[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

for (int i = 0; i < 21; i++) {
          //if(GamePadData[i] < 0x10) {Serial.print("0");}
          Serial.print(GamePadData[i], HEX);
          //Serial.print("::");
        }

Should i send it as bytes and not transcode it to HEX ?

I had commented the string termination bit to see if it changed something which it did not.

Is this a Type issue ?

I don't get it, i'm sending 21 characters but it writes 30 to the serial. Is it the conversion to HEX that adds characters ?

That’s not 21 characters

I know, but my original data is a 21 characters long array, that i'm sending. I don't know where the ending "0" come from.

You said

For exemple I’m sending this :

<FF735AFFFF748F6D80000000000000>

Which is it?

Ok, so basically i have this :

The sender sends this :

<FF735AFFFF748F6D80000000000000>

but it has this code :

byte GamePadData[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


 for (int i = 0; i < 21; i++) {
          //if(GamePadData[i] < 0x10) {Serial.print("0");}
          Serial.print(GamePadData[i], HEX);
          //Serial.print("::");
        }

So it should print a 21 characters long string right ?

This is Data from a controller, that I need to get back thru serial on the receiver Arduino.

It is based off this project :

but I need the Arduino Uno to act as usb interface because i can’t use python as it is used on this projet.

Sorry if i’m not really clear in my explaination, i’m kinda lost here.

Each byte can hold two hex digits so printing 21 bytes in HEX can produce between 21 and 42 characters.

BE WARNED that .print() does not add a leading '0' if your value is below 0x10. When displaying binary bytes in HEX it is traditional to send two digits for each byte so the boundaries between bytes are unambiguous.

Ok, so basically i have this :

No common ground unless those USB cables go to the same computer. Best to just link the grounds together.

Grumpy_Mike:
No common ground unless those USB cables go to the same computer. Best to just link the grounds together.

Sorry, this is just a basic representation, my arduino is actually powering the other one.

I noticed my HEX data aren't actually read as HEX but as single characters like F0 would be stored as Data[0] = F and Data[1] = 0.
How could i do it so that there is always a pair sent, and a pair received then ? Or process it aferward to rejoin pairs ? like a concatenation of Data[0] and Data[1] and so forth

if (value < 16)
  Serial.print ('0');
Serial.print (value, HEX);

for the sending side.
Always.

I uncommented this in my code after seeing the responses
if(GamePadData[i] < 0x10) {Serial.print("0");}.
That works right ?

yuukiflow:
That works right ?

You made the assertion; you tell us