Codevergleich aus Liste, wie fange ich an?

Hallo zusammen,

ich möchte einen Codevergleich eines eingegebenen Codes mit einer Codeliste programmieren, wie stelle ich das am besten an?

Mein Ansatz ist der Folgende:

Ich gebe dem Arduino eine bestimmte Menge an richtigen Codes vor. Wenn ich einen Code erhalte soll dieser mit den zulässigen Codes verglichen werden und dann die entsprechende Aktion durchgeführt werden.

Wie gebe ich dem Arduino die Codes vor? Kann ich das so lösen, dass ich jedem Code eine Definition gebe, also z.B.

int code1 = 1234567890
int code2 = 0987654321
int code3 = 6754238923
...
...
...
int code10 = 9536547829

Wenn das so geht, wie mache ich dann den Vergleich?

Muss ich den eingelesenen Code dann mit jedem richtigen Code in einer if-Schleife vergleichen um eine Aktion auszulösen oder gibt es da eine andere Funktion?

Mein Sketch hätte ungefähr den folgenden Aufbau:

1.(Liste der Codes)

-> hier mit definierter Codeliste arbeiten?

2.(Warte auf neuen Code)

-> Code über Tastatur, RFID, oder sonst irgendwie einlesen

3.(Codevergleich)

-> mit if-Bedingung für jeden Code, oder gibt es eine bessere Möglichkeit?

4a.(wenn Bedingung Codegleichheit erfüllt -> "öffne die Bundeslade")

-> ergibt sich diese Bedingung schon aus 3., wenn jeder Code mit "if" verglichen wird, also z.B.

if
{ codeneu == code1
 digital.Write(Ausgabepin,HIGH);
}

4b.(wenn Bedingung Codegleichheit nicht erfüllt ->"zünde die Bombe")
hier dann mit einer "else" Funktion arbeiten?

Ist mein Ansatz richtig, oder bin ich da auf dem falschen Dampfer?
Bin über jeden Tip froh... :confused:

Arrays! Arrays und for-Schleifen sind immer eine gute Idee. int geht auf gar keinen Fall als Datentyp. unsigned long eventuell. Ein Array aus char wäre auch eine Option.

Hier gab es gerade erst so eine ähnliche Anwendung:
http://forum.arduino.cc/index.php?topic=371679.msg2565130#msg2565130
Verwendet < und > als Anfangs- und Endzeichen. Dazwischen eine beliebige Anzahl an ASCII Zeichen oder auch rohen Bytes.

Kann man auch so schreiben, dass keine Anfangs- oder Endzeichen verwendet werden. Siehe Antwort #10 auf der ersten Seite.

Kommt aber letztlich darauf an wie lange deine Codes sind. Wenn die in einen unsigned long passen (geht bis 4.294.967.295), reicht auch if/else, bzw. switch/case

Du hast da den typischen Anwendungsfall für SwitchCase: https://www.arduino.cc/en/Reference/SwitchCase

Das wäre bei dir

switch (codeneu){
case 1234567890
//tue dies und das
break;
case 0987654321
//tue was anderes
break;

.....

default
//code nicht erkannt
break;
}

Vorsicht mit den Vergleichsdaten! Zahlen, die mit 0 beginnen, werden als Oktalzahlen übersetzt, nicht dezimal. Also führende Nullen weglassen.

Und was für Werte willst Du tatsächlich vergleichen, Zahlenwerte (int oder long), oder Strings (char)?
Oder anders gefragt: was für ein Gerät wird für die Eingabe des Codes benutzt, was für Daten liefert das?

Sorry, hat ein paar Tage gedauert, hatte zu viel anderes zu tun.

DrDiettrich:
Vorsicht mit den Vergleichsdaten! Zahlen, die mit 0 beginnen, werden als Oktalzahlen übersetzt, nicht dezimal. Also führende Nullen weglassen.

ist das auch so wenn ich einen Code als "int" definiere?

Und was für Werte willst Du tatsächlich vergleichen, Zahlenwerte (int oder long), oder Strings (char)?
Oder anders gefragt: was für ein Gerät wird für die Eingabe des Codes benutzt, was für Daten liefert das?

ich möchte einen Zahlencode als Dezimalzahlen aus einem RFID-Modul auslesen, ich habe mir mal 10 bekannte und einige unbekannte Codes vorgenommen. Damit möchte ich eine Art Sortierstation mit einer Weiche bauen, praktisch die Codes 1 bis 5 sollen in den ersten Schacht geschoben werden, 6 bis 10 in den zweiten und die übrigen in den dritten Schacht.

Nach dem wie ich es verstanden habe ist hier der switch case wohl die richtige Anwendung.

Bin ich hier auf dem richtigen Weg, wenn ich den Sketch wie folgt aufbaue:

  1. die Libraries, etc einbinden, Pins definieren, etc.

  2. die 10 Codes definieren über

int code0 = 1111111
int code1 = 2222222
...
int code2 = 9999999
  1. den Switch-Case aufbauen
switch (codeneu){
  case 1111111
    //schalte Pin X HIGH, Warte auf Sensor im Schacht 1, schalte Pin X LOW
    break;

...

  case 555555
    //schalte Pin Y HIGH, Warte auf Sensor im Schacht 2, schalte Pin Y LOW
    break;

  .....

 default
    //Code passt nicht, schalte Pin Z HIGH, Warte auf Sensor im Schacht 3, schalte Pin Z LOW
  break;
  }

Wie Löse ich das dann mit dem nicht erkannten Code? Wird "default" immer dann ausgelöst wenn kein switch passt?

Chris779:
ist das auch so wenn ich einen Code als "int" definiere?

Das hat rein gar nichts mit dem Datentyp zu tun

Wie Löse ich das dann mit dem nicht erkannten Code? Wird "default" immer dann ausgelöst wenn kein switch passt?

Ja. Genau dafür ist es da

Du möchtest möglicherweise sowas:

#define CODE0 1111111
#define CODE1 2222222
...
#define CODE9 9999999

...

switch (codeneu){
  case CODE0:
    //schalte Pin X HIGH, Warte auf Sensor im Schacht 1, schalte Pin X LOW
    break;

...

  case CODE1:
    //schalte Pin Y HIGH, Warte auf Sensor im Schacht 2, schalte Pin Y LOW
    break;

  .....

 default:
    //Code passt nicht, schalte Pin Z HIGH, Warte auf Sensor im Schacht 3, schalte Pin Z LOW
  break;
  }

Da wird eine reine Textersetzung gemacht, aber Du hast die Definition am Sketchanfang.

EDIT: Doppelpunkt ergänzt

Nach dem "case X" und default fehlt bei euch noch der Doppelpunkt

Serenifly:
Das hat rein gar nichts mit dem Datentyp zu tun

Das bedeutet dann also dass wenn ein RFID-Chip einen Code mit führender "0" hat, der ankommende Code immer als Oktalzahl behandelt wird und ich einen solchen Chip nicht als Transponder verwenden kann?

:cry:

Das hat auch nichts dem RFID Chip zu tun! Wir reden hier von C. Wenn du in C Zahlen mit führenden Nullen schreibst werden die als Oktal-Zahl interpretiert. Das ist alles.

Ich verstehe manchmal nicht wieso Leute immer solche Probleme mit absoluten Grundlagen haben. Dass man Oktalzahlen oder deren Schreibweise in C nicht kennt ist ok. Die sind heutzutage obskur und den Fehler gibt öfters. Aber zu verstehen wie Variablen deklariert werden sollte doch zu den aller ersten Sachen gehören die man lernt!

Datentyp Variablenname = Integer-Literal;

Das sind zwei Schritte! Zuerst wird das Literal vom Parser interpretiert und dann der Variable zugewiesen. Was rechts steht hat erst mal nichts mit dem was links steht zu tun! Der Datentyp kann byte, int, long oder was auch immer sein. Rechts gibt es eben 0nnnn für Oktal, 0xnnnn für Hexadezimal und alles andere ist Dezimal

Wenn deine RFID Tags Codes mit führenden Nullen haben kommt es dann auf das Format an. Wenn es ein ASCII String ist, dann muss man '0' natürlich beachten. Wenn du den eingelesen Code als Integer bekommst, wirst du führende Nullen wohl ignorieren können.

Serenifly:
:cry:

Das hat auch nichts dem RFID Chip zu tun! Wir reden hier von C. Wenn du in C Zahlen mit führenden Nullen schreibst werden die als Oktal-Zahl interpretiert. Das ist alles.

genau das war meine Frage. Hier hat es insofern was mit dem RFID-Chip zu tun, da hier her meine Codes kommen :wink:
Ich hätte die Frage auch ohne das Wort "RFID stellen können...

Ich verstehe manchmal nicht wieso Leute immer solche Probleme mit absoluten Grundlagen haben. Dass man Oktalzahlen oder deren Schreibweise in C nicht kennt ist ok. Die sind heutzutage obskur und den Fehler gibt öfters. Aber zu verstehen wie Variablen deklariert werden sollte doch zu den aller ersten Sachen gehören die man lernt!

Ich kenne die Oktalzahlen noch aus meiner Ausbildung, auch KV-Diagramme, etc. sind mir ein Begriff.
Es tut mir Leid dass die Welt der SPSen von Siemens, Mitsubishi, Eaton und Schneider eine andere als die der Arduinos ist.
Ich bin hier ein Neuling, der gerne etwas neues lernen will und das hier ist eines meiner ersten problemorientierten Projekte :confused:

Datentyp Variablenname = Integer-Literal;

Das sind zwei Schritte! Zuerst wird das Literal vom Parser interpretiert und dann der Variable zugewiesen. Was rechts steht hat erst mal nichts mit dem was links steht zu tun! Der Datentyp kann byte, int, long oder was auch immer sein. Rechts gibt es eben 0nnnn für Oktal, 0xnnnn für Hexadezimal und alles andere ist Dezimal

Wenn deine RFID Tags Codes mit führenden Nullen haben kommt es dann auf das Format an. Wenn es ein ASCII String ist, dann muss man '0' natürlich beachten. Wenn du den eingelesen Code als Integer bekommst, wirst du führende Nullen wohl ignorieren können.

Danke für diese Erklärung, jetzt weiß ich das auch. Ich habe es ausprobiert, wenn ich bei dem einen XXID-Chip die führenden "00" weg lasse wird der case eindeutig ausgeführt.
Danke! :wink:

agmue:
Du möchtest möglicherweise sowas:

#define CODE0 1111111

#define CODE1 2222222
...
#define CODE9 9999999

...

switch (codeneu){
 case CODE0:
   //schalte Pin X HIGH, Warte auf Sensor im Schacht 1, schalte Pin X LOW
   break;

...

case CODE1:
   //schalte Pin Y HIGH, Warte auf Sensor im Schacht 2, schalte Pin Y LOW
   break;

.....

default:
   //Code passt nicht, schalte Pin Z HIGH, Warte auf Sensor im Schacht 3, schalte Pin Z LOW
 break;
 }



Da wird eine reine Textersetzung gemacht, aber Du hast die Definition am Sketchanfang.

EDIT: Doppelpunkt ergänzt

Ja, genau, so habe ich das gebraucht. Das hat in der Grundfunktion geklappt, ich habe das zum testen jetzt mal so gelöst:

#include <SPI.h>    //serielle Peripheriekommunikation einbinden
#include <MFRC522.h> // Library für Lesemodul einfügen

#define SS_PIN 10   // Slave Select auf Pin 10 einstellen
#define RST_PIN 9   // Reset auf Pin 9 einstellen

#define CODE0 285440    //Codedefinition
#define CODE1 2522560   //Codedefinition

MFRC522 mfrc522(SS_PIN, RST_PIN);   //Definitionen für Lesemodul

 

void setup()

{

Serial.begin(9600);
SPI.begin();

mfrc522.PCD_Init();     //Initialisierung Leseeinheit

}

 

void loop()

{

if ( ! mfrc522.PICC_IsNewCardPresent())   // wenn neue Karte vorhanden

{

return;   // mache weiter

}

 

if ( ! mfrc522.PICC_ReadCardSerial())     //wenn Code auslesbar

{

return;   // mache weiter

}

 

long code=0;      // Definition Variable "code"

for (byte i = 0; i < mfrc522.uid.size; i++) // Codelänge definieren

 

 

{

code=((code+mfrc522.uid.uidByte[i])*10);  // Wertübernahme für Variable "code"

}

 
switch (code){    // switch aufbauen
  case CODE0:  // falls Code 1 erkannt
    Serial.print("Code 1 erkannt"); //schreibe "Code 1 ekannt an Seral monitor
    delay (1000); //warte eine Sekunde, später durch millis ersetzen
    break; // ende

  case CODE1:
    Serial.print("Code 2 erkannt");
    delay (1000);
    
    break;

default:  // wenn kein bekannter Code eingelesen wird
 Serial.print("falscher Code erkannt");
    delay (1000);
  break;
 

}
}

Sorry, dass ich etwas giftig rüberkam. Ich habe das auch nicht nur auf dich speziell bezogen. Mich verwundert es nur ab und zu mal welche Projekte manche Leute anfassen ohne grundlegende Dinge der Programmiersprache zu verstehen. Dass man nicht alle Details kennt ist klar, aber hier ging es u.a. darum dass der Datentyp einer Variable nichts damit zu tun hat wie man als Programmierer eine Zahl schreibt. Auch der Inhalt ist streng genommen davon unabhängig, da letztlich alles Binär ist.

Hier wird es wohl wirklich um den Unterschied zwischen SPS und Computer-Programmierung allgemein gehen. Das ist zwar oberflächlich ähnlich, aber geht im Detail doch stark auseinander. Das ist übrigens nicht mal eine reine C Sache. Auch andere Sprachen haben da bestimmte Schreibweisen für verschiedene Zahlensysteme. Wobei C mit der einfachen 0 davor gemein ist. "0o" oder "o" wie in manchen anderen Sprachen wäre da sinnvoller.

Ich gehe mal davon aus, daß Du Deinen Sketch hier zeigst, damit er kritisch betrachtet wird. Also der Kommentar return; // mache weiter sollte wohl return; // mache nicht weiter lauten, oder?
Mit unsigned long code kannst Du doppelt so große Zahlen verwenden, da negative nicht benötigt werden.

Serenifly:
Sorry, dass ich etwas giftig rüberkam. Ich habe das auch nicht nur auf dich speziell bezogen. Mich verwundert es nur ab und zu mal welche Projekte manche Leute anfassen ohne grundlegende Dinge der Programmiersprache zu verstehen. Dass man nicht alle Details kennt ist klar, aber hier ging es u.a. darum dass der Datentyp einer Variable nichts damit zu tun hat wie man als Programmierer eine Zahl schreibt. Auch der Inhalt ist streng genommen davon unabhängig, da letztlich alles Binär ist.

Hier wird es wohl wirklich um den Unterschied zwischen SPS und Computer-Programmierung allgemein gehen. Das ist zwar oberflächlich ähnlich, aber geht im Detail doch stark auseinander. Das ist übrigens nicht mal eine reine C Sache. Auch andere Sprachen haben da bestimmte Schreibweisen für verschiedene Zahlensysteme. Wobei C mit der einfachen 0 davor gemein ist. "0o" oder "o" wie in manchen anderen Sprachen wäre da sinnvoller.

passt schon, ich wollte nur mal kurz meinen Hintergrund darstellen.
ich bin recht "unbedarft" was Hochsprachen angeht und das will ich mit dem Arduino als "Spielzeug" ändern.
Bei den SPS hat man eben den Vorteil dass man für jedes Problem mit irgend einer Komponente einen Fachmann ans Telefon bekommt, der eine Lösung parat hat. Allerdings bekommt man dann auch keine "CPU" für den Preis eines Mega, sondern höchstens die Anschlussklemmen. Bei den Microkontrollern ist man eben auf die Hilfe eines Forums wie diesem hier angewiesen und muss einen Kommunikationsweg zwischen Nerd und Trottel(also ich) finden.
Ich habe mich durch mehrere Tutorials gelesen und programmiert, aber der Unterschied zwischen Schule und Beruf macht sich eben erst bei den ersten "eigenen" Gehversuchen bemerkbar...

agmue:
Ich gehe mal davon aus, daß Du Deinen Sketch hier zeigst, damit er kritisch betrachtet wird. Also der Kommentar return; // mache weiter sollte wohl return; // mache nicht weiter lauten, oder?
Mit unsigned long code kannst Du doppelt so große Zahlen verwenden, da negative nicht benötigt werden.

Eigentlich habe ich den Code hier mal für den einen oder anderen Newbie reingesetzt um einen Ansatz zu finden, wenn sich jemand genau so blöd anstellt wie ich :smiley:

ich habe es so verstanden, dass "return" bedeutet, dass das Programm weiter laufen soll, wenn die Bedingung erfüllt ist, in meinem Sketch also wenn eine neue Karte erkannt wird?!

"unsigned long" meinst du an der Stelle "long code=0;" bei der Definition?
Das habe ich so aus dem Programmbeispiel übernommen, ich werde es mal umschreiben.
EDIT:
habs probiert, ich nutze jetzt "unsigned long".

Chris779:
ich habe es so verstanden, dass "return" bedeutet, dass das Programm weiter laufen soll, wenn die Bedingung erfüllt ist, in meinem Sketch also wenn eine neue Karte erkannt wird?!

Nö, return wird eigentlich als Ende einer Funktion genutzt: "Terminate a function and return a value from a function to the calling function, if desired." In diesem Fall wird loop() beendet.

Das macht auch Sinn:

if ( ! mfrc522.PICC_IsNewCardPresent())   // wenn neue Karte nicht vorhanden
{
return;   // mache nicht weiter
}

PICC_IsNewCardPresent() sollte wahr sein, wenn die Karte vorhanden ist. Durch "!" wird dies negiert. Sinnvoller wäre das in einer eigenen Funktion zu nutzen:

bool kartelesen()
{
  if ( ! mfrc522.PICC_IsNewCardPresent())   // wenn neue Karte nicht vorhanden
  {
    return false;   // mache nicht weiter, Fehler
  }
...
  return true;     // fertig, kein Fehler
}

Chris779:
ich habe es so verstanden, dass "return" bedeutet, dass das Programm weiter laufen soll, wenn die Bedingung erfüllt ist, in meinem Sketch also wenn eine neue Karte erkannt wird?!

Das ist wohl eher eine Frage des Standpunktes:

Mit "return" wir die Funktion beendet und verlassen, und das Programm der darüberliegenden Ebene weiter ausgeführt.

guntherb:
Das ist wohl eher eine Frage des Standpunktes:

Mit "return" wir die Funktion beendet und verlassen, und das Programm der darüberliegenden Ebene weiter ausgeführt.

So habe ich das gemeint :wink: