Hallo zusammen,
ich habe hier ein kleines Problem beim Schreiben auf eine SD-Karte. Der Beispiel-Sketch funktioniert; daher ist das Problem vermutlich auf einen Programmfehler / Verständnisfehler von von mir zurückzuführen.
Hintergrund:
Bei einem 10A Solar-Laderegler möchte ich täglich eine neue Logdatei auf der SD-Karte erstellen. Der Dateiname soll das Datum beinhalten --> Log_20191207.csv.
Ich verwende das Loggershield Wemos D1 mini in Verbindung mit einem Arduino Nano every welcher nebem dem Logging auch die Display-Ansteuerung, MPPT- und Laderegelung übernimmt.
Zum Fehler:
Das Programm funktioniert wenn ich den Dateinamen händisch eingebe:
File LogFile = SD.open("Log_12341212.csv", FILE_WRITE);
Wenn ich den Dateiname mit snprintf zusammensetze und als Variable übergebe tritt bei der SD.exists-Abfrage der Fehler auf und es wird nichts auf die SD-Karte geschrieben.
Könnte es sein, dass ich ein Fehler bei der Deklaration der Variable dateiName (char dateiName[16]; ) gemacht habe und die SD.open / SD.exists Funktion damit nicht klarkommt?
Hier mein aktueller Quellcode
Main:
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
analog sensors on analog ins 0, 1, and 2
SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const int chipSelect = 4;
File LogFile;
#define CSV_TRENNZEICHEN ";"
int loggingInterval = 300; //Logginginterval in ms
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
if (! rtc.begin()) {
Serial.println("Keine RTC gefunden");
//rtc_Fehler = true;
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
}
}
void loop() {
writeSD(false); //Schreibe Daten nicht sofort -->Logginginterval
}
SD-Karte
//
// =======================================================================================================
// WRITE SD CARD
// =======================================================================================================
//
void writeSD(boolean noDelay) {
static unsigned long lastLog;
static byte letzteSekunde = 0;
static byte SD_SekundenZusatz = 0;
char dateiName[16];
byte SD_Tag, SD_Monat, SD_Minute, SD_Stunde, SD_Sekunde;
int SD_Jahr;
if (millis() - lastLog >= loggingInterval || noDelay) {
lastLog = millis();
DateTime now = rtc.now();
SD_Tag = now.day();
SD_Monat = now.month();
SD_Jahr = now.year();
SD_Stunde = now.hour();
SD_Minute = now.minute();
SD_Sekunde = now.second();
snprintf(dateiName, 17, "Log_%04d%02d%02d.csv", SD_Jahr, SD_Monat, SD_Tag);
Serial.print ("Dateiname: ");
Serial.println (dateiName);
//Prüfen ob Datei vorhanden ist, wenn nicht wird eine Datei mit "Kopf" erstellt
if (!SD.exists(dateiName)) { //Wenn Datei noch nicht vorhanden ist
File LogFile = SD.open(dateiName, FILE_WRITE); //Logfile im CSV-Formaterstellen
if (LogFile) {
LogFile.print("Datum");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Zeit");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Input Voltage");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Input Current");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Input Power");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Battery Voltage");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Battery Current");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Battery Power");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("Converter Mode");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("targetPanelVoltage");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.println("DutyCycle");
LogFile.close();
//sd_Fehler = false;
}
else {
//sd_Fehler = true;
Serial.println("SD-Fehler 1 Kopf schreiben");
}
}
LogFile = SD.open(dateiName, FILE_WRITE);
LogFile.close();
LogFile = SD.open(dateiName, FILE_WRITE); //Logfile im CSV-Format
if (LogFile) {
//Datum
LogFile.print(SD_Tag);
LogFile.print(SD_Monat);
LogFile.print(SD_Jahr);
LogFile.print(CSV_TRENNZEICHEN);
//Zeit
/*
Da die RTC 1307 keine Millisekunden liefert wird über einen kleine Workaround geprüft,
ob in der selben Sekunde mehrere Messwerte angefallen sind. Wenn ja, wird ein Zähler hochgezählt (Variable SD_SekundenZusatz)
*/
LogFile.print(SD_Stunde);
LogFile.print(SD_Minute);
LogFile.print(SD_Sekunde);
if (SD_Sekunde == letzteSekunde) {
SD_SekundenZusatz++;
}
else
{
SD_SekundenZusatz = 0;
letzteSekunde = SD_Sekunde;
}
Serial.println(SD_SekundenZusatz);
letzteSekunde = SD_Sekunde;
LogFile.print(CSV_TRENNZEICHEN);
//El. Werte
LogFile.print("12");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("1");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("12");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("13.4");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("2");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("23");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("1");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.print("targetPanelVoltage");
LogFile.print(CSV_TRENNZEICHEN);
LogFile.println("DutyCycle");
LogFile.close();
Serial.println("SD geschrieben!!!");
}
else {
//sd_Fehler = true;
Serial.println("SD-Fehler 2");
}
}
Ich bin Dankbar für jede Antwort und jeden Hinweis.
Grüße Ben