Toilettenampel mit RF-ID, Problem beim Zwischenspeichern

Hallo!
Ich bin neu hier im Forum und auch habe mit dem Arduino bisher nur kleine Einstiegsprojekte mit Anleitung gemacht.
Jetzt habe ich mich mal an einer eigenen Idee probiert. Ich möchte eine Art Toiletten-Ampel für die Schule bauen, da sich immer nur einer in dem Toilettenbereich aufhalten darf.
Dazu soll man sich mit einem RF-ID Chip berührungslos "einchecken", die Lampe soll von grün auf rot springen. Wenn man wieder "auscheckt", soll sie wieder grün werden. Das habe ich geschafft.

Ich wollte als Zusatz einbauen, dass die rote Lampe auch weiterhin eingeschaltet bleibt, wenn ein anderer Chip eingelesen wird und erst auf grün schaltet, wenn sich der erste wieder auscheckt.

Meine Versuche sind aber daran gescheitert, die ausgelesenen Nummern zwischenzuspeichern und zu vergleichen.
Ich habe das Auslesen als Funktion geschrieben. Wenn ich die ausgelesene Nummer dann als Variable speichern möchte, wird mir nur 0 angezeigt, beim direkten anzeigen der Methode bekomme ich die Nummer. (Serial.println(codeEins) liefert 0; Serial.println(auslesen()) liefert die Nummer)

Was habe ich denn falsch gemacht?

Ich habe einen Funduino Uno und habe den RC522 zum auslesen genutzt.

#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

int red = 2;
int green = 3;
long codeEins;
long codeZwei;

long auslesen() {
  long code = 0;
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) { //Wenn eine Karte gefunden und gelesen wird

    for (byte i = 0; i < mfrc522.uid.size; i++) {
      code = ((code + mfrc522.uid.uidByte[i]) * 10); //Kartennummer wird unter der Variablen "code" abgespeichert
    }
  }
  return code;
}

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  pinMode (red, OUTPUT);
  pinMode (green, OUTPUT);
}



void loop()
{
  while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
  codeEins = auslesen();
  Serial.print("Die Kartennummer 1 lautet:");
  Serial.println(codeEins); //Hier wird nur 0 angezeigt?
  // Serial.println(auslesen()); //Hier wird die Nummer tatsächlich angezeigt
  digitalWrite(red, HIGH);
  digitalWrite(green, LOW);
  delay(2000);
  while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
  codeZwei = auslesen();
  Serial.print("Die Kartennummer 2 lautet:");
  Serial.println(codeZwei);
  delay(1000);

  while (codeEins != codeZwei) {
    while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
    codeZwei = auslesen();
    Serial.print("Die Kartennummer 2 lautet:");
    Serial.println(auslesen());
    delay(100);
  }


  digitalWrite(red, LOW);
  digitalWrite(green, HIGH);
  delay(1000);

}

PiaMind:
Ich wollte als Zusatz einbauen, dass die rote Lampe auch weiterhin eingeschaltet bleibt, wenn ein anderer Chip eingelesen wird und erst auf grün schaltet, wenn sich der erste wieder auscheckt.

Jemand, der alles richtig gemacht hat in seinem Post ohne Reply...
Soweit bin ich mitgekommen, aber kannst Du mal beschreiben, was Du da oben meinst?

Ich hab mal versucht den Code zu überblicken. Ist recht schwer.
ABER:!

while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
 codeEins = auslesen();
 Serial.print("Die Kartennummer 1 lautet:");

und

while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
 codeZwei = auslesen();
 Serial.print("Die Kartennummer 2 lautet:");

und

while (codeEins != codeZwei)
   {
   while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
   codeZwei = auslesen();

kann nicht funktionieren.
Ich denke zudem, das die Ampel immer umschaltet, wenn irgendeine Karte gelesen wird.

Willst Du das so funktionieren lassen:

EINER rein - Ampel rot
Ampel bleibt solange rot, bis genau dieser eine wieder raus kommt.
Es kann ZWEI (oder drei oder xxx) sich noch "anmelden" die Ampel bleibt auf rot, solange die Anzahl der angemeldeten RFID's !=0 ist?

Dazu zwei Gedanken:

  1. Was passiert, wenn EINER sich nicht mehr "abmeldet"
  2. Im Falle eines Neustarts weiss der Arduino nicht, wer drin und wer angemeldet.
    2.1. Wenn EINER jetzt rauskommt, meldet er sich an anstatt ab. Damit ist Die Bedingung !=0 immer erfüllt
  3. Was passiert wenn sich ZWEI es anders überlegt und nach dem "Checkin" nicht mehr müssen muss?

Ein sehr schönes Thema, bitte mach Dir ein paar Gedanken zu dem, was ich schon als Hürde sehe und dann noch eine Bitte: Formatiere Deinen Code in der Arduino IDE mit STRG-F und kopiere den oben erneut rein.

Ich sehe da ein poentielles Privacyproblem, da die RFID eine eindeutige Seriennummer haben.
Außerdem würde ich nicht auf die bedingungslose, 100%verläßliche Mitarbiet aller Beteiligten zählen.
Wie willst Du denn garantieren daß nicht 2 gleichzeitig mit nur einer RFID erfassung eintreten, Daß nicht der eine eintritt wenn der andere die Tür zum heraustreten öffnet ecc?

Ich selbst vergesse oft meine Arbeitszeitstempelungen; und die sind in meinen ureigenen Interesse. :wink: :wink: :wink:
Grüße Uwe.

Moin Uwe,

uwefed:
Ich sehe da ein poentielles Privacyproblem, da die RFID eine eindeutige Seriennummer haben.

Das umgeht man mit privacy by design.
Es gibt 500 ID's.
Die kommen in eine grosse Kiste, jeder nimmt sich einen Tag raus und bestätigt das er einen bekommen hat und ihn irgendwann wieder zurück gibt.

Der Arduino speichert die ID nur während der Rot-Phase.
Am Ende der Zeit wird der TAG wieder abgegeben und fertig.
Eine Prüfung auf Seriennummer entfällt, da nicht notwendig.

Ich sehe eher die Umsetzung kritisch, da fails, zumindest derzeit, nicht ausgeschlossen werden können.

uwefed:
Ich sehe da ein poentielles Privacyproblem, da die RFID eine eindeutige Seriennummer haben.
Außerdem würde ich nicht auf die bedingungslose, 100%verläßliche Mitarbiet aller Beteiligten zählen.
Wie willst Du denn garantieren daß nicht 2 gleichzeitig mit nur einer RFID erfassung eintreten, Daß nicht der eine eintritt wenn der andere die Tür zum heraustreten öffnet ecc?

Ich selbst vergesse oft meine Arbeitszeitstempelungen; und die sind in meinen ureigenen Interesse. :wink: :wink: :wink:
Grüße Uwe.

Hallo Uwe,

wenn die Chps alle unterschiedliche Nummern hjaben ( was ja ausschlisslich Sinn macht ), und anschließend wahllos an die Leute verteilt werden, weil es egal ist, ob gerade chip 1, 2 oder x pinkelt, dann ist das nicht mehr personalisierbar.

Man weiß anschließend, das Chip 2 dreimal sooft dort war, aber wenn am Ende alle ihre Chips wieder in einen Eimer schmeißen, weiß man nicht, wem welcher Chip in der Hosentasche gesessen hat.

Außerdem ist das nur Pausenrelevant. Geht einer während des Unterrichts pinkeln, wissen sowieso alle, das "er" derjenige ist, der jetzt pinkeln geht.

Das ganze wäre somit eindeutig DSGVO-konform, da nicht personell zugeordnet.

Anders wäre das nur, wenn registriert wird, wer den Chip mit genau dieser Nummer bekommt.
Davon war hier aber nicht die Rede.

jmtc:
Man kann Datenschutz also auch völlig sinnlos übertreiben.


Ansonsten gebe ich dir völlig recht, dass das so nicht gehen wird.

Als erstes wird nämlich der sicher vielen bekannte Schüler Nietnagel ( Mommsen-Gymnasium :-)) )
einfach gehen, und sich amüsieren, das die Ampel stundenlang rot bleibt.
ICH, ..... täte das ganz sicher, nur um dem Programmierer eins auszuwischen:-)))

Das geht wenn nur, mit Türöffner, 2-Leser Betrieb und Anti Passback.

Das hätte sogar noch den Vorteil, das ruhig alle Chips die selbe Nummer haben können.
Man geht rein, indem der Leser "Eingang" gelesen hat.
Jetzt bleibt der Leser solange stumm, bis der jenige den Ausgangsleser betätigt. Muss er auch, weil sonst die Tür nicht aufgeht. ( gängige Funktion guter ZuKo-Systeme )

Dazu muss eine Notöffnung möglich sein ( vorzugweise mit Alarmauslösung ), damit er auch noch rauskommt, wenn ihm aus versehen der Chip in die Schüssel gefallen ist ( man sieht: Der Teufel steckt im Detail ). ( grüner Umlegefrosch z.B: )

Die oben beschriebene Lösung des TE ist völlig sinnfrei, sorry.
Einfache Zutrittslösungen sind entweder nicht Funktionssicher ( obiger Fall ) oder sperren ggf. ein, wenn sie nicht völlig durchdacht sind. Nicht umsonst ein Fall für Fachleute und Sicherungsexperten ).
btw. mein täglich Brot.

Danke für die vielen Antworten :slight_smile:

Ich wollte unser jetziges sehr fragwürdiges System verbessern. Momentan liegt ein einlaminiertes Blatt auf dem Boden, welches man mit dem Fuß von "frei" auf "besetzt" dreht. Da dies eine große Rutschgefahr sein kann, wollte ich eine berührungslose alternative mit dem Arduino bauen (und mich in die RF-ID Geschichte einarbeiten).
Bisher gibt es also auch die Möglichkeit, dass man vergisst, das Blatt wieder umzudrehen. Oder der Schüler Nietnagel lässt die Blätter ganz verschwinden. (Dann kann man immer noch hineinrufen und fragen ob jemand drin ist.)
Natürlich kann man auch mit Lichtschranken und Türöffnungssensoren,... arbeiten. So kompliziert wollte ich es aber gar nicht machen.

Genau, die Lampe schaltet momentan noch immer um, wenn irgendeine Karte gelesen wird, da beide Werte die ganze Zeit 0 sind.

Mein Ziel:

  • Person A meldet sich an
  • Ampel auf rot
  • Person B (und C,....) halten ihren Chip davor, die Ampel bleibt auf rot. Diese Nummern müssen nicht abgespeichert werden.
  • Person A meldet sich ab
  • Ampel auf grün
  • Person B kann sich anmelden.

Und ein Reset, falls jemand vergisst sich abzumelden.

Die Nummern sollen nicht länger gespeichert werden. Sobald man wieder hinausgeht, soll die Nummer wieder vergessen werden. Und es wird auch nicht zugeordnet, wer welchen Chip bekommt. Ich möchte auch vorher gar nicht alle Chips einlesen und die Nummern abspeichern um sie dann abgleichen zu können. Man weiß also gar nicht, welche Nummern existieren oder wem sie zugeordnet sind.

Viele eurer Gedanken hatte ich mir auch schon gemacht, aber noch nicht im Code umgesetzt, da es schon daran scheiterte, den gerade ausgelesenen Code zwischenzuspeichern und abrufen zu können bzw. einen zweiten Code auszulesen und mit dem ersten zu vergleichen.

Hier konnte ich den Rückgabewert aus meiner Funktion unter der Variable "ergebnis" abspeichern und ausgeben.

int a = 1;
int b = 3;
int c;


int addition() {
  c = a + b;
  return c;
}


void setup() {
  Serial.begin(9600);
}

void loop() {

  int ergebnis = addition();
  Serial.println(ergebnis);
  delay(1000);
}

Hier konnte ich den Rückgabewert vom Auslesen auch als Variable "codeEins" speichern und ausgeben.

#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);


// Funktion um die Nummer auszulesen
long auslesen() {
  long code = 0;
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) { //Wenn eine Karte gefunden und gelesen wird

    for (byte i = 0; i < mfrc522.uid.size; i++) {
      code = ((code + mfrc522.uid.uidByte[i]) * 10); //Kartennummer wird unter der Variablen "code" abgespeichert
    }
  }
  return code;
}


void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
}

void loop() {
  long codeEins = auslesen();
  Serial.print("Die Kartennummer 1 lautet:");
  Serial.println(codeEins); 
  delay(1000);
}

Aber in meinem Code ging es dann nicht mehr.

while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
  long codeEins = auslesen();
Serial.print("Die Kartennummer 1 lautet:");
  Serial.println(codeEins);

Dieser Abschnitt war so gedacht, dass der Arduino so lange wartet, bis wieder eine Karte präsentiert wird.

Muss ich die Methode vorher nochmal aufrufen?
Wenn ich es so mache (Zeile "auslesen();):

while (!mfrc522.PICC_IsNewCardPresent() && !mfrc522.PICC_ReadCardSerial()) {}
  auslesen();
  long codeEins = auslesen();
  Serial.print("Die Kartennummer 1 lautet:");
  Serial.println(codeEins);

wird mir die Nummer angezeigt.
War es wirklich so einfach...??
Warum hat das in meinem Test oben auch ohne funktioniert?

Ich werde weiter an meinem Code arbeiten...