[Gelöst] UID vom RFID auslesen

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Ich möchte gerne die UID eines RFID-Chips auslesen und weiter verarbeiten.

    Leider klappt das nicht so, wie ich möchte, weshalb ich mal hier nachfrage.

    Ich habe meinen Raspberry Pi mit Arduino IDE, an dem habe ich einen Arduino Nano (?) und einen Kartenleser mit PN532-Chip per Software-Serial angeklemmt.

    Einen passenden Beispielcode habe ich auch schon gefunden, das funktioniert auch soweit, nur bekomme ich die UID nicht rausgequetscht, damit ich sie weiter verarbeiten kann.

    Naiv wie ich bin, dachte ich, ich könnte eine einfache if-Abfrage ab Zeile 75 machen, nach dem Motto if (uid) == ("12ABC789"){, dann digitalWrite(13, HIGH); oder so, das klappt aber nicht.

    Ausgabe auf dem seriellen Monitor sieht so aus, aber Abfragen enden bei mir im Chaos.

    Code
    Starte Programm ...
    RFID gefunden:32
    Firmware ver. 1.6
    Warte auf ISO14443A Karte ...
    UID Länge: 4 bytes
    UID: 12ABC789

    Der Beispielcode:

    Kann mir da jemand auf die Sprünge helfen ? :helpnew:

  • Go to Best Answer
  • UID-Länge ist 4 Bytes - das heißt, die ID ist als 4-Byte Zahl gespeichert, nicht als String. Der Vergleich müsste dann gehen mit


    if (uid == 0x12ABC789) {...}


    Wäre zumindest meine Vermutung.


    Außerdem ist deine Klammersetzung falsch, wenn ich mich nicht irre. Es müsste heißen:


    if (uid == "12ABC789") {...}

    nicht

    if (uid) == ("12ABC789") {...}

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    • Best Answer
    Code
    #include <string.h>
    
    uint8_t code[4] = { 0x12, 0xAB, 0xC7, 0x89 } ;
    uidLength = 4 ;
    
    if( memcmp(uid,code,uidLength) == 0 )
    {
       Serial.println( "passt" ) ;
    }

    Bei nur 4 Bytes kannst du auch den Inhalt von uid in einen uint32_t konvertieren und dann vergleichen:


    Code
    uint32_t value = (uid[0] << 24) | (uid[1] << 16) | (uid[2] << 8) | uid[3] ;
    
    if( value == 0x12ABC789u )
    {
       Serial.println( "passt" ) ;
    }

    Schau sicherheitshalber mal nach wie lang ein int auf deiner Plattform ist. Fuer diesen Vergleich braucht es einen 32 Bit int.

  • Ja prima, so klappt es. :bravo2: Hier nochmal der ganze Code, vielleicht hilft es ja dem ein oder anderen, der das gleiche Problem hat:

    Und die Ausgabe auf der seriellen Konsole, einmal mit dem richtigen Tag und einmal mit dem "falschen" Tag:

    Code
    Starte Programm ...
    Kein RFID-Modul gefunden !RFID gefunden:0
    Firmware ver. 0.0
    Warte auf ISO14443A Karte ...
    UID Länge: 4 bytes
    UID: 12ABC789
    Passende UID gefunden
    UID Länge: 4 bytes
    UID: 472A0CA
    Falsche UID

    Eine abschliessende Frage hätte ich dennoch.

    Wie kann man das als Liste machen, damit ich mehrere RFID-Chip mit unterschiedlichen UIDs nehmen kann ?

    :denker: Aber ich probiere es erst einmal selbst, vielleicht komme ich ja drauf. :danke_ATDE:

    Wie Frage ich nach Hilfe?

    Der despotische Bierbaron sagt: Kein Support per PN ! :angel::wink:

    Edited 2 times, last by fred0815: 30 Sekunden Verzögerung bei falscher UID eingebaut. ().

  • > Wie kann man das als Liste machen, damit ich mehrere RFID-Chip mit unterschiedlichen UIDs nehmen kann ?

    Wenn alle IDs gleich lang sind:


    Code
    uint8_t codes[2][4] = { { 0x12, 0xAB, 0xC7, 0x89 }, { 0x12, 0xAB, 0xC7, 0x8A } } ;
    
    Der Vergleich sieht dann so aus:
    
    if( memcmp(uid,codes[0],uidLength) == 0 )

    Wenn die IDs unterschiedlich lang sind: ein Array of Pointer to uint8_t.

  • Müssen denn die Vergleichswerte zwingend als Array von 4 x 1 Byte vorliegen? Bei memcmp wird doch der Speicher verglichen ausgehend vom ersten Element. Wenn man 0x12ABC789 hinterlegt, müsste das doch genauso gehen, oder?


    uint8_t codes[2] = {0x12ABC789, 0x12ABC78A} ;


    Und gibts nicht einfach ne Möglichkeit, eine unsigned-long-Variable zu erzeugen auf den Beginn der ID ( UID[0] ) zeigen zu lassen? C müsste das doch mit den Zeigern können. Dann könnte man es einfach vergleichen. So in der Art


    uint32_t *id = &UID[0];

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    Edited 5 times, last by Gnom ().

  • Vorsicht, solche Spielchen sind sehr heikel! Sie haengen von der Byte-Order des Prozessors ab. ( fred0815: lass besser die Finger davon)


    Ohne Typecast wird der Compiler motzen. Die "korrekte" Version sieht so aus:


    uint32_t *ptr = (uint32_t *)uid ;


    Wenn man sich aber schon die Muehe macht, holt man sich besser gleich den Wert:


    uint32_t value = *(uint32_t *)uid ;


    Das ist ziemlich undurchsichtig, so wird es ein bisschen klarer:


    uint32_t value ;


    memcpy( &value, uid, sizeof(uint32_t) ) ;


    Den value kann man dann direkt mit den erwarteten Werten vergleichen. Falls die Byte-Order nicht stimmt muss man dafuer die erwarteten Werte anpassen.