einzelne iButton LED´s zuweisen

Hallo Community,

vorab möchte ich gerne betonen, dass ich ein totaler Neuling bin. Meine letzten Aufgaben konnte ich immer peu à peu erledigen und mich durchangeln, bei dieser hier beiße ich allerdings auf Granit.

Die Aufgabe ist es verschiedene iButtons (5) den LED´s zuzuweisen, welche dann in der Reihenfolge binär aufleuchten sollen (001 - 010 - usw.) soweit so gut, damit gabs keine Schwierigkeiten.
Jetzt ist es jedoch so, dass die ID´s der iButton nicht einfach in den Sketch sollen, die sollen in einen nicht flüchtigen Speicher - ich habe mich dabei für eine Text-Datei entschieden. In denen habe ich die ID´s eingetragen und diese Lese ich mit meinem Sketch aus und Speicher diese als String.

Um nun den iButtons den LED´s zuzuweisen muss ich einen Vergleich anstellen, zwischen der ibutton ID (welche grade gelesen wird) und den Strings aus den Text Dokumenten.
Der Vergleich haut bei mir allerdings nicht hin, ich denke es liegt daran, dass ich die ausgelesene ID des iButton nicht richtig als String darstelle. (obwohl ich eigentlich auch dies über den Ser. Monitor getestet hatte, dort waren ID aus dem Text Dokument und ID welche ausgelesen wird exakt gleich, der Vergleich klappte jedoch nicht)

Ihr fragt euch sicherlich warum die ID`s aus einem Text Dokument abfragen wenn man es doch viel einfacher machen kann. Das muss ich tun, denn es soll auch eine Funktion des “anlernen” der iButtons erfolgen. Sprich das System erkennt meinen iButton nicht, aber ich habe die Möglichkeit die unbekannte ID in ein Text Dokument zu schreiben und wieder auszulesen - somit “anzulernen”.

Programmieren tue ich das ganze (versuche es) für einen ESP8266.
In einem vorhergehenden Sketch hatte ich den Vergleich, inspiriert aus dem Forum, noch auf eine andere Art und Weise versucht (über “==”), jedoch las ich im Internet, dass dies bei Strings zu Problemen führen kann.

Ich hoffe ich konnte mein Problem und meine Aufgabe einigermaßen verständlich erklären, zu dem hoffe ich natürlich sehr, dass ihr mir zu einer Lösung verhelfen könnt, denn ich stehe leider momentan echt auf dem Schlauch.
Meinen zusammengebastelten Sketch füge ich natürlich ein (hier habe ich die iButtons zum Test erstamal aufzwei beschränkt, anders als obern beschreiben).

OneWire library

#include <OneWire.h>
#include <FS.h>

OneWire ibutton (0);

byte buffer[10];

//LED für Binär-Code
int GELB1 = 4;
int GELB2 = 5;
int GELB3 = 16;

//LED ungültiger iButton
int ROT = 2;


void setup()
{
  Serial.begin(115200);
  pinMode(GELB1, OUTPUT);
  pinMode(GELB2, OUTPUT);
  pinMode(GELB3, OUTPUT);
  pinMode(ROT, OUTPUT);
  digitalWrite(GELB1, LOW);
  digitalWrite(GELB2, LOW);
  digitalWrite(GELB3, LOW);
  digitalWrite(ROT, LOW);
  delay(4000);
  Serial.println("Bitte iButton anlegen - ");
  Serial.println("__");
}

void loop() {

  if (!ibutton.search (buffer)) {
    ibutton.reset_search();
    digitalWrite(GELB1, LOW);
    digitalWrite(GELB2, LOW);
    digitalWrite(GELB3, LOW);
    digitalWrite(ROT, LOW);
    return;
  }

  //iButton ID in ser. Mon.
  Serial.println("iButton ID:");
  for (int x = 0; x < 10; x++)
  {
    Serial.print(String(buffer[x]));
  }
  Serial.println("\n");


  //ersten Schlüssel auslesen (aus txt.dokument)
  SPIFFS.begin();
  File f = SPIFFS.open( "/Schluessel.txt", "r");
  if (!f)
  {
    Serial.println("Datei öffnen Fehlgeschlagen");
  }

  //ausgelesenen Schlüssel im String speichern
  String data = f.readString();
  f.close();
  Serial.println("Inhalt der geöffneten Datei-Schluessel:");
  Serial.println(data);
  Serial.println("__");
  delay(222);



  //zweiten Schlüssel auslesen (aus text.dokument)
  SPIFFS.begin();
  File g = SPIFFS.open( "/Schluessel2.txt", "r");
  if (!g)
  {
    Serial.println("Datei öffnen Fehlgeschlagen");
  }

  //ausgelesenen Schlüssel im String speichern
  String data2 = g.readString();
  g.close();
  Serial.println("Inhalt der geöffneten Datei-Schluessel2:");
  Serial.println(data2);
  Serial.println("__");
  delay(222);


  //------------------------
  //Vergleich erster iButton
  for (int x = 0; x < 10; x++)
    Serial.print(String(buffer[x]));
  Serial.println("\n");
  delay(3222);
  for (int x = 0; x < 10; x++)
    //data = ausegelesene ID und "String buffer" = eingelesenen ID (vom iButton) als String
    if (data.equals(String(buffer[x])))
    {
      Serial.println("iButton ID gütlig");
      Serial.println("iButton 1 erkannt");
      Serial.println("001 - 1");
      digitalWrite(GELB1, LOW);
      digitalWrite(GELB2, LOW);
      digitalWrite(GELB3, HIGH);
      delay(5000);
      Serial.println("__");
    }
    else {
      Serial.println("iButton ungültig");
      digitalWrite(ROT, HIGH);
      return;
    }


  //------------------------
  //Vergleich zweiter iButton
  for (int x = 0; x < 10; x++)
    Serial.print(String(buffer[x]));
  Serial.println("\n");
  delay(3222);
  for (int x = 0; x < 10; x++)
    //data2 = ausegelesene ID und "String buffer" = eingelesenen ID (vom iButton) als String
    if (data2.equals(String(buffer[x])))
    {
      Serial.println("iButton ID gütlig");
      Serial.println("iButton 2 erkannt");
      Serial.println("010 - 2");
      digitalWrite(GELB1, LOW);
      digitalWrite(GELB2, HIGH);
      digitalWrite(GELB3, LOW);
      delay(5000);
      Serial.println("__");
    }
    else {
      Serial.println("iButton ungültig");
      digitalWrite(ROT, HIGH);
      return;
    }




}

Gruß Hannes

iButton_Sketch_Forum.ino (3.22 KB)

Programmieren tue ich das ganze (versuche es) für einen ESP8266, was ich gerne als Info gebe, allerdings nicht von Bedeutung sein sollte.

du irrst, die Angabe des Target ist sehr bedeutend für uns.

Nun aber, was ist die konkret Frage? Oder willst dein Konzept generell in Frage stellen?

noiasca:
du irrst, die Angabe des Target ist sehr bedeutend für uns.

Nun aber, was ist die konkret Frage? Oder willst dein Konzept generell in Frage stellen?

Das habe ich gleich korregiert.
Ja generell stelle ich das Konzept / den Sketch in Frage.
Beziehungsweise wüsste ich gerne, ob das Sinn macht und warum es nicht ganz hinhaut.

myllabfuhr:
Das habe ich gleich korregiert.
Ja generell stelle ich das Konzept / den Sketch in Frage.
Beziehungsweise wüsste ich gerne, ob das Sinn macht und warum es nicht ganz hinhaut.

Dann poste doch bitte deinen Sketch hier in Code-Tags, damit alle, auch mobile User am Smartphone und Tablet deinen Sketch richtig lesen können.
Verwende dazu die Schaltfläche </> oben links im Editor-Fenster.

HotSystems:
Dann poste doch bitte deinen Sketch hier in Code-Tags, damit alle, auch mobile User am Smartphone und Tablet deinen Sketch richtig lesen können.
Verwende dazu die Schaltfläche </> oben links im Editor-Fenster.

Erledigt, danke dir.

als erstes solltest du uns genau beschreiben was du aus der iButton als Ergebnis bekommst.
byte buffer[10];?
Also genau dieses byte Array befüllt?

außerdem, einen Link auf die Lib setzen dass wir uns das ansehen können. Vieleicht gibts auch ein Beispiel in der Lib wie man auf ein (hardcoded) tag prüft.

ich würde die Datei übrigens durch den ESP schreiben lassen,
vermutlich komma-separted die einzelnen (10?) Bytes je Tag und mit einem CR/LF abschließen.
und beim einlesen einfach mit STRTOK zerteilen.
CSV ist halt so ein Kompromiss zwischen Mensch-Lesbar und Maschinen-Lesbar.

Manches verstehe ich in dem Programm nicht!

File f = SPIFFS.open( "/Schluessel.txt", "r");

if (!f)
 {
   Serial.println("Datei öffnen Fehlgeschlagen");
 }

//ausgelesenen Schlüssel im String speichern
 String data = f.readString();

Hier frage ich mich: Warum wird nach feststellen, dass die Datei nicht geöffnet wurde, noch ganz optimistisch ein String gelesen?
Als wenn man versucht in ein Auto einzusteigen, obwohl man doch gerade festgestellt hat, das es geklaut wurde.

Auch mehrfach zu finden:

 Serial.print(String(buffer[x]));

Wozu der Umweg über die String Klasse?

Was gefällt an:

Serial.print(buffer[x]);

nicht?

combie:
Manches verstehe ich in dem Programm nicht!
Hier frage ich mich: Warum wird nach feststellen, dass die Datei nicht geöffnet wurde, noch ganz optimistisch ein String gelesen?
Als wenn man versucht in ein Auto einzusteigen, obwohl man doch gerade festgestellt hat, das es geklaut wurde.

Auch mehrfach zu finden:

 Serial.print(String(buffer[x]));

Wozu der Umweg über die String Klasse?

Was gefällt an:

Serial.print(buffer[x]);

nicht?

Das oben stimmt, das muss ich nochmal umändern, danke für den Hinweis.

Der Umweg über die String Klasse ist Notwendig damit ich die ausgelesene iButton ID (buffer) mit der im Text Dokument gespeicherten ID vergleichen kann, ein Vergleich zweier Strings.
Jedoch bin ich mir bei dem Punkt ja auch unsicher, ob das so überhaupt richtig umgewandelt und allgemein der richtige Weg ist.

und wenn man - Serial.print(buffer); - benutzt kommt das gleiche bei raus, ich bin aber der Meinung dann klappt der Vergleich wieder nicht.

Du solltest Dich grundlegend mit Zeichenketten beschäftigen. Hier gibt es einige Infos dazu.

Gruß Tommy

noiasca:
als erstes solltest du uns genau beschreiben was du aus der iButton als Ergebnis bekommst.
byte buffer[10];?
Also genau dieses byte Array befüllt?

außerdem, einen Link auf die Lib setzen dass wir uns das ansehen können. Vieleicht gibts auch ein Beispiel in der Lib wie man auf ein (hardcoded) tag prüft.

ich würde die Datei übrigens durch den ESP schreiben lassen,
vermutlich komma-separted die einzelnen (10?) Bytes je Tag und mit einem CR/LF abschließen.
und beim einlesen einfach mit STRTOK zerteilen.
CSV ist halt so ein Kompromiss zwischen Mensch-Lesbar und Maschinen-Lesbar.

Genau, dieses bekomme ich befüllt wieder.

Link habe ich gesetzt, die FS.h library bekommt man wenn man das ESP8266 als Board hinzufügt und auswählt.

Die ID´s die schon festgelegt sind? Sprich derzeit in den Text Dokumenten stehen?
Bei den iButtons zum "anlernen" ist das ja selbstverständlich.
Und wie sollte ich denn den Vergleich machen, wenn ich den String zerlege? Ein String - String Vergleich ist dann ja nicht mehr möglich oder?

wir missverstehen einander.

WAS steht in den 10 Bytes des

byte buffer[10];

bei einem erfolgreich gelesenen iButton?

mach vorsichtshalber eine Ausgabe in Hex, separiere jede Zeile damit wir wirklich sehen, was da drinnen steht.

Serial.println((buffer), HEX);

Poste deine Serial.Monitor - Ausgabe (auch in Code-Tags!)

noiasca:
wir missverstehen einander.

WAS steht in den 10 Bytes des

byte buffer[10];

bei einem erfolgreich gelesenen iButton?

mach vorsichtshalber eine Ausgabe in Hex, separiere jede Zeile damit wir wirklich sehen, was da drinnen steht.

Serial.println((buffer), HEX);

Poste deine Serial.Monitor - Ausgabe (auch in Code-Tags!)

Bei erfolgreich ausgelesenen iButton escheint: 1262121911007200 (Dezimal) , 11AD4BF1004800 (Hexadezimal). Man kann das ganze der Übersichtshalber auch mit Kommata oder Leerzeichen ausgeben lassen: 1,26,212,191,1,0,0,72,0,0 (Kommata).

Ich hoffe das meinst du, sonst missverstehe ich dich wohl richtig.

1,26,212,191,1,0,0,72,0,0

ok, damit kann man arbeiten.

jetzt liest dich mal ein zu memcmp und dann vergleichst du einfach zwei Arrays.

das sollte doch nicht so schwierig sein oder?

Der Umweg über die String Klasse ist Notwendig damit ich die ausgelesene iButton ID (buffer) mit der im Text Dokument gespeicherten ID vergleichen kann, ein Vergleich zweier Strings.
Jedoch bin ich mir bei dem Punkt ja auch unsicher, ob das so überhaupt richtig umgewandelt und allgemein der richtige Weg ist.

und wenn man - Serial.print(buffer); - benutzt kommt das gleiche bei raus, ich bin aber der Meinung dann klappt der Vergleich wieder nicht.

Serial.print vergleicht doch nichts!
Und der erzeugte String wird auch mit nichts verglichen.
String erzeugen, ausgeben und verwerfen.
Ohne jeden Vergleich oder Einfluss auf irgendeinen Vergleich.
Einfach nur ein unnötiger Umweg über Posemuckel.

Hi

myllabfuhr:
...
Man kann das ganze der Übersichtshalber auch mit Kommata oder Leerzeichen ausgeben lassen: 1,26,212,191,1,0,0,72,0,0 (Kommata).

Also, auch ohne Übersichtshalber
11 A D4 B F 1 0 04 80 0 interpretiert ... wenn man denn will.
Dabei wurde doch expliziet: 01 1A D4 BF 01 00 00 48 00 00 übertragen - worin ich schon einen Unterschied sehe.

Weshalb Du hier die Werte in einen String kippen willst, erschließt sich mir zwar, ist aber völlig unnötig.
Vll. liegt's auch einfach an Deinem Verständnis der übertragenen Zahlen - die 'Nicht-Komma-Zahl' lässt zumindest darauf schließen ... 1 26 ist halt schon etwas Anderes als 12 6 ... wenn man nur die Zahlziffern zusammen klatscht, kann Das bei Übereinstimmung zwar klappen - aber auch, wenn eine falsche, aber so halt doch passende ID gelesen wurde.

MfG