In Teil 1 & Teil 2 dieser Anleitung habe ich beschrieben, wie man einen Ersatz (oder Nachfolger) für das Funkcodeschloss Keymatic KM300 CAC (baugleich Abus CFT 1000) bauen kann. Dabei ist ein Arduino Nano die zentrale Koordinationsstelle, welche die Codes / RFID Eingaben auswertet, bei richtiger Eingabe den Sender aktiviert um den Türschlossantrieb zu aktivieren und die Klingel zu betätigen.
Den Arduino programmieren
In diesem abschließenden Teil 3 geht es um die Software für den Arduino. Wer noch nie mit einem Arduino gearbeitet hat: Es ist wirklich einfach.
- Den hier bereitgestellten Sourcecode herunterladen: Wiegand_Controller
- Die Arduino IDE (das ist das Entwicklungstool inkl. Compiler) von arduino.cc herunterladen. Diese Software ist Opensource und kostet nichts.
- Sourcecode mit der IDE öffnen. Alle vier .ino Dateien gehören zur Software. Am besten die Datei Wiegand_Controller.ino laden. Die anderen 3 Dateien werden automatisch mitgeladen.
- Arduino Nano per USB an den Rechner anschließen. Etwas warten, bis die USB Treiber installiert sind.
- Im Menü Tools den richtigen seriellen Port auswählen (meistens gibt es nur einen).
- Im Menü Tools unter Board den Arduino Nano auswählen.
- Pfeiltaste oben rechts anklicken (–> Upload).
Mehr muss man nicht tun. Der Sourcecode wird übersetzt. Das dauert ca. 30 Sekunden. Danach wird die Software auf den Arduino übertragen. Wenn der Upload fertig ist, ist auch schon alles erledigt. Der Arduino ist fertig programmiert.
Beschreibung der Software
Wiegand_Controller.ino
Enthält nicht viel. Initialisiert den seriellen Port und ruft die Initialisierungsroutinen der anderen Module. Enthält weiterhin die Grundschleife sowie die Debug Ausgabe für eingegebene Codes.
Wiegand_LowLevel.ino
Es gibt einige Wiegand Libraries für den Arduino von der Stange. Ich war mit keiner zufrieden (zu kompliziert & zu unflexibel). Deshalb habe ich meine eigenen Routinen aufgesetzt. Die Routinen WiegandD0 und WiegandD1 werden an die Interrupts für die Arduino Pins D2 und D3 bei einer fallenden Flanke gehangen. In diesen Routinen werden die empfangenen Bits gezählt (D0) und unterschieden, ob einen 1 oder 0 empfangen wurde (D1). Wenn 50ms lang keine Pulse mehr ankommen, geht der Code davon aus, dass die Wiegand Übertragung abgeschlossen ist; es gibt beim Wiegand Protokoll weder Anfang noch Ende. Irgendwann kommen Pulse und irgendwann sind sie halt wieder vorbei.
Die Routine WiegandDecode regelt die Umrechnung der empfangenen Bits in den Facility-Code und den Card-Code. Diese Routine ist die Stelle, an der man die Wiegand Dekodierung gegebenenfalls erweitern muss. Die Hersteller kochen öfters ein eigenen Süppchen mit eigenen Bitlängen und Aufteilungen auf Facility- und Card-Code. Mit einer passenen Ergänzung der switch/case Anweisung sollten andere Formate unterstützbar sein.
UI.ino
Hier wird das textbasierte Userinterface für die Arduino Software realisiert. Das ist ein einfaches Menü. Der Code ist nicht sonderlich kompliziert und sollte falls nötig leicht zu erweitern sein.
HandleCodes.ino
Hier ist der Kern des Codeschlosses realisiert. Am Anfang sind in den #define Statements die Pins für die jeweiligen Anschlüsse definiert. Die Längen für die Funksignale sind festgelegt. Ebenso wird festgelegt, wie oft hintereinander ein falscher Code eingegeben werden darf (ich habe 5 festgelegt) und wie lange das Codeschloss nach dieser Anzahl an Fehleingaben blockiert (3 Minuten).
Im Kern wird in diesem Softwareteil ein Array verwaltet, welches die korrekten Codes verwaltet. Jeder Code hat auch einen Realnamen, also z.B. Paul. Wenn Paul dann irgendwann nicht mehr rein darf oder seinen RFID verloren hat, ist der Code leicht zu identifizieren und zu löschen.
In der Setup Routine wir weiterhin das verfügbare RAM sowie der EEProm Speicher überprüft und entschieden, wieviele Codes gespeichert werden können. Auf einem Arduino Nano können 53 Codes gespeichert werden. Wer mehr braucht, kann darüber nachdenken, den #define MAXNAMESIZE zu reduzieren. Diesen habe ich auf 10 gestellt; jeder Code kann einen 10-1=9 Zeichen langen Realnamen haben.
Weiterhin wird in diesem Sofware Teil das Lesen & Speichern aus dem EEProm geregelt. Dies umfasst auch das sogenannte TamperFlag. Dieses Flag wird gesetzt und im EEProm gespeichert, wenn ein falscher Code eigegeben wird. Das Tamperflag wird nur gelöscht, wenn ein richtiger Code eingegeben wurde oder nachdem die Strafzeit von 3 Minuten nach 5 falschen Eingaben abgelaufen ist. Der Sinn des TamperFlags ist es, eine Sicherheitslücke durch die Manipulation der Stromversorgung zu verhindern. Sonst könnte man ja 4 Codes ausprobieren, dann kurz die Stromversorgung unterbrechen (kommt von der Klingel und ist vor der Tür per Schraubenzieher erreichbar) und dann wieder 4 Codes probieren. Dank des TamperFlags geht dies nicht: Ein falscher Code und die Unterbrechung der Stromversorgung wird mit 3 Minuten Pause geahndet.
Verwendung der Software
Wenn man den Arduino neu programmiert hat und das erste Mal startet, ist der EEProm noch unbeschrieben. Wenn man Pech hat (50% Chance) ist da Tamperflag gesetzt und man muss erst einmal 3 Minuten warten. Eine entsprechende Ausgabe erscheint, wenn man mit einem seriellen Monitor bzw Terminalprogramm auf die Ausgaben des Arduino lauscht. Die serielle Schnittstelle muss auf 9600 Baud, 8 Bit, N=keine Parität,1=ein Stopbit gesetzt werden. Ich nehme übrigens putty, weil man hier eine gute Copy/Paste Unterstützung hat.
Nach dem ersten Sart sollte man in etwa folgendes sehen – hier als Beispiel hat das Tamperflag zugeschlagen:
Wiegand Controller - S.T. 2014
RAM before Codelist allocation: 1645
EEProm size limits Codelist array.
RAM after Codelist allocation: 636
Codes that can be stored: 53
Codes loaded from EEProm: 0
TAMPERED?? - Restart with wrong-code counter active -> Go into wait mode.
Too many wrong codes entered. Will sleep this amount of seconds - also on serial: 180... Done.
Nach der Wartezeit von 3 Minuten kommt dann das Menü und als erstes löschen wir den EEProm:
***** MENU ****
<enter> -> print this menu
1 -> learn a code / paste csv-list of codes
2 -> delete a code
3 -> display all codes
7 -> reset tamper flag & reboot
8 -> save all codes to eeprom
999 -> delete ALL codes in eeprom
Notes: Name entries max 9 characters.
Action entries 1 for open, 0 for close.
>999
Erasing EEprom…
Codes saved to EEProm: 0
Nun kann man neue Codes anlegen. Oder auch einfach mal zum Test einen RFID vor das Codeschloss halten; der RFID Code erscheint dann im seriellen Fenster. Aber Achtung: Wenn man 5 falsche (weil noch nicht angelernte) RFID Codes hintereinander einliest, hat man wieder 3 Minuten Wartezeit gewonnen.
Mit der Eingabe 1 kann man einen Code anlernen oder auch eine komplette Codeliste in das Fenster des Terminalprogramms einfügen. Das Format für die Eingabe wird kurz vom Arduino genannt, dann können die Eingaben erfolgen. Eine Codeliste sieht z.B. so aus:
User1,0,1234,1
User2,0,246835,1
User3,0,9933,1
RFIDTag1,13,9384632,1
RFIDTag2,12,3834672,1
RFIDTag3,21,9287374,1
Close,0,0,0
In diesem Beispiel gibt es 3 Benutzer mit einem Pin zur Eingabe per Tastatur. User 2 muss 246835# auf der Tastatur eintippen. Daraufhin wird Kommando 1 ausgelöst; Kommando 1 ist Türe öffnen. Will man abschließen, so tippt man 0000# ein; hier ist eine 0 als Kommando hinterlegt.
Weiterhin sind 3 RFIDs angelert. Tag 1 hat den Facility Code 13 und den Card Code 9384632. Würde man bei RFIDTag1 die letzte 1 gegen eine 0 tauschen, so würde dieser RFID ab jetzt die Türe abschließen.
Nach der Eingabe die Liste mit Enter abschließen und die Codeliste mit 8 im EEProm speichern. Fertig.
Die restlichen Eingaben sollten selbsterklärend sein. So kann man mit 3 eine Liste aller angelernten Codes ausgeben. Diese ist so formatiert, dass man sie im Anlernmodus auch direkt wieder zum Einfügen verwenden kann.
Mit der Eingabe 2 kann man einen Code / RFID löschen. Dazu muss dann der Realname des Codes/RFIDs eingegeben werden. Falls man den nicht mehr so genau weiss, einfach vorher mittels 3 mal in die Liste schauen.
Falls jemand das vorgestellte Konzept nutzt oder erweitern, würde ich mich über einen Kommentar freuen.
Ergänzung (30.04.2015):
Hier geht es zum Teil 4 für die Version 1.1 mit einer breiteren Unterstützung von Wiegand Codeschlössern.
_________________________
Link für die in Kommentar Nr. 4 erwähnte Codeanpassung für einen Pin, der zuviel e falsche Codeeingaben nach außen signalisiert: Wiegand_Controller_WrongCodePin –> diese Änderung wurde auch in die Version 1.1 in Teil 4 übernommen.