Warten auf RFID Input

Hallo Zusammen

Ich möchte ein Rätsel bauen, bei dem man vier verschiedene RFID tags in der richtigen Reihenfolge nacheinander einlesen muss (über ein MFRC522), um es zu lösen.
Also sprich:
tag 1 abfragen

wenn dieser richtig ist, auf tag 2 warten

wenn dieser auch stimmt, auf tag 3 warten

etc.

sollte aber der falsche tag zum falschen Zeitpunkt eingelesen werden, dann springe wieder an den Anfang zurück und warte wieder auf tag 1.

Wie mach ich das am besten? Arbeite ich am besten mit diversen Voids?

Bitte entschuldigt die Anfängerfrage, bin relativ neu im Thema und komm seit ewig auf kein Lösungsweg..

Gruss Dave

Was ist eine Void? C++ verwendet functions. :wink:

eine Zustandsmaschine scheint angebracht

Hast du dir schon mal die Beispiele in der IDE angesehen ?
Diese helfen bei den meisten Problemen, um einen Anfang zu finden.
Weiteres findest du in den Beispielen der Library zum RFID-Reader.

Hallo,
Irgendwo musst Du die richtige Reihenfolge hinterlegen und dann am besten mit einer Schrittkette arbeiten.

schritt 1
Karte abfragen
richtige Karte schritt 2
schritt 2
Karte abfragen
richtige Karte schritt 3 nein schritt 1
schritt 3
Karte abfragen
richtige Karte schritt 4 nein schritt 1
schritt 4
Karte abfragen
richtige Karte (Hura) nein schritt 1

wie Du siehst kommt Karte anfragen mehrfach vor damit bietet sich an dazu eine Function zu verwenden. Du kannst auch mit Arrays arbeiten und den Ablauf mittels des index steuern.

Heinz

das Wort "void" legt fest das eine function keinen Wert zurückgibt.

Beispiele:

void myFunction ()

void BlaBlaQuatschi()

void Schrittkette()

Die Befehle innerhalb der function werden abgearbeitet und das war es.

functions können aber auch Werte zurückgeben

Beispiele:
meinMesswert = analogRead(TempSensor);

StartTaste = digitalRead(StartTasten_Pin);

blubblub = digitalRead(furzSchnurz)

an den unsinnigen Namen kannst du ablesen welche Namen man selbst aussuchen kann und welche nicht.

Die schon vordefinierten functions analogRead() bzw. digitalRead() geben einen Wert zurück

Beispiel für eine selbst definierte function

long mySumme (int Summand1, int Summand2) {
int summe = Summand1 + Summand2;
return Summe
}

die function mySumme gibt das Ergebnis der Rechenoperation Summand1 plus Summand2
zurück

Man könnte auch schreiben
long halliGalli (int Pubs, int Flasche) {
int Stuhl = Pubs + Flasche;
return Stuhl
}

aber diese Namen machen natürlich keinen Sinn.

Wenn du dieses Spiel programmieren willst, dann musst du erst einmal einige Stunden
ganz grundlegendes Programmieren lernen.
Sonst hast du hier - ungelogen - alle 30 Sekunden die nächste Frage.

Dieses grundlegende Programmieren hat noch nichts mit RFID lesen zu tun.

Das hier ist eine von vielen Einstiegsmöglichkeiten
https://www.hobbyelektroniker.ch/roboter/arduinoprogrammierung/

vgs

Doppelter Einspruch.
Void sagt daß kein Argument übergeben wird. Es kann in einer Funktion sowohl signalisieren daß kein Eingabewert übertragen wird als auch keine Rückgabewert.

void eineFuktion (void)

ist zulässig.

C kennt keine Befehle, weder außerhalb noch innerhalb von Funktionen.

Grüße Uwe

stimmt. Macht es einem newcomer aber schon schwerer. kogintive Interferenz.

Na dann dürfte es ja leicht fallen mal die wirklichen Fachbegriffe zu nennen.

Wie nennst du
die Nicht-Dinge die hier

beschreiben werden.?

Mach mal.
Wo Du doch sonst auch alles und jeden belehren kannst. Sei kritisch mit Dir selbst.

Der Compiler ist C++, nicht C.

C und C++ unterscheiden sich, wenn void als Argument der Funktion verwendet wird.

Wenn der TO relativ gut englisch kann könnte man auch dieses Tutorial als Einstieg nehmen

Arduino Programming Course

Noch eine Möglichkeit wäre sich die Texte von google-translate übersetzen zu lassen.
Ich habe das mal ausprobiert und fand das Ergebnis ganz passabel.
vgs

Auf alle Fälle nicht "Befehle".

Hallo Dave,

man kann einen Schrittweisen Programmablauf programmieren.
Das ist das was weiter oben auch schon einmal beschrieben wurde.
Im englishen nennt sich das "state-machine" Wenn man es eindeutscht könnte man es
Zustands-Automaten nennen.

Kannst du damit schon etwas anfangen?
Wenn du das Projekt weiterverfolgen willst müsstest du mal ein bisschen Input in Form von Fragen geben.

vgs

Stand schon in #4
sogar ausführlich und abschliesend erklärt...

Versuch mal - nur aus der holen Hand, ich kann das nicht testen.
Musst die Codes und Pins auf Dich anpassen, weil Du es leider bis jetzt nicht geschafft hast DEINEN Code zu zeigen.

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

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  pinMode (2, OUTPUT); // Relais
}

void loop()
{
  if ( ! mfrc522.PICC_IsNewCardPresent()) // neue Karte in den Seriellen Monitor schreiben
  {
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  long code = 0;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    code = ((code + mfrc522.uid.uidByte[i]) * 10);
  }
  Serial.print("Kartennummer:");
  Serial.println(code);
  if ((kartenSchritt == 0) && (code == 1643730))
  {
    kartenSchritt = 1;
  }
  else if (kartenSchritt == 1)
  {
    if (code == 1643731)
    {
      kartenSchritt = 2;
    }
    else
    {
      kartenSchritt = 0;
    }
  }
  else if (kartenSchritt == 2)
  {
    if (code == 1643732)
    {
      kartenSchritt = 3;
    }
    else
    {
      kartenSchritt = 0;
    }
  }
  else if (kartenSchritt == 3)
  {
    if (code == 1643733)
    {
      Serial.println(f("open!"));
      kartenSchritt = 0;

    }
    else
    {
      kartenSchritt = 0;
    }
  }
}

Und ihr seid schon bei #13, was da-po nicht geholfen hat.

Ich denke da bin ich der falsche Adressat - ich hab nicht darum gebeten, das sich hier um void oder nicht void gerangelt wird.

Aber ich nehm das mit...

Danke für die zahlreiche Antworten :smirk:
Basic programieren kann ich ja, nur sobald es um was neues geht (z.B. State-Machines), dann komm ich halt mal an meine Grenzen. Darum frag ich ja die Profis :wink:

Aber zum Thema: mit States zu arbeiten scheint mir eine vernünftige Vorgehensweise zu sein. Werde morgen (hoffentlich) mal ein paar Versuche starten und euch den Code präsentieren :wink:

Frage: Wenn man nun zum Beispiel state 3 "aktiviert", bleib der Controller in dem state in einer Schleife stecken oder springt er nach einem Durchgang wieder raus?

Gruss

Das Programm springt - vom internen Ablauf her gesehen - nach jedem Durchgang wieder heraus.

(Der Uwe kann mir ja mal in einem extra-Thread erklären warum das verwenden des Wortes Befehl in diesem Zusammenhang das Verständnis von Programmieren erschwert bis unmöglich macht)

Für den Benutzer sieht es von aussen so aus als ob das Programm nur in diesem Zustand bleibt.

Welche Befehle / Programmteile in welchem Zustand abgearbeitet werden hängt ja von der Programmierung ab. Man kann jeden Programmteil abhängig von if-bedingungen machen und dadurch steuern wann welcher Programmteil ausgeführt wird.

Man benutzt loop() als die eine große Schleife die immer durchlaufen wird.

void loop() {
  CheckeKarten();
  BlinkeLEDS();
  HintergrundMusikAbspielen();

mit jedem Durchlauf von loop wird in die drei functions
CheckeKarten();
BlinkeLEDS();
HintergrundMusikAbspielen();
"hinein gesprungen" und nach einem Durchlauf der function wieder "herausgesprungen"

so ganz treffend sind die Worte hin/heraussrpingen aber nicht. Man würde eher von function-Aufruf sprechen.

Dave wie gut kannst du denn englisch? Wenn man englische Tutorials zum lesen dazunehmen kann dann fallen mir viel mehr Tutorials ein als deutsche.
vgs

Noch nicht perfekt ausgereift aber es tut, was es soll:

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

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  pinMode (2, OUTPUT); // Relais
}

void loop()
{
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }
  long code = 0;
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    code = ((code + mfrc522.uid.uidByte[i]) * 10);
  }
  
  Serial.print("Kartennummer:");
  Serial.println(code);
  if ((kartenSchritt == 0) && (code == 497720))
  {
    kartenSchritt = 1;
     Serial.println("Schritt 1:");
      delay (1000);
  }
  else if (kartenSchritt == 1)
  {
    if (code == 651310)
    {
      kartenSchritt = 2;
      Serial.println("Schritt 2:");
      delay (1000);
    }
    else
    {
      kartenSchritt = 0;
       Serial.println("Schritt 0:");
      delay (1000);
    }
  }
  else if (kartenSchritt == 2)
  {
    if (code == 2036210)
    {
      kartenSchritt = 3;
        Serial.println("Schritt 3:");
      delay (1000);
    }
    else
    {
      kartenSchritt = 0;
        Serial.println("Schritt 0:");
      delay (1000);
    }
  }
  else if (kartenSchritt == 3)
  {
    if (code == 2266010)
    {
      Serial.println(("open!"));
      kartenSchritt = 0;
      delay (1000);

    }
    else
    {
      kartenSchritt = 0;
    }
  }
}

Wobei bei einem Teil bin ich mir nicht sicher, was er macht:

long code = 0;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
code = ((code + mfrc522.uid.uidByte[i]) * 10);
}

Ist das zur Verschlüsselung? Oder nur ein Werkzeug um etwas lesbarer zu machen? Theoretisch könnte man auch einfach die originale UID jeder Karte verwenden oder sehe ich das falsch?

Danke und Gruss

Das ist die UID umgewandelt in ein long.
Das macht das Vergleichen einfacher, weil man nicht jedesmal über die Bytes iterieren muss.