ESP32 file leer

Hallo,

ich weis ich nerve vermutlich schon aber es ist halt jedes mal was neues.

Diesmal aber eine einfache bitte an jemanden der einen ESP32 und ein SD shield hat.

Hier ein Bsp code der mir zwar das file auf der SD Karte erzeugt aber nichts hineinschreibt?
Oder habe ich etwas falsch gemacht im code?

/*
  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 = 5;

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 = "Hallo";


  // 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.flush();
    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");
  }
}

Wie gesagtmir wird das file auf der SD karte erstellt aber "Hallo" nicht hineingeschrieben, bleibt einfach leer.

Mein code wo ich dann wirklich was reinschreibe macht fast das selbe jedoch schreibt er genau 1 mal die daten auf das file und dann nciht wieder.
Dachte zuerst es liegt am interupt der im code ist aber wie gesagt passiert am minimalbsp. garnichts

Hier mein code der eigendlich laufen soll:

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

#include <OneWire.h>
#include <DallasTemperature.h>

#include <RTClib.h>

RTC_DS3231 rtc;

DeviceAddress DS18B20_Address;

const int oneWireBus = 16;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

DeviceAddress sensor1 = { 0x28, 0x0, 0x3E, 0x4F, 0x26, 0x4C, 0xF, 0x90 };
DeviceAddress sensor2 = { 0x28, 0x84, 0xC2, 0x7, 0xD6, 0x1, 0x3C, 0x1E };

const int chipSelect = 5;
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
char Date[14];
char Time[13];
String dataStringTempsensor1 = "";
String dataStringTempsensor2 = "";
String dataStringTemp = "";
String dataStringNois = "";
int RTC_temp;
int sleep_time;
int new_time;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
#define LED 2
#define CLOCK_INTERRUPT_PIN 33
#define VOLT_NOIS_PIN 35

void CreateLogfileName() {
  DateTime now = rtc.now();
  snprintf(Date, sizeof(Date), "%02d%02d%02d.log", now.year(), now.month(), now.day()); // ein 8.3 Name wie z.B.  "06032345.log"
  snprintf(Time, sizeof(Time), "%02d%02d%02d.log", now.hour(), now.minute(), now.second()); // ein 8.3 Name wie z.B.  "06032345.log"
}

void onAlarm() {
  Serial.println("Alarm occured!");
}

void setup() {
  Serial.begin(9600);

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); //1 = High, 0 = Low //Pin 33
  //esp_sleep_enable_ext1_wakeup(0x400000000, ESP_EXT1_WAKEUP_ALL_LOW); //Pin 34

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  rtc.disable32K();

  pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);

  rtc.clearAlarm(1);
  rtc.clearAlarm(2);

  rtc.writeSqwPinMode(DS3231_OFF);

  sensors.begin();

  while (!Serial) {
    ;
  }
  Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  Serial.println("card initialized.");
  /*
    rtc.disableAlarm(2);

    if (!rtc.setAlarm1(rtc.now() + TimeSpan(30), DS3231_A1_Second // this mode triggers the alarm when the seconds match. See Doxygen for other options
                      )) {
      Serial.println("Error, alarm wasn't set!");
    } else {
      Serial.println("Alarm will happen in 30 seconds!");
    }
  */

  rtc.disableAlarm(1);

  rtc.setAlarm2(rtc.now(), DS3231_A2_PerMinute); // this mode triggers the alarm when the minutes match. See Doxygen for other options
  Serial.println("Alarm 2 will happen in 2 minutes (when full minutes match)!");

}

void loop() {

  RTC_temp = rtc.getTemperature();

  sensors.requestTemperatures(); // Send the command to get temperatures

  dataStringTempsensor1 = String(sensors.getTempC(sensor1));
  dataStringTempsensor2 = String(sensors.getTempC(sensor2));
  dataStringTemp = dataStringTempsensor1 + "," + dataStringTempsensor2;

  unsigned long startMillis = millis(); // Start of sample window
  unsigned int peakToPeak = 0;   // peak-to-peak level

  unsigned int signalMax = 0;
  unsigned int signalMin = 4096;

  while (millis() - startMillis < sampleWindow)
  {
    sample = analogRead(VOLT_NOIS_PIN);

    if (sample < 4096)  // toss out spurious readings
    {
      if (sample > signalMax)
      {
        signalMax = sample;  // save just the max levels
      }
      else if (sample < signalMin)
      {
        signalMin = sample;  // save just the min levels
      }
    }
  }

  peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
  //Serial.print("PeakToPeak: ");
  //Serial.println(peakToPeak);
  double volts = (peakToPeak * 3.3) / 4096;  // convert to volts
  dataStringNois = String(volts, 2);

  CreateLogfileName();
  String date_str = String(Date);
  String FileName = "/" + date_str;

  File dataFile = SD.open(FileName, FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(Time);
    dataFile.print("Sensor temperature: ");
    dataFile.println(dataStringTemp);
    dataFile.print("Volts noise: ");
    dataFile.println(volts);
    dataFile.print("RTC temperature: ");
    dataFile.println(RTC_temp);
    Serial.println("Dato to file ok");
    dataFile.flush();
    dataFile.close();
  }
  else {
    Serial.println("error opening xxxx.txt");
  }

  if (rtc.alarmFired(2)) {
    rtc.clearAlarm(2);
    Serial.println("Alarm 2 cleared");
  }
  /*
    if (rtc.alarmFired(1)) {
    rtc.clearAlarm(1);
    Serial.println("Alarm 1 cleared");
    }
  */
  DateTime now = rtc.now();
  new_time = now.second();
  sleep_time = new_time + 30;
  Serial.print("Now time loop: ");
  Serial.println(now.second(), DEC);

  if (new_time == 30) {
    Serial.println("Going to sleep now");
    esp_deep_sleep_start();
  }
  //delay(1000);
}

Und so sieht das ergebnis aus:

231626.logSensor temperature: 28.19,28.56
Volts noise: 0.02
RTC temperature: -20

Info: das println wurde erst danach verÀndert also der nicht vorhandene Zeilenumbruch ist ok
Jedoch wundert mich die Temperatur welche ich vom RTC DS3231 bekomme schon, da es eigendlich im bereich der beiden anderen temperaturen liegen sollte

Wie immer danke an jeden

Lg

Info: was ich glaube rausgefunden zu haben ist, das bei meinem 2 Code zumindest beim ersten mal etwas auf die SD geschrieben wird.
Vermute ich wegen dem log der zeit im file

Weiters noch:

wenn ich im 2ten code

 if (dataFile) {
    dataFile.println(Time);
    dataFile.print("Sensor temperature: ");
    dataFile.println(dataStringTemp);
    dataFile.print("Volts noise: ");
    dataFile.println(volts);
    dataFile.print("RTC temperature: ");
    dataFile.println(RTC_temp);
    Serial.println("Dato to file ok");
        delay(1000);
    dataFile.flush();
    dataFile.close();
  }

also ein delay form close bzw flush einbaue, dann schreibt mir dieser auch keine daten mehr auf die SD karte, also auch nicht beim ersten mal mehr.

Kennt jemand sowas?

Kann es entweder mit der zeit zu tun haben oder das das file nicht geschlossen wird?

WĂ€re wirklich fĂŒr jeden tipp dankbar.

Dann mal gute nacht und bis morgen

Lg
Lg

Bei mir bewirkt das nichts, es hilft nur delay(500).

Dir fehlt eine Schrittkette. - HÀ? - loop() ist eine Schleife, die stÀndig durchlaufen wird, da wird Deine SD-Karte kirre.

So geht es bei mir, getestet mit ESP32:

/*
  Hard SPI:
  MICROSD - ESP32
   CS   - IO5
   SCK  - IO18
   MOSI - IO23
   MISO - IO19
   Vcc  - 3.3V
   GND  - GND
*/

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

const int chipSelect = 5;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  delay(500);
  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 = "Hallo";
  File dataFile;
  static uint8_t schritt = 0;
  switch (schritt) {
    case 0:
      // open the file. note that only one file can be open at a time,
      // so you have to close this one before opening another.
      dataFile = SD.open("/datalog.txt", FILE_WRITE);

      // if the file is available, write to it:
      if (dataFile) {
        dataFile.println(dataString);
        dataFile.flush();
        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");
      }
      schritt++;
      break;
    case 1:
      dataFile = SD.open("/datalog.txt", FILE_READ);
      if (dataFile) {
        Serial.print("Read from file: ");
        while (dataFile.available()) {
          Serial.write(dataFile.read());
        }
        dataFile.close();
      }
      schritt++;
      break;
  }
}

Initializing SD card...card initialized.
Hallo
Read from file: Hallo

Es lebe die Schrittkette :slightly_smiling_face:


Eigentlich möchtest Du doch sowas:

Boot number: 12
Wakeup caused by external signal using RTC_IO
Alarm will happen in 10 seconds!
Initializing SD card...card initialized.
letzte Messung: 13:02:34
13:02:44
Read from file:
13:00:55
13:01:04
13:01:14
13:01:24
13:01:34
13:01:44
13:01:54
13:02:04
13:02:14
13:02:24
13:02:34
13:02:44
Going to sleep now

Getestet mit ESP32:

/* Hard SPI:
  MICROSD - CS    SCK   MOSI  MISO  Vcc   GND
  ESP32   - IO5   IO18  IO23  IO19  3.3V  GND
*/
#include <SPI.h>
#include <SD.h>
const int chipSelect = 5;

#include <RTClib.h>
RTC_DS3231 DS3231;
RTC_DATA_ATTR uint32_t unixZeit;

const byte LED = 13;
bool fehler = false;

RTC_DATA_ATTR int bootCount = 0;  // diese Variable ist auch nach deep sleep vorhanden

void print_wakeup_reason()
{
  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch (wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
  }
}

void setup()
{
  Serial.begin(115200);
  delay(500); //Take some time to open up the Serial Monitor
  pinMode(LED, OUTPUT);
  ++bootCount;
  Serial.printf("\nBoot number: %d\n", bootCount);
  print_wakeup_reason();  //Print the wakeup reason for ESP32
  pinMode(GPIO_NUM_33, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); //1 = High, 0 = Low

  if (!DS3231.begin())
  {
    Serial.println("Couldn't find DS3231!");
    fehler = true;
  } else {
    DS3231.disable32K();  //we don't need the 32K Pin, so disable it
    DS3231.writeSqwPinMode(DS3231_OFF);  // stop oscillating signals at SQW Pin, otherwise setAlarm1 will fail
    DS3231.clearAlarm(1);                // set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
    DS3231.clearAlarm(2);
    DS3231.disableAlarm(2);              // turn off alarm 2 (in case it isn't off already)
    if (!DS3231.setAlarm1(
          DS3231.now() + TimeSpan(10),   // schedule an alarm 10 seconds in the future
          DS3231_A1_Second            // this mode triggers the alarm when the seconds match
        ))
    {
      Serial.println("Error, alarm wasn't set!");
    } else {
      Serial.println("Alarm will happen in 10 seconds!");
    }
  }

  Serial.print("Initializing SD card...");
  if (SD.begin(chipSelect)) {
    Serial.println("card initialized.");
  } else {
    fehler = true;
    Serial.println("Card failed, or not present");
  }
}

void loop() {
  File dataFile;
  DateTime zeit = DateTime(unixZeit);
  char dataString[10] = "hh:mm:ss";
  static byte schritt = 0;
  switch (schritt) {
    case 0:
      digitalWrite(LED, HIGH);
      Serial.printf("letzte Messung:  %2u:%02u:%02u\n", zeit.hour(), zeit.minute(), zeit.second() );
      unixZeit = DS3231.now().unixtime();
      DS3231.now().toString(dataString);
      if (fehler) {
        Serial.println("Wegen Fehlers kein Schreiben auf SD-Karte!");
      } else {
        dataFile = SD.open("/datalog.txt", FILE_APPEND);
        if (dataFile) {
          dataFile.println(dataString);
          dataFile.flush();
          dataFile.close();
        } else {
          Serial.println("error opening datalog.txt");
        }
      }
      Serial.println(dataString);
      schritt++;
      break;
    case 1:
      dataFile = SD.open("/datalog.txt", FILE_READ);
      if (dataFile) {
        Serial.println("Read from file: ");
        while (dataFile.available()) {
          Serial.write(dataFile.read());
        }
        dataFile.close();
      }
      schritt++;
      break;
    default:
      digitalWrite(LED, LOW);
      Serial.println("Going to sleep now");
      Serial.flush();
      esp_deep_sleep_start();
      Serial.println("This will never be printed");
      break;
  }
}

Oder?

Wozu am ESP32 ĂŒberhaupt ein SD-Cardreader ?
Da geht doch sicher auch LittleFS oder evtl. auch Preferences ?

Hallo,
nö ich will dann so viele Messungen machen und wenn nötig ĂŒber lĂ€ngere Zeit speichern, dass ich eine SD Karte benötige.
Daten wĂ€ren sonst zu groß.

Lg

Hey,

ja genau so in etwa nur das ich keinen case und schritt brauche, da ich nur aufs file schreiben will und nicht davon lesen
Werde das mal versuchen auf meine Sache umzubauen und geb dann RĂŒckmeldung.

Danke mal fĂŒr deine Hilfe und das du mir das gegeben hast!
Mega nett..

Sobald ich was hab meld ich mich wieder.

Lg

Ok, dann soll es so sein.

Mein letzter post stimmt nicht, hab was ĂŒbersehen.

LÀuft jetzt anscheinend, mal schaun, was passiert wenn es lÀnger lÀuf.

Meld mich dann

DANKE!!

lg

Trotzdem danke, jede Idee ist Willkommen!

Lg

Habs jetzt zum laufen gebracht mit meine code.

Edit: fehler war das ich beim schreiben auf die SD Karte bei bsp von dem ich das hatte, vergessen habe append bei schreiben auf die SD hinzuzufĂŒgen
Ich weiß lĂ€cherlich aber am Anfang passiert sowas
Nur falls jemand auch so dumm ist wie ich :grin:

Jedoch bewirkt das öffnen und schließen, das nicht mehr in regelmĂ€ĂŸigen abstĂ€nden log gemacht werden sondern manchmal dauert es 1sec bis zum nĂ€chsten log und manchmal 2 sec.

mit delay wird das nicht lĂ¶ĂŸbar sein?
Jemand eine idee zu einem einfachen weg, mir fÀllt nichts ein..

Danke

Lg

Dan sind drei mögliche Fehlerquellen

  1. Dein Programm
  2. SD Karte
  3. Kartenleser

Was fĂŒr Kartenleser wird benutzt? Link wĂ€re gut

Hier das Datasheet vom SD Karten Reader
SPI Reader DE.pdf (3,1 MB)

Danke

LG

Das ist ein 5 Volt Type. Der braucht 5 Volt Spannung und auch 5 Volt Datenleitungen.
Da kann es schon mal sein, das er bei 3,3V versagt.

So wie schon @HotSystems schreibt das ist ein 5V Reader fĂŒr Uno, Nano, Mega.
Und wen Du den mit 5V betreibst dann kann passieren das dein ESP 32 nicht lange lebt.

Ach ok, wo habt ihr das genau gelesen das der SPI auch 5V hat?
Oder weil der Logger an 5V Vcc hÀngt?

Es funktioniert aber ohne Probleme.
Vlt sollte ich weiter noch sagen, das auch die Zeit am Serial Monitor vom loop geprintet welche von der RTS ds3231 kommt, auch manchmal um 1sec weiter hĂŒpft und manchmal um 2 sec.

Hatte ich vergessen, deshalb meine vermutung, dass das öffnen und schließen vom Datalogger jedes mal im loop zu lange dauert.

Weiß aber nicht was dagegn tun

BrĂ€uchte nemlich fĂŒr meine fft welche ich dann mit einigen daten mache, immer einen gleichen abstand der messwerte

Danke

Lg

Noch funktioniert es.
Der Reader hat einen Levelshifter drauf. Der liefert an den Pins 5Volt, das ist fĂŒr den ESP32 tötlich sein kann.

Hm, danke, das ist sehr gut zu wissen!
Dann muss ich da halt zusÀtzlich einen leverlshifter einbauen um das zu beheben.
Oder kann ich einfach einen Spannungteiler machen?

trotzdem besteht ja mein anderes problem noch
Dazu auch einen tipp?

Danke

Lg

Sorry falls ich blöde fragen stelle :grimacing:

Du solltest besser einen Cardreader verwenden, der direkt an 3,3 Volt arbeitet und keinen eigenen Levelshifter drauf hat.
FĂŒr dein Problem habe ich leider keinen Tipp, da ich am ESP32 keinen Cardreader betreibe.

Ist doch logisch wen Du auf den Reader 5V gibst dann haben die SPI Pins auch 5V, dafĂŒr sorgt der 16 beiniger KĂ€fer auf dem Modul, das ist ein Level Schifter was passt die Spannung zw SD Karte und SPI an.
SD Karten arbeiten intern mit 3,3V, das macht der Spannungsregler.