Gå til innhold

Trenger hjelp til omgjøring Hex, ascii og til decimal OPPDATERING: problemer med store tall


Anbefalte innlegg

Hei

Skjønner ikke helt manualen til RFID leseren min

Den skal lese øremerker for dyr. 

Får resultatet i ascii formen av HEX. Også må jeg gjøre det om til desimal.

 

Skal programmere det hele inn på en arduino. 

Kan noen forklare meg dette, helst med å vise hvordan de får tallet i decimal(bilde): 

post-101198-0-30005900-1570307334_thumb.jpg

 

Hele databladet: https://www.google.no/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwjD-qLe-oXlAhWBysQBHYFmAnYQFjAAegQIARAC&url=https%3A%2F%2Fforum.arduino.cc%2Findex.php%3Faction%3Ddlattach%3Btopic%3D516199.0%3Battach%3D236634&usg=AOvVaw0z4WsUYDdSfV-Re3XLMRH_

Endret av morgan_kane
Lenke til kommentar
Videoannonse
Annonse

Det var ikke særlig bra beskrevet i dokumentasjonen.

 

Vi liker hex fordi det er en enkel og grei måte å representere bytes på. En byte er typisk to tall/bokstaver fra 0x00 til 0xFF, som er 0 til 255 i vanlig desimaltall.

 

Hvis du har 31 37 31 og 41 (0x31, 0x37, 0x31, 0x41) så har du fire bytes, hvor mange bytes som utgir et nummer er beskrevet over det du tok utklipp av. ASCII har 1 byte per bokstav og ASCII-tabellen ser slik ut:

Dec Hex    Dec Hex    Dec Hex  Dec Hex  Dec Hex  Dec Hex   Dec Hex   Dec Hex  
  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p
  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q
  2 02 STX  18 12 DC2  34 22 "  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r
  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s
  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t
  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u
  6 06 ACK  22 16 SYN  38 26 &  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v
  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w
  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x
  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y
 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z
 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {
 12 0C FF   28 1C FS   44 2C ,  60 3C <  76 4C L  92 5C \  108 6C l  124 7C |
 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }
 14 0E SO   30 1E RS   46 2E .  62 3E >  78 4E N  94 5E ^  110 6E n  126 7E ~
 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL

Ikke helt relevant til det du driver med, men fortsatt greit å nevne:

Hvis du skal ha en 32-bit integer så tar du fire hex-bytes (8-bit hver) og slår sammen til ett nummer, så:

0x00 0x00 0x00 0x01 er et 32-bit nummer for 1

0xFF 0x00 0x00 0x00 er 4278190080

Gitt at vi snakker om MSB first, men det skal ikke være nødvendig å gå inn i, LSB er bare bytene flippet om.

 

Men over til databladet ditt!

 

Du har module output:

02 31 37 31 41 39 32 35 33 41 33 34 38 33 30 30 31 30 30 30 30 30 30 30 30 30 30 07 F8 03

 

Som skal mappes til:

Screenshot_20191005_225847.png

 

Vi jobber i bytes med mindre annet er angitt. Her er alt bytes, men noen skal oversettes til ASCII

Start number er 0x02

Card number er 0x31 0x37 0x31 0x41 0x39 0x32 0x35 0x33 0x41 0x33 som oversettes til ASCII ved hjelp av tabellen over: 171A9253A3 (nettside som oversetter for deg)

Country number er de neste 4 bytene: 0x34 0x38 0x33 0x30 som i ASCII er 4830 (datablad sier 483 :shrug:)

Data flag er 0x30, så ASCII 0

Animal flag er 0x31, så ASCII 1

Reserved-blokkene er alle bare fylt med ASCII 0

Så er det to bytes med checksum som IKKE skal være ASCII, men en XOR-checksum

og en 0x03 på slutten

 

Gi beskjed om jeg skal forklare XOR-checksumming også.

  • Liker 2
Lenke til kommentar

Er det bare kortnummeret du vil ha ut (250000023921)? Det er forholdsvis enkelt ettersom tekststrengen er organisert med LSB (least significant bit) først.

* Kall tekststrengen som inneholder hele beskjeden fra RFID-leseren rfidMessage
* Lag en variabel (int) som skal inneholde kortnummeret, som du kaller cardNumber, og setter til 0
* Gå gjennom de ti karakterene som utgjør kortnummeret med f.eks. en for-løkke der du bruker tellevariabelen i som skal gå fra og med 1 til og med 10.

Inne i for-løkken må du da for hver karakter gjøre følgende:

cardNumber += ( ( int )rfidMessage[i] - 48 ) << ( ( i-1 ) * 4 )

Forklaring:
- For å konvertere en enkelt karakter fra ascii til tall må du caste til int og trekke fra 48 (eller 0x30 hex)
- Ettersom teksten er organisert med LSB (least significant bit) først, og der hver karakter tilsvarer fire bits, må hver karakter etter den første skiftes henholdsvis 4, 8, 12 osv. bits mot venstre.

Hvis du bruker kalkulatoren i Windows/MacOS og setter den i programmer-mode kan du se hvordan hex-strengen 171A9253A3 blir til kortnnummeret. Velg hex (16-tall), og skriv inn strengen baklengs, dvs 3A3529A171, og slå over til desimal (10-tall), og se hva det blir til :)

Si fra om det er noe i forklaringen du ikke forstår. For å gjøre programmet ditt litt mer robust kan det lønne seg å kontrollere at første tegn i strengen er 0x02 samt å verifisere sjekksummen og den inverterte sjekksummen, men det er et hakk videre på stigen :)

Lenke til kommentar

Tusen takk for forklaring. dere skrev mye bra og fordøyer enda en god del :) Har nå forstått hvordan jeg gjør fra hex til decimal. Skjønte ikke først at jeg måtte snu den omvendt når jeg konverterte .

'

Men har et annet problem nå.

 

Jeg leser av 

 

2 57 48 48 70 50 65 65 66 70 51 50 52 50 48 48 49 48 48 49 48 48 48 48 48 48 48 12 61 29 3

fra chippen min. Dette er et øremerke for dyr. Jeg får ikke noen HEX jeg kan konvertere til decimal ut fra dette. 

Får dette: wHHpPeeepQPRPHHIHHIHHHHHHH fra ASCII tabellen :S

Endret av morgan_kane
Lenke til kommentar

Inne i for-løkken må du da for hver karakter gjøre følgende:

cardNumber += ( ( int )rfidMessage[i] - 48 ) << ( ( i-1 ) * 4 )

 

Eller bruke sprintf. :)

 

Tusen takk for forklaring. dere skrev mye bra og fordøyer enda en god del :) Har nå forstått hvordan jeg gjør fra hex til decimal. Skjønte ikke først at jeg måtte snu den omvendt når jeg konverterte .

'

Men har et annet problem nå.

 

Jeg leser av 

fra chippen min. Dette er et øremerke for dyr. Jeg får ikke noen HEX jeg kan konvertere til decimal ut fra dette. 

Får dette: wHHpPeeepQPRPHHIHHIHHHHHHH fra ASCII tabellen :S

 

Og det er en FDX-B tag du har?

Lenke til kommentar

Virker ut til å stemme ja. Og i koden så har du Serial.begin(9600, SERIAL_8N2);?

int messa;

void setup() {

  // put your setup code here, to run once:

Serial.begin(9600);

  Serial2.begin(9600);

 

  Serial.println("Start");

}

void loop() {

  // put your main code here, to run repeatedly:

 

   if (Serial2.available()>0)

  { messa= Serial2.read();

  if (messa !=0)

  {Serial.print(" ");

  Serial.print(messa);

   //Serial.print();

   messa=0;

  

   delay(200);}

 

   }

   else

   {}

  

   }

 

Har denne koden. Kjører den på en arduino MEga.

 

Hva betyr SERIAL_8N2?

 

Og en annen ting. Har kjør RFID modulen på 5 V. Testa den på 9V som spesifisert i datablad og da printer den hele tiden random greier.

Lenke til kommentar

Ah! Det er litt sent for meg nå. Du får selvsagt tallene ut i desimaler, ikke hex.

 

Bytt

Serial.print(messa);

med

Serial.print(messa, HEX);

Det kan stemme, sjekker med dyremerke iløpet av 2 min

 

EDIT: 2 39 30 30 46 32 41 41 42 46 33 32 34 32 30 30 31 30 30 31 30 30 30 30 30 30 30 7E 81 3

Tror dette kan stemme. Skal sjekke i forhold til dyreID som er påstemplet.

 

EDIT 2: det stemmer med påstemplet DyreID :D Tusen takk. 

 

Da skal jeg se om jeg får til en forløkke for å automatisere prosessen, men nå er det natt. Tusen takk igjen :D

Endret av morgan_kane
Lenke til kommentar

Inne i for-løkken må du da for hver karakter gjøre følgende:

cardNumber += ( ( int )rfidMessage[i] - 48 ) << ( ( i-1 ) * 4 )

 

Beklager, glem denne. Snarveien med å trekke fra 48 vil bare fungere så lenge det bare er tallene 0-9 du skal konvertere, jeg glemte i forbifarten at det var snakk om hex her.

Lenke til kommentar
  • 8 måneder senere...

hei

Dette prosjektet ble satt litt på pause på grunn av andre prosjekter. Holder nå på og sluttføre dette prosjektet og har støtt på et nytt problem.

Arduino takler ikke et 12bit nummer. Og jeg finner ingen måte og løse dette på. 

 

Jeg skal ha dette nummeret om til decimal: 3FBAA2F009

 unsigned long HexInDec( char message[], int beg, int len){
    unsigned long mult= 1; //setter opp formel for exponential for omgjøring hex dec
    unsigned long nbr=0;  //tallet som skal returneres til koden
    byte nextInt;
    unsigned long bignumber = 0;

    for(int i = beg; i< beg+len; i++){
      nextInt= message[i];
       if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    nbr = nbr + (mult * nextInt);
   
    mult = mult * 16;
    //Serial.println(nextInt);
  //  Serial.print(mult);

}
    
  }
  return nbr;
    
}

 

Edit, fikk det til ved hjelp av bignumber biblioteket. Men fikk problemer med å bruke modulo funksjonen der. 

Endret av morgan_kane
Lenke til kommentar
  • 1 måned senere...

Hvis du har mye minne ledig på arduino, kan du bruke "unsigned long long" data typen, den bruker 64-bit/8-byte med data plass.

unsigned long long xFromHex = 0LL;
{
byte *fillerPtr = (byte*)&xFromHex;
fillerPtr[0]=0x09;
fillerPtr[1]=0xF0;
fillerPtr[2]=0xA2;
fillerPtr[3]=0xBA;
fillerPtr[4]=0x3F;
}

 

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...