Wenn du da einfach nur delay(10000) einbaust
was soll das bringen?
Der Prozessor dreht dann 10 Sekunden lang Däumchen statt 5 Sekunden.
Du benutzt
WiFi.hostByName("pool.ntp.org", timeServerIP);
Solche externen Zeitserver werden durch die immer größer werdende Zahl von Geräten die sich Internetzeit von Zeitservern holen immer stärker belastet. Deshalb blocken die ntp-server allzu häufige Anfragen ab.
Wenn du eine fritzbox als Router hast dann nimm die fritzbox als Zeitserver
WiFi.hostByName("fritz.box", timeServerIP);
das hat dann gleich zwei Vorteile:
Entlastung der öffentlichen Server, ganz geringe Belastung des Zeitservers den du benutzt.
@Tommy56 Ich bin leider auf einen Speedport Smart 4 angewiesen (Hybridanschluss). Ein NTP Server auf diesem Gerät ist mir nicht bekannt.
@StefanL38 Idee war, dass er einfach mehr Zeit hat ggf. die Verbindung neu aufzubauen.
Die externen Server sind immer Mist. Mir fehlt nur irgendwie eine Alternative. Hast du eine?
Lösung wäre ggf. noch die Zeit nur zum Start abzufragen und nicht zu aktualisieren?
@Tommy56 Mit dem Pi wäre noch eine Option. Schaue ich mir mal an. Habe hier noch einen.
WLAN ist immer so eine Sache. Aktuell steht der Arduino ca. 3 Meter vom Router entfernt und hatte die Abbrüche. Das sollte jetzt eigentlich nicht das Thema sein. Checke ich aber trotzdem.
Du hattest nur einige Zeilen Serial debug gepostet.
Ich nehme an dass vorher der Zeitserver schon eine Antwort gegeben hat
also eine - im Prinzip - aktuelle Zeit vorhanden ist.
Dann baue in die Zeitabfrage nicht blockierendes timing ein, dass die function beliebig oft aufgerufen werden kann, aber nur einmal pro Minute wirklich eine ntp-Anfrage gesendet wird.
Ja und es geht mit noch weniger Zeilen Code.
Man kann auch einfach
benutzen. Dann macht des FreeRTOS die Zeit-Synchronisation im Hintergrund. Es dauert allerdings 1 bis ca. 10 Sekunden bis die Zeit tatsächlich synchronisiert ist. Zumindest wenn ich meine fritz.box als NTP-Server benutze.
Daher die Warteschleife
Hier ein Demo-Code der das zeigt
#include <WiFi.h>
unsigned long MyTestTimer = 0; // timing variables MUST be of type unsigned long
const byte OnBoard_LED = 2;
const char *ssid = "SSID";
const char *password = "passwort";
//const char* ntpServer = "fritz.box";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 7200;
#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
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 connectToWifi() {
Serial.print("Connecting to #");
Serial.print(ssid);
Serial.println("#");
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
yield(); // very important to give the FreeRTOS time for its things
BlinkHeartBeatLED(OnBoard_LED, 333);
delay(332);
Serial.print(".");
}
Serial.print("\n connected.");
Serial.println(WiFi.localIP() );
}
void synchroniseWith_NTP_Time() {
Serial.print("configTime uses ntpServer ");
Serial.println(ntpServer);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.print("synchronising time");
int myCnt = 0;
while (myTimeInfo.tm_year + 1900 < 2000 ) {
yield(); // very important to give the FreeRTOS time for its things
time(&now); // read the current time
localtime_r(&now, &myTimeInfo);
BlinkHeartBeatLED(OnBoard_LED, 100);
delay(100);
showTime();
Serial.print(".");
myCnt++;
if (myCnt > 600) {
break;
}
}
if (myCnt < 600) {
Serial.print("\n time synchronsized \n");
showTime();
}
else {
Serial.print("\n time NOT synchronsized \n");
}
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println(__FILE__);
Serial.print( F(" compiled ") );
Serial.print(__DATE__);
Serial.print( F(" ") );
Serial.println(__TIME__);
}
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
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) );
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n Setup-Start \n");
PrintFileNameDateTime();
connectToWifi();
synchroniseWith_NTP_Time();
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 100);
if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
showTime();
}
}
Und diese Demo-Code soll ich bei mir nutzen, anstatt meiner ganzen anderen Zeit abfragen? Das geht für meinen Arduino oder ist das jetzt was für den ESP32?
Es wäre sehr schön wenn du explizit jedesmal benennen würdest welcher Code läuft auf exaktwas für einem Arduino
bzw. auf exakt was für einem ESP32
Arduino Uno
Arduino Mega
Arduino was weiß ich
Arduino ESP32
Und wenn da ein Arduino ESP32 im Spiel ist dann reicht es auch nicht
einfach nur "ESP32" zu schreiben sondern dann muss es ganz präzise benannt werden!
ESP32
ESP32-S2
ESP32-S3
ESP32-C3
ESP32-C6
usw.
Ich hatte im Eingangspost ja geschrieben, welchen Arduino ich habe -> Arduino UNO Wifi Rev2
Aber kann ich machen.
Der Code funktioniert so nicht für meinen Arduino. Ist scheinbar für ESP. Daher auch meine Frage, ob das für meinen geht.
Ich habe jetzt mal nur deinen Code eingefügt und alles andere entfernt.
Arduino UNO Wifi Rev 2
Sketch
#include <WiFi.h>
unsigned long MyTestTimer = 0; // timing variables MUST be of type unsigned long
const byte OnBoard_LED = 2;
const char *ssid = "XXX";
const char *password = "XXX";
//const char* ntpServer = "fritz.box";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 7200;
#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
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 connectToWifi() {
Serial.print("Connecting to #");
Serial.print(ssid);
Serial.println("#");
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
yield(); // very important to give the FreeRTOS time for its things
BlinkHeartBeatLED(OnBoard_LED, 333);
delay(332);
Serial.print(".");
}
Serial.print("\n connected.");
Serial.println(WiFi.localIP() );
}
void synchroniseWith_NTP_Time() {
Serial.print("configTime uses ntpServer ");
Serial.println(ntpServer);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.print("synchronising time");
int myCnt = 0;
while (myTimeInfo.tm_year + 1900 < 2000 ) {
yield(); // very important to give the FreeRTOS time for its things
time(&now); // read the current time
localtime_r(&now, &myTimeInfo);
BlinkHeartBeatLED(OnBoard_LED, 100);
delay(100);
showTime();
Serial.print(".");
myCnt++;
if (myCnt > 600) {
break;
}
}
if (myCnt < 600) {
Serial.print("\n time synchronsized \n");
showTime();
}
else {
Serial.print("\n time NOT synchronsized \n");
}
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println(__FILE__);
Serial.print( F(" compiled ") );
Serial.print(__DATE__);
Serial.print( F(" ") );
Serial.println(__TIME__);
}
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
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) );
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n Setup-Start \n");
PrintFileNameDateTime();
connectToWifi();
synchroniseWith_NTP_Time();
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 100);
if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
showTime();
}
}
Fehlermeldungen
/Balkonkraftwerk_sketch/Balkonkraftwerk_sketch.ino: In function 'void connectToWifi()':
/Balkonkraftwerk_sketch/Balkonkraftwerk_sketch.ino:48:8: error: 'class WiFiClass' has no member named 'persistent'; did you mean 'setPersistent'?
WiFi.persistent(false);
^~~~~~~~~~
setPersistent
/Balkonkraftwerk_sketch.ino:49:8: error: 'class WiFiClass' has no member named 'mode'
WiFi.mode(WIFI_STA);
^~~~
/Balkonkraftwerk_sketch/Balkonkraftwerk_sketch.ino:49:13: error: 'WIFI_STA' was not declared in this scope
WiFi.mode(WIFI_STA);
^~~~~~~~
/Balkonkraftwerk_sketch.ino:49:13: note: suggested alternative: 'WIFIESPAT1'
WiFi.mode(WIFI_STA);
^~~~~~~~
WIFIESPAT1
Balkonkraftwerk_sketch.ino: In function 'void synchroniseWith_NTP_Time()':
/Balkonkraftwerk_sketch/Balkonkraftwerk_sketch.ino:67:3: error: 'configTime' was not declared in this scope
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
^~~~~~~~~~
Mehrere Bibliotheken wurden für "WiFi.h" gefunden
Benutzt: /Arduino/libraries/WiFiEspAT
Nicht benutzt: /Arduino/libraries/WiFiNINA
exit status 1
Compilation error: 'class WiFiClass' has no member named 'persistent'; did you mean 'setPersistent'?
Poste mal ein Serial-Debug-Log dass nicht nur 5 Zeilen enthält sondern 2 Minuten.
Ach oh -- wahrscheinlich noch ein Problem:
Benutzt du die IDE 2.X?
Da ist der serielle Monitor ein richtiger Krüppel im Vergleich zur IDE 1.8.19
In der IDE 1.8.19 kann man tausende Zeilen in den seriellen Monitor schreiben lassen und dann auch in die Zwischenablage kopieren.
Bei IDE 2.X geht das nicht und das IDE-Entwicklungsteam lässt diesen verkrüppelten Zustand einfach immer weiter so bestehen. Das ist zum
Zwei Lösungsmöglichkeiten:
Ardiuno-IDE portable Version 1.8.19 installieren die dann völlig unabhängig von der anderen funktioniert
Anderes serielles Terminal-programm benutzen:
Ich bevorzuge Br@ys Terminal.
@StefanL38 Danke schön! Ich nutze einen Mac, da ist das schwierig. Aber ich habe noch eine ältere IDE-Version griffbereit.
Anbei mal die letzten fünf Minuten seit Start. Ich lasse laufen und poste dann auch die letzten fünf Minuten, bevor er stehen bleibt (mal schauen, ob und wann). Als Sketch ist jetzt deiner mit den Debug-Ausgaben hinterlegt.
Musste meinen Post vorher einmal löschen. Da ging der Upload nicht richtig.
Edit: Hat dann doch nicht so lange gedauert. Anbei dann die Logs fünf Minuten bis zum "Abbruch".
Danach läuft der Sketch scheinbar weiter, aber befindet sich in der Endlosschleife für MQTT. Kurz vorher aber wieder die Zeit nicht mehr da gewesen.
Du verwendest in deinem Code ziemlich viele Strings.
Du machst das lokal zum Teil in if-bedingungen usw.
Mich hat diese Frage jetzt selber interessiert und ich habe im englischen Programmier-Forum allgemein gefragt
Die Antworten waren wie vorher nicht so ganz eindeutig ob nun lokal deklarierte Strings Probleme machen oder nicht.
Ich selbst benutze ausschließlich SafeStrings.
Der Name ist Programm. Da SafeStrings bei der Deklaration eine eindeutig definierte Länge bekommen weiß man schon zur Compile-Time wie viel Speicherplatz die verbrauchen. Wenn man zu viel SafeStrings definieren würde dann würde der Compiler meckern.
Bei Strings ist das viel komplizierter und hängt von vielen Faktoren ab ob es irgendwann zum Programm-Crash führt oder nicht.
Das ist übrigens noch ein Grund von diesem komischen "UnoESPuino" auf reinen ESP32 umzusteigen.
Auf deinem Board hast du schlappe 2 kB 6 kB RAM weil das RAM vom Atmega 4809-chip benutzt wird.
Auf einem puren ESP32 hast du 160 kB RAM.
Wenn es denn unbedingt weiterhin der "UnoESPuino" sein muss
dann könntest du mal auf SafeString umsteigen.
Die meisten anderen hier werden die c_strings (array of char) empfehlen. Mit denen hat man aber das Problem das man verdammt sorgfältig auf Array-Grenzen achten muss. Wenn man bei c_strings außerhalb der Array-Grenzen schreibt dann crasht das Programm auch.
Da sind mir persönlich die SafeStrings sehr viel lieber.
Die haben fast den gleichen Komfort wie Strings.
Die Syntax ist eben anders. Also man muss schon was neues lernen.
Hier ein Demo-Code wie man mit Safestrings programmiert und wie sie sich verhalten
// SafeStrings are based on array of chars
// SafeStrings offer almost the same comfort as Strings
// but avoid some dis-advantages of variable-type String
// the name SafeString is PROGRAM They are safe to use
// with the alternatives "String" must not always but CAN
// eat up memory over time which will make the code crash
// with zero-terminated array of chars (c_string)
// you have to take care of boundary checking yourself
// otherwise your code will start to behave weird and this kind of bug is very hard to find
// you can read more about this here https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html#safestring
// and here https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
// very basic demo-code to show how to declare a SafeString-variable
// and how to assign text to them
// as a personal convention I use the suffix "_SS" to indicate
// THIS IS A SAFESTRING-VARIABLE
// but you can name it whatever you like
#include "SafeString.h"
createSafeString(myTitle_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(myString_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(myExtraloongString_SS, 128); // reserve 128 bytes for the SafeString-variable
int myInteger = -1234;
float myFloat = -987.009;
float myFloat2 = -12345.6789;
float myFloat3 = -1234.567;
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
Serial.println();
myString_SS = F("fixed text directly assigned");
Serial.print( F(" #") ); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println(F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myTitle_SS = F("content of an integer:");
myString_SS = myInteger;
Serial.println(myTitle_SS);
Serial.print( F(" #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myTitle_SS = F("content of a float:");
myString_SS = myFloat;
Serial.println(myTitle_SS);
Serial.print( F(" #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myTitle_SS = F("you can append more text with the +=-operator ");
myString_SS = F("text ");
myString_SS += myInteger;
myString_SS += F(" ,");
myString_SS += myFloat;
Serial.println(myTitle_SS);
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
myString_SS += F(" ,");
myString_SS += myFloat2;
myString_SS += F(" ,");
myString_SS += myFloat3;
Serial.println(myTitle_SS);
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
Serial.println( F(" now let's try to assign wayyyyyy too many characters 012345678900123456789001234567890012345678900123456789001234567890") );
myString_SS = "";
myString_SS += F(" now let's try to assign wayyyyyy too many characters 012345678900123456789001234567890012345678900123456789001234567890");
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
Serial.println( F(" now let's try to add more and more characters at the end of the SafeString") );
myString_SS = "";
for (byte i = 10; i < 64; i++) {
myString_SS += i;
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
}
Serial.println( F(" assigning a number of chars the SafeString can really hold") );
myExtraloongString_SS = F("less than 64 characters");
myString_SS = myExtraloongString_SS;
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
Serial.println( F(" assigning too many chars than the SafeString can really hold") );
Serial.println( F("more than 64 characters 1234567890123456789012345678901234567890123456789012345678901234567890") );
// 10 20 30 40 50 60 70
// 1234567890123456789012345678901234567890123456789012345678901234567890
myExtraloongString_SS = F("more than 64 characters 1234567890123456789012345678901234567890123456789012345678901234567890");
myString_SS = myExtraloongString_SS;
Serial.print( F("result: #" )); // leading double-cross "#" to show where the string starts
Serial.print(myString_SS);
Serial.println( F("#") ); // trailing double-cross "#" to show where the string REALLY ends
}
void loop() {
}
Ich probiere gerade den Code auf SafeString umzuschreiben.
Ich bekomme es aber nicht kompiliert
C:\Arduino-Pure-Portable\arduino-1.8.19\portable\sketchbook\libraries\WiFiNINA\src/utility/wifi_drv.h:293:12: error: 'PinStatus' does not name a type
Ich habe die WiFiNINA Version
Alternatives for WiFiNINA.h: [WiFiNINA@1.8.14]
Stell sonst gerne mal rein und ich teste mal auf dem Board selbst. Die WiFiNINA läuft eigentlich gut. Mit PIN Status meinst du den Zustand von PIN 12? Für den Windsensor?
Nein der Compiler meckert ein Detail in einer Library an
Ich habe gegoogelt und jetzt noch die MKR-Boards installiert.
Jetzt bekomme ich einen gaaanz anderen Fehler
C:\Arduino-Pure-Portable\arduino-1.8.19\arduino-builder returned 2
Error compiling for board Arduino Uno WiFi.