Grundsatzfragen SD lesen und Werte zuordnen.

Hallo in die Runde, ich fange nun grade an mich mal an dem Einsatz einer SD- Karte zu versuchen. Ich nutze die SD- Library und einen Teensy 3.6 mit dessen internem Kartenslot.

Das Ziel soll sein, dass ich Kalender- (und Wecker) Einträge am Teensy oder Rechner erstelle und auf der SD- Karte speicher, als Text- Datei sollte das ausreichen.

Mit dem Schreiben klappt alles wie gewünscht, ich bekomme meine Einträge erstellt, die aus einem Namen und einigen Zahlen bestehen und mit einem "," von einander getrennt sind.

Wie kann ich nun aber beim Einlesen der Werte diese verschiedenen Variablen zuordnen? Also wie muss ich den Sketch schreiben, damit er das "," als Trennzeichen erkennt?

Für grundsätzliche Tipps darüber hinaus wäre ich auch sehr dankbar. Also macht es eher Sinn für jeden Eintrag eine separate Datein zu erstellen? Oder besser alle in eine Datei? Wie kann ich per Sketch bestimmte Zeilen löschen?

MaHa76:
Wie kann ich nun aber beim Einlesen der Werte diese verschiedenen Variablen zuordnen?

Grundsätzlich gibt es folgende, mir hier sinnvoll erscheinende Möglichkeiten:

  1. Du speicherst gemeinsam mit dem Wert auch den Bezeichner, beispielsweise "Breite:50". Die Reihenfolge ist damit beliebig, erfordert aber mehr Aufwand.

  2. Du speicherst alle Werte in einer festen Reihenfolge, so daß die Position die Bedeutung eines Wertes angibt. Einfacher aber auch fehlerträchtiger.

MaHa76:
Also macht es eher Sinn für jeden Eintrag eine separate Datein zu erstellen? Oder besser alle in eine Datei?

Das kann man allgemein kaum beantworten.

MaHa76:
Wie kann ich per Sketch bestimmte Zeilen löschen?

Ich wüßte nicht, daß das geht. Du kannst aber eine Dateikopie erstellen und den Inhalt durch einen Filter verändern. Oder jeder Termin steht in einer eigenen Datei, die nach Verwendung gelöscht wird.

Ich möchte Dir einen Blick in das Beispiel readCSV der Bibliothek SdFat vorschlagen, da sollten einige Deiner Fragen eine Antwort finden. Ob SdFat beim Teensy 3.6 funktioniert, weiß ich allerdings nicht.

@MaHa76: Wenn Du die Daten am PC erzeugen willst, ist das Textformat vorzuziehen, da beide Systeme evtl. unterschiedliche Längen/Ausrichtungen für Datentypen haben.
Wenn Du sie händisch erzeugst, ist die Variante Schlüsselwort1:Inhalt1;Schlüsselwort2:Inhalt2Zeilenvorschub die bessere. Du musst vor allem nicht immer alle Werte angeben.

Für eine Steuerung einer RGB-LED über Serial habe ich mal sowas zusammengebaut. Da sind verschiedene Entwicklungsstände drin. Evtl. kannst Du beim Einlesen davon was recyceln.

Gruß Tommy

Hier ein ähnliches Projekt von mir:

http://forum.arduino.cc/index.php?topic=491121.0

Viele Grüße
Jörg

Das ist ein interessantes Projekt.

Gruß Tommy

Hi

Ein Müll-Kalender gab einen Pluspunkt und eine Nennung auf meiner To-Do-Liste.

MfG

Für grundsätzliche Tipps darüber hinaus wäre ich auch sehr dankbar. Also macht es eher Sinn für jeden Eintrag eine separate Datein zu erstellen? Oder besser alle in eine Datei? Wie kann ich per Sketch bestimmte Zeilen löschen?

Wenn die Daten nicht am PC editiert werden müssen, dann ist ganz klar eine feste Blockgröße vorzuziehen.

Also alle Daten, pro Termin, in eine Struktur, und die in einem Wumms lesen und schreiben, ohne jede Verarbeitung.

Für "Gelöscht", kann man in der Struktur ein Flag vorsehen.

Vor allem vielen Dank an Jörg!!!! Das ist ja mal echt ein tolles Projekt- vor allem - wenn ich es richtig verstanden habe - war das das erste Projekt!?! Ich bin sehr gespannt was da noch kommt :slight_smile:

Ich hoffe, dass mein Touch-TFT-Wecker-Kalender-Wetterstation-Lampensteuerung auch bald fertig wird und andere zum Nachbauen anregt :slight_smile:

Also, dass ich ein zu löschenden Eintrag nicht wirklich von der Karte löschen kann, sondern nur als ungültig markieren kann, wäre für mich eine Lösung, wenn ich man sicher stellen könnte, dass von hinten begonnen wird zu lesen. Ich hole mal noch etwas aus und erkläre die gewünschte Funktion.

Ich werde 2 Textdateien anlegen- eine für Kalendereinträge, einen für die Weckfunktionen.

Ich kann schon meine Wecker-Einträge erstellen und der Alarm geht auch pünktlich los- das speichern auf SD klappt auch- basierend auf Jörgs Umsetzung werde ich die Struktur anpassen und dann sollte auch das lesen an sich klappen.

Mein Gerät soll mit max. 10 Weckzeiten arbeiten, im Menu kann bekomme ich die Einträge untereinander gelistet und kann die dann dort aktivieren, deaktivieren und löschen, bzw. erstmal zum löschen markieren (hier ist eine Variable, die 0, 1 oder 2 sein kann)- gelöscht wird er erst, wenn ich im Feld daneben das löschen bestätige- die Markierung bleibt so lange erhalten, bis ich diese wieder änder- ich könnte also diese Kennung "fürs löschen vorgemerkt" schon dafür nutzen, dass dieser Eintrag auch auf der SD so geflaggt ist.
Nun würde ich den Eintrag aber quasi so lange einlesen, wie noch Platz im Gerät ist- erst wenn ein neuer Eintrag, also quasi ein 11. erstellt wird, sollte dann der zum löschen vorgemerkte Eintrag nicht mehr angezeigt werden.
Das Einlesen sollte also nach Prioritäten erfolgen- erst die Weckzeiten die mit "1" markiert sind (also aktive Wecker), dann die mit "0" (also deaktivierte) und wenn noch Platz ist könnte ich die mit "2" markierten noch reinholen, um sie bei Bedarf "wieder herstellen" zu können- ich kann ja dann hier reinbringen, dass die Variable bei bestätigtem Löschen "3" annimmt...

Warum passt du die Größe des Arrays nicht dynamisch an die Anzahl der Einträge an? In der loop mit static müsste das doch gehen?

Und warum kannst du die Daten nach dem tatsächlichen löschen der Einträge nicht mehr zurück schreiben?

Also das dynamische will ich bei den Kalendereinträgen versuchen... auch wenn ich schon 3 Jahre mit Arduino bastel bin ich noch immer blutiger Anfänger und tue mir mit einigen Sachen sehr schwer...

Ich hab zwar schon die Touchfunktion sehr flüßig zum laufen bekommen und eine Qwertz- Tastatur dafür selbst gebastelt und inzwischen bald 20 Menü-Ebenen/Zweige, aber ich glaube ganz vieles von meinem Code hätte man statt in 2000 Zeilen auch in 20 packen können...

Ich bin also froh wenn ich erstmal meine 10 festen Wecker- Plätze sauber zum laufen bringe :slight_smile:

Als nächstes muss ich mich mit der dynamischen Arraygröße befassen, weil der Kalender früher oder später durchaus Einträge im 3-stelligen Bereich haben kann.... :confused:

Im Moment hänge ich daran- den eingelesenen String in Zahlen die als Integer deklariert sind zu zerlegen- das Beispiel von Jörg arbeitet ja direkt mit string...
EDIT: das letzte Problem hing nur an einem Vertipper - sorry :slight_smile:

Alles in einen struct, dann Anzahl der Datensätze der sd Karte zählen und damit im loop ein
static daten[Anzahl der Datensätze + x];
x wäre die Reserve, wo du neue Daten rein schreiben kannst.
Allerdings muss man dann nach dem Speichern resetten, um neu einzulesen.
Wäre mein Ansatz Zum ausprobieren

Ui.... gibt es dafür ein Beispiel? Ich begreife am schnellsten wenn ich eine funktionierende Lösung sehe und damit rumspielen kann. :-[

Das es Sinn macht sehe ich schon anhand der Menge an Zeile für die paar Wecker-Einträge :o

Hab keinen Teensy zum rumspielen bzw. testen da.

Was kannst du von folgendem nicht:
0. struct mit deiner Datenstruktur anlegen

  1. Anzahl der Datensätze der sd Karte zählen

  2. static daten[Anzahl der Datensätze]; in die loop an den Anfang schreiben

  3. mit einer for Schleife for (uint16_t index=0; index<Anzahl der Datensätze;index++) in den struct array daten einlesen

  4. dto, aber eben daten array seriell testweise ausgeben

Eigentlich ist der Teensy gar nicht so anders wie ein Mega oder so...

also 2 und 3 traue ich mir zu- wenn auch mit etwas probieren...

Wenn du 3. kannst, kannst du auch 4.
Was ist mit 1.? Wie liest du jetzt ein?
0. da musst du dich etwas einlesen, das kannst nur du selbst, da wir ja deine Datenstrukturen nicht kennen.

Ich begreife am schnellsten wenn ich eine funktionierende Lösung sehe und damit rumspielen kann.

Am schnellsten vielleicht.

Meine Ansicht, aus eigener schmerzhafter Erfahrung, denn ich habe auch mal so argumentiert:

Aber die Tiefe bleibt einem dann verborgen.
Der Grund, warum es so getan wird, wie es getan wird, bleibt im Dunkel.
Darum lernt man das dann auch so schnell.

Da man das Verborgene, den Grund, nicht erfahren hat, ist es dann leider quasi unmöglich, das Verfahren, auf andere Problemstellungen zu transferieren.

Schade:
Habe gerade meine Platte nach einer (halb)fertigen Datenbank für kleine µC durchsucht. Denn hatte mal sowas gebastelt. Scheint leider futsch zu sein.

Im Grunde waren das nur ein paar Methoden, in einer Template Klasse, welche ein FileHandle bekommen haben, und damit beliebige Strukturen lesen und schreiben konnten.

Schade...

Wenn das eh nur maschinenlesbar ist, warum dann nicht ins Eeprom?

Man soll auch Datensätze am PC anlegen oder bearbeiten können- dafür bietet sich die SD- Karte an...

Ja und das Einlesen mache ich derzeit händisch, sehr rustikal, Schritt für Schritt, basierend auf dem Sketch von Jörg. Ich habe aber für jeden Weckeintrag eine eigene Datei. Was mich da aktuell als einziges stört, ist der Umstand, dass ich den Inhalt der Datei nicht löschen kann, um neue Daten anzulegen- bzw. die alten Daten einfach überschreiben kann...

Dann ist es eben etwas mehr Aufwand, das umzustricken. Die Einlese und Abspeicherfunktion wird etwas komplexer.

Zeig doch mal, wie du deine Daten nun strukturiert hast und den Inhalt eines Datenfiles

Soll ich dafür mal den kompletten Sketch hochladen? Oder reicht es ein paar Zeilen als Ausschnitt zu zeigen?