Go Down

Topic: <Solved> Arduino schreibt falsche Werte auf SD (Read 220 times) previous topic - next topic

ardumaker_ch

Sep 11, 2020, 05:36 pm Last Edit: Sep 12, 2020, 12:04 am by ardumaker_ch
Guten Tag zusammen

Ich bin neu im Forum und freue mich, hier zu sein.
Ich habe bereits einige Projekte auf dem Arduino realisiert, aber jetzt habe ich ein Problem mit meiner SD, die von einem Arduino Nano (alter Bootloader) bearbeitet wird.

Mein Programm macht folgendes: Zuerst rufe ich die Funktion set() auf. Diese liest eine Textdatei in ein String-Array (muss ein String-Array sein, da ich auch Zahlen durch Buchstaben ersetzen möchte) mit 8 Zeilen und 5 Spalten ein. Natürlich hat die SD genau diese 8 Zeilen und 5 Spalten.

Dann rufe ich die Funktion delet_row() auf, die die gewünschte Zeile "löscht", indem sie die Zeile beim Schreiben überspringt. Um die richtige Anzahl von Zeilen am Ende zu erhalten, füge ich am Ende eine neue Zeile ein, die mit Nullen gefüllt und wie der Rest durch ";" getrennt ist.

Mein Problem jetzt. Wenn ich das Programm zum ersten Mal starte, funktioniert alles einwandfrei. Beim zweiten Mal fügt es jedoch an der drittletzten Zeile eine zusätzliche Null ein und nimmt an der vorletzten Zeile eine Null weg. Beim dritten Versuch wird es nur noch schlimmer... :smiley-sad:

Ich versuche schon lange, den Fehler zu finden, scheitere aber jedes Mal.
Ich würde mich freuen, wenn ihr mir helfen würden, und ich bin für jede Nachricht dankbar. Herzlichen Dank!

Mein Programm:
Code: [Select]

#include <SPI.h>
#include <SD.h>

String toRead= "REWR.TXT"; //Name des Files, das ich bearbeiten will.
char delim = ';';  //Damit ist im File die Spalte getrennt
const int x = 5;  //Anzahl Spalten
const int y = 8;  //Anzahl Zeilen
String param[y][x];  //String-Array, indem das File geladen wird bei set()



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

  set();  //Funktion, die das File in den String-Array lädt
  delete_row(0);  //Löscht Zeile, bzw. liest gewünschte Zeile nicht wenn die Daten vom String auf die SD kommen
}

void loop()
{
  delay(1000);
}


void set(){
  delay(100);
  SD.begin(4);
  File dataFile;
  dataFile = SD.open(toRead);
  int i=0;  //Zähler, damit Anzahl Spalten stimmt und eine neue Zeile angefangen werden kann
  int j=0;  //Zähler, damit Anzahl Zeilen (v.a. letzte Zeile) stimmt und am Schluss keine neue Zeile angefangen wird.
  String stringOne = "";  // hier wird beim Einlesen der Datei die einzelnen Zeilen- und Spalteneinträge zwischengespeichert
  while (dataFile.available()) {
    char letter = dataFile.read();  // liest einzelne char's
    if (letter != '\r' || letter != delim ){
      stringOne.concat(String(letter));  // verbindet char's zu string, wenn kein Trennzeichen oder Umbruch
    }
    if (letter == delim || letter == '\r'){  // wenn Trennzeichen oder Umbruch, dann...
      if (i == x){  
        i = 0;
        j++;
      }
      stringOne.replace(String(delim),""); // nimmt dem String das Trennzeichen weg
      stringOne.replace("\n","");  // nimmt dem String den Umbruch weg
      param[j][i] = stringOne;
      i++;
      stringOne="";
    }
  }
  param[j][i]=stringOne;  // liesst fertigen String in String-Array ein
  dataFile.close();  // schliesst die geöffnete Datei
  stringOne = "";
}


void delete_row(int del_row){

  delay(100);
  SD.begin(4);
  File dataFile;
  SD.remove(toRead);  // löscht die Datei mit dem Namen REWR.TXT
  
  delay(100);

  SD.begin(4);
  dataFile = SD.open(toRead, FILE_WRITE);  //öffnet eine neue Datei zum schreiben mit dem gleichen Namen REWR.TXT
  if(dataFile){   // Wenn die Datei geöffnet/erstellt werden kann, dann...
    int i=0;
    int j=0;
    for (i = 0; i < (y+1); i++) { // Zähler für Anzahl Zeilen
      delay(1000);
      if (i == del_row){  // wenn die Zeile, die zu löschen ist, i ist, dann überspringt es diese Zeile
        Serial.println(i);  // Kontrolle auf dem Serial Monitor
        continue;
      }
      for (j = 0; j < x; j++) {  // Zähler für Anzahl Spalten
        if (i == y){
          if (j == (x-1)){  //Wenn letzte Zeile und letzte Spalte
            dataFile.print("0");  //Schreib auf SD null (0)
            Serial.print("0");
          }
          else{  // Wenn letzte Zeile aber nicht letzte Spalte
            dataFile.print("0"); // Schreib auf SD null (0) und Trennzeichen (;)
            dataFile.print(String(delim));
            Serial.print("0");
            Serial.print(String(delim));
          }
        }
        else{
          if (j == (x-1)){  // Wenn letzte Spalte, aber nicht letzte Zeile
            dataFile.print(String(param[i][j]));
            dataFile.print("\n");
            Serial.print(String(param[i][j]));
            Serial.print("\n");
          }
          else{ // Wenn nicht letzte Spalte und nicht letzte Zeile
            dataFile.print(String(param[i][j]));
            dataFile.print(String(delim));
            Serial.print(String(param[i][j]));
            Serial.print(String(delim));
          }
        }
      }
     }
   }
  dataFile.close();
  delay(100);
}


Meine Datei "REWR.TXT, die ich bearbeiten möchte:
Code: [Select]

1;2;3;4;5
11;21;31;41;51
12;22;32;42;52
13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;57


Ergebnis nach einer Ausführung: (alles funktioniert gut) wie gewünscht erhalte ich auf letzte Zeile nur Nullen und die erste Zeile ist weg.
Code: [Select]

11;21;31;41;51
12;22;32;42;52
13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;57
0;0;0;0;0


Ergebnis nach zwei Ausführungen: (fügt eine Null hinzu) Wieder die erste Zeile ist weg im vergleich zur ersten Ausführung, aber die Null ist falsch positioniert.
Code: [Select]

12;22;32;42;52
13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;570
0;0;0;0;
0;0;0;0;0


Ergebnis nach drei Ausführungen:  (eine neue Null) Eine Null weniger in der zweitletzten Spalte und wird bei ursprünglich 57 hinzugefügt
Code: [Select]

13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;5700
0;0;0;0;0
0;0;0;;
0;0;0;0;0


Ergebnis nach vier Ausführungen:  (irgendetwas :o )
Code: [Select]

14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;57000
0;0;0;00;0
0;;0;0;0
0;0;;;
0;0;0;0;0

Peter-CAD-HST

Moin ardumaker_ch
Spendiere ein paar Kommentare und/oder beschreibende Variablenamen in deinem Sketch.
Gruss Peter
und gesund bleiben
KISS Q&D - keep calm and carry on - mind the gap - beware of sharks! -

ardumaker_ch

Vielen Dank für deine Nachricht.

Habe soeben den Code mit Kommentaren versetzt und zusätzlich einige Infos ergänzt.


my_xy_projekt

Habe soeben den Code mit Kommentaren versetzt und zusätzlich einige Infos ergänzt.
Deine Überschrift stimmt nicht. ;) Der Arduino schreibt eh keine, aber der Code schreibt schon richtige Werte auf die SD.

Wass fällt Dir auf?
Code: [Select]

void set()
{
  SD.begin (4);
  File dataFile;
  dataFile = SD.open (toRead);
}


void delete_row (int del_row)
{
  SD.begin (4);
  File dataFile;
  SD.remove (toRead); // löscht die Datei mit dem Namen REWR.TXT
  SD.begin (4);
  dataFile = SD.open (toRead, FILE_WRITE); //öffnet eine neue Datei zum schreiben mit dem gleichen Namen REWR.TXT
  dataFile.close();
}

ardumaker_ch

Guten Abend my_xy_projekt

Danke für deinen Hinweis.

"SD.begin (4);" sollte eigentlich nur im setup und "File dataFile;" bei mir als globale Variable deklariert werden.

Habe den Code auch gerade laufen lassen, jedoch ohne Erfolg. Genau die gleiche Ausgabe wie zuvor... :(

DrDiettrich

Welchen Arduino benutzt Du denn? Auf den kleineren kann String nicht richtig funktionieren, dann muß das ganze Programm erst einmal umgeschrieben werden.

ardumaker_ch

Ich benutze einen Arduino Nano. Den Code habe ich aber auch auf einem Arduino Uno laufen lassen, mit dem gleichen Fehler.

Tommy56

Da ist ja der gleiche Prozessor drin, mit der gleichen Menge RAM.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

ardumaker_ch

Ist so  :smiley-sweat:

Ein Uno / Nano sollte es jedoch zu Stande bringen, einen Text auf eine SD Karte zu schreiben.
Wenn ich sonst etwas auf eine SD schreiben will mit dem Uno / Nano, hat das auch immer funktioniert.

Aber danke für die Info Tommy56  ;)

my_xy_projekt

"SD.begin (4);" sollte eigentlich nur im setup und "File dataFile;" bei mir als globale Variable deklariert werden.

Habe den Code auch gerade laufen lassen, jedoch ohne Erfolg. Genau die gleiche Ausgabe wie zuvor... :(
Das der Code nicht funktioniert, ist klar - es ist Deiner!
Nur runter gekürzt auf das minimale.
incl. aller SD.begin.

Ich seh auch grade, das sich da noch was geändert hat in der Zeit, als ich das rauskopiert, bearbeitet und dann meinen Post verfasst habe - Ist das da oben in #0  jetzt der Code der endgültig ist oder machst Du das dahin was Du vorgibst?
Denn derzeit ist noch immer mehrfach SD.begin drin. Stand jetzt 3x.

ardumaker_ch

Ist eine etwas schroffe Antwort...

Was meinst du mit „ Nur runter gekürzt auf das minimale.
incl. aller SD.begin."

Den usprünglich Code, den für das Arduino habe, ich hier im Forum nicht geändert. Habe deinen Vorschlag mal bei mir probiert.

DrDiettrich

Ein Uno / Nano sollte es jedoch zu Stande bringen, einen Text auf eine SD Karte zu schreiben.
Richtig erkannt, an denen liegt es nicht. Also steckt das Problem in Deinem Code, oder in dem, der diesen Code geschrieben hat.

Auf den kleinen Arduinos muß man auf etlichen Komfort verzichten, zu allererst auf diesen "String" Datentyp.

Tommy56

#12
Sep 11, 2020, 09:07 pm Last Edit: Sep 11, 2020, 09:08 pm by Tommy56
@TO: Sind das nur (ganze) Zahlen, die Du lesen/schreiben willst? In welchem Wertebereich?

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

ardumaker_ch

Ich möchte Buchstaben und Zahlen schreiben. Wenn Buchstaben gehen, sollten dann auch float-typen funktionieren, wenn ich die als String lese und schreibe.

Ich habe auch schon probiert, alle zahlen mit Wörtern zu ersetzen. Der genau gleiche Fehler.

Erster durchgang gut, dann nimmt es einen Buchstaben weg und fügt ihn anderswo ein.

Tommy56

Ich glaube, Du solltest erst mal verständlich erklären, was Du überhaupt willst.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Go Up