Probleme mit SD-Karte

Hallo zusammen,

für mein kleines Projekt brauche ich bitte eure Hilfe.

Ich habe ein kleines Gerät gebaut, welches meinen Nintendo 3DS automatisiert steuert.
Das klappt auch sehr gut, aber ich möchte jetzt Daten auf die SD-Karte schreiben.
(Kleine logs, nichts wildes)

Über das Tutorial von Arduino.cc mit SD Read/Write funktionierts, wenn ich aber versuche das in meinen Sketch zu übernehmen passiert leider nichts.
Ich habe es geschafft immerhin die Datei anlegen zu lassen, aber ich kriege leider keine Daten drauf geschrieben.

Hat jemand vielleicht eine Idee?

/* Erste Tests mit den Servos fürs laufen*/

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

Servo servolh;                  // servo 1 für links & hoch
Servo servorr;                  // servo 2 für rechts & runter
Servo servoyb;                  // servo 3 für y & b
Servo servoxa;                  // servo 4 für x & a
Servo servo1;                   // start button

LiquidCrystal lcd(9, 8, 3, 2, 1, 0);

File data;

int pos = 90;                   //Grundstellung Servos -> mittig
int sensorWert = 0;             //Helligkeitsmessung
byte eier = 0;                  //Eier im Team
byte hatch = 0;                 //geschlüpfte Pkm
int pc = 0;                     //abgelegte Pkm
byte pkm = 0;

const byte  buttonPin = 7;      // the pin that the pushbutton is attached to
byte buttonState = 0;           // current state of the button

boolean pension = false;
boolean repeat = false;

void setup() {
  servolh.attach(A2);         // attaches the servo on pin A2 to the servo object
  servorr.attach(6);          // attaches the servo on pin 6 to the servo object
  servoyb.attach(5);          // attaches the servo on pin 5 to the servo object
  servoxa.attach(4);          // attaches the servo on pin 4 to the servo object
  servo1.attach(A1);          // attaches the servo on pin A1 to the servo object
  servolh.write(pos);         // tell servo to go to position in variable 'pos'
  servorr.write(pos);         // tell servo to go to position in variable 'pos'
  servoyb.write(pos);         // tell servo to go to position in variable 'pos'
  servoxa.write(pos);         // tell servo to go to position in variable 'pos'
  servo1.write(pos);          // tell servo to go to position in variable 'pos'
  lcd.begin(16, 2);           // Initialisierung LCD Display
  lcd.clear();
  lcd.print("Initializing SD");

    if (!SD.begin(10)) {
      lcd.println("initiali failed!");
      return;
    }
    lcd.println("initiali done.");

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    data = SD.open("test.txt", FILE_WRITE);

    // if the file opened okay, write to it:
    if (data) {
      lcd.print("Writing test.txt");
      delay(3000);
      data.println("testing 1, 2, 3.");
      delay(3000);
      // close the file:
      data.close();
      lcd.print("done.");
      delay(3000);
    } else {
      // if the file didn't open, print an error:
      lcd.print("error test.txt");
      delay(3000);
    }
}

void loop() {
  sensorWert = analogRead(A0);
  buttonState = digitalRead(buttonPin);
  lcd.setCursor(0, 0);
  lcd.print("Knopf druecken  ");
  lcd.setCursor(0, 1);
  lcd.print("fuer start! ");
  lcd.setCursor(12, 1);
  lcd.print(sensorWert);
  lcd.setCursor(15, 1);
  lcd.print("R");
  delay(1000);
  while (buttonState == HIGH) {
    repeat = true;
    pension = true;

    while (repeat) { //Wiederholen der Aktionen bis 30,60,90,120 Eier im PC...

      while (pension) //Weg aus der Pension zum Wärter / Start!
      { //pension loop
        sensorWert = analogRead(A0);
        data.println(sensorWert);
        data.println("R Anfangswert");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Gehe Eier holen");
        lcd.setCursor(0, 1);
        lcd.print(eier);
        lcd.setCursor(1, 1);
        lcd.print("Ei");
        lcd.setCursor(4, 1);
        lcd.print(hatch);
        lcd.setCursor(5, 1);
        lcd.print("Hatch");
        lcd.setCursor(11, 1);
        lcd.print(pc);
        lcd.setCursor(14, 1);
        lcd.print("PC");
        data = SD.open("data.txt");
        if (data) {
          data.println("Gehe Eier holen");
          data.println(eier);
          data.println("Ei");
          data.println(hatch);
          data.println("Hatch");
          data.println(pc);
          data.println("PC");
          data.println("_________________________________________________________");
          data.close();
        }
        delay(1000);
.
.
.
.
.

Vielen Dank! :slight_smile:

MadBlade: Hat jemand vielleicht eine Idee?

Ideen habe ich alle Nas’ lang. Zumindest für Dein Posting fällt mir aber gerade nur ein, dass Du die falschen Tags benutzt hast.

Gruß

Gregor

gregorss: Ideen habe ich alle Nas’ lang. Zumindest für Dein Posting fällt mir aber gerade nur ein, dass Du die falschen Tags benutzt hast.

Gruß

Gregor

Was genau meinst du bitte? Dann kann ichs ändern :)

Du setzt, zumindest in dem Teil das ich sehen kann, weder Repeat noch Pension jemals auf false, also terminieren beide Whileschleifen nie !

Ulli

beeblebrox: Du setzt, zumindest in dem Teil das ich sehen kann, weder Repeat noch Pension jemals auf false, also terminieren beide Whileschleifen nie !

Ulli

Erm, das liegt daran, dass ich nicht den kompletten Sketch eingefügt habe. Wollte euch knapp 600 Zeile Code ersparen :) Also mein Sketch läuft generell gut. Hab den jetzt über Nacht ~6-7h durchlaufen lassen.

Ich möchte jetzt aber halt die Möglichkeit des Datenloggings aufnehmen :)

MadBlade: Was genau meinst du bitte? [Tags] Dann kann ichs ändern :)

Ich meine, dass Du die „Code“-Tags benutzen solltest, um Code als solchen zu kennzeichnen. Machen viele aber nichtmal mit den falschen Tags.

Gruß

Gregor

gregorss: Ich meine, dass Du die „Code“-Tags benutzen solltest, um Code als solchen zu kennzeichnen. Machen viele aber nichtmal mit den falschen Tags.

Gruß

Gregor

Ah, der Button war vorn versteckt. Danke für den Hinweis! :)

Habs geändert.

MadBlade: Wollte euch knapp 600 Zeile Code ersparen :)

Hast Du schon mal einen Testsketch aus den Beispielen der SD-Bibliothek erstellt? Dann weiß man schon mal, wie es grundsätzlich funktioniert. So ein kleiner Sketch ist dann im Forum auch eher zu überschauen.

agmue: Hast Du schon mal einen Testsketch aus den Beispielen der SD-Bibliothek erstellt? Dann weiß man schon mal, wie es grundsätzlich funktioniert. So ein kleiner Sketch ist dann im Forum auch eher zu überschauen.

Ja, der Beispielsketch funktioniert ja z.B. Also Gerät und Verkabelung passen :)

SD - ReadWrite

Ich bin nur "zu doof" selbst Daten im Loop auf die Karte schreiben zu lassen :(

Die Initialisierung der Datei test.txt funktioniert also?

Da Du nur ein Fragment Deines Programms zeigst, kann ich nur spekulieren: while ist blockierend und stört.

agmue: Die Initialisierung der Datei test.txt funktioniert also?

Da Du nur ein Fragment Deines Programms zeigst, kann ich nur spekulieren: while ist blockierend und stört.

Ich nutze sehr viele while Schleifen, da ich dauernd Werte vom Fotowiderstand abfrage und damit div. Counter erhöhe... Da dies mein erstes "Programm" ist, sieht das entsprechend chaotisch aus und kommt auf über 600 Zeilen :)

Ja, die Testfiles laufen gut. Sobald ich natürlich erst den Serial Monitor öffne. Was für mein Programm aber nicht in frage kommt.

Generelle Frage: Muss ich die Datei bei jedem Schreibzugriff öffnen und schließen? Könnte das noch ein Problem sein?

Muss ich die Datei bei jedem Schreibzugriff öffnen und schließen? Könnte das noch ein Problem sein?

  1. Nein. 2. Ja

Wirklich geschrieben wird erst bei close() oder flush(), oder wenn du mehr als 512 Zeichen schreibst.

Dein sketch wird einfacher, wenn du bedenkst, dass loop selbst eine große Schleife ist. Wenn diese "immer sofort" fertig ist und meistens nur feststellt, dass nichts zu tun ist, brauchst du nur noch ein paar Zustandsvariable, aber selbst keine while schleifen mehr.

Wenn du nur ab und zu was schreibst, du keine Performance-Probleme hast, und da ein Arduino Sketch üblicherweise kein "Ende" kennt, ist es in der Regel einfacher, jedesmal open und close zu machen.

Eventuell noch eine LED während des Schreibens leuchten lassen, was dich davon abhält, genau dann die SD-Karte zu entnehmen oder den Arduino auszuschalten..

michael_x: 1. Nein. 2. Ja

Wirklich geschrieben wird erst bei close() oder flush(), oder wenn du mehr als 512 Zeichen schreibst.

Dein sketch wird einfacher, wenn du bedenkst, dass loop selbst eine große Schleife ist. Wenn diese "immer sofort" fertig ist und meistens nur feststellt, dass nichts zu tun ist, brauchst du nur noch ein paar Zustandsvariable, aber selbst keine while schleifen mehr.

Wenn du nur ab und zu was schreibst, du keine Performance-Probleme hast, und da ein Arduino Sketch üblicherweise kein "Ende" kennt, ist es in der Regel einfacher, jedesmal open und close zu machen.

Eventuell noch eine LED während des Schreibens leuchten lassen, was dich davon abhält, genau dann die SD-Karte zu entnehmen oder den Arduino auszuschalten..

Danke für deine Gedanken michael.

Also mein Programm endet schon. Das der loop eine sich immer wiederholende Schleife ist, weiß ich. Danke aber für den Hinweis. Daher aber auch die div. while Schleifen. Das Gerät soll mir etwas "arbeit" auf dem Nintendo 3DS abnehmen. Dafür habe ich ihm gesagt, sobald du eine Gewisse Anzahl von Pokemon gezüchtet hast, setze alle booleans auf false.

Was ich halt noch an potentiellen Fehlerquellen sehe.

In jedem Sketch mit SD-Karten sehe ich im Setup "Serial.begin(9600);".

Brauche ich dieses ebenfalls, obwohl ich mein Gerät nich am PC betreibe?

Vielen Dank & Gruß Jan

MadBlade: In jedem Sketch mit SD-Karten sehe ich im Setup "Serial.begin(9600);".

Brauche ich dieses ebenfalls, obwohl ich mein Gerät nich am PC betreibe?

Das brauchst du wenn du serielle Kommunikation machst. Egal mit welchen Gerät. Wenn nicht, braucht man es natürlich nicht.

Serenifly: Das brauchst du wenn du serielle Kommunikation machst. Egal mit welchen Gerät. Wenn nicht, braucht man es natürlich nicht.

Da das SD-Karten Modul ja über SPI läuft, also nicht.