Forum: Mikrocontroller und Digitale Elektronik RFID per USB HID in windows übertragen.


von Marcel M. (hurrykane)


Lesenswert?

Hallo zusammen,

ich benötige mal eure Tipps wie ich vorgehen soll.

Ausgangslage.

Sprechanlage mit RFID Leser welcher nur über die Software Programmierbar 
ist in dem man sich auf der Sprechanlage einloggt und dann auf Lesen 
klickt. Danach Transponder vor Sprechanlage Code wird gelesen und in ein 
nebenstehendes Feld übernommen.

Nun das Problem: Man muss immer an der Sprechanlage sein um einen RFID 
Transponder anzulernen. MAcht wenig sinn bei 90 Wohnungen in einem 
Objekt und ein MIeter verliert einen.

Was ich vor habe. ICh möchte einen RFID Leser (habe ich vom Hersteller 
der sprechanlage bekommen) welcher per UART die Daten sendet gerne mit 
USB verbinden und die Hexadezimal Zahl direkt in windows wie eine 
Eingabe Übertragen. Das Feld in der Software habe ich bereits getestet, 
lässt eingaben zu. Somit müsste ich nicht Physisch bei der Sprechanlage 
sein.

Was bereits getestet wurde. Leser Funktioniert, angeschlossen an einen 
USB Serielwandler und mit Hterm ausgelesen. Baudrate wieviel Bits usw. 
habe i8ch beriets alles raus gefunden so das der Code auch korrekt ist.

Jetzt meine Idee:
Arduino Micro Pro mit dem Leser direkt verbinden. Meines wissens nach 
kann er ja HID.
Was muss ich beachten, bzw. muss ich machen?
Muss ich jetzt jede stelle in C umwandeln in die passende Windows 
Tastenzahl und diese dann übertragen?
Und kann ich abfragen ob eine RX signal empfangen wurde um den Schritt 
auszulösen?

Vielen Dank schon mal im Vorraus für eure Unterstützung.

P.s.: Ich weis es gibt zu haufe USB RFID Leser, aber die Lassen alle die 
Starbits weg was mir also nichts bringt.

von David G. (Firma: 10.08.1985) (follow2000)


Lesenswert?

Hi Marcel,

um das Problem zu lösen würde ich eine Software schreiben. Mir fällt das 
spontan Labview ein. In der Community Version Kostenlos. Ich denke vom 
Ablauf her willst du die ganzen RFID Chips erstmal nur alle über den 
Leser ziehen um sie in der Software der Gegensprechanlage schon mal drin 
zu haben, richtig?

Man kann sich den Leser über einen USB RS232 Wandler an den PC 
anschließen und LabVIEW liest ihn aus. Wenn ein RFID Chip gelesen wurde 
kann man die Eingabe (wie bei einer Tastatur) ins Programm eintippen 
lassen.

LabVIEW ist relativ einfach zu erlenen.

von Rahul D. (rahul)


Lesenswert?

Marcel M. schrieb:
> Das Feld in der Software habe ich bereits getestet,
> lässt eingaben zu. Somit müsste ich nicht Physisch bei der Sprechanlage
> sein.

Du kannst also die Sprechanlage über Windows (über LAN) konfigurieren?

Dann muss dein Arduino-RFID-Leser nur eine Tastatur emulieren (Dazu 
sollte es ein Beispiel geben; es ist kein Problem, mehrere Tasturen 
gleichzeitig an einen PC anzuschließen), der die RFID-ID in das Feld 
"eintippt".

von Marcel M. (hurrykane)


Lesenswert?

Danke für die Info.

Labview kenne ich natürlich. Aber hier bin ich nicht anwender sondern 
der Verwalter der Häuser. Wir reden nicht über ein paar Transponder.

Sondern jeder Transponder wird einmal an ein ABUS zugangssystem für 
Kellerräume angelert z.B. Heizung, Technik, Müllraum usw. Dann muss der 
selbe tranponder auch in die Sprechanlage.

ABUS hat einen USB RFID Leser welcher genau das macht was ich möchte, 
aber eben für das ABUS System als Misfare verschlüsselt.

Die Sprechanlage kann aber kein Misfare sondern lediglich die UID 
verarbeiten. Nehme ich also den Leser von ABUS klappt das bei der 
Sprechanlage leider nicht.

Wir reden hier über das Verwalten von über 10000 RFID Transponder 
tendendz steigend.

Also ziehl soll sein:
Leser in USB vom PC -> Feld in Sprechanlage mit der Maus anklicken -> 
Transponder vor Leser halten und Speichern.

von Marcel M. (hurrykane)


Lesenswert?

Rahul D. schrieb:
> Marcel M. schrieb:
>> Das Feld in der Software habe ich bereits getestet,
>> lässt eingaben zu. Somit müsste ich nicht Physisch bei der Sprechanlage
>> sein.
>
> Du kannst also die Sprechanlage über Windows (über LAN) konfigurieren?

Das ist korrekt.
Aktuell habe ich für eine Wohnungsbaugesellschafft ca. 20 Sprechanlagen 
Online die Sie aus der Ferne warten bzw. Namen Zugangsberechtigungen 
usw. einstellen können.

Darf ich annehmen das Du soetwas hier meinst?


#include "Keyboard.h"

void setup() {

  // open the serial port:

  Serial.begin(9600);

  // initialize control over the keyboard:

  Keyboard.begin();
}

void loop() {

  // check for incoming serial data:

  if (Serial.available() > 0) {

    // read incoming serial data:

    char inChar = Serial.read();

    // Type the next ASCII value from what you received:

    Keyboard.write(inChar + 1);

  }
}

: Bearbeitet durch User
von David G. (Firma: 10.08.1985) (follow2000)


Lesenswert?

Vielleicht ist das etwas für dich:
https://www.nfc-tag-shop.de/NFC-UID-Reader-ACR1281U-C2-schwarz-keyboard-emulation/68747

Ansonsten noch die Möglichkeit einen Arduino zu programmieren der die 
UID ausliest und per Tastatur Emulation raussendet.

Den kann man über eine Software auch noch konfigurieren.

: Bearbeitet durch User
von N. M. (mani)


Lesenswert?

Wenn du das bereits über UART lesen kannst, warum willst du dann 
überhaupt noch zusätzliche Hardware?

Ein Python Skript der den COM Port öffnet, die Daten konvertiert (falls 
notwendig) und dann wieder in dein Feld schreibt sollte doch genügen.

Gerade kurz ausprobiert PyAutoGUI oder ähnliche Libs können das.

von Marcel M. (hurrykane)


Lesenswert?

N. M. schrieb:
> Wenn du das bereits über UART lesen kannst, warum willst du dann
> überhaupt noch zusätzliche Hardware?
>
> Ein Python Skript der den COM Port öffnet, die Daten konvertiert (falls
> notwendig) und dann wieder in dein Feld schreibt sollte doch genügen.
>
> Gerade kurz ausprobiert PyAutoGUI oder ähnliche Libs können das.

Um es Anwenderfreundlich zu gestallten. Jeder soll es bedienen können 
und nichts start müssen. Einfach USB rein fertig.

von Marcel M. (hurrykane)


Lesenswert?

David G. schrieb:
> Ansonsten noch die Möglichkeit einen Arduino zu programmieren der die
> UID ausliest und per Tastatur Emulation raussendet.
>
> Den kann man über eine Software auch noch konfigurieren.

Ich denke ich werde das erstmal versuchen mit dem micro pro. Der kommt 
morgen an.

von David G. (Firma: 10.08.1985) (follow2000)


Lesenswert?

Darf man den Fragen um welche Technik/Anbieter von der Gegensprechanlage 
es sich handelt? Nur die UID zu lesen um sich damit evtl. Zugang zu 
verschaffen ist schon sehr bedenklich.

von Marcel M. (hurrykane)


Lesenswert?

David G. schrieb:
> Darf man den Fragen um welche Technik/Anbieter von der Gegensprechanlage
> es sich handelt? Nur die UID zu lesen um sich damit evtl. Zugang zu
> verschaffen ist schon sehr bedenklich.

Hast eine PN zwecks Hersteller.

Aber in Sachen Zugang, kann ich Euch beruhigen. Damit käme man höchstens 
ins Treppenhaus. Da ist dann schicht.

von Heinz R. (heijz)


Lesenswert?

wenn nur die UID genutzt wird und es jeder bedienen können soll - ich 
würde einen fertigen Leser kaufen

Die gibt es für unter 20 Euro

von Loco M. (loco)


Lesenswert?

Wie wäre es mit einem CH9329 als Serial Port to USB-HID Konverter.

Boards mit dem Chip gibt es für einen kleinen Taler bei den üblichen 
Verdächtigen: AliExpress, Ebay, Amazon ...

von Marcel M. (hurrykane)


Lesenswert?

Heinz R. schrieb:
> wenn nur die UID genutzt wird und es jeder bedienen können soll - ich
> würde einen fertigen Leser kaufen
>
> Die gibt es für unter 20 Euro

Kann Dich totschmeissen mit den Dingern. Das problem ist das manche die 
Startbits weglassen andere wiederrum die falsche Baudrate haben und 
somit die UID falsch ist die ausgegeben wird.

Und genau das ist mein Problem. nicht ein einziger Leser hat mir die UID 
ausgegeben die mir der Leser der Sprechanlage ausgibt.

von Marcel M. (hurrykane)


Lesenswert?

Loco M. schrieb:
> Wie wäre es mit einem CH9329 als Serial Port to USB-HID Konverter.
>
> Boards mit dem Chip gibt es für einen kleinen Taler bei den üblichen
> Verdächtigen: AliExpress, Ebay, Amazon ...

Wäre nen Versuch wert. Hab mir so nen Ding für morgen mal geordert. 
Werde berichten was er mir rausschmeißt.

von Hmmm (hmmm)


Lesenswert?

Marcel M. schrieb:
> Das problem ist das manche die
> Startbits weglassen

Sicher, dass Du weisst, was Startbits sind?

von Marcel M. (hurrykane)


Lesenswert?

Sorry, start ist hier irreführend, da hast Du recht.
Die ersten Bits der gelesenen UID lassen die reader die ich bisher 
getestet hatte weg und somit ist die UID zu kurz.

Startbit wäre hier ja Sinngemäß das Bit welches vorweg gesendet wird, 
dann die UID und dann das Stopbit oder 1,5 oder 2 je nach 
Anwendungsfall.

Sorry für die falsche Ausdrucksweise.

von N. M. (mani)


Lesenswert?

Marcel M. schrieb:
> Wäre nen Versuch wert. Hab mir so nen Ding für morgen mal geordert.
> Werde berichten was er mir rausschmeißt.

Wenn der RFID Leser nicht gerade ASCII rauswirft vermutlich das falsche.

von Rahul D. (rahul)


Lesenswert?

Marcel M. schrieb:
> Darf ich annehmen das Du soetwas hier meinst?
Vermutlich, aber ich bin bei dem Thema nicht tiefer drin.

von Marcel M. (hurrykane)


Lesenswert?

Also der CH9329 wird in Windows zwar ekannt wirft aber rein garnichts 
raus.
Nehme an, das er vermutlich ASCI erwartet. Da der RFID Leser aber Hex 
rausgibt wird das damit nicht klappen.

Also werde ich mich an den Micro Pro bzw. den Leonardo setzen müssen um 
das zu realisieren.

von Marcel M. (hurrykane)


Angehängte Dateien:

Lesenswert?

Bräuchte mal Eure Hilfe, stehe auf dem Schlauch, ist schon länger her 
mit dem C bei mir.

Ich bin zumindest schon mal soweit, das ich etwas auf dem PC ausgegeben 
bekomme.

Aber nicht das richtig. Habe mal ein Bild angehangen von HTherm.
Die Blaue Zeile will ich ausgelesen haben und so wie Sie da steht an 
Windows übertragen.

Aber in windows wird rB8wa ausgegeben.
Das ist die Erste Zeile ASCII Bit 5, 7, 8, 9, 11,
was ja folgendem in Hex enspricht:72, 42, 38, 77, 61,

Aber wie bekomme ich jetzt Bit 1, 2, 3, 4, 6, 10, 12 ebenfalls 
übermittelt.

Also irgendwo habe ich einen Denkfehler. Bitte um kleinen 
Gedankenanstoß.

#include <Keyboard.h>

void setup() {
  Serial1.begin(9600);    // Serieller Port für RFID
  Keyboard.begin();       // Start HID-Keyboard
}

void loop() {
  if (Serial1.available()) {
    String uid = "";
    while (Serial1.available()) {
      char c = Serial1.read();
      if (isPrintable(c)) {
        uid += c;
      }
      delay(5); // Kurze Pause zum Puffern
    }

    if (uid.length() > 0) {
      Keyboard.print(uid); // UID als Tastatureingabe senden
      Keyboard.press(KEY_RETURN); // Optional: Enter senden
      delay(100);
      Keyboard.releaseAll();
    }
  }

: Bearbeitet durch User
von Marcel M. (hurrykane)


Lesenswert?

So liebe Community,

ich bin zum Ziel gekommen. Und da es bestimmt mal den ein oder anderen 
gibt der es evtl. auch mal benötigen könnte kommt hier meine Lösung für 
die Nachwelt.

#include <Keyboard.h>

const int UID_LENGTH = 12; // UID Länge 12 Bit
byte uid[UID_LENGTH];
int index = 0;

void setup() {
  Serial1.begin(9600);   // RFID Leser (UART)
  Keyboard.begin();      // HID-Tastatur
}

void loop() {
  if (Serial1.available())
  {
    byte b = Serial1.read(); // Serielle Daten Lesen
    uid[index++] = b;

    if (index >= UID_LENGTH)
    {
      // UID vollständig empfangen, jetzt senden
      for (int i = 0; i < UID_LENGTH; i++)
      {
        if (uid[i] < 0x10) Keyboard.print("0");  // führende Null 
hinzufügen
        String hex = String(uid[i], HEX);
        hex.toUpperCase();
        delay(50);
        Keyboard.print(hex);
      }

      Keyboard.press(KEY_RETURN);  // optional: ENTER für neue Zeile, 
kann man auch weglassen.
      delay(100);
      Keyboard.releaseAll();

      index = 0;  // zurücksetzen
    }
  }
}

von N. M. (mani)


Lesenswert?

sprintf mit %X wäre auch gegangen.

von Marcel M. (hurrykane)


Lesenswert?

N. M. schrieb:
> sprintf mit %X wäre auch gegangen.

Stimmt hätte auch Funktioniert.

Habe aber gerade noch ein kleines Problem Festgestellt.

Spiele ich die Software auf den Arduiono klappt alles tippitoppi:

Er gibt dann folgendes raus was auch stimmt:
020C11047287423877806103

Ziehe ich den Arduino jetzt aus dem USB raus uns stecke ihn wieder ein 
klappt das auch soweit aber:

Er gibt dann das raus:
423877806103020C11047287

Genauer betrachte gibt er dann erst bit 7-12 raus und dann 1-6 dahinter

423877806103 Bit 7-12

020C11047287 Bit 1-6

Ne idee wie ich das noch auf kurzem weg lösen kann?

von Loco M. (loco)


Lesenswert?

Du müsstest mal einen weiteren Transponder einlesen und die Daten 
vergleichen, bzw. schauen ob die Bytes am Anfang und Ende immer 
dieselben sind.

Ich vermute, dass das erste Byte '0x02' und das letzte Byte '0x03' den 
Anfang und Ende des Telegramms kennzeichnen. Falls das stimmt, ist eine 
Möglichkeit die '02' im Buffer zu suchen und die Ausgabe dann ab dieser 
Stelle zu beginnen. Eine andere Möglichkeit ist, auf die '02' zu warten, 
und erst dann den Buffer zu füllen, z.B.
1
  if (Serial1.available())
2
  {
3
    byte b = Serial1.read(); // Serielle Daten Lesen
4
    if ((b == 0x02) || (index != 0)) {
5
      uid[index++] = b;
6
    }
7
    ...

PS: Bitte in deinen Beiträgen nicht 'Bit' schreiben, wenn Bytes gemeint 
sind. Das ist sonst sehr verwirrend.

: Bearbeitet durch User
von N. M. (mani)


Lesenswert?

Das mit der Länge ist allgemein Quatsch.
Wenn sich das Ding beim Einschalten irgendwas einfängt, dann ist das für 
alle Zeiten verrutscht.

Mach es mit Timeouts:
1
Gerät startet.
2
Alle Puffer Initial ablöschen. 
3
Zyklisch prüfen ob neue Zeichen dazu gekommen sind. 
4
Wenn 300ms keine neuen Zeichen gekommen sind, wird alles seither empfangene gesendet.

von Marcel M. (hurrykane)


Lesenswert?

N. M. schrieb:
> Das mit der Länge ist allgemein Quatsch.
> Wenn sich das Ding beim Einschalten irgendwas einfängt, dann ist das für
> alle Zeiten verrutscht.
>
> Mach es mit Timeouts:
>
1
> Gerät startet.
2
> Alle Puffer Initial ablöschen.
3
> Zyklisch prüfen ob neue Zeichen dazu gekommen sind.
4
> Wenn 300ms keine neuen Zeichen gekommen sind, wird alles seither 
5
> empfangene gesendet.
6
>

Du meinst so z.B.: ?

void setup()
{

  delay(500); // Leser gibt evtl. direkt
  Daten aus nach dem starten.

  while (Serial1.available())

  Serial1.read();  // UART leeren

  Serial1.begin(9600);
  Keyboard.begin();
}

von N. M. (mani)


Lesenswert?

Marcel M. schrieb:
> Du meinst so z.B.: ?

Nö.
So wartest du ja einfach 500ms und sendest einfach alles was du bis 
jetzt hast. Egal ob gerade noch neue Daten kommen oder nicht. Egal 
wieviel Daten es sind.

Eher so:
Immer wenn neue Zeichen dazu kommen merkst du dir den aktuellen 
Zeitpunkt (millis()). Wenn die Zeitdifferenz zwischen aktuellen 
Zeitpunkt und gemerktem Zeitpunkt größer als 100 bis 300ms ist, dann 
sendest du die Daten.

von N. M. (mani)


Lesenswert?

N. M. schrieb:
> Nö.
> So wartest du ja einfach 500ms und sendest einfach alles was du bis
> jetzt hast.

Vergiss das, es ist einfach zu spät.
Du hast ja nur den Code für das leeren beim Startup gezeigt. Ich hätte 
pauschal erwartet, dass das begin() bereits alle Puffer initialisiert. 
Aber ohne in die Implementierungen zu schauen wäre ich mir da auch nicht 
sicher. Ich würde wahrscheinlich folgende Reihenfolge probieren:
1
delay(500); // Leser gibt evtl. direkt Daten aus nach dem starten.
2
3
Serial1.begin(9600);
4
while (Serial1.available())
5
{
6
  Serial1.read(); // UART leeren
7
}

Und für die Geschichte mit dem Timeout gibt es scheinbar auch eine 
Funktion setTimeout() die du vermutlich verwenden kannst.

von Rahul D. (rahul)


Lesenswert?

Marcel M. schrieb:
> Er gibt dann folgendes raus was auch stimmt:
> 020C11047287423877806103

Mit "02" am Anfang und "03" am Ende sieht das ziemlich nach einer 
STX-ETX-Synhronisation aus. Da braucht man nicht unbedingt ein Timeout, 
sondern eher die Soll-Länge des Strings (die UUID hat doch 64 Bit / 8 
Bytes oder so).
Das Timeout würde wieder für einen initialen Datenzustand sorgen.

von Marcel M. (hurrykane)


Lesenswert?

Rahul D. schrieb:
> Marcel M. schrieb:
>> Er gibt dann folgendes raus was auch stimmt:
>> 020C11047287423877806103
>
> Mit "02" am Anfang und "03" am Ende sieht das ziemlich nach einer
> STX-ETX-Synhronisation aus.



Danke für die Info, das war genau das was ich gebraucht habe.
Habe es jetzt wie folgt gemacht:

#include <Keyboard.h>

const byte STX = 0x02; //STX Start of Text
const byte ETX = 0x03; //ETX End of Text

bool reading = false;
char hexChars[] = "0123456789ABCDEF";

void setup()
{
  Serial1.begin(9600); // RFID-Leser über UART
  Keyboard.begin(); // USB-Tastatur start
}

void loop() {
  while (Serial1.available())
  {
    byte b = Serial1.read();

    if (b == STX)
    {
      reading = true;
      Keyboard.print("02"); // STX als HEX ausgeben
    }
    else if (b == ETX && reading)
    {
      Keyboard.print("03"); // ETX als HEX ausgeben
      Keyboard.press(KEY_RETURN);
      delay(100);
      Keyboard.releaseAll();
      reading = false;
    }
    else if (reading)  // Byte als zwei HEX-Zeichen ausgeben
    {
      Keyboard.print(hexChars[b >> 4]);
      Keyboard.print(hexChars[b & 0x0F]);
    }
  }
}

Damit klappt es Problemlos auch nach aus und wieder einstecken. Und ich 
bin nicht mehr an eine feste UID-länge gebunden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.