Forum: Mikrocontroller und Digitale Elektronik Arduino auf SD-Karte kann nicht geschrieben werden


von Flo D. (floflovaldo)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe 2 Wiegesensoren am Arduino angeschlossen. Diese bekomme ich 
soweit ausgelesen und alles. Die Gewichtsmessung soll gestartet und 
gestoppt werden, dies mache ich in meinem Fall über den Seriellen 
Monitor.

Nun würde ich gerne alle Messwerte die in der Konsole angezeigt werden 
auch auf einer SD-Karte in einer Datei speichern.

Leider klappt das mit der SD-Karte echt nicht mit meinem Code, bei 
gleichem Aufbau mit dem Beispielskript aber schon.. Von dem her liegt es 
so wie es aussieht ganz stark irgendwo an meinem Code.

Das Programm springt in die else rein bei der Abfrage ob datafile (also 
die Datei) existiert und ob neue Sensordaten bereitliegen. Wenn ich das 
"dataFile" negiere springt er mir in die if rein, schreibt aber auch 
nichts auf die SD-Karte.

Das Problem scheint das dataFile zusein, verstehe es aber nicht da im 
Beispielcode so mit dem gleichen Aufbau funktioniert und auf die 
SD-Karte schreibt.

Ich häng zusätzlich noch den Beispielcode dran mit dem ich gearbeitet 
hab.

Ich kann mir das Problem echt nicht mehr erklären, und find auch kein 
Fehlerteufel der sich irgendwo eingenistet hat..

Würde mich sehr freuen wenn jemand von euch mal kurz drüber gucken 
könnte, ich komm echt nicht drauf. Das wär sehr lieb.

Viele Grüße
Florian

: Bearbeitet durch User
Beitrag #6617480 wurde von einem Moderator gelöscht.
von Flo D. (floflovaldo)


Lesenswert?

Sorry, ist nun als Anhang. Danke fürs drauf aufmerksam machen.

von Jim M. (turboj)


Lesenswert?

Flo D. schrieb:
> negiere springt er mir in die if rein, schreibt aber auch
> nichts auf die SD-Karte.

Das File "datalog.csv" existiert hinterher nicht? Dann ist was faul. 
Eventuell mal eine andere SD Karte probieren.

Falls nur Daten fehlen: Die stehen in der dataString  Variable gar nicht 
drin.

von Flo D. (floflovaldo)


Lesenswert?

Hallo, die Datei wird auf der SD-Karte erstellt. Ist aber leer, das ist 
aber auch wiederum logisch da die Daten ja erst in der if danach 
geschrieben werden wo mein Programm gar nicht reinspringt weil irgendwas 
mit dem "dataFile" scheinbar nicht klappt und das Programm in die else 
direkt springt und den Fehler ausgibt das eben was mit dem Öffnen der 
Datei nicht funktioniert hat.

Komisch ist nur das es mit dem Beispielcode direkt funktioniert, bei mir 
im Code aber nicht und es eig identisch gemacht ist wie ich meine.

von Jim M. (turboj)


Lesenswert?

Im Falle "newDataReady" == false wird die Datei nicht geschlossen und 
kann daher im nächsten Durchlauf auch nicht mehr geöffnet werden.

von Flo D. (floflovaldo)


Angehängte Dateien:

Lesenswert?

Danke für den Hinweis. Die Datei mache ich nun auch zu wenn er in die 
else springt. Änderte aber grundsätzlich nichts.

Ich habe jetzt mal das File.close() nochmal explizit vor jeden Durchgang 
gesetzt. Dann springt er in die if, startet die Messung, macht 
allerdings nur Messwert und das System startet sich vermutlich neu die 
setup neu abgearbeitet wird.

Anbei der Screenshot von der Seriellen Ausgabe und dem aktuellen Sketch 
als Anhang. Ich versteh echt nicht wieso er sich so verhält und vorallem 
jetzt auch neustartet.

Für weitere Hinweise wär ich sehr dankbar.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Flo D. schrieb:
> Dann springt er in die if, startet die Messung, macht
> allerdings nur Messwert und das System startet sich vermutlich neu die
> setup neu abgearbeitet wird.

Ob Setup() wieder durchlaufen wird, sollte sich doch feststellen lassen.

von Flo D. (floflovaldo)


Lesenswert?

Setup wird definitiv durchlaufen, sonst würde die Ausgabe nicht erneut 
erscheinen.

von Hermann G. (df2ds)


Lesenswert?

Hallo,
ich kann beim besten Willen in deinem Code nicht finden, wo du den 
"datastring "mit Inhalt füllst. Da ist nur die Ausgabe auf die Konsole 
mit Serial.print....

Einer von uns beiden hat da etwas übersehen.

GL
  Hermann

von Flo D. (floflovaldo)


Lesenswert?

Hallo Hermann,

zum Testen versuche ich gerade gar nicht die Sensorwerte 
reinzuschreiben, da irgendwas ja schon mit dem Öffnen der eigentlichen 
Datei nicht funktioniert.
Deshalb pack ich den den dataString aktuell nur die ID die pro Datensatz 
hochgezählt wird.

Das passiert hier mit hier:
1
dataString = String(id) + ",";

Viele Grüße,
Flo

von Hermann G. (df2ds)


Lesenswert?

Noch eine Frage: Ist es beabsichtigt, dass am Beginn der loop-Funktion 
"newDataReady" nur in der Sensor_1-Abfrage aktualisiert wird? Das 
bedeutet ja, dass auch nur auf die SD geschrieben wird, wenn Sensor1 
"ready" ist. Spielt Sensor_2 hier nicht mit?

Wenn kein Sensor "ready" ist, wird ja auch nichts geschrieben!

Ich schlage vor, zum Testen mal Dummy-Werte vorzugeben, so als ob die 
Sensoren dann "newDataReady" melden. Wenn diese Dummy-Daten auf der SD 
landen, liegt die Ursache im Programmablauf (was ich auch eher vermute 
als ein Problem beim Schreiben der SD).

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Flo D. schrieb:
> Für weitere Hinweise wär ich sehr dankbar.
1
 
2
  // Initialisierung, Stabilisierung, TARA beider Module gleichzeitig 
3
  while ((sensor_1_rdy + sensor_2_rdy) < 2) {
4
    if (!sensor_1_rdy) sensor_1_rdy = sensor_1.startMultiple(stabilizingtime, _tare);
5
    if (!sensor_2_rdy) sensor_2_rdy = sensor_2.startMultiple(stabilizingtime, _tare);
6
  }

Sowas macht man auch nicht. Wenn man die Schleife so lange durchlaufen 
will, wie beide Sensoren nicht bereit sind, dann schreibt man das DIREKT 
hin! Die Addition ist Unsinn, auch wenn sie hier funktioniert.
1
  // Initialisierung, Stabilisierung, TARA beider Module gleichzeitig 
2
  while (!(sensor_1_rdy && sensor_2_ready)) {

Aber das eigentliche Problem ist dein diffuses Programm in loop(). Wer 
soll da durchsehen? Was soll da überhaupt passieren? Man erkennt 
keinerlei klares oder gar sinnvolles Konzept, und das bei den wenigen 
Zeilen Code!
Man muss auch nicht dauern die Datei öffnen und schließen. Man öffnet 
sie einmal am Anfang der Datenaufzeichung, schreibt dann x Datensätze 
rein und wenn nix mehr aufgezeichnet werden soll macht man sie zu. Dazu 
braucht es aber eine sinnvolle Programmstruktur.

Die Datei öffnet man einmalig am Ende von Setup() und schließt sie 
einmalig, wenn die Messung beendet wird. Dein Ansatz mit diversen Flags 
check1, check2 ist erstmal OK, aber man sollte sie sinnvoll benennen. 
Dann ist deren Funktion auch selbsterklärend.
Messung_aktiv wäre ein sinnvoller Name für so eine Steuervariable. Oder 
halt measure_active, wenn's denn eher englisch sein soll.
Solche flags kann man direkt logisch auswerten, da muss man nicht mit 
==0 vergleichen. Siehe Grundlagen der logischen Ausdrücke in c.
Das mit der prüfung, ob die Tare-Funktion der Sensoren erfolgreich war, 
will man auch nicht immer haben.
Außerdem sollte man den Quelltext gut strukturieren, um eine bessere 
Übersicht zu bekommen.

Wenn man dein Programm compiliert, gibt es eine Warnung,
1
Globale Variablen verwenden 1859 Bytes (90%) des dynamischen Speichers, 189 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
2
Wenig Arbeitsspeicher verfügbar, es können Stabilitätsprobleme auftreten.

Das sollte man ernst nehmen. Es gibt gute Chancen, daß die diversen 
Funktionen zuviel Stack benötigen und somit deine globalen Variablen 
überschreiben, dann stürzt dein Programm undefiniert ab. Wenchen Arduino 
hast du? Mit dem Uno/Nano wird es knapp, ein MEGA sollte reichen.
Ahhh, ich sehe warum. Du hast viele konstante Texte in 
Funktionsaufrufen! Die landen alle sinnloserweise im RAM! Da muss man 
das F() Makro nutzen!

https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

Ahhh, siehe da, es sind nur noch 1177 Bytes (57%) vom RAM!

Siehe Anhang.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.