Hallo, mit dem Seeeduino XIAO ESP32 fiel es mir das este Mal auf, dass die GET Abfrage von openwaether.org nur die erste kurze Zeit funktioniert und danach nur noch der Fehlercode -1 zurückliefert, was einfach heisst dass die Seite nicht gefunden wurde. Ich zieh mir da einen JSON String runter. url = openwaether.api./data/.... HTTPClient http; int result = http.get(url) ergibt result = -1 Häh? Normalerweise funktioniert etwas nicht einmal und dann nie wieder zudem es auf einem normalen ESP32 WROOM einwandfrei spielt. Ich verwende aber String in der Funktion als Container für die Payload der Seite. Openweather erlaubt 1000 Aufrufe pro Monat und 60/Minute. Danach ersheint ein leerer Datensatz. Testweise habe ich mal google.de aufgerufen, was Fehler 301 zurückliefert, weil google kein http unterstützt. Ich benutze wificlient.h und HTTPClient als Libs für die Arduino IDE. Gruss, Thorsten
:
Bearbeitet durch User
Thorsten M. schrieb: > url = openwaether.api./data/.... Und mit dieser URL soll das funktionieren? Glaub ich nicht...
Am PC mit dem Browser wird "openwaether.org" auch nicht gefunden.
Zeig mal mehr code. Dein Schnipsel ist nicht korrekt, und passt nicht zur aktuellen Version vom ESP32-HTTP-Client: https://github.com/espressif/arduino-esp32/blob/master/libraries/HTTPClient/src/HTTPClient.h#L211 Auch das aussenherum ist wichtig: Z.B. erzeugst du jedesmal einen neuen HTTP-Client, mit Keep-Alive oder ohne, räumst du nach dem Request auch wieder auf? Wie stellst du das Timing mit "60 Requests pro Minute" sicher? Wie schnell ändert sich das Wetter bei dir, dass du eine so hohe Polling-Frequenz brauchst?
Εrnst B. schrieb: > Z.B. erzeugst du jedesmal einen neuen HTTP-Client, mit Keep-Alive oder > ohne, räumst du nach dem Request auch wieder auf? Wie stellst du das > Timing mit "60 Requests pro Minute" sicher? Wie schnell ändert sich das > Wetter bei dir, dass du eine so hohe Polling-Frequenz brauchst? Dass ich die richtige url benutzte sollte klar sein. Code heute abend, bin auf Arbeit in der Pause. Nur was ich im Kopf hatte. Und es geht nur um den Fehlercode, die URL ist wumpe dabei.
:
Bearbeitet durch User
Thorsten M. schrieb: > Und es geht nur > um den Fehlercode, der ist "Connection Refused". z.B. Wlan offline, Firewall sperrt den Zugriff, aber auch: Keine freien TCP-Sockets am ESP mehr verfügbar, weil alle in irgendwelchen verlorenen Keep-Alive HTTP-Clients hängen. Bei zuvielen Zugriffen auf den Service würde der eher mit HTTP Error "509 Bandwidth exceeded" oder so antworten.
:
Bearbeitet durch User
Hier ist mal ein Teil des Codes. Lief den ganzen Tag 1x die Stunde, nach 3-4 Aufrufen Fehlercode -1 . Aktuell läuft er an einer http Testseite, die für ssolche Zwecke besteht wo nur Text drauf ist einwandfrei durch... komisch. -1 heisst dass die url nicht erreicht wurde aber im Browser kriege ich einwandfrei den json container angezeigt, egal wie oft ich F5 drücke. Spielt einwandfrei: http://www.testingmcafeesites.com/index.html Spielt nicht oder nur wenige Male http://api.openweathermap.org/data/2.5/forecast?q=Kassel,DE&APPID=<XXXXXXXXXXXXXXXXX>&mode=json&units=metric&cnt=1
1 | static JsonDocument doc; |
2 | static HTTPClient http; |
3 | static String payload; |
4 | |
5 | /* Anfragen an Server richten */
|
6 | int RequestWeather() { |
7 | |
8 | String url = openweather; |
9 | |
10 | /* Starte die Anfrage und hole die payload ab */
|
11 | http.begin(url); |
12 | debugln("GET Anfrage ..."); |
13 | int httpCode = http.GET(); |
14 | debug("HTTP Fehlercode:"); |
15 | debugln(httpCode); |
16 | |
17 | if (httpCode > 0) { |
18 | if (httpCode == HTTP_CODE_OK) { |
19 | payload = http.getString(); |
20 | debugln(F("HTTP Weather Request successful.")); |
21 | |
22 | // Versuche das JSON-Dokument zu analysieren
|
23 | DeserializationError jsonError = deserializeJson(doc, payload); |
24 | if (jsonError) { |
25 | debug(F("JSON Weather parsing error!")); |
:
Bearbeitet durch User
Bei dir im Screenshot schaut's doch auch so aus, als würden alle Requests beantwortet ("HTTP 200 OK"), nur das Json-Parsing schlägt fehl. Bau mal im if (jsonError) { eine Ausgabe von "payload" mit ein, damit du schauen kannst ob das gültiges Json ist. Falls ja: Hat dein JsonDocument genug Speicher? Hat dein ESP genug freien Speicher für String und JsonDocument gleichzeitig?
Εrnst B. schrieb: > f (jsonError) { > eine Ausgabe von "payload" mit ein, damit du schauen kannst ob das > gültiges Json ist. Auf der Testseite steht nur Testzeugs, da parsed json natürlich nicht. Hauptsache die Seite lädt. Lese aber grad auf openwaethermap, dass sie die api 2.5 diesen Monat abschalten und ein neues Bezahlmodell einführen. Kann sein, dass die die Anfragen einfach begrenzen. Jetzt gibt es Wetter nur noch gegen Geld.
Wenn man immer wieder 'http.begin' aufruft, ohne vorher mit 'http.end()' aufzuräumen, dann sind vermutlich irgendwann irgendwelche Ressourcen erschöpft.
Rolf schrieb: > Wenn man immer wieder 'http.begin' aufruft, ohne vorher mit 'http.end()' > aufzuräumen, dann sind vermutlich irgendwann irgendwelche Ressourcen > erschöpft. Das ist schon alles ok so. Es tritt nach endlosem Testen nur aufd wenn ich langsamer als 1 Mal die Minute abtaste. So verrückt das klingt. Alle 5 Minuten und dann ist die zweite Abtastung nach Reset schon ein Fehler. Auch die NTP Zeit Abfrage schlägt dann fehl um die interne Uhr zu synchronisieren weil Ticker.h Timer nicht sonderlich genau sind. Reichen würde 1x die Stunde. Und ich vermute fast dass dieser Seeeduino Xiao ne Macke hat in seinen Eingeweidden, denn das ist noch nie passiert vorher. Ich teste das mal mit nem normalen Esp32 Board am WE. Gibt aber auch noch andere Libraries und Möglichkeiten als die verwendete.
1 | /* Anfragen an Server richten */
|
2 | int RequestWeather() { |
3 | |
4 | JsonDocument doc; |
5 | HTTPClient http; |
6 | String payload; |
7 | |
8 | String url = openweather; |
9 | |
10 | debugln("GET Anfrage Openweathermap..."); |
11 | http.begin(url); |
12 | int httpCode = http.GET(); |
13 | debug("HTTP Fehlercode:"); |
14 | debugln(httpCode); |
15 | |
16 | if (httpCode > 0) { |
17 | if (httpCode == HTTP_CODE_OK) { |
18 | payload = http.getString(); |
19 | debugln(F("HTTP Weather Request successful.")); |
20 | |
21 | // Versuche das JSON-Dokument zu analysieren
|
22 | DeserializationError jsonError = deserializeJson(doc, payload); |
23 | if (jsonError) { |
24 | debug(F("JSON Weather parsing error!")); |
25 | http.end(); |
26 | return 0; |
27 | } else { |
28 | // Drucke den analysierten JSON-Inhalt in Buffer
|
29 | //serializeJsonPretty(doc, Serial);
|
30 | }
|
31 | |
32 | /* Daten auslesen in Variablen */
|
33 | JsonObject item = doc.as<JsonObject>(); /* Erzeuge ein Json Wurzel Object */ |
34 | item = doc["list"][0]; /* zeige auf Array der Liste Index = 0 */ |
35 | Temperatur = (float)item["main"]["temp"]; |
36 | Windspeed = 3.6 * (float)item["wind"]["speed"]; |
37 | WetterID = (int)item["weather"][0]["id"]; |
38 | Wettertext = String(item["weather"][0]["description"]); |
39 | Druck = (int)item["main"]["pressure"]; |
40 | Wolkendichte = (int)item["clouds"]["all"]; |
41 | Feuchte = (int)item["main"]["humidity"]; |
42 | Windstaerke = GetWindstaerke(Windspeed); |
43 | }
|
44 | } else { |
45 | debugln(F("HTTP Weather Request failed!")); |
46 | http.end(); |
47 | return 0; |
48 | }
|
49 | |
50 | http.end(); |
51 | return 1; |
52 | }
|
:
Bearbeitet durch User
Zeige mal detailliert, wie du die Stromversorgung gemacht hast. Schaltplan, Fotos samt Netzteil und Leitungen. Ich will auch die Platzierung der Pufferkondensatoren sehen. Weil: Dort liegt fast immer die Problemursache bei "seltsamen" Instabilitäten nach längerer zeit.
Aehm... Usb Stecker rein und fertig. Seeeduino Ciao eben. 20ma Display dran und 3 Leds Schaltplan im Kopf, verdraten und fertig am I2C Bus
Thorsten M. schrieb: > Auch die NTP Zeit Abfrage schlägt dann fehl um die interne Uhr zu > synchronisieren weil Ticker.h Timer nicht sonderlich genau sind. Solche Details wären halt am Anfang hilfreich. d.H. es liegt nicht am HTTPClient, es liegt nicht am Json-Parser. Vermutlich ist der ESP aus dem WLan geflogen... Verwendest du Sleep-Modi? Lange Schleifen ohne delay() und yield()? Ansonsten: Zielgerichtet den Fehler suchen. z.B. Ausgabe von "WiFi.isConnected()", "WiFi.localIP()" usw. im Fehlerfall. Vom PC einen Ping auf den ESP durchlaufenlassen. Bricht der ab, wenn die Fehler auftreten? Thorsten M. schrieb: > Ich teste das mal mit nem normalen Esp32 Board am WE Gerade beim Problem mit langen Schleifen kann das helfen das Problem zu verschleiern, Single-Core vs. Dual-Core.
:
Bearbeitet durch User
Dafuer hab3 ich wifi Events, die allerdings nicht getriggert haben. Ich reduziere alles die Tage auf diese eine Routin3 und schaue weiter Via Handy Thorsten
Thorsten M. schrieb: > Aehm... Usb Stecker rein und fertig Das USB Kabel kann schon der Knackpunkt sein. Oder das Netzteil regelt schwankende Stromaufnahme nicht schnell genug aus. Thorsten M. schrieb: > Seeeduino Ciao eben Das scheint es nicht zu geben. Wo sind die technischen Unterlagen zu dem Modul, insbesondere der Schaltplan? Es gab schon öfter mangelhafte gestaltete Module. Wenn es dieses ist: https://files.seeedstudio.com/wiki/XIAO_WiFi/Resources/Seeeduino-XIAO-ESP32C3-SCH.pdf Dann hat es zu wenig Pufferkapazität. Hänge an 3,3V und GND einen 100µF Elko. Das hat schon vielen geholfen.
Monk schrieb: > Dann hat es zu wenig Pufferkapazität. Hänge an 3,3V und GND einen 100µF > Elko. Das hat schon vielen geholfen. Das werde ich am WE machen in meiner Werkstatt. Übrigens läuft alles auch, wenn man den Code komplett zusammen streicht und nur die Client Routine stehen lässt. Alle Timer raus usw. Da scheint irgendwas strubblig zu werden. Also ertst puffern, dann Code Stück für Stück wieder dazu geben und schauen ob es nach jedem Schritt noch läuft. Mancher Code ist ja auch fehlerhaft aus den Libraries. Tja, die Wunder der Technik... immer wieder ein Vergnügen :-)
Kurze Info: Der 100uF Elko an 3.3V out vom Modul hat das Problem vollständig behoben!
:
Bearbeitet durch User
Thorsten M. schrieb: > Der 100uF Elko an 3.3V out vom Modul hat das Problem > vollständig behoben! Siehst du, man kann den Tipp gar nicht oft genug wiederholen.
Thorsten M. schrieb: > url = openwaether.api./data/.... Thorsten M. schrieb: > http://api.openweathermap.org/data/2.5/forecast?q=Kassel,DE&APPID=<XXXXXXXXXXXXXXXXX>&mode=json&units=metric&cnt=1 ---> openwaether openweather ?
Mache das Display mal dunkler, wenn es länger als 1 Jahr halten soll. Oder ergänze den Aufbau mit einem PIR Sensor, womit das Display nur bei Bedarf eingeschaltet wird.
Monk schrieb: > Mache das Display mal dunkler, wenn es länger als 1 Jahr halten soll. > Oder ergänze den Aufbau mit einem PIR Sensor, womit das Display nur bei > Bedarf eingeschaltet wird. Das geht nicht, 0 oder 1. Es brennt schnell ein, daher ständig wechselt und nachts geht es aus. Zeit kommt vom NTP Server. 4 Pins ablöten, neues Display rein und fertig. 4 Euro das Stück bei Aliexpress. Das EEPROM oben wird schon so rolierend beschrieben, dass die Datensätze der Grafiken immer neue Plätze buchen.
1 | /* Datensicherung im EEPROM rolierend */
|
2 | void SafeToEE(tables_t* data) { |
3 | |
4 | const int len = sizeof(*data); |
5 | |
6 | /* Erzeuge eine zufällige Blockadresse */
|
7 | const int max_blocks = EESIZE / len; |
8 | int newBlock = random(0, max_blocks); |
9 | |
10 | EE_WritePtr = newBlock * len; // Zieladresse im EEPROM |
11 | data->valid = DVALID; // Block gültig markieren |
12 | data->blknr++; // Laufende Nummer |
13 | |
14 | sprintf(buf, "EE Block Nr.%u Data Set = %d Adr = %04X", newBlock, data->blknr, EE_WritePtr); |
15 | debugln(buf); |
16 | |
17 | /* Funktion erwartet den Typ als Parameter ohne Angabe der Länge */
|
18 | myMem.put(EE_WritePtr, *data); |
19 | }
|
20 | |
21 | |
22 | /* Daten lesen aus aktuellem Datensatz */
|
23 | int ReadFromEE(tables_t* data) { |
24 | |
25 | uint16_t EE_AdrPtr = 0; |
26 | uint16_t maxn = 0; |
27 | uint16_t adr_found = 0; |
28 | bool found = false; |
29 | |
30 | /* Position von valid ermitteln */
|
31 | const uint32_t validOffs = (uintptr_t) & (data->valid) - (uintptr_t) & (*data); |
32 | const uint32_t blknrOffs = (uintptr_t) & (data->blknr) - (uintptr_t) & (*data); |
33 | const int len = sizeof(*data); |
34 | |
35 | /* EE durcchsuchen nach gültigem valid */
|
36 | int16_t marke, id; |
37 | while (EE_AdrPtr < (EESIZE - len)) { |
38 | myMem.get(EE_AdrPtr + validOffs, marke); // Valid Marke auslesen als int16_t |
39 | if (marke == DVALID) { |
40 | myMem.get(EE_AdrPtr + blknrOffs, id); // Block Nummer auslesen als int16_t |
41 | sprintf(buf, "Adresse: %04X = %u ID = %u", EE_AdrPtr, marke, id); |
42 | debug(buf); |
43 | /* Werte müsen gecasted werden! */
|
44 | if ((uint16_t)id >= maxn) { |
45 | adr_found = EE_AdrPtr; |
46 | maxn = (uint16_t)id; |
47 | debug("*"); |
48 | }
|
49 | debugln(); |
50 | found = true; |
51 | }
|
52 | EE_AdrPtr += len; // Nächster Datensatz |
53 | }
|
:
Bearbeitet durch User
Thorsten M. schrieb: > Das geht nicht, 0 oder 1 Aber selbstverständlich kann man den Kontrast per Software einstellen! Auszug aus meinem Treiber:
1 | i2c.beginTransmission(display_address); |
2 | i2c.write(0x00); |
3 | i2c.write(0x81); |
4 | i2c.write(contrast); |
5 | i2c.endTransmission(); |
Mir reicht in Innenräumen ein kleiner "contrast" Wert um 50.
> Es brennt schnell ein,
Eben deswegen der Vorschlag mit dem PIR Sensor. Du kannst es im
Ruhezustand auf einen ganz niedrigen Kontrast (z.B. 8) stellen und wenn
der Sensor auslöst für eine Minute auf 128 erhöhen.
Monk schrieb: > Aber selbstverständlich kann man den Kontrast per Software einstellen! Ich baue es mal eben ein.... ist aber nur fürs Büro mit dem Handy als Hotspot für Wifi da Firmen Wlan leider an MAC Adresse gekoppelt ist aus Sicherheitsgründen. Könnte ich zwar ändern im XIAO auf die meines Laptops aber lieber nicht. PS: Klappt! :-) Danke! 50 reicht vollkommen aus.
:
Bearbeitet durch User
Thorsten M. schrieb: > 50 reicht vollkommen aus. Probiere noch weniger. Das Auge reagiert logarithmisch. Vielleicht reicht dir sogar 20.
Das passt schon mit 60 jetzt, der Kontrast ist sogar noch besser geworden. Vielleicht spendiere ich noch einen LDR für den A0 Pin für die Licht Sensierung mit einer Look Up Table für die Helligkeit. Gibt es ja diese Logarithmus Tabellen für LEDs. Ups... Sturmwarnung für heute abend. Windstärke 5-6 ... woher das?
:
Bearbeitet durch User
Ich popp den Threasd nochmal hoch. Nachdem ich mich intensiv mit dem Xiao, Firebeetle und Wrover befasst habe und deren Connektivität zum Wlan fallen natürlich auch viele Berichte im Netz auf. Kurz und knapp: Seit dem Zurücksetzen des Core von 3.03 auf 2.11 sind die Probleme weg! Der Core nervt schon desswegen weil vieles nicht mehr funktioniert bzw anders .Der Watchdog verhält sich nicht mehr wie beschrieben, braucht jetzt einen Struct und egal was man da einträgt, die Zeiten stimmen nicht. LED Pwm anders, Timer anders usw usw. Zudem scheinen etliche Wrapper Funktionen von Libraries nicht angepasst zu sein, da die ja die Espressiv API nur kapseln. Zurück auf 2.11 und alles wurde gut, auch keine Vebindungsabrüche mehr. Habe auch den Eindruck, dass der Esp32 gerne mal den wifi Core abschmieren lässt ohne dass das bemerkbar wird. Er bleibt weiter angemeldet im Netz also sichtbar aber reagiert auf nichts mehr. Abhilfe ist zyklisches Resetten des ESP32, stört mich nicht in der Anwendung und die Daten sind im spiffs ja speicherbar.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.