[SOLVED] Data format from that device is a complete mystery to me

Hello, everyone

I feel like I miss something very profound and obvious, but can’t track it down. I have no idea how to get the RFID tag number. I have a reader (TX), I have a tag (sticker with a number is available), and a commercially available device (that gives the number on a sticker) for verification. Tags are for tagging animals on farms

What I’m trying to do is to get number from RX pin 17 on Mega2560 and pass it into COM in a form that is presented on a sticker

Code:







```
String hexString;

String decValue;

void setupcolor=#aaaaaa[/color] {
Serial.begincolor=#aaaaaa[/color];
Serial2.begincolor=#aaaaaa[/color]; Serial.printlncolor=#aaaaaa[/color];
}

void loopcolor=#aaaaaa[/color] {

if color=#aaaaaa[/color] { // If anything comes in Serial1 (pins 0 & 1)
hexString = Serial2.readStringcolor=#aaaaaa[/color]; // read it and send it out Serial (USB)

[b][color=#d35400]Serial[/color][/b][color=#aaaaaa].[/color][color=#d35400]println[/color][color=#aaaaaa]([/color][color=#d9d9d9]hexString[/color][color=#aaaaaa])[/color][color=#d9d9d9];[/color]

}
}
```

|

what I get is
72EC7EAB513820010000000000~⸮

what is it supposed to be
643093330066983

I found that, but printing with DEC argument doesn’t help

I thought that from serial I get ASCII, but converting to DEC doesn’t help. I only have to “decypher” 14 bytes on a left (except the very first one)

Weirdly enough, that piece of “documentation” with example doesn’t make any sense to me (I even checked with an online calculator)

Am I stupid or smthg?

Part of your issue I think is that the number from the tag is least significant byte first. Do that conversion and you will see something from the label.

can you elaborate on a function I should use? Or link to example
Thanx

At this point I suggest that you spend some time decoding it manually - I just typed the digits into a hex calculator and although the tag number appears, there was other stuff I haven't figured out yet.

I put it in a calculator, but I don't get anything resembling the label, what am I doing wrong?

very good that ypou posted the documentation of the serial interface it says

9600 baud 8N2. This is non-standard

standard is 8N1 but the serial interface can be configured for 8N2

you can find in in the reference
https://www.arduino.cc/reference/en/language/functions/communication/serial/begin/

so you could change

Serial2.begin(9600)

to

Serial2.begin(9600,SERIAL_8N2)

to see if it makes a difference

best regards Stefan

For "LSB" read "least significant character".

From the example:
card number decimal 250000023921 is in hex notation 3A3529A171
ASCII characters emitted by the reader: 171A9253A3
hex notation for above ASCII, (byte values) 31 37 31 41 39 32 35 33 41 33

Your "presumed" decimal number is 643093330066983
Which is 248E3D57EFE27 in hex notation.

When reversed, that has some similarity to the number you report reading. The difference could be explained by read errors, baud rate errors, your presumption is wrong or typos in your post.

StefanL38:
to see if it makes a difference

it didn't

Collect and post more examples, with different tags.

You got this: 72EC7EAB51382001 but it's LSB first so you have to reverse it.
Reversed, the first 10 characters are: 15BAE7CE27 which is decimal 93330066983 which is most of the tag number.

If you do the same thing with the country code you get 0643 which pretty much accounts for the rest.

mirasderbissalin:
it didn’t

Not really a surprise. The reader is sending two stop bits, you expect one but getting an extra one makes no difference, you’ll still pick up the next character when you see the start bit.

jremington:
When reversed, that has some similarity to the number you report reading. The difference could be explained by read errors, baud rate errors, your presumption is wrong or typos in your post.

I mean 4 out of 13 characters are the same, I don't think that is much of a lead, but I'll keep it in mind in the future
I verify readings with the commercially available reader, so it definitely the target I'm aiming at. Typos are excluded by copy-paste hotkeys. Read/baud errors are unlikely, those results are consistent

wildbill:
You got this: 72EC7EAB51382001 but it's LSB first so you have to reverse it.
Reversed, the first 10 characters are: 15BAE7CE27 which is decimal 93330066983 which is most of the tag number.

If you do the same thing with the country code you get 0643 which pretty much accounts for the rest.

Wow, that helps! Is there is a quick way to reverse it in code? Or only manually, so I can go from there?
Thank you for sticking with me

I pasted your string into a tiny sketch and used strrev. Since you are using String objects (not a very good idea on a small Arduino) you will need to get the bytes you want into a C string before you can use strrev.

Obviously you can do it by hand with a for loop instead.

wildbill:
Obviously you can do it by hand with a for loop instead.

Yeah, seems to be the way. Can you also lead me to how get 93330066983 from 15BAE7CE27 codewise? strtol not gonna fit, right?

strtol, no. How about strtoll though? Disclaimer: never used it myself.

Having 2 stop bits is only significant on the sending side! When receiving with 2 stop bits, it only means the transmission just takes longer to be received. On receive, there is no difference between 1 or 2 or even 10 stop bits. We are dealing with asynchronous transmission and there is never a timing problem BETWEEN characters.

Paul

Thank you, everyone!

I’m posting a working solution here, but warning - it’s garbage, perfectionist’s nightmare, for some glaring “inadequacies” I suspect there is a solution (for example how I dealt with “trash bytes”), for some - I’m not sure (the longest math of manual hex to dec conversion).

However, I want to save some time for the next poor soul trying to solve that since this forum helped me so much and garbage code is a bad excuse.

Edit: oh, the feeling of closing all the tabs…

String decString;
String decStringC;
String decStringT;


char hexArray [10];
char decArray [12];


char hexArrayC [3];
char decArrayC [3];


uint64_t tag;
uint64_t country;
byte tagI[12];


char flushChar;
char hexadecimal [16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
byte i = 0;
word HDindex[3];
uint64_t HDindex2[10];




void setup() {
  Serial.begin(9600);
  Serial2.begin(9600, SERIAL_8N2);
  Serial.println("Start");
}


void loop() {


  if (Serial2.available()) {
    if (i == 0) {
      flushChar = Serial2.read();
      i++;
    }
    else if (i < 11) {
      hexArray [10 - i] = Serial2.read();
      i++;
    }
    else if (i < 14) {
      hexArrayC [13 - i] = Serial2.read();
      i++;
    }
    else if (i == 29) {
      flushChar = Serial2.read();
      i = 0;
      goConvertC();
      goConvertT();
      if (decStringT.length() < 12){
        word loopzeros = 12 - decStringT.length();
        for (int lz = 0; lz < loopzeros; lz++){
          decStringT = '0' + decStringT;
        }
      }
      decString = decStringC  + decStringT;
      Serial.println (decString);
    }
    else {
      flushChar = Serial2.read();
      i++;
    }
  }
}


void goConvertC() {
  for (byte c = 0; c <= 2; c++) {
    for (byte cc = 0; cc <= 15; cc++) {
      if (hexArrayC[c] == hexadecimal[cc]) {
        HDindex[c] = cc;
        //Serial.println(HDindex);
        break;
      }
    }
  }
  country = HDindex[0] * 16 * 16 + HDindex[1] * 16 + HDindex[2];
  decStringC = uint64ToString(country);
}


void goConvertT() {
  for (byte c = 0; c <= 9; c++) {
    for (byte cc = 0; cc <= 15; cc++) {
      if (hexArray[c] == hexadecimal[cc]) {
        HDindex2[c] = cc;
        break;
      }
    }
  }
  
  tag = HDindex2[0] * 68719476736 + HDindex2[1] * 4294967296 + HDindex2[2] * 268435456 + HDindex2[3] * 16777216 + HDindex2[4] * 1048576  + HDindex2[5] * 65536 + HDindex2[6] * 4096 + HDindex2[7] * 256 + HDindex2[8] * 16 + HDindex2[9] ;
  decStringT = uint64ToString(tag);
  
}


String uint64ToString(uint64_t input) {
  String result = "";
  uint8_t base = 10;


  do {
    char c = input % base;
    input /= base;


    if (c < 10)
      c += '0';
    else
      c += 'A' - 10;
    result = c + result;
  } while (input);
  return result;
}