ich baue gerade ein Sensorshield mit MQ-7 (CO-Sensor), MQ-2 (Rauchsensor), LCD-Display, DHT22 für Temperatur und Luftfeuchte, SD-Karte zum Loggen der Werte, Summer für Alarmton, und Webserver zum Anzeigen der Werte sowie Download der Logdatei per HTTP.
Das Ganze soll später auf einem Ethermega laufen. http://www.lipoly.de/index.php?main_page=product_info&products_id=214051 - und ein per Fritzing erstelltes Shield ist auch fast fertig.
Bisher ist folgendes fertig:
Hardware
Datum und Uhrzeit werden per NTP gezogen
Die Werte der Sensoren werden alle 15 Minuten in eine(!) Logdatei auf die SD-Karte geschrieben
Alarm funktioniert
Webserver zeigt die Werte an
Der Webserver zeigt mir alle vorhandenen Dateien auf der SD-Karte an
Was mir noch fehlt:
Eine Logdatei pro Tag erstellen
Download der Logdatei per HTTP
Die vorhanden Dateien auf der SD-Karte werden nur beim ersten Aufruf angezeigt, danach nicht mehr.
Bisher habe ich alles per Try-and-Error sowie "Codeklau" von diversen Internetseiten / Howtos / Foren zum laufen gebracht.
Der Code ist mit Sicherheit alles andere als perfekt.
Zum ersten Problem:
Ich kann mir auf der seriellen Konsole schön das Datum formatieren:
das Ergibt: "2013-08-03"
Wie kann ich mir daraus einen String bauen, damit ich Dateien nach dem Schema "2013-08-03.csv" auf der SD-Karte erstellen kann?
Bzw. prüfen kann, ob schon eine Datei "2013-08-03.csv" existiert?
Thombo84:
Wie kann ich mir daraus einen String bauen, damit ich Dateien nach dem Schema "2013-08-03.csv" auf der SD-Karte erstellen kann?
Bzw. prüfen kann, ob schon eine Datei "2013-08-03.csv" existiert?
Gar nicht. Beim einfachen FAT-Dateisystem bist Du auf 8.3 Dateinamen beschränkt.
"2013-08-03.csv" ist zwei Zeichen zu lang, um ihn als Dateinamen auf SD-Karte mit FAT-Dateisystem zu verwenden.
Möglich wäre ein Dateiname wie "20130803.csv", also maximal 8.3 Zeichen lang.
Beispiel einer Formatierungsfunktion mit Test-Sketch zum erzeugen zufälliger Dateinamen:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
char* formatFilename(int day, int month, int year, char* ext)
{
static char filename[13];
snprintf(filename,sizeof(filename),"%04d%02d%02d.%s",year,month,day,ext);
return filename;
}
void loop() {
// put your main code here, to run repeatedly:
int day=random(1,31);
int month=random(1,13);
int year=random(2010,2014);
char* filename=formatFilename(day,month,year,"CSV");
Serial.println(filename);
}
Danke für den Tipp mit 8.3
Der Code funktioniert wunderbar. Vielen Dank.
Es stellte sich gerade heraus dass ich noch Probleme mit der SD-karte habe.
Ich habe eine Funktion welche mir alle Dateien auf der SD-karte ausgibt, was solange funktioniert bis ich etwas in die LogDatei schreibe. Danach funktioniert das Ausgeben aller Dateien nicht mehr.
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
wird mir eingebaut in die loop() Schleife immer "5481" ausgegeben. Ich denke das ist genug freier Speicher.
Die Sktechgröße beträgt 39.236 Bytes von 258.048 Bytes.
Thombo84:
wird mir eingebaut in die loop() Schleife immer "5481" ausgegeben. Ich denke das ist genug freier Speicher.
Ja, halbwegs "normale" Arduino-Programme laufen selbst mit nur ca. 250 Bytes freiem Speicher nach Initialisierung aller Objekte und Variablen noch einwandfrei. Du hast ja noch mehr RAM frei als ein UNO überhaupt eingebaut hat.
Thombo84:
EDIT:
Ich habs! Die Lösung ist
dir.seek(0);
Danke für das Feedback, dann kann ich ja aufhören zu überlegen und Du hast eine Lösung selbst gefunden!
Für Interessierte anbei der bisherige Code (der bei weitem nicht perfekt ist).
Der Code ist leider zu groß fürs Forum, daher gibts den im Anhang.
Verbesserungen werden immer gerne angenommen.
UPDATE: Mittlerweile ist der Code erweitert worden
DCF77 für Zeit
E-Mail Benachrichtigung bei Alarm
zusätzlicher DS1820 Temperatursensor.
... und etwas aufgeräumt im Code. Bei Interesse bitte melden.