Forum: Mikrocontroller und Digitale Elektronik Arduino - 4 x Codeschloss mit Wiegand-Code


von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

Ich hab jetzt einige der billigen aber recht funktionalen Codeschlösser 
mit Wiegand-Codierung gekauft, das Programm am Arduino-Atmega 
funktioniert recht gut, belegt aber die Interrupt-Pins 2 und 3.

Insgesamt möchte ich 4 Codeschlösser anschließen. Es ist fast 
auszuschließen, dass 2 davon gleichzeitig bedient werden. Entsprechend 
dem Wiegand-Protokoll kann man die sicher parallel alle an 2 und 3 
anhängen.
Die Leitung ist hier immer auf 5V, nur beim Senden immer ganz kurz auf 
Masse gezogen.

Nur wie weiß ich dann, welches Codeschloss betätigt wurde?
Ich hab jetzt an eine Matrix gedacht, wenn ich einen der Pins mit einer 
Diode an einen anderen Prozessoreingang zusätzlich anhänge sollte das 
klappen, aber gehts nicht auch anders?

Schloss 1-----Data 0 -------|<------PIN2 (Pullup-Widerstand gesetzt)
                      |
                      |-------------PIN22 (damit erkenn ich Schloss 1)

Schloss 1-----Data 1----------------PIN3

Schloss 2-----Data 0 -------|<------PIN2 (Pullup-Widerstand gesetzt)
                      |
                      |-------------PIN23 (damit erkenn ich Schloss 2)

Schloss 2-----Data 1----------------PIN3

Hoffe, das ist halbwegs verständlich
Gibts da andere Ideen, die auch ohne Dioden funktionieren?

Danke

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Welche Datenrate hat der Code denn?
Ein Link auf den Code wäre gut.
Man könnte für alle 8 Leitungen die Pin-Change Interrupts benutzen oder 
sie im Timerinterrupt pollen.

von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

Ja, super danke für die Antwort, PIN-Change Interrupts hatte ich heute 
auch gegoogelt, das Timing ist ein bisserl kritisch, weil mein Ardunio 
hat neben 4xWiegand auch noch als Modbus TCP/IP Gateway zu tun. Also 
denk ich Interrupts sind die beste Wahl. Das mit den PIN-Change 
Interrupts muss ich mir aber erst aus dem ATMEGA Datenblatt rauslesen, 
also wenn hier schon jemand mal ein Beispiel hat - wär perfekt.

Datenrate ist 100 uS für einen Impuls,
Wiegand Code ist hier z.B. detailliert beschrieben: 
https://docs.tibbo.com/taiko/ser_wiegand_mode
Hier mein bereits funktionierender Codeteil:
1
unsigned long oldMillis = 0;
2
uint8_t oldBitCount=0;
3
uint8_t interval = 50;  //Timeout
4
5
volatile uint8_t bitCount = 0;
6
volatile unsigned long code=0; //4 bit binaer 0-9,*,# oder RFID 26 Bit
7
unsigned long key=0; //eingegebener Code am Keypad, max. 999.999.999
8
9
10
void DATA0(void) { //PIN 2
11
    bitCount++;
12
    code = code << 1;
13
}
14
15
void DATA1(void) { //PIN 3
16
   bitCount++;
17
   code = code << 1;
18
   code |= 1;
19
}
20
21
void setupWiegand() { //wird von void setup() aufgerufen
22
  for(int i = 2; i<4; i++){
23
    pinMode(i, OUTPUT);
24
    digitalWrite(i, HIGH); 
25
    digitalWrite(i, LOW); 
26
    pinMode(i, INPUT);
27
    digitalWrite(i, HIGH); 
28
  }
29
  attachInterrupt(0, DATA0, FALLING);  
30
  attachInterrupt(1, DATA1, FALLING);
31
}   
32
33
void sWiegand(unsigned long &code) { //wird aus der void loop() aufgerufen
34
  if (bitCount>0)
35
    if (bitCount!=oldBitCount){
36
      oldBitCount=bitCount;
37
      oldMillis=millis();
38
    }
39
    else if (millis() - oldMillis > interval) {
40
      if(bitCount==4){ //Taste vom Codeschloss, 4 Bit binaer
41
        if (code==10){ //Taste *
42
          //Serial.println("0=gelöscht");
43
          key=0;
44
        }
45
        else if(code==11){  //Taste #
46
          //Serial.println(code);
47
          //Serial.println("Abgeschickt");
48
          sWriteBuffer(key); //Weiterverarbeitung, key 0 setzen
49
        }
50
        else if (key<100000000){ //Code maximal 9-stellig
51
          key*=10+code;
52
          //Serial.println(key);
53
        }
54
      }
55
      else if(bitCount>4){ //RFID-Karte gelesen
56
        sWriteBuffer(code);  //Weiterverarbeitung
57
      }
58
      bitCount=0; 
59
      code=0;
60
   }  
61
}

: Bearbeitet durch User
von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

So, nach dem das vorhin nur ein eher untaugliches Codefragment war, hier 
jetzt der fertige Code für den Arduino Atmega, damit sind 1, 2, 3 oder 4 
Keypads abfragbar, leider hab ich nur eines (ohne RFID) da, die anderen 
sind noch per Post unterwegs..

Danke noch an Peter Dannegger für seinen Hinweis an den PIN Change 
Interrupt, den hatte ich zwar in einem anderen Projekt vor 2 Jahren 
schon irgendwo im Einsatz nur schon wieder vergessen.. jetzt erspar ich 
mir ein Diodenarray und die Anschlüsse sind einfach nebeneinander.

Es sollte sogar möglich sein, alle 4 Keypads gleichzeitig zu bedienen, 
nur in dem seltenen Fall, dass 2 Impulse im gleichen uS-Bereich kommen, 
könnte eine Doppeltriggerung erfolgen.. aber die Wahrscheinlichkeit 
dafür geht gegen null. Also falls es jemand mal braucht, die ganze Sache 
kommt ohne delay und ohne weiterer Arduino-Library aus.

Viel Spaß beim Testen und vielleicht findet jemand ja noch 
Optimierungspotential.
1
#define cKeyPads 4 //Keyboards max.4, wenn nur 1, dann 1 eingeben
2
/*
3
 Keypad 1: grün/Data0 auf PIN A8
4
 Keypad 1: weiß/Data1 auf PIN A9, GND nicht vergessen ;-)
5
 Keypad 2: grün/Data0 auf PIN A10
6
 Keypad 2: weiß/Data1 auf PIN A11, GND nicht vergessen ;-)
7
 Keypad 3: grün/Data0 auf PIN A12
8
 Keypad 3: weiß/Data1 auf PIN A13, GND nicht vergessen ;-)
9
 Keypad 4: grün/Data0 auf PIN A14
10
 Keypad 4: weiß/Data1 auf PIN A15, GND nicht vergessen ;-)
11
*/
12
#define cTimeOut 70  //Timeout in mSec, einzelne Ziffern oder RFID-maximale Codeuebertragung
13
#define cTimeOutReset 3000  //ab wann sind die Eingaben, Keys ungültig, Key wird wieder 0
14
unsigned long oldMillis[cKeyPads];
15
uint8_t oldBitCount[cKeyPads];
16
volatile uint8_t bitCount[cKeyPads];
17
volatile unsigned long code[cKeyPads];
18
unsigned long key[cKeyPads];
19
20
ISR(PCINT2_vect){
21
  uint8_t portValue=PINK;
22
  for(uint8_t i=0;i<cKeyPads;++i){
23
    uint8_t in=portValue & 3;
24
    portValue>>=2;
25
    if (in==2 || in==1){
26
      bitCount[i]++;
27
      code[i]<<=1;
28
      code[i]|=in & 1;
29
    }
30
  }
31
}
32
33
void setup() {
34
  Serial.begin(9600);
35
  cli();
36
  PCICR|=(1<<PCIE2); //PK0..PK7, A8..A15 PIN Change Interrupts
37
  PCMSK2=0;
38
  for (uint8_t i=0;i<cKeyPads;++i){
39
      key[i]=0;  //Codes am Anfang sind 0
40
      PCMSK2<<=2;
41
      PCMSK2|=PCMSK2 | 3;
42
  }
43
  sei();
44
  Serial.println("Wiegand Reader");
45
}
46
47
void loop() { 
48
  for (uint8_t i=0;i<cKeyPads;++i){
49
    if (key[i]>0)
50
      if (millis() - oldMillis[i] > cTimeOutReset){
51
        key[i]=0;
52
        Serial.print(i+1);
53
        Serial.print(".Keypad: ");
54
        Serial.println("Zeitablauf - Reset Eingabe");
55
      }
56
    if (bitCount[i]>0)
57
      if (bitCount[i]==1){
58
        oldMillis[i]=millis();
59
      }
60
      else if (millis() - oldMillis[i] > cTimeOut) {
61
        //g_Timer=millis();
62
        if (bitCount[i]==4){
63
          if (code[i]==10){ //Taste *
64
            Serial.print(i+1);
65
            Serial.print(".Keypad: ");
66
            Serial.println("Clear");
67
            key[i]=0;
68
          }
69
          else if (code[i]==11){ //Taste #
70
            sResult(key,i);
71
          }
72
          else if (key[i]<100000000){  //Code max. 9 Stellen = long
73
            key[i]=key[i]*10+code[i];
74
            Serial.print(i+1);
75
            Serial.print(".Keypad: ");
76
            Serial.println(key[i]);
77
          }
78
        }
79
        else if (bitCount[i]>10){ //RFID Wiegand Code meist 26 Bits
80
          key[i]=code[i];
81
          sResult(key,i);
82
        }
83
        code[i]=0;
84
        bitCount[i]=0;
85
    }
86
  }
87
}
88
89
void sResult(unsigned long key[], int i){
90
  Serial.print(i+1);
91
  Serial.print(".Keypad RESULT=");
92
  Serial.println(key[i]);
93
  key[i]=0;  //wichtig key Reset
94
}

von Reinhard Dopheide (Gast)


Lesenswert?

Hallo zusammen,

nach dem ich, "ahnungsloser Vielleicht-
Arduino-Einsteiger" einige Stunden am PC nach Lösungen für Fingerprint 
an eqiva Motorschloss, sowohl über Raspi als auch über Arduino gesucht 
habe, viel "spanisch" verstanden habe, und kurz vor dem Aufgeben stehe, 
frage ich jetzt mal hier, wenn ich das darf(?), ob mir jemand sowas 
bauen kann:
Ich möchte einen Fingerprint über das Wiegandsignal mit einem eqiva 
Motorschloss, dass sich nur über Bluetooth ansteuern lässt, verbinden. 
Hier sehe ich das Potenzial, dass ich nicht habe, hier gibt es, wenn ich 
das richtig interpretiere, Lösungen und Leute, die sowas schreiben 
können.
Ich hätte gerne einen Arduino, oder auch Raspi, mit entsprechender 
Software fertig installiert, der eben das Wiegand-Protokoll auslesen 
kann, und an den eqiva per Bluetooth übermittelt. Oder eben auch 
Teillösungen. Wenn ich dazu weiß, an welche Pins ich die 4 Wiegand-Kabel 
anschließen muss, ich weiss mit Spannungsteiler, dürfte ich den Rest 
hinbekommen.
Wenn jemand Interesse hat, mir sowas zusammenzubauen, bitte ich um ein 
Angebot.
Ich weiß, dass ist hier so nicht üblich, sollte ich sowas hier gar nicht 
dürfen, bitte ich um Nachsicht, und Information, dann ziehe ich meine 
Anfrage selbstverständlich zurück.

LG Reinhard

von Peter D. (peda)


Lesenswert?

Reinhard Dopheide schrieb:
> Ich möchte einen Fingerprint über das Wiegandsignal mit einem eqiva
> Motorschloss, dass sich nur über Bluetooth ansteuern lässt, verbinden.

Und was hat das mit dem Codeschloß zu tun?
Zu neuen Fragen macht man nen eigenen Thread auf.
Und verlinke mal all die ungekannten Geräte, denn keiner kann in Deinen 
Kopf schauen.
Ich befürchte aber, daß es keine Doku zu deren Internas gibt, d.h. die 
sind nur mit den professionellen Komponenten verwendbar, für die sie 
gedacht sind.

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.