ESP32 und SD Card Frage

Hallo zusammen, im Grunde steht mein code im ESP32.
Ich habe ein Computer Tool Programmiert und sende über WLAN an den ESP32
Befehle und ich bekomme alle Infos von der miroSD Card.
Eins verstehe ich aber nicht, wenn ich das erstemal Connect mit dem ESP32 mache
kann ich check_sd_card(); und dann listDir(SD, "/", 0); machen. Und das sieht gut aus.
Aber schliesse ich jetzt mein Delphi Tool und starte es neu und drücke auf Connect
kann ich nur noch check_sd_card(); machen, bei listDir(SD, "/", 0); bekomme ich nichts
zurück.

Jetzt muss ich den ESP Reseten, danach bekomme ich wieder listDir(SD, "/", 0);

Und jetzt kommts noch dicker. bevor ich mein delphi tool zu mache, und ich
einmal readFile(SD, "/MyTest.txt"); mache. Kann ich mein Delphi Tool zu machen,
danach neu starten und es geht wieder alles.

Ich komme einfach nicht mehr weiter.
Hier mal mein Code.

mfg

//=========================
// Check  SD Card
//========================= 
void check_sd_card()
{
  if(!SD.begin(5)){
    client.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    client.println("No SD card attached");
    return;
  }
  client.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    client.println("MMC");
  } else if(cardType == CARD_SD){
    client.println("SDSC");
  } else if(cardType == CARD_SDHC){
    client.println("SDHC");
  } else {
    client.println("UNKNOWN");
  }
  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  client.printf("SD Card Size: %lluMB\n", cardSize);
  client.println("Ende Check SD Card");
}



//=================
//    List Dir  
//=================
void listDir(fs::FS &fs, const char * dirname, uint8_t levels)
{
  //client.printf("Listing directory: %s\n", dirname);
  Sende_str.clear();
  File root = fs.open(dirname);
  if(!root){
    client.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    client.println("Not a directory");
    return;
  }
  File file = root.openNextFile();
  Sende_str = "(";                              //selbst gebauter string
 
  while(file){
    if(file.isDirectory()){
      //client.print("DIR : ");
      client.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {

      Sende_str += file.name(); 
      Sende_str += ":"; 
      Sende_str += file.size(); 
      Sende_str += ":"; 
      Sende_str += ")";
      Sende_str += "(";      
    }   
    file = root.openNextFile();
  } 
  client.println(Sende_str);  
}


//=========================
// Read File
//========================= 
void readFile(fs::FS &fs, const char * path){
  client.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if(!file){
    client.println("Failed to open file for reading");
    return;
  }
  client.print("Read from file: ");
  while(file.available()){
    client.write(file.read());
  }
  file.close();
}



void loop()
//Das sollte klar sein das ich hier client abhole und dann
//entscheide, code wollte ich nicht zeigen 

  check_sd_card(); 
  listDir(SD, "/", 0); 
  readFile(SD, "/MyTest.txt");

Was macht das und wo wird es angeschlossen?

und zum debuggen benutze statt client.println("UNKNOWN");
serial.println("UNKNOWN");

UND: Der gezeigte Code ist unvollständig.

Du brauchst doch Hilfe, nicht wir !
Also kompletten Sketch zeigen.

Das ist mein Programm-Tool am Computer, was ich unter Delphi (Pascal) geschrieben habe.
Damit sende ich Befehle über LAN an meinen Router und dann über WLAN zu meinen
ESP32.

ok die Setup wäre noch wichtig

void setup() 
{
  Serial.begin(115200);
  ssid = "*********";
  pass = "************";
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);                
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }
    server.begin(); 
 }

mfg

Auch dieser Code ist nicht vollständig.
Brauchst Du Hilfe, dann gib uns vollständige Codes oder willst Du nur trollen?

Gruß Tommy

ok hier mein Code.

#include <Arduino.h>
#include <WiFi.h>

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <errno.h>
using namespace std; 
#include <float.h>
#include <math.h>
#include <stdio.h>
#include "time.h"

#include <TFT_eSPI.h> 

uint32_t delayMS;

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

//File root;

String Empf_str1;      //Für Serielle
String Empf_str2;      //Für Serielle
String rec_str = "";   //Für Serielle

int port = 23;  //Port number
String ssid;
String pass;

WiFiServer server(port);

WiFiClient client;

int status = WL_IDLE_STATUS;

#define TFT_GREY 0x5AEB
TFT_eSPI tft = TFT_eSPI();       // Invoke custom library


// My Time and Date
#define MY_NTP_SERVER "at.pool.ntp.org"
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"
/* Globals */
time_t now;                          // this are the seconds since Epoch (1970) - UTC
tm tm;                               // the structure tm holds time information in a more convenient way *

char                  ntpDate[50];                                                                                //Datum
char                  ntpTime[50];                                                                                //Uhrzeit


//==============================================================
 String empf_str;  //Für WLAN Empfang 
 String Sende_str;
 const char* empf_chr;

 char Name_Chr[14];
 char Memo_Chr[200];

 String Name_Str;
 String Memo_Str;
 


//==============================================================
void showTime() {
  time(&now); // read the current time
  localtime_r(&now, &tm);             // update the structure tm with the current time 
  snprintf (ntpDate, 50, "%02d.%02d.%0002d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);  
  snprintf (ntpTime, 50, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec + 1);
}
 


//===========================================
// Das ist mein erstes was ich mache 
// Nach 2-3 mal Befehl senden bekomme ich true
void check_sd_card()
{
  if(!SD.begin(5)){
    client.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    client.println("No SD card attached");
    return;
  }
  client.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    client.println("MMC");
  } else if(cardType == CARD_SD){
    client.println("SDSC");
  } else if(cardType == CARD_SDHC){
    client.println("SDHC");
  } else {
    client.println("UNKNOWN");
  }
  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  client.printf("SD Card Size: %lluMB\n", cardSize);
  client.println("Ende Check SD Card");
}


//===================================================
//    List Dir  D
//===================================================
void listDir(fs::FS &fs, const char * dirname, uint8_t levels)
{
  //client.printf("Listing directory: %s\n", dirname);
  Sende_str.clear();

  File root = fs.open(dirname);
  if(!root){
    client.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    client.println("Not a directory");
    return;
  }
  File file = root.openNextFile();
  Sende_str = "(";
 
  while(file){
    if(file.isDirectory()){
      //client.print("DIR : ");
      client.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {

      Sende_str += file.name(); 
      Sende_str += ":"; 
      Sende_str += file.size(); 
      Sende_str += ":"; 
      Sende_str += ")";
      Sende_str += "(";      
    }   
    file = root.openNextFile();
  } 
  client.println(Sende_str);  
}

//=========================================
//nur zum testen vom originalen demo
void readFile(fs::FS &fs, const char * path){
  client.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if(!file){
    client.println("Failed to open file for reading");
    return;
  }
  client.print("Read from file: ");
  while(file.available()){
    client.write(file.read());
  }
  file.close();
}
//nur zum testen vom originalen demo


//==================================
// Datei lesen ist ok
void read_sd_demo()
{   //debug ausgabe, kommt raus
    //client.println("file open " + Name_Str);
    File file = SD.open("/" + Name_Str);    
    if (file) {   
    // aus der Datei lesen, bis nichts mehr darin ist:
    while (file.available()) {
      client.write(file.read()); 
    }
    // close the file:
    //client.println("file close ");
    file.close();
    } else {
    // if the file didn't open, print an error:
    client.println("error opening "  + Name_Str);
    }
}

//=================================
// ok
void datei_erstellen_sd_demo()
{
    client.println("Creating eine datei " + Name_Str);
    File file = SD.open("/" + Name_Str , FILE_WRITE);
    file.close();
    // Check to see if the file exists:
    if (SD.exists("/" +  Name_Str)) {
      client.println(Name_Str +   " exists.");
    } else {
    client.println(Name_Str + " doesn't exist.");
    }
}

//=============================
// ok delete the file:
void delete_sd_demo()
{
  client.println("Removing example.txt...");
  SD.remove("/" + Name_Str);
  if (SD.exists(Name_Str)) {
    client.println(Name_Str + " Datei wurde nicht geloescht");
  } else {
    client.println(Name_Str + " Datei wurde geloecht.");
  }
}

//================================
// ok Write in Datei
void write_sd_demo()
{
  //Debug Ausgabe 
  //client.println("Name fuer Datei " +  Name_Str);
  //client.println("Memo fuer Datei " +  Memo_Str);
  
  File file = SD.open(Name_Str, FILE_WRITE);
  // if the file opened okay, write to it:
  
  if (file) {    
    file.println(Memo_Str);
    // close the file:
    file.close();
    client.println("Fertig. !");
  } else {
    // if the file didn't open, print an error:
    client.println("Konnte nichts in Datei schreiben");
  }
}

//=============================
// ok geht auch
void append_sd_demo()
{
  File file = SD.open("/" + Name_Str, FILE_APPEND);
  if(!file){
  Serial.println(F("failed to open file"));
  }  
  file.print(Memo_Str);
  file.print("\n");
  file.close();
}



//==============================================================
//                     SETUP
//==============================================================
void setup() 
{
  Serial.begin(115200);

  ssid = "********";
  pass = "************";

  configTime(0, 0, MY_NTP_SERVER);  // 0, 0 because we will use TZ in the next line
  setenv("TZ", MY_TZ, 1);            // Set environment variable with your time zone
  tzset();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);                    //WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  server.begin(); 
  
  tft.init();
  tft.setRotation(2);
  tft.fillScreen(TFT_BLACK);
  //tft.fillScreen(TFT_RED);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);  // Adding a background colour erases previous text automatically
}

//==============================================================
//                     LOOP
//==============================================================
void loop () 
{    
  showTime();
  tft.drawCentreString(ntpTime,120,10,4);        
  tft.drawCentreString(ntpDate,120,35,4);     
  delay(200); // dirty delay

    client = server.available();
    while(client.connected())
    {
     // kommt später wieder rein       
     // showTime();
     // tft.drawCentreString(ntpTime,120,10,4);        
     // tft.drawCentreString(ntpDate,120,35,4);  

        while (client.connected() && client.available())
        { 
          empf_str.clear();          
          empf_str =  client.readStringUntil(12);  // \n  
         
              //======================================= INIT SD Card
              if (empf_str[0] == 'C')
              {     
                check_sd_card();                               
              }                

              //======================================== List Dir
              if (empf_str[0] == 'D')
              {      
               listDir(SD, "/", 0); 
               client.println("ok1");              
              }   
             
              //
              //======================================== "2" read datei  Demo
              if (empf_str[0] == '2')
              { 
                empf_str.remove(0,1);  
                //Name_Str = empf_str;  
                //read_sd_demo();

                //Zum testen die Original Demo datei
                readFile(SD, "/MyTest.txt");
              }  
              //   
              //======================================== "3" write Datei 
              if (empf_str[0] == '3')
              {       
                empf_str.remove(0,1);  
                Name_Str = empf_str; 
                datei_erstellen_sd_demo();
              }

              //======================================== "4" delete Datei  
              if (empf_str[0] == '4')
              {       
                empf_str.remove(0,1);  
                Name_Str = empf_str; 
                 delete_sd_demo();
              }

              //======================================== "5" Schreiben in Datei  
              if (empf_str[0] == '5')
              {       
                empf_str.remove(0,1);   
                String s = empf_str;
                int pos = s.indexOf('{'); 
                Name_Str = s.substring(0,pos);    
                s.remove(0,pos+1);    
                Memo_Str = s;
                write_sd_demo();                
              }
    
              //======================================== "6" append 
              if (empf_str[0] == '6')
              {       
                empf_str.remove(0,1);  
                Name_Str = empf_str; 
                append_sd_demo();
                 
              }
        }   
    }
}    



mfg

Mal auf die Schnelle 1 Fehler.
Wenn mehrere Zeichenketten da sind, löschst Du sie laufend wieder. Das clear() gehört vor das while().
12 ist nicht \n, das ist FormFeed. Du suchst 10 LineFeed (\n) Schau Dir mal eine ASCII-Tabelle an.

Gruß Tommy

Ich habe so ein verdacht das da was auf bleibt wenn ich disconnect mache.
Und wenn ich wieder connect mache das ich da ein neuen Handle bekomme.

mfg

Dann baue Dir einen Sketch, der nur die Erkennung der Kommandos macht und prüfe auf diesem.
Nute dazu anstelle des readStringUntil ein zeichenweises Einlesen, um zu sehen, was Dein PC wirklich sendet:

while (client.connected() && client.available()) {
 char z = client.read();
 Serial.println(z,HEX);
}

Gruß Tommy

Das hat nichts mit dem PC zu tun, ich denke im ESp32 bleibt was auf.
Das habe ich vorher alles getestet das der PC anständig an den ESP32 sendet.

Weil ich sende ja auch "/Name" und Text mit und das kommt auch an.

Was ich einfach nicht verstehe, wenn ich vorher Read File sende und dann
disconnect mache, kann ich bei einen neuen Connect des ESP wieder
ListDir machen.

mfg

Dann probiere doch mal den client nach getaner Arbeit zu schließen.

Gruß Tommy

Genau Tommy56,

das werde ich mal naher testen, da suche ich auch im Internet nach einer schönen
Routine. Und da kommte ich auch alles andere schliessen. Gibts das ? SD.close();

mfg

ja. Schau einfach mal in die Header-Dateien (*.h) Deiner Libs. Da steht alles, was Du aufrufen kannst.

Gruß Tommy

Hallo Tommy56

Jetzt geht alles, das hatte gefehlt.

    }
    client.stop();
    SD.end();
}    

Danke für eure Hilfe.

mfg

Prima und danke für die Rückmeldung.

Gruß Tommy

Guten morgen, jetzt muss ich doch noch etwas dazu schreiben.
Meine micro SD Card ging soweit sehr gut, hatte keine Probleme mehr mit ListDir.
Nun wollte ich die Uhrzeit in mein TFT jede sec anzeigen, dabei habe ich nach diesen
Demo ein Task eingebaut,

Starte ich den Task mit vTaskResume(Task2); bekomme ich wieder Probleme
mit ListDir, was hat dieser Task mit meiner microSD Card zu tun ?

Mein Code habe ich schon hier gezeigt. Ich poste nur mal das was ich genau
eingebaut habe.

TaskHandle_t Task2;

Hier mein Task2 wo ich nur die Uhrzeit ausgebe. Also nix mit SD Card

//Task2code: 
void Task2code( void * pvParameters ){ 
  for(;;){
    while(!timeClient.update()) {
      timeClient.forceUpdate();
    }
    // The formattedDate comes with the following format:
    // 2018-05-28T16:00:13Z
    // We need to extract date and time
    formattedDate = timeClient.getFormattedDate();

    // Extract date
    int splitT = formattedDate.indexOf("T");
    dayStamp = formattedDate.substring(0, splitT);
    tft.drawCentreString(dayStamp,120,10,4); 

    // Extract time
    timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
    tft.drawCentreString(timeStamp,120,35,4); 
   
   delay(1000);
  } 
}

Und hier noch einmal mein Setup

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

  ssid = "********";
  pass = "************";

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);                    //WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  server.begin(); 
  
  tft.init();
  tft.setRotation(2);
  tft.fillScreen(TFT_BLACK);
  //tft.fillScreen(TFT_RED);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);  // Adding a background colour erases previous text automatically

  // Initialize a NTPClient to get time
  timeClient.begin();
  timeClient.setTimeOffset(3600);
  

  xTaskCreatePinnedToCore(
                    Task2code,   /* Task function. */
                    "Task2",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,            /* priority of the task */
                    &Task2,      /* Task handle to keep track of created task */
                    1);          /* pin task to core 0 */                  
  delay(500);
}

mfg

Das tust Du doch bereits hier:

Die Verwendung von FreeRTOS ist nicht falsch, aber auch nicht notwendig und m. E. auch nicht sinnvoll. Ich kann daher den Sinn Deines Tuns leider nicht nachvollziehen.

Im Detail kann ich Dir das nicht beantworten, da ich FreeRTOS nicht nutze. Aber es ist ein µC mit einem Speicher, weshalb 10000, /* Stack size of task */ zu groß oder zu klein sein könnte. Nur mal beispielhaft.

Hallo agmue,
sorry das war noch der alte Code, ich habe mir einen neuen Code gesaugt für
uhrzeit und datum. genau da hatte ich doch auch schon probleme.
Könnte das an meiner TFT LILI9341 und mein microSD Card anschlüsse sein.

Ich habe den Treiber für ili9341
bodmer/TFT_eSPI@^2.5.43 genommen.

Und andere Pins genommen. Nicht die von VSPI
#define TFT_MISO 25 //
#define TFT_MOSI 27 //
#define TFT_SCLK 26 //
#define TFT_CS 13 // Chip select control pin D8
#define TFT_DC 14 // Data Command control pin
#define TFT_RST 12 // Reset pin (could connect to NodeMCU RST, see next line)

mein ESp32 hat 30pin

Mein microSD Card habe ich an VSPI angeschlossen. Jedesmal wenn ich den Task
starte habe ich kein Zugriff nehr auf meine SD Card. Kann sich da was schlagen ?

Dem ILI9341 kann ich doch neue Pins geben oder nicht.?
Oder muss der an einen richtigen SPI Port dran sein ?

mfg

Der ESP32 hat eine Pin-Matrix, weshalb man die SPI-Hardware nahezu beliebigen Pins zuordnen kann. Es gibt zwei freie SPI in Hardware, genannt HSPI und VSPI. Wenn Du also die eine SPI-Hardware mit SD und die andere mit dem Display verbindest, sollte es gehen.

Muss ich da nicht eine neue SPIClass spi(HSPI); erstellen.?
Also für das TFT ILI9341

mfg