Ich rufe die Funktion aus der Loop auf und versuche Werte auf einer SD KArte zu speichern. Das funktioniert super.
Wenn ich die SD Karte aus dem Slot nehme, schreibt er allerdings weiter "SD beschrieben". Er denkt also weiter das die Datei geöffnet ist und bringt nicht die Fehlermeldung aus der else Schleife.
Wenn ich in der Loop die Datei einmal vorab öffne, funktioniert es. Weshalb sollte ich die Datei allerdings in der Loop öffnen? Reicht doch sicher auch in der Funktion.
//RTC DS1307
#include "RTClib.h"
//TempSensor DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
//SD SPI Modul
#include <SD.h>
//OLED
#include <SPI.h>
#include <Wire.h>
//OLED
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
// Define proper RST_PIN if required.
#define RST_PIN -1
SSD1306AsciiAvrI2c oled;
RTC_DS1307 rtc;
const int chipSelect = 10;
#define ONE_WIRE_BUS 3
#define DS18B20_Aufloesung 12
DeviceAddress DS18B20_Adressen;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature myDS18B20(&oneWire);
#define Anzahl_Sensoren_DS18B20 2 // Anzahl der angeschlossenen Sensoren - Mögliche Werte: '0','1','2'
const float No_Val = 999.99;
float Temperatur[2] = {No_Val,No_Val};
//DateTime now;
//String Tsensor1 = "";
//String Tsensor2 = "";
char buf1[] = "hh:mm:ss";
char buf4[] = "DD.MM.YYYY";
void setup() {
Serial.begin(9600);
//OLED
#if RST_PIN >= 0
oled.begin(&Adafruit128x32, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
oled.begin(&Adafruit128x32, I2C_ADDRESS);
#endif // RST_PIN >= 0
// Call oled.setI2cClock(frequency) to change from the default frequency.
oled.setFont(Adafruit5x7);
oled.clear();
oled.setRow(1);
oled.set2X();
oled.println("Booting ...");
delay(1000);
Wire.begin();
rtc.begin();
//RTC
if (! rtc.isrunning()) {
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(__DATE__, __TIME__));
}
else Serial.println("RTC is running");
oled.clear();
oled.setRow(0);
oled.set1X();
oled.println("RTC is running");
delay(500);
oled.setRow(1);
oled.set1X();
oled.println("Initializing SD card");
Serial.print("Initializing SD ...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed / No Card");
oled.setRow(2);
oled.set1X();
oled.println("Card failed / No Card");
delay(1000);
// Endlosschleife/Reset erforderlich
while (1);
}
Serial.println("card initialized.");
oled.setRow(2);
oled.set1X();
oled.println("card initialized.");
delay(1000);
oled.setRow(3);
oled.set1X();
oled.print("Counted DS18B20: ");
delay(1000);
Serial.print("Anzahl aktivierter Sensoren: ");
Serial.println(Anzahl_Sensoren_DS18B20);
if ((Anzahl_Sensoren_DS18B20 > 0) and (Anzahl_Sensoren_DS18B20 < 3)) {
myDS18B20.begin();
Serial.print("Anzahl angeschlossener Sensoren: ");
Serial.println(myDS18B20.getDeviceCount(), DEC);
Serial.println();
oled.setRow(3);
oled.set1X();
oled.print(myDS18B20.getDeviceCount(), DEC);
delay(1000);
for(byte i=0 ;i < myDS18B20.getDeviceCount(); i++) {
if(myDS18B20.getAddress(DS18B20_Adressen, i)) {
myDS18B20.setResolution(DS18B20_Adressen, DS18B20_Aufloesung);
}
}
}
delay(1000);
}
void saveTempToSD() {
String Tsensor1 = "";
String Tsensor2 = "";
Tsensor1 += String(Temperatur[0]);
Tsensor2 += String(Temperatur[1]);
File dataFile = SD.open("datalog.csv", FILE_WRITE);
//Schreibe Datum / Temp - Werte auf die SD Karte
if (dataFile) {
dataFile.print(buf4);
Serial.println(buf4);
dataFile.print(";");
dataFile.print(buf1);
Serial.println(buf1);
dataFile.print(";");
dataFile.print(Tsensor1);
Serial.println(Tsensor1);
dataFile.print(";");
dataFile.println(Tsensor2);
Serial.println(Tsensor2);
dataFile.close();
Serial.println("SD beschrieben");
}
else {
Serial.println("error opening TempDataLog.csv");
}
}
void measureTemp(){
//Wieviel Sensoren sind angeschlossen
if ((Anzahl_Sensoren_DS18B20 > 0) and (Anzahl_Sensoren_DS18B20 < 3)) {
myDS18B20.requestTemperatures();
//Schleife für Messung aller Sensoren
for(byte i=0 ;i < Anzahl_Sensoren_DS18B20; i++) {
if (i < myDS18B20.getDeviceCount()) {
Serial.print("Sensor ");
Serial.print(i+1);
Serial.print(": ");
Temperatur[i] = myDS18B20.getTempCByIndex(i);
if (Temperatur[i] == DEVICE_DISCONNECTED_C) {
Temperatur[i] = No_Val;
Serial.println("Fehler");
}
else {
Serial.print(Temperatur[i]);
Serial.println(" 'C");
}
}
}
saveTempToSD();
}
}
void loop() {
//RTC abrufen
DateTime now = rtc.now();
// Zeit in String
Serial.println(now.toString(buf1));
Serial.println(now.toString(buf4));
oled.clear();
oled.setRow(0);
oled.set1X();
oled.print(now.toString(buf4));
oled.print(" ");
oled.println(now.toString(buf1));
File dataFile = SD.open("datalog.csv", FILE_WRITE);
measureTemp();
delay(5000);
}
Mit dem Code wird zu Beginn gefragt ob eine Karte vorhanden ist. Ich möchte gerne nur, dass beim Herausnehmen der Karte im Betrieb eine Fehlermeldung angezeigt wird.
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed / No Card");
oled.setRow(2);
oled.set1X();
oled.println("Card failed / No Card");
delay(1000);
// Endlosschleife/Reset erforderlich
while (1);
}
Bedient habe ich mich an dem Beispiel zur SD.h Lib.
/*
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>
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
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.");
}
void loop() {
// make a string for assembling the data to log:
String dataString = "";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += ",";
}
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
Wenn du nur im Setup nachfrags, ob eine Karte vorhanden ist, reicht das sicher nicht.
Da musst du zwischendurch immer nachfragen.
Ob es tatsächlich bei deinem Reader auch so funktioniert, musst du prüfen.
Es gibt Reader mit speziellem Kontakt, ob eine Karte gesteckt ist. Dieser Kontakt ist in deinem Reader nicht vorhanden.
Oh die SdFat sieht allerdings wesentlich komplizierter aus.
Ich frage doch eigentlich immer nach jedem Öffnen der Datei ob die Datei vorhanden ist.
Wenn dataFile nicht geöffnet, dann soll er mir den Error bringen. Und das tut er leider nicht, sondern gibt leider ein true zurück oder interpretier ich das falsch?
File dataFile = SD.open("datalog.csv", FILE_WRITE);
//Schreibe Datum / Temp - Werte auf die SD Karte
if (dataFile) {
dataFile.print(rtcdate);
Serial.println(rtcdate);
dataFile.print(";");
dataFile.print(rtctime);
Serial.println(rtctime);
dataFile.print(";");
dataFile.print(Tsensor1);
Serial.println(Tsensor1);
dataFile.print(";");
dataFile.println(Tsensor2);
Serial.println(Tsensor2);
dataFile.close();
Serial.println("SD beschrieben");
}
else {
Serial.println("error opening TempDataLog.csv");
}
Lasse Dir doch anzeigen, WAS Er zurück bekommt.
1x bei einer definitiv vorhandenen Datei
1x bei einer definitiv NICHT vorhandenen Datei
Das wäre auch für die Nachwelt lesenswert und würde Dich ggf. einen Schritt weiter Richtung Ziel bringen.
MfG
Er liefert eine 1 zurück.
Warum auch immer, allerdings wenn ich die Datei im Setup einmal öffne und wieder schließe, funktioniert der Error beim vorzeitigen Herausnehmen der SD Karte.