Please tell me how to convert from HEX to characters

I'm reading a file in .txt format from a memory card. Inside the file there is the number 5. The module returns the contents of the file in hex format. My number 5 turns into 35. How can I fix the code so that it displays normally?



String mystr="";

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);





 
}

void loop() {
  if (Serial.available()) {      // If anything comes in Serial (USB),
    Serial1.write(Serial.read());   // read it and send it out Serial1
  }

  if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1)
  mystr += (char)Serial1.read();    
  
  }
  Serial.print(mystr);   // read it and send it out Serial (USB)
}

I don't see that in the sketch that you posted

I am using the command AT+AR/02test/03text.txt
02test is the folder name and 03text is a text file. I send to the port and in response the module sends the contents of the file that it read.

Which module is that ?

BT201 module
But the issue here is probably not in the module itself. The question is how to return normal values ​​in the form of symbols.

it depends on the method you using to read a text from the file.
Could you provide a real code example rather than such pseudo-code as in your first comment?

1 Like

But this is the real code. I am sending the command AT+AR/02test/03text.txt to the serial port. The module reads the command and sends a response to the request. The response comes to the serial port. I don't do anything extra.

How do you expecting to convert a multichar string like "1234" to the integer 1234, if you process a single char at the time?
I think you should start from "Serial input basics" tutorial at the forum.

1 Like

Probably if I had known, I wouldn’t have asked how :slight_smile: That’s the point :slight_smile: I asked for help with the code.

I changed the code. The value is stored in a string. Is it possible to get a character from a string containing a hex value? Is it possible to convert somehow?

I presume that you mean that you have changed the code in your original post. This is considered bad manners because any comments made about the post as it was do not now make sense

Please never do that again. If you change code in future please post the new version in a reply to the topic

Character strings contain binary values. HEX is a human readable representation of binary values, as is decimal.

If the binary value represents an ASCII character, you can print it, like this,

byte value = 65;  // decimal value for ASCII character 'A'
Serial.write(value); //print the A on the serial monitor.

or as a HEX value, like this:

Serial.println(value, HEX);

or as a decimal value, like this:

Serial.println(value, DEC);

How about posting that file here? Attach it so we can see any strange characters and line endings. So we can see what you're talking about.
How about posting details of what is the content of that file. E.g. the first two characters represent the length of the line, the next four characters are a checksum and the remainder is the data.

If it is indeed hex data, you can read two bytes and convert them. The below example demonstrates the conversion from 2 characters to an ascii character.

// simulation of received data
char fileContent[32];
// two characters from fileContent plus terminator ('\0')
char hexText2[3];
// the ascii character that those two characters represent
char asciiChar;

void setup()
{
  Serial.begin(115200);

  // create some simulated file content
  strcpy(fileContent, "31323334"); // hex 1234

  // needs to be an even number
  if (strlen(fileContent) % 2 != 0)
  {
    Serial.println("Even number of character expected");
    for (;;);
  }

  // process two characters at a time
  for (uint8_t cnt = 0; cnt < strlen(fileContent); cnt += 2)
  {
    // collect two characters from input
    hexText2[0] = fileContent[cnt];
    hexText2[1] = fileContent[cnt + 1];

    Serial.print("hexText2 = ");
    Serial.println(hexText2);

    // convert
    if (convert() == true)
    {
      Serial.print("asciiChar = '");
      Serial.print(asciiChar);
      Serial.println("'");
    }
  }
}

void loop()
{
  // put your main code here, to run repeatedly:

}

/*
   Convert text representing a hex value to char
   Returns:
     true on success, else false
*/
bool convert()
{
  char *endptr;

  asciiChar = strtoul(hexText2, &endptr, 16);
  if (endptr == hexText2)
  {
    Serial.println("No hex digits found in hexText2");
    return false;
  }
  if (*endptr != '\0')
  {
    Serial.println("Additional characters detected");
    return false;
  }
  return true;
}
1 Like

03text.txt (1 Byte)

2
3


Test text. It’s just the number 5. If I manage to convert from HEX to a symbol, then I already think I’ll understand how to proceed. In fact, I don’t plan to store anything other than numbers in the text book. This number will indicate the number of tracks in the folder so that later I can make random playback of tracks in the folder.

I'll try to understand your examples but they look huge of course. I thought there was an easier way.

The HEX representation of binary value for the ASCII character for the digit 5 is 35.

These three lines of code all store the same binary value:

char c = 0x35;  //hexadecimal representaton
char d = '5';  //ASCII representation
char e = 53; //decimal representation
1 Like

The text symbol is in ASCII code where in hex '0' is 0x30.
If I read text '5' I get the value by '5' - '0'.
Your compiler sees 'symbol' as the ASCII value.

If I have a variable
byte myDigit =7; // digits are only 0 to 9!
To convert to text symbol, textDigit = '0' + myDigit, will be 0x37!

Making binary juman readable is a study in itself! The compiler helps! In decimall numbers begin at 48 (hex 30) , uppercase alphas start at 65 (hex 41) and lowercase starts at 97 (hex 61).
With the compiler, hex 30 is '0', 41 is 'A' and 61 is 'a', no table needed.

When you edited the code you posted, changing the original

by adding a global variable

and some minor changes

Those comments add very little. Readers here can clearly see the if and the Serial.read and the Serial1.write, etc. (Thanks for posting as <CODE/>) There's no need to say those parts, they are very basic, and the structure is simple. The only additional info added is what each serial is connected to, and just barely: the USB and pins 0&1. It's not obvious which one is printing the 35 OK in your screen shot.

If you're actually using the code as edited to produce the output in that screen shot: since you moved Serial.print out of the if-block, it'd guess it's not that one, since it would print repeatedly with every iteration of the loop function. IOW, best case: 55555555555555555555555. If mystr starts out as an empty String, then repeatedly printing an empty string has no visible effect, and that would not be an issue. However, that is the part of the code you tried to fix.

Who is printing the OK? Can you control that? What Board are you using?

If the screenshot is the result of the Serial1.write, then write generally has two kinds of variants

  • a number
    • write(uint8_t)
    • write(int
    • write(unsigned int)
    • etc
  • an array or buffer
    • write(const char *) -- write a C-string, an array of zero or more char terminated by a NUL
    • write(uint8_t *buf, size_t len)

read in fact returns an int: the unsigned character value (zero or greater) or -1 if no character is available. The fact that you just called available is irrelevant: you should never receive -1, but it's still a number.

So maybe, for whatever reason, if you pass a number, it outputs that number in hex (and OK)? Does Serial1 have print? You can try to force the character array variant of write

  Serial1.write(String((char) Serial.read()).c_str());

If that giant hack works, it can be explained and refined.

If not, then it was just a guess based on limited information.

For your own sake with Arduino, don't use C++ String.
Use C char array string.

In a small memory environment, String is a bad Idea. There have been 100's of threads, long threads covering this. ALL C++ Container Classes are fat troublemakers on small machines.