Einstiegshilfe zu ESP32 WLAN gesucht

Hallo zusammen,

ich bin dabei für ein Projekt vom Arduino-Nano/UNO zum ESP32 WLAN umzusteigen.

Habe mir dazu von AZ so ein Dings gekauft und die ersten gefundenen Tutorials und Beispiele durchgeackert.

Die Kommunikation des ESP mit meinem Handy (Bluetoothterminal) funktioniert schon mal.

Jetzt fehlt mir aber die Lösung für eine Netzwerkübertragung. Habe schon gesucht, aber nichts Passendes gefunden. Oder wenn, dann nur ein brpcken Brocken oder für ganz andere Geräte.

Meine Vorstellung:

ESP32WLAN mit Akku(pack) im Stromsparmodus laufen lassen. (wie?)

Alle 5 Minuten aufwachen (wie?)

Einen Dallas-Sensor abfragen und eine entsprechenden Textstring erzeugen (ok - geht bei meinem Arduino bereits)

Textstring per FTP auf meinen Web-Server an eine Log-Datei anhängen (wie?)

Das technische Drumrumhandling dürfte dank Erfahrung mit Arduino machbar sein.

Nur der Netzwerkteil ist für mich noch ein böhmisches Dorf. FTP kenne ich bisher nur für File-Up/Download. Aber nicht zum schrittweisen Aufbau eines Logfiles.

Ideal wäre es, wenn ich die Netzwerk-Login-Daten per Bluetooth an das Ding senden könnte. Und dann den Prozess starten oder stoppen. Default sollte meine Heimadresse genutzt werden. Unterwegs dann Start/Stopp per Handy nach Eingabe der jeweils lokalen Netzwerkadresse.

Hat ja zufällig jemand passende Links oder selbst sowas gestrickt, was man passend ummodeln könnte? Am liebsten sind mir immer fertige Programme zum passend umstricken.

Gerne nehme ich auch andere Links und Tipps zum ESP32 an. Irgendwie fördern da meine Suchen nicht viel Brauchbares. Im Gegensatz zum Arduino, wo es ja tausende Beispiele zu jedem Thema gibt. Ok - vieles kann man auf den ESP direkt umscchreiben. Aber ein paar Sachen sind ja ganz ESP-spezifisch und beim UNO z.B. nicht vorhanden.

Danke schon mal vorab.

Wenn es wirklich stromsparend werden soll dann musste einen speziell auf stromsparen optimierten ESP32 nehmen.
Gibt es von

Die 0815-ESP32 brauchen slebst im deepsleep immer noch 8 bis 15 mA.
statt 0,015 mA

Demo-Code der fast genau das macht. Nur fast weil die Daten per UDP gesendet werden.
inklusive python-code als Kommentar am Ende des Codes.

UDP senden ist gerade mal drei Zeilen

// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  }

#define dbgc(myFixedText, variableName) \
  { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }

#define dbgcf(myFixedText, variableName) \
  { \
    static float lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *

const byte redLED1     = 16;
const byte greenLED1   = 17;
const byte OnBoard_LED = 18;

#define ON  LOW
#define OFF HIGH 

// I wrote some basic documentation about receiving the UDP-messages with python at the end of the file
#include <WiFi.h>
#include <SafeString.h>
#include <time.h>                   // time() ctime()
time_t now;                         // this is the epoch
tm myTimeInfo;                      // the structure tm holds time information in a more convient way

#include <OneWire.h>
#include <DallasTemperature.h>
const byte onewire_pin = 4;

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(onewire_pin);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature DS_18B20(&oneWire);

const uint32_t sleeptime = 10 * 1000UL * 1000UL ;      // in microseconds
RTC_DATA_ATTR uint16_t bootCounter = 0;                // test variable in RTC memory

#define MaxMsgLength 1024
createSafeString(UDP_Msg_SS, MaxMsgLength);
//uint8_t UDP_Msg_uint8_Buffer[MaxMsgLength + 1]; // for some strange reasons on ESP32 the udp.write-function needs an uint8_t-array

createSafeString(FileNameDateTime_SS, 256);

#define MaxHeaderLength 32
createSafeString(Header_SS, MaxHeaderLength);

#define MaxTimeStampLength 64
createSafeString(TimeStamp_SS, MaxTimeStampLength);

char HeaderDelimiter = '$'; // must match the delimiter defined in the python-code

const char* ssid = "your SSID";
const char* password = "your password";

IPAddress    remoteIP     (192, 168, 178, 160); // receiver-IP
unsigned int remotePort = 4210;                 // receiver port to listen on must match the portnumber the receiver is listening to

WiFiUDP Udp;

const char* ntpServer = "fritz.box";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 7200;

int sensorCount;

unsigned long OneWireTimer    = 0;
unsigned long startConnectingToWifi;
unsigned long finishedConnectingToWifi;

unsigned long startSynchronisingTime;
unsigned long finishedSynchronisingTime;

float Temp [3] = {11.1, 22.2, 33.3};


void DS18B20_Setup() {
  DS_18B20.begin(); //Starten der Kommunikation mit dem Sensor
  sensorCount = DS_18B20.getDS18Count(); //Lesen der Anzahl der angeschlossenen Temperatursensoren.
  dbg("DS18B20", sensorCount);
}

void printValue(float value, String text) {
  Serial.print(value);
  Serial.println(text);
}


void Read_DS18B20_Sensors() {
  DS_18B20.requestTemperatures();  // Temperaturen abfragen

  //Ausgabe aller Werte der angeschlossenen Temperatursensoren.
  for (int i = 0; i < sensorCount; i++) {
    Serial.print(i);
    Serial.print(". Temperatur :");
    Temp[i] = DS_18B20.getTempCByIndex(i);
    printValue(Temp[i], "°C");
  }

  Serial.println();
}



void shutdown() {
  Serial.print("goto Deepsleep for ");
  Serial.print(sleeptime / 1000000);
  Serial.println(" seconds");
  Serial.println("shutdown - deepsleep");
  Serial.flush();
  bootCounter++;
  dbg("sd",bootCounter);
  esp_sleep_enable_timer_wakeup(sleeptime);
  esp_deep_sleep_start();
}


boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod )
  {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}


int BlinkTime = 500;

void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

unsigned long TestTimer;
unsigned long UDP_SendTimer;

int myCounter = 0;
int HeaderNr  = 0;


void PrintFileNameDateTime() {
  Serial.print("Code running comes from file ");
  Serial.println(__FILE__);
  Serial.print(" compiled ");
  Serial.print(__DATE__);
  Serial.println(__TIME__);
}


void setFileNameDateTime_SS() {
  FileNameDateTime_SS = F("Code running comes from file ");
  FileNameDateTime_SS.print( F(__FILE__));
  FileNameDateTime_SS.print( F(" compiled ") );
  FileNameDateTime_SS.print( F(__DATE__) );
  FileNameDateTime_SS.print( F(__TIME__) );
}


void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(myTimeInfo.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(myTimeInfo.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(myTimeInfo.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(myTimeInfo.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(myTimeInfo.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(myTimeInfo.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(myTimeInfo.tm_wday);         // days since Sunday 0-6
  if (myTimeInfo.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");

  Serial.println();
}


void StoreTimeStampIntoSS(SafeString& p_RefToSS, tm p_myTimeInfo) {

  time(&now);                               // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time

  //p_RefToSS = " ";
  p_RefToSS  = myTimeInfo.tm_year + 1900;
  p_RefToSS += ".";

  // month
  if (p_myTimeInfo.tm_mon + 1 < 10) {
    p_RefToSS += "0";
  }
  p_RefToSS += myTimeInfo.tm_mon + 1;

  p_RefToSS += ".";

  // day
  if (p_myTimeInfo.tm_mday + 1 < 10) {
    p_RefToSS += "0";
  }
  p_RefToSS += myTimeInfo.tm_mday;

  p_RefToSS += "; ";

  // hour
  if (p_myTimeInfo.tm_hour < 10) {
    p_RefToSS += "0";
  }
  p_RefToSS += myTimeInfo.tm_hour;
  p_RefToSS += ":";

  // minute
  if (p_myTimeInfo.tm_min < 10) {
    p_RefToSS += "0";
  }
  p_RefToSS += myTimeInfo.tm_min;

  p_RefToSS += ":";

  // second
  if (p_myTimeInfo.tm_sec < 10) {
    p_RefToSS += "0";
  }
  p_RefToSS += myTimeInfo.tm_sec;
  //p_RefToSS += ",";
}


void connectToWifi() {

  startConnectingToWifi = millis();

  int myCounter = 0;
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);

  WiFi.persistent(false);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    yield();
    BlinkHeartBeatLED(OnBoard_LED, 200);
    delay(100);
    Serial.print(".");
    myCounter++;

    if (myCounter % 20 == 0) {
      Serial.println();
    }

    if (myCounter > 15) {
      ESP.restart();
    }
  }
  Serial.print("\n connected.");
  Serial.println(WiFi.localIP() );
  digitalWrite(OnBoard_LED, ON);
  finishedConnectingToWifi = millis();
}


void synchroniseWith_NTP_Time() {
  startSynchronisingTime = millis();

  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");

  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    BlinkHeartBeatLED(greenLED1, 100);
    delay(100);
    Serial.print(".");
  }
  finishedSynchronisingTime = millis();

  Serial.print("\n time synchronsized \n");
  digitalWrite(greenLED1,ON);
  showTime();
}


void ScanForWiFiNetworks() {
  Serial.println("start scanning for WiFi...");
  int numberOfNetworks = WiFi.scanNetworks();
  Serial.println("scanning finished");
  dbg("a:", numberOfNetworks);

  for (int i = 0; i < numberOfNetworks; i++) {
    Serial.print("Network name: ");
    Serial.println(WiFi.SSID(i));
    Serial.print("Signal strength: ");
    Serial.println(WiFi.RSSI(i));
    Serial.println("-----------------------");
  }
}

void flashLed(byte IO_Pin) {
  digitalWrite(IO_Pin,ON);
  delay(50);
  digitalWrite(IO_Pin,OFF);    
  delay(100);
}


void setup() {
  digitalWrite(OnBoard_LED,OFF);
  digitalWrite(greenLED1,OFF);
  digitalWrite(redLED1,OFF);

  pinMode(OnBoard_LED,OUTPUT);
  pinMode(greenLED1,  OUTPUT);
  pinMode(redLED1,    OUTPUT);

  flashLed(OnBoard_LED);
  flashLed(greenLED1);
  flashLed(redLED1);

  WiFi.persistent(false);

  Serial.begin(115200);
  Serial.println("\n Setup-Start \n");
  PrintFileNameDateTime();
  DS18B20_Setup();
  Serial.print("InitSensor() done \n");
 
  //ScanForWiFiNetworks();

  connectToWifi();
  synchroniseWith_NTP_Time();
  Header_SS = "Pool-Temp";

  UDP_Msg_SS = Header_SS;
  UDP_Msg_SS += HeaderDelimiter;

  StoreTimeStampIntoSS(TimeStamp_SS, myTimeInfo);

  UDP_Msg_SS += TimeStamp_SS;
  setFileNameDateTime_SS();
  UDP_Msg_SS += "; ; ; ; ; ;";
  //UDP_Msg_SS += FileNameDateTime_SS;
  UDP_Msg_SS += " connect to WiFi; ";
  UDP_Msg_SS += finishedConnectingToWifi - startConnectingToWifi;
  UDP_Msg_SS += "; ms; ";

  UDP_Msg_SS += " synchronise time; ";
  UDP_Msg_SS += finishedSynchronisingTime - startSynchronisingTime;
  UDP_Msg_SS += "; ms; ";

  UDP_Msg_SS += ";RSSI;";
  UDP_Msg_SS += WiFi.RSSI();

  PrintUdpMsg();
  sendUDPMsg();
/*
  UDP_Msg_SS = "";

  UDP_Msg_SS = Header_SS;
  UDP_Msg_SS += HeaderDelimiter;

  StoreTimeStampIntoSS(TimeStamp_SS, myTimeInfo);
  UDP_Msg_SS += TimeStamp_SS;

  UDP_Msg_SS += " booted";
*/
  PrintUdpMsg();
  sendUDPMsg();
}


void PrintUdpMsg() {
  Serial.print("UDP_Msg_SS #");
  Serial.print(UDP_Msg_SS);
  Serial.println("#");
}

void setUpUdpMsg() {

  UDP_Msg_SS = "";

  UDP_Msg_SS = Header_SS;
  UDP_Msg_SS += HeaderDelimiter;

  StoreTimeStampIntoSS(TimeStamp_SS, myTimeInfo);
  UDP_Msg_SS += TimeStamp_SS;

  UDP_Msg_SS += "; ";
  UDP_Msg_SS += Temp[0];
  UDP_Msg_SS += "; °C";

  UDP_Msg_SS += "; RSSI ; ";
  UDP_Msg_SS += WiFi.RSSI();
}


void sendUDPMsg() {
  Serial.print("Send Message to #");
  Serial.print(remoteIP);
  Serial.print(":");
  Serial.println(remotePort);

  Udp.beginPacket(remoteIP, remotePort);
  Udp.write((const uint8_t*)UDP_Msg_SS.c_str(), UDP_Msg_SS.length() );
  Udp.endPacket();
}



void loop() {
  BlinkHeartBeatLED(OnBoard_LED, BlinkTime);

  if (TimePeriodIsOver(UDP_SendTimer, 1000) ) {
    Read_DS18B20_Sensors();
    setUpUdpMsg();
    PrintUdpMsg();
    sendUDPMsg();
    shutdown();
  }
}
/*
  This is a democode that demonstrates how to send TCP/UDP-messages with a timestamp
  The time is synchronized using a NTP-server. Most local routers like Fritz!Box can be used as the NTP-timer-server

  The message has a userdefinable header which could be used for identifying the sender on the recieverside
  There is a user-definable Header-delimiter that can be used to identify which characters of the
  UDP-message belong to the header and which to the userdata

  The code makes use of the SafeString-library. SafeStrings don't cause memory-problems like datatype "Strings"
  and are easier to use than arrays of char. Example adding an integer to a SafeString-variable is as easy as
  MySafeString = myInteger;

  The userdata has commas between each data so you can import the textfile
  into table-calculation-software or databases as CSV-file comma separated values

  the code has some additional useful functions as there are
  - PrintFileNameDateTime() printing the path and filename of sourcecode file this program was generated with

  - boolean TimePeriodIsOver  a non-blocking timing-function based on millis which is suitable for
  timed execution in a regular manner (repeat every n milliseconds)

  - BlinkHeartBeatLED() blinks the onboard-LED of ESP32 nodeMCU-boards. Gives visual feedback if the code is running

  The lines of code are grouped by functionality into several functions
  The functions name says what the function does

  I use this code for easy datalogging on a computer with a python-code that acts as the UDP-listener for
  incoming messages. Inside your ESP32-code you have to adjust the IP-adress to the receiver
  and the portnumber must be the same on sender (ESP32) and receiver-side

  In the python-code The header is used to create a file with the header as filename and extension ".txt" or if file
  is already existant to append the actual received UDP-message at the end of the file.

  here is the python-code that does this. I tested it with python 3.9.2 for windows
  #Start of python-code
  # very simple and short upd-receiver based on python-code I found here
  # https://www.studytonight.com/network-programming-in-python/working-with-udp-sockets#

  import socket

  sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)      # For UDP

  udp_host = socket.gethostname()            # Host IP
  udp_port = 4210                     # specified port to connect

  sock.bind((udp_host,udp_port))
  print ("Waiting for client...")

  HeaderDelimitChar = "$"

  while True:
  data,addr = sock.recvfrom(1024)         #receive data from client
  print("data #",data,"#")
  Msg = data.decode('utf-8')
  print ("Received Message: #",Msg,"# from",addr)
  EndOfHeader = Msg.find(HeaderDelimitChar)
  HeaderBytes = Msg[0:EndOfHeader]
  FileName = HeaderBytes + ".txt"
  print("Filename #",FileName,"#")
  myFile = open(FileName, "a+")
  EndOfStr = data.find(0)
  MsgToWrite = Msg[EndOfHeader + 1 :1024] + '\r'
  myFile.write(MsgToWrite);
  myFile.close()
  print ("Data #",MsgToWrite,"#")

  #End of python-code

  For learning more about python just google with keyword "python" "your keyword of interest"
*/

Gute Quelle für ESP32-tutorials ist random nerd tutorial

1 Like

ich denke du musst dir erst mal klar machen von wo nach wo wie Daten gesandt werden sollen.

Ich habe dazu einmal diesen Überblick geschrieben:
https://werner.rothschopf.net/microcontroller/202403_esp_arduino_data_transmission_en.htm

Es behandelt die Schlagworte UDP, TCP, HTTP und wann man sich wofür entscheiden könnte.

nach dem Lesen solltest du beantworten:

  • Wer soll an Wen schicken (bzw. Wer soll von wem Daten abholen)
  • Wo sollen die Daten gespeichert werden
  • Wie siehst du die Daten am Ziel ein (also in welcher Form willst du sie dann schlussendlich nutzen)

Hallo
generell muss ich @noiasca erst mal zustimmen.
Aber natürlich kannst Du einen ESP mittels deepSleep betreiben und den beim aufwecken in dein Heimnetz WIFI einloggen. Dann macht er eine Messung und sendet den Messwert mit einem Zeitstempel an einen FTP Server. Anschließend geht er wieder in den Deep Sleep. Modus.

Für FTP gibt es einen append Modus , damit kannst Du eine Datei anlegen und mit jedem neuen Messwert eine Zeile an die Textdatei anhängen. Das Format könnte eine Textdatei im CSV Vormat sein.

Für FTP gibt es mehrere Libs , damit ist das relativ einfach. Deep-Sleep ist auch ein Hexenwerk
hier mal ein link zur Doku

oder hier

https://docs.espressif.com/projects/arduino-esp32/en/latest/

https://randomnerdtutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/

Gruß Heinz

1 Like

Ich finde genau die Fragen wurden im ursprünglichen Post bereits beantwortet.

  • Wer soll an Wen - ESP an FTP Server
  • Wo sollen die Daten gespeichert werden - in Logfile auf dem FTP Server
  • Wie siehst du die Daten am Ziel ein - erzeugtes Logfile lesen

Wen es um den Transfer der einzelnen Datensätze geht, hat @StefanL38 ja schon einen interessanten Alternativvorschlag gemacht. Ich würde MQTT bevorzugen und Node Red um ggf. dieses Logfile zu erzeugen und gleich noch mehr damit machen zu können. Das hängt dann doch mit der 3. Frage von @noiasca zusammen, was denn sonst noch so mit den Daten passieren soll. Also grafische Anzeige der Daten in einem Webinterface z.B. .

Durch append: smlFile = LittleFS.open("/sml.txt", "a");

#include <FTPClient.h>  //FTPServer and FTPClient Version=0.9.7 https://github.com/dplasa/FTPClientServer
FTPClient ftpClient(LittleFS);                                                 // tell the FTP Client to use LittleFS
FTPClient::ServerInfo ftpServerInfo(FTP_USER, FTP_PASSWORD, "www.fritz.box");  // provide FTP servers credentials and servername

Ich baue die Log-Datei in LittleFS zusammen und übertrage sie sporadisch zum FTP-Server.

Eventuell magst Du den WiFiManager

Eventuell findest Du Esp32 Webserver Arduino Tab und meine Anleitung: Einführung zu fipsok.de hilfreich.

Mein Tipp: Zerlege Dein Projekt in einzelne Aufgaben, dann kann man Dir auch gezielter helfen :slightly_smiling_face:

Danke - 15mA kann ich verkraften. Bzw. der Akkupack

Ich habe meine Aufgabe in der Frage ganz genau beschrieben.

Nochmal kurz:

Ich möchte einfache Textstrings (Messwerte) zyklisch via Heimnetz auf (m)einem FTP-Server bei meinem Provider an eine Logdatei anhängen. Gegebenenfalls muss sie auch neu erstellt werden, falls ich sie zwischenzeitlich downgeloadet und gelöscht habe.

Alles andere ist mir klar. Auch was ich mit den Daten dann auf dem Server mache.

Ich bin hier jetzt mit Infos von mehreren Leuten regelrecht erschlagen worden. Ist ja alles gut gemeint. Aber ich meine, das ist viel zu viel Programm für das bisschen Aufgabe?

Ich werde mir aber alle Links durchsuchen und lesen. Und mir dann was daraus zurecht schnippeln.

Danke erst mal.

Das habe ich schon beschrieben.
ESP -> Heimnetz -> FTP-Server - >Logfile

Super tolle Abhandlung - aber nicht ganz mein Thema

Wie schon gesagt - ESP -> Heimnetz -> FTP-Server - >Logfile

Danke

Genau das will ich

Das kenne ich so von PC-Seite aus. Deswegen möchte ich das ja nun vom ESP so lösen

Danke

Ein Logfile dem Logfile wegen ist für mich eben keine Antwort auf den Nutzen.

Das war das zweite Suchergebnis zu ESP32 FTP append line und die Antwort schaut vernünftig aus:

Der Logfile soll nicht des Logfiles wegen sein! Akzeptiere bitte einfach, dass die Daten in einem Logfile "appended" werden sollen. Alles Weitere wie Nutzen des Files hat mit der ESP-Seite nichts zu tun und ist nicht Inhalt meiner Frage.

Danke - wenn man die richtigen Suchbegriffe hat, ist jede Suche leichter. Das ganze sieht auf den ersten Blick so aus, wie ich mir das vorstelle. Scheint aber noch Macken zu haben. Ich werde es mal eintippen und probieren.

Welche Erwartungen hast Du an die Art der Hilfe? Vermutlich hat niemend der hier im Forum Aktiven genau das gemacht, was Du machen möchtest. Aber genau das ist doch das Spannende an diesem Hobby, finde ich. Also muß man sich aus Tipps und Anregungen das zusammensuchen, was für das eigene Programm nützlich ist.

Ich lese den Strommesser menütlich aus, speichere den Verbrauch in LittleFS und kopiere die Datei per FTP auf eine Festplatte an meiner Fritz!Box. Das kommt Deinem Projekt nahe, ist aber nicht identisch. Angefangen habe ich bei Fips, dann die Funktionalität schrittweise erweitert. Inzwischen hat das Programm trotz Unterstützung durch Programmbibliotheken ohne html, js und css 959 Zeilen, wobei ich nicht auf Kürze geachtet habe. Nur mal so als Größenordnung.

Doch - perfekter Volltreffer von "noiasca"- genau passend auf meine Frage mit funktionierendem Beispiel im Link

Und umso schöner ist es, wenn man freundlicherweise genau eine zur Frage passende Antwort bekommt und nicht mit einem Überfluss an bestimmt tollen, aber nicht nutzvollen Informationen regelrecht erschlagen wird. Aber das ist in Foren leider oft so. Manche meinen einfach einen offensichtlichen Nichtprofi mit ihrem geballten Wissen erschlagen zu müssen. Und wenige erkennen die Aufgabe auf Anhieb und haben dann eine passende Lösung.

Alles schön und gut für dich - passt aber nicht zu meiner einfachen Aufgabe. Aber die perfekte einfache Lösung ohne große Schnörkel habe ich inzwischen ja bekommen und es funktioniert auf Anhieb.

Danke allerseits

Damit ich diesen Fehler nicht mache, werde ich Dir nicht antworten.

Gruß Tommy

1 Like

Hallo
Kleiner Tipp noch:
Schau mal nach was passiert wenn die Verbindung nicht geklappt hat. Also Fehlerauswertung.

Wenn es Dir egal ist wenn mal ein Datensatz fehlt dann kannst du auch drauf verzichten
Gruß Heinz

FTP überträgt also immer ganze Dateien und überschreibt eventuell die kurze alte Datei durch die längere neue Version, "append per FTP" würde ich das nicht nennen.

Kommt natürlich nach und nach alles rein.

Es macht normal nichts, wenn da ab und zu mal ein Satz fehlt. Bisher hatte ich die Lösung mit Laptop statt ESP. Und das hat so gut wie immer fehlerfrei funktioniert. Natürlich kann das Internet auch mal ausfallen. Aber i.d.R. ist es hier sehr stabil.

Danke für den Hinweis

Macht mir gar nichts aus. Ich habe schon eine gute Antwort bekommen. Du spielst du keine Rolle mehr :frowning:

Nee, etwas anders: Ich öffne die Datei in LittleFS und hänge da eine neue Zeile an die Datei. Nach einer Woche kopiere ich die Datei mit Datumsstempel per FTP auf die Festplatte. Also kein "append per FTP", sondern viele Wochendateien. Damit wollte ich den Unterschied zwischen meinem Projekt und diesem deutlich machen. Außerdem hätte der Umweg über LittleFS ja auch eine Möglichkeit für dieses Projekt darstellen können, was wir nun aber wohl ausschließen können :slightly_smiling_face: