Werte Foristi,
ich versuche mich grade an einer "Türöffnung" ähnlich der in diesem Thread beschriebenen. Den Sketch habe mich mir aus diversen Quellen zusammenstückeln können und grundsätzlich funktioniert es auch - leider komme ich mit dem Array nicht klar, und das übersteigt meine bestenfalls rudimentären Programmierkenntnisse dann doch erheblich.
Zunächst mal zur Problembeschreibung: Im Array sind wie im verlinkten Beispiel die iButton-IDs hinterlegt. Allerdings löst nur die jeweils erste ID im Array die gewünschte Aktion aus - und das auch nur, wenn der Wert für SCHLUESSEL der Anzahl der eingepflegten IDs entspricht. Ändere ich die Reihenfolge der IDs, wandert das Problem nicht mit, es bleibt immer die erste ID (insofern kann ich Tippfehler bei den IDs als naheliegendste Ursache ausschließen).
Vollends irritiert mich dann aber, dass JEDE iButton-ID die gewünschte Aktion dann auslöst, wenn der Wert für SCHLUESSEL größer ist als die Anzahl der im Array befindlichen IDs - und dann aber auch solche, die gar nicht eingepflegt sind, also jeder x-beliebige iButton, der als solcher erkannt wird (ein simpler Kurzschluss am iButton-Reader triggert nix, immerhin)
Meine konkrete Frage zu meinem Sketch lautet dementsprechend, was am Array bzw. an der Vergleichs-Schleife falsch sein könnte?
const byte SCHLUESSEL = 4; // Anzahl der gueltigen Schluessel
byte ibuttonid[SCHLUESSEL][10] = {{1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,2}, {1,1,1,1,1,1,1,3}, {1,1,1,1,1,1,1,4}};
byte buffer[10]; //ibutton ID-Ablage
boolean result; // Ergebnis der iButton-Abfrage
...
// iButton-ID vergleichen
result = false;
for (int b = 0; b < SCHLUESSEL; b++) {
result = true;
int x = 0;
do {
int compare1 = ibuttonid[b][x];// Array vergleichen
int compare2 = buffer[x];
if (compare1 != compare2) { // ID nicht im Array
result = false;
}
x++;
} while (result && (x < SCHLUESSEL));
if (result) {
b = SCHLUESSEL;
result = true;
}
if(result == true) { // ID ist im Array
...
Um nicht nur etwas zu erfragen, sondern als kleiner Beitrag meinerseits hier noch die komplette Beschreibung und der entsprechende Sketch, evtl. hilft's ja jemand: Es geht um die Ansteuerung von Zentralverriegelungsaktoren aus dem KFZ-Bereich, die man recht günstig bekommt. Damit werden zwei Zusatzriegel einer Fahrradschuppen-Tür angetrieben. Man braucht zwar immer noch den mechanischen Schlüssel, die Riegel sind eher als "zweite Verteidigungslinie" gedacht. Ein weiteres Projekt mit demselbem Aufbau wird eine Entriegelung für mehrere Werkstattschränke.
Wer diese ZV-Antriebe nicht kennt: Das sind kleine Gleichstrom-Motoren, die mit einer zwischenübersetzung eine Zahnstange von einem zum anderen Anschlag fahren, ein paar N können die schon stemmen. Es gibt zwei Varianten, einmal mit Endlagen-Schaltern, einmal ohne. Der Motor wird einfach umgepolt zur Drehrichtungsumkehr, ich habe das mit einer L298n-H-Brücke gelöst, die die Motoren für 200ms bestromen (die Dinger haben ein ulkiges elektromechanisches Verhalten, bei Dauerplus fahren sie einmal in den Anschlag und zucken dann ryhthmisch immer wieder in die Richtung, nicht unbedingt das, was ich als Elektro-Laie erwartet hätte).
Sobald ein (berechtigter) iButton erkannt wird, fahren die (in meinem Fall) zwei Motoren in die jeweils andere Endlage. Dazu wird abgefragt, ob der dem Status "eingefahren" entsprechende Endlage-Schalter Kontakt hat. Derzeit wird nur der eine Schalter abgefragt, wenn die beiden Motoren also von Hand "asynchron" sind, ist also eine zweite Schleife notwendig, bis die Dinger sich synchronisiert haben. Die Verzögerung von zwei Sekunden am Ende ist dazu gedacht, dass der iButton entfernt wird.
Es fehlen noch ein paar Details, u.a. will ich de zweiten Endlagen-Schalter auslesen und die beiden Werte vergleichen, so dass die Motoren schon in der ersten Schleife synchronisiert werden. Und dann noch ein paar nette Gimmicks wie Rückmeldungen per LEDs und Buzzer, ein Taster parallel zum iButton-Leser, wenn man von innen entriegeln will (den Fahrradschuppen, nicht die Werkstattschränke) und das Ansteuern eines Relais fürs Licht im Schuppen (nicht im Schrank).
//iButton
#include <OneWire.h>
OneWire ibutton (2); // iButton zugewiesen an PIN 2.
const byte SCHLUESSEL = 4; // Anzahl der gueltigen Schluessel
byte ibuttonid[SCHLUESSEL][10] = {{1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,2}, {1,1,1,1,1,1,1,3}, {1,1,1,1,1,1,1,4}};
byte buffer[10]; //ibutton ID- "Ablage".
boolean result; // Diese Variable enthaelt das Ergebnis der iButton-Abfrage
// Gleichstrommotor 1
int GSM1 = 10;
int in1 = 9;
int in2 = 8;
int out1 = 11;
// Gleichstrommotor 2
int GSM2 = 5;
int in3 = 7;
int in4 = 6;
int out2 = 12;
void setup(){
Serial.begin(9600);
// Pinmodes
pinMode(GSM1, OUTPUT);
pinMode(GSM2, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(out1, INPUT_PULLUP);
pinMode(out2, INPUT_PULLUP);
}
void loop(){
if (!ibutton.search (buffer)){//iButton auslesen und Ergebnis in Buffer schreiben
ibutton.reset_search();
delay(100);
return;
}
for (int x = 0; x<8; x++){
Serial.print(buffer[x],DEC); //Buffer in Monitor ausgeben
Serial.print(" "); // Leerzeichen
}
Serial.println("\n"); // Neue Zeile
// iButton-ID vergleichen
result = false;
for (int b = 0; b < SCHLUESSEL; b++) {
result = true;
int x = 0;
do {
int compare1 = ibuttonid[b][x];// Array vergleichen
int compare2 = buffer[x];
if (compare1 != compare2) { // ID nicht im Array
result = false;
}
x++;
} while (result && (x < SCHLUESSEL));
if (result) {
b = SCHLUESSEL;
result = true;
}
if(result == true) { // ID ist im Array
// Motor 1
if(digitalRead(out1) == HIGH) { //Auslesen des Positionsschalters Motor 1
digitalWrite(in1, HIGH); // Motor 1
digitalWrite(in2, LOW);
analogWrite(GSM1, 255); // Motor 1 PWM
Serial.println("Entriegeln Motor 1");
} else {
digitalWrite(in1, LOW); // Motor 1 gegensinnig
digitalWrite(in2, HIGH);
analogWrite(GSM1, 255); // Motor 1 PWM
Serial.println("Verriegeln Motor 1");
}
// Motor 2
if(digitalRead(out1) == HIGH) { //Auslesen des Positionsschalters Motor 1 -> Motor 2 folgt später
digitalWrite(in3, HIGH); // Motor 2
digitalWrite(in4, LOW);
analogWrite(GSM2, 255); // Motor 2 PWM
Serial.println("Entriegeln Motor 2");
} else {
digitalWrite(in3, LOW); // Motor 2 gegensinnig
digitalWrite(in4, HIGH);
analogWrite(GSM2, 255); // Motor 2 PWM
Serial.println("Verriegeln Motor 2");
}
delay(200);
digitalWrite(in1, LOW); // Motoren werden abgeschaltet
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
delay(2000); // zwei Sekunden Zeit, den iButton zu entfernen
}
//Buffer auf 0 zuruecksetzen
for (int x=0; x<10; x++){
buffer[x] = 0 ;
}
}
}