How To Write Text File Data As Hexadecimal Numbers

Im using Arduino Uno with RFID Reader and SD card components. I'm trying to send my SD card text file contents to a laptop via serial port. The laptop will receive my data as ASCII characters

I have a text file with data made out of "0,1,2..9, A, B, C...F" characters. This text file contains RFID IDs in Hexadecimal form

4F5C23AA
5AFF0123
566777CC

and I want to write my text file content as hexadecimal numbers to the serial port

Serial.write(0x0Z) // Z in here should be every data in text file

// For example :
Serial.write(0x04);
Serial.write(0x0F);
Serial.write(0x05);
// I want to write all text file content

How can I achieve this in a loop?

Before we get into that, how will the device on the other end of the serial react to what you want to send?

Please explain exactly what you want to do. It would be best to explain why, because "something like this" suggests that you don't yet quite understand the goal.

The device on the other hand is a laptop. My Arduino Uno and Laptop communicate through a port. So the laptop takes the ASCII equivalent of what I send. It will convert it via c# function and write it to the web app.

ok you are right i should modify my post

you need to parse the text file to read the bytes and then write the bytes out.

if the RFID is only 4 bytes long, you could use strtoul()

const char * rfids[] = {"4F5C23AA", "5AFF0123", "566777CC"};
const byte count = sizeof rfids / sizeof * rfids;

void setup() {
  Serial.begin(115200);
  Serial.println("------------------");
  // or traditional for loop
  for (byte i = 0; i < count; i++) {
    unsigned long r = strtoul (rfids[i], nullptr, 16);
    Serial.print("I read 0x"); Serial.println(r, HEX);
  }
  Serial.println("------------------");
  // or if you want to use the fancy range based for loop
  for (auto &&id : rfids) {
    unsigned long r = strtoul (id, nullptr, 16);
    Serial.print("I read 0x"); Serial.println(r, HEX);
  }
}

void loop() {}

now the actual bytes are in memory (little endian format) so you can send them out if you want to.

sscanf() or fscanf() would also be able to parse an hex number from a string (or file for fscanf)

EDIT: now you modified your first post so my answer and work does not make any sense. Good luck.

You are sending x'00 through x'of to the PC. What ASCII equivalent are you referring to?

so you have ASCII in the text file and you want to dump it to Serial? just read the bytes (they will be ascii) and write them out ... nothing special is required

PS: now that you modified your first post so my previous answer and work does not make any sense. so Good luck.

I might be used the wrong technical terms.
For example if I send

Serial.write(0x05);
Serial.write(0x45);
Serial.write(0x0A);

The computer will receive them as

5,45,10

Send the ASCII instead, character by character, straight from the text file. As previously suggested.

Eh, this is my first post so I definitely mess it up :). thnx nonetheless

No, the computer will receive then EXACTLY as you have sent them. You are looking at them after they have been massaged by your program.

Is this what you want to achieve as serial out- and input?

------------------
0x04
0x0F
0x05
0x0C
0x02
0x03
0x0A
0x0A
------------------
0x05
0x0A
0x0F
0x0F
0x00
0x01
0x02
0x03
------------------
0x05
0x06
0x06
0x07
0x07
0x07
0x0C
0x0C
------------------

This sketch does it:

const String rfid[] = {"4F5C23AA", "5AFF0123", "566777CC"};
const byte count = sizeof rfid / sizeof rfid[0];

void setup() {
  Serial.begin(115200);
  Serial.println("------------------");
  // traditional for loops
  for (byte i = 0; i < count; i++) {
    for (byte j=0; j< rfid[i].length();j++){
      Serial.print("0x0");
      Serial.println(rfid[i][j]);
    }
  if (i < count-1) Serial.println("------------------");
  };     
  Serial.println("------------------");
}

void loop() {}

Just guesswork ...

(Thanks to @J-M-L! Just "borrowed" and modified your sketch slightly ... :wink: )

I want to write text file characters as hexadecimal numbers

This post is a redo of my previous poorly asked question maybe it will help somebody. Anyway...

I have arduino uno with RFID-RC522 reader and SD card components. I'm reading a text file from my SD card. This text file contains card IDs in hexadecimal form and it only consists characters of " 0,1,2,...,8,9,A,B,C...F ". My text file looks like this

4CFB33DA
998877AA
7DCAB1A9
8D6F0503
AFD234FA

On the other end of the arduino there is a laptop. Arduino chip and laptop communicates through a serial port. Arduino send these text file's contents with the code below

myFile = SD.open("myFile.txt"); // pretty basic file reading
      if (myFile) {
        while (myFile.available()) {
           Serial.write(myFile.read()); // basic serial write
         // Serial.write("0x0"+myFile.read()) // I tried this but it sends nonsense
        }
        myFile.close();

How my laptop recieve what i sent? If I send

Serial.write(0x05);
Serial.write(0x0A);
Serial.write(0x09);
Serial.write(0x04); //...

Laptop will recieve them as

5,10,9,4...

I want arduino to send the text file characters as hexadecimal numbers dynamically. Like :

Serial.write(0x04);
Serial.write(0x0C);
Serial.write(0x0F);
Serial.write(0x0B); // ... all the text file 

How can I do this? Do i need to convert file contents? or should i use a loop?

Why?

I couldn't quite explain my goal. Thats why :slight_smile:

You want to convert each binary 8 bit byte of data to a pair of 7-bit ASCII characters.
Ok, so you have to isolate each nibble (4 bits) of the byte and then convert each nibble to the corresponding ASCII char for transmission.

String hex2A(int valu)
{
int msn = ( valu & 0b11110000 );  // isolate MSN
msn >> 4;  // shift right
int lsn = ( valu & 0b00001111 );  // No shift needed on bottom nibble

if (msn > 9) msn = msn +7;  // bump A-F into that part of ASCII
msn = msn + int("0");  // Add ASCII offset
//
if (lsn > 9) lsn = lsn +7;   // Ditto for LSN
lsn = lsn + int("0");
//
return (String(msn, 0) + String(lsn, 0) );
}

That should work.

If you call it with one byte it should return a two character string ready to print to the serial port.

int byte1 = 0x0e;
Serial.println("Raw: " + String(byte1) );
Serial.println("Easy using String: " + String(byte1, HEX) );
Serial.println( "ASCII: " + hex2A(byte1) );

That should print "0E" instead of some garbage symbol.

use sprintf()?, e.g.

int main(void) {
  char data[]={"4CFB33DA"};
  for (int i=0;i<sizeof(data);i++) {
    char text[50]={0};
    sprintf(text,"%#02x\n",data[i]);
    printf("%s",text);
  }
}

prints

0x34
0x43
0x46
0x42
0x33
0x33
0x44
0x41
00

Hi @AmogusFloppa. I appreciate you making the effort to reference the previous topic when you created a new one on the subject. However, I still feel that there is no need to have two separate topics on the identical subject, and that having two risks confusion and wasted time caused by parallel discussions. For that reason I have merged the two topics into one.

Regards, Per

ok thanks

1 Like