RFID per USB HID in windows übertragen.

#7926152
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.

(Firma: 10.08.1985) #7926159
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.

#7926164
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".

#7926165
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.

#7926168
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) {

1
// read incoming serial data:
2

3
char inChar = Serial.read();
4

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

7
Keyboard.write(inChar + 1);

} }

: Bearbeitet durch User
#7926178
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.

#7926183
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.

#7926256
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.

#7926289
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.

#7926709
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 }

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

}

Angehängte Dateien:
: Bearbeitet durch User
#7926748
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;

1
if (index >= UID_LENGTH) 
2
{
3
  // UID vollständig empfangen, jetzt senden
4
  for (int i = 0; i < UID_LENGTH; i++) 
5
  {
6
    if (uid[i] < 0x10) Keyboard.print("0");  // führende Null hinzufügen
7
    String hex = String(uid[i], HEX);
8
    hex.toUpperCase();
9
    delay(50); 
10
    Keyboard.print(hex);
11
  }
12

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

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

} }

#7926782
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?

#7926816
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
#7926841
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.
#7926908
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(); }

#7926924
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.

#7926929
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.

#7926951
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.

#7928983
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();

1
if (b == STX) 
2
{
3
  reading = true;
4
  Keyboard.print("02"); // STX als HEX ausgeben
5
}
6
else if (b == ETX && reading) 
7
{
8
  Keyboard.print("03"); // ETX als HEX ausgeben
9
  Keyboard.press(KEY_RETURN);
10
  delay(100);
11
  Keyboard.releaseAll();
12
  reading = false;
13
}
14
else if (reading)  // Byte als zwei HEX-Zeichen ausgeben
15
{
16
  Keyboard.print(hexChars[b >> 4]);
17
  Keyboard.print(hexChars[b & 0x0F]);
18
}

} }

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren