ESP32 Header Frage

Hallo allerseits, ich arbeite mich gerade in header ein. Da ich eine micro sd Card angeschlossen habe und viele funktionen wie listdir getdir usw. möchte ich die raus
aus main.cpp haben sonst wird die zu voll, das haut auch hin.
Serielle ausgabe von listdir geht auch.

Programmiere unter Platform IO
Meine datein sind,
main.cpp
MySd.hpp
MySd.cpp

Aber wenn ich über client senden will, bekomme ich error da client in MySd.cpp nicht gibt
Ich versuche mal meinen Code zu zeigen.

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

Und hier die loop schleife

void loop () 
{       
    client = server.available();  
    while(client.connected())
    {       
        while (client.connected() && client.available())
        { 
          empf_str.clear();
          empf_str =  client.readStringUntil('\n');   

Die Datei MySd.cpp

#include <Arduino.h>
#include "MySd.hpp"
//===================================================
void check_sd_card()
{
        {
          if(!SD.begin(5)){
            client.println("Card Mount Failed");   // <=== Error bei client
            return;
          }
          uint8_t cardType = SD.cardType();
          if(cardType == CARD_NONE){
            Serial.println("No SD card attached");
            return;
          }

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

ich Frage mich die ganze zeit warum Serial Ausgabe in MySd.cpp geht
aber nicht client ausgabe.

mfg

Ich mich auch.
Wird wohl irgendwo in einem Code-Teil versteckt sein, den Du nicht zeigst.
Bitte alle Dateien komplett zur Verfügung stellen.

Moin @schuby ,

da Du allem Anschein nicht den kompletten Code sondern unvollständige Anteile gepostet hast, ist eine sinnvolle Fehlersuche nicht möglich.

Was Du anscheinend möchtest, ist das Auslagern von Funktionen in externe, durch #include eingebundene Dateien, korrekt?

Hier gibt es Erläuterungen zur Verwendung von Header-Files:

https://www.learncpp.com/cpp-tutorial/header-files/

und hier zu sogenannten "Header Guards"

https://www.learncpp.com/cpp-tutorial/header-guards/

die verhindern, dass eine include-Datei mehrfach in einem Projekt geladen wird. Du kannst aber auch in den Kopf der include-Datei einfach

#pragma once

schreiben, das hat den gleichen Effekt:

https://learn.microsoft.com/de-de/cpp/preprocessor/once?view=msvc-170

Für weitere Hilfe bitte den Code komplett posten ...

Sorry ich hatte gedacht es würde reichen. Ich poste jetzt alles was ich habe.

main.cpp

#include <Arduino.h>

#include <iostream>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WIFI.h>
#include <stdio.h>
#include <stdlib.h>
#include <String.h>
using namespace std; 
#include <float.h>
#include <math.h>
#include <stdio.h>
#include "time.h"

#include <TFT_eSPI.h> // Hardware-specific library

// eigene units einbinden
#include "MySd.hpp"

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

const char* ssid   = "************";
const char* pass   = "************";

String rec_str = "";   //Für Serielle
int port = 23;  //Port number

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
//==============================================================
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);
}
//==============================================================
//                     SETUP
//==============================================================
void setup() 
{
  Serial.begin(115200);
  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.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(100); // dirty delay


    //=========================
    client = server.available();
    //=========================


    while(client.connected())
    {       
      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('\n');   
          client.println(empf_str); //sende zurück zum prüfen        

              //=================================================================
              if (empf_str[0] == 'A')
              { 
                client.println(ntpDate);                      
              }

              //=================================================================
              if (empf_str[0] == 'B')
              {           
                client.println(ntpTime);
              }
              //=================================================================
              if (empf_str[0] == 'C')
              {           
                check_sd_card();            
              }                

              //=================================================================
              if (empf_str[0] == 'D')
              {           
                listDir(SD, "/", 0);          
              }   
        }   
    }
}

MySd.hpp

#pragma once

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

#include <WIFI.h>
#include <iostream>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <stdio.h>
#include <stdlib.h>
#include <String.h>
#include <errno.h>
using namespace std; 
#include <float.h>
#include <math.h>
#include <stdio.h>


void check_sd_card();
void listDir(fs::FS &fs, const char * dirname, uint8_t levels);

Und die MySd.cpp

#include <Arduino.h>
#include <WiFi.h>
#include "MySd.hpp"


// Hier kann ich nichts über client senden, nur über Serial.print 

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


          uint8_t cardType = SD.cardType();

          if(cardType == CARD_NONE){
            Serial.println("No SD card attached");
            return;
          }

          Serial.print("SD Card Type: ");
          if(cardType == CARD_MMC){
            Serial.println("MMC");
          } else if(cardType == CARD_SD){
            Serial.println("SDSC");
          } else if(cardType == CARD_SDHC){
            Serial.println("SDHC");
          } else {
            Serial.println("UNKNOWN");
          }

          uint64_t cardSize = SD.cardSize() / (1024 * 1024);
          Serial.printf("SD Card Size: %lluMB\n", cardSize);
        }      
}



void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
  Serial.printf("Listing directory: %s\n", dirname);

  File root = fs.open(dirname);
  if(!root){
    Serial.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while(file){
    if(file.isDirectory()){
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

Bitte bedenkt, ich bin Anfänger. Ich übe C/C++

mfg

So könnte es gehen :slight_smile:

1 Like

Ne geht auch nicht, ich bekomme unter platformio probleme.

extern WiFiClient client;
Linking .pio\build\esp32dev\firmware.elf
c:/users/xxxx/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\esp32dev\src\main.cpp.o:(.literal._Z17Print_Zugang_WLANv+0x20): undefined reference to `client'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\esp32dev\firmware.elf] Error 1

Ich habe mir auch mal ein einfaches Demo für den ESP32 unter Arduino Installiert.
Da bekomme ich auch Probleme mit NetworkServer server(80);
In der Arduino IDE laßt es sich compilieren. Aber nicht unter platformio

mfg

Ob das jetzt alles so schön ist, lassen wir mal dahin gestellt, aber so sollte es sich zumindest kompilieren lassen:

main.cpp


#include <Arduino.h>

#include <iostream>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WIFI.h>
#include <stdio.h>
#include <stdlib.h>
#include <String.h>
using namespace std;
#include <float.h>
#include <math.h>
#include <stdio.h>
#include "time.h"

#include <TFT_eSPI.h>   // Hardware-specific library

// eigene units einbinden
#include "MySd.hpp"

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

const char* ssid = "************";
const char* pass = "************";

String rec_str = "";   // Für Serielle
int port = 23;         // Port number

WiFiServer server(port);

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
//==============================================================
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.%04d", 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);
}
//==============================================================
//                     SETUP
//==============================================================
void setup() {
  Serial.begin(115200);
  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.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(100);   // dirty delay

  //=========================
  client = server.available();
  //=========================

  while (client.connected()) {
    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('\n');
      client.println(empf_str);   // sende zurück zum prüfen

      //=================================================================
      if (empf_str[0] == 'A') { client.println(ntpDate); }

      //=================================================================
      if (empf_str[0] == 'B') { client.println(ntpTime); }
      //=================================================================
      if (empf_str[0] == 'C') { check_sd_card(); }

      //=================================================================
      if (empf_str[0] == 'D') { listDir(SD, "/", 0); }
    }
  }
}

Die Definition von "client" erfolgte in der main.cpp zu spät, weil Du das Objekt schon in der MySd.cpp verwendest. Darum wurde diese aus main.cpp entfernt.

MySd.hpp

#pragma once

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

#include <WIFI.h>
#include <iostream>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <stdio.h>
#include <stdlib.h>
#include <String.h>
#include <errno.h>
using namespace std; 
#include <float.h>
#include <math.h>
#include <stdio.h>


void check_sd_card();
void listDir(fs::FS &fs, const char * dirname, uint8_t levels);

extern WiFiClient client;    // << Bekannt machen, dass dieses Objekt irgendwo im Code mal vorkommen wird.

MySd.cpp

#include <Arduino.h>
#include <WiFi.h>
#include "MySd.hpp"

WiFiClient client;    //  << client Objekt  definieren, weil es "weiter unten" benötigt wird.


// Hier kann ich nichts über client senden, nur über Serial.print 

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


          uint8_t cardType = SD.cardType();

          if(cardType == CARD_NONE){
            Serial.println("No SD card attached");
            return;
          }

          Serial.print("SD Card Type: ");
          if(cardType == CARD_MMC){
            Serial.println("MMC");
          } else if(cardType == CARD_SD){
            Serial.println("SDSC");
          } else if(cardType == CARD_SDHC){
            Serial.println("SDHC");
          } else {
            Serial.println("UNKNOWN");
          }

          uint64_t cardSize = SD.cardSize() / (1024 * 1024);
          Serial.printf("SD Card Size: %lluMB\n", cardSize);
        }      
}



void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
  Serial.printf("Listing directory: %s\n", dirname);

  File root = fs.open(dirname);
  if(!root){
    Serial.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while(file){
    if(file.isDirectory()){
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}
1 Like

Guten morgen und ein frohes neues.

Ich habe jetzt deine Info verarbeitet und ich darf nicht in MySd.cpp
WiFiClient client; schreiben, danach Compiliert das Programm, aber ich kann
immer noch nichts an client senden. Dann ist mir aufgefallen das ich in den
header datein #include <WiFi.h> drin stehen habe, dies habe ich in der Header datei gelöscht
und nun bekomme ich wieder Error beim Compilieren.
Ist es richtig das ich nur einmal in der main.cpp #include <WIFI.h> schreiben darf ?

mfg

Jetzt geht es ...

Ich musste #include <WIFI.h> aus der main.cpp raus nehmen und in die MySd.hpp einpacken.
und in MySd.hpp das einschreiben -> extern WiFiClient client;

Aber nichts mehr in MySd.cpp nur diese beiden include datein

#include <Arduino.h>
#include "MySd.hpp"

Danke an alle die mir geholfen haben.

mfg