Hallo, bevor sich vieles wiederholt: Ich habe sämtliche im Netz verfügbaren Tipps und angebliche Lösungen ausprobiert. Gibt auch Bug Reports. Der Hostname eines ESP32 WROOM lässt sich nicht setzen fürs Wifi. Weder die Reihenfolge der Befehle verändern, noch das Löschen des Flashs, noch Resetten der Fritzbox oder wifi.mode (STA) etc halfen etwas. In der Liste steht immer ein ESP-xxxxxx und das nervt. Jemand eine Idee?
Also das hier in jeder nur denkbaren Variante
1 | void initWiFi() { |
2 | WiFi.mode(WIFI_STA); |
3 | WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); |
4 | WiFi.setHostname(hostname.c_str()); //define hostname |
5 | WiFi.begin(ssid, password); |
6 | Serial.print("Connecting to WiFi .."); |
7 | while (WiFi.status() != WL_CONNECTED) { |
8 | Serial.print('.'); |
9 | delay(1000); |
10 | }
|
11 | Serial.println(WiFi.localIP()); |
12 | }
|
Die FritzBox merkt sich den Hostnamen und die Mac Adresse, damit immer dieselbe IP vergeben werden kann. Der Hostnamen kann dadurch auch in der FritzBox geändert werden.
Thorsten M. schrieb: > Jemand eine Idee? Wird der Hostname nicht mit mDNS bekanntgegeben? Ich meine, beim ESP8266 hätte ich sowas mal gesehen ... LG, Sebastian
esp8266 klappt alles, ist aber ne ganz andere Kiste, andere befehle usw.
Jim M. schrieb: > Der Hostnamen kann dadurch auch in der FritzBox geändert werden. ja, kann er, einfach editieren. Aber eben auch nur für die FB. Davon merkt der Client aber nichts.
Thorsten M. schrieb: > Also das hier in jeder nur denkbaren Variante > >
1 | > void initWiFi() { |
2 | > WiFi.mode(WIFI_STA); |
3 | > WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); |
4 | > WiFi.setHostname(hostname.c_str()); //define hostname |
5 | > WiFi.begin(ssid, password); |
6 | > Serial.print("Connecting to WiFi .."); |
7 | > while (WiFi.status() != WL_CONNECTED) { |
8 | > Serial.print('.'); |
9 | > delay(1000); |
10 | > } |
11 | > Serial.println(WiFi.localIP()); |
12 | > } |
13 | >
|
Setze mal den Hostname vor WiFi.mode
1 | void initWiFi() { |
2 | WiFi.setHostname(hostname.c_str()); //define hostname |
3 | WiFi.mode(WIFI_STA); |
4 | WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE); |
5 | WiFi.begin(ssid, password); |
6 | Serial.print("Connecting to WiFi .."); |
7 | while (WiFi.status() != WL_CONNECTED) { |
8 | Serial.print('.'); |
9 | delay(1000); |
10 | }
|
11 | Serial.println(WiFi.localIP()); |
12 | }
|
Hatte mit einem ESP32 das gleiche Problem. Seither funktioniert es. Grüße
Ich probiers aus, danke! Da ich vom Web nichts verstehe, bzw fast nichts... ich will nur einen struct voller Daten versenden von einem Server zu einem Client. server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", readPres().c_str()); }); Kann mir jemand mal Wort für Wort erklären,w was dieser Ausdruck bedeutet? Ja, es ist ein HTTTP GET Request Response. Er installiert eine Callback Funktion, die auf /pressure in der URL IP.x.y.z./pressure reagiert. Lässt sich sowas ummodeln um damit einen Binärstruct zu versenden? Oder muss ich da über JSON gehen? verstehe von C++ nur Bahnhof, was da gemacht wird, schon die Syntax ist krpytisch: Anweisungen / Quellcode in einem Methodenaufruf? https://github.com/me-no-dev/ESPAsyncWebServer#the-async-web-server
1 | / Send a GET request to <IP>/get?message=<message> |
2 | server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { |
3 | String message; |
4 | if (request->hasParam(PARAM_MESSAGE)) { |
5 | message = request->getParam(PARAM_MESSAGE)->value(); |
6 | } else { |
7 | message = "No message sent"; |
8 | }
|
9 | request->send(200, "text/plain", "Hello, GET: " + message); |
10 | });
|
:
Bearbeitet durch User
Hi, // Costum Hostname const char* hostname = "WiFi-Thorsten"; (global). Router neu starten!
Ist anderes Thema aber neuer Thread lohnt nicht. Ist dieses Konstrukt da unten geeignet mir Daten aus einem Struct an einen Client zu schicken, wenn ich meinen Struct Element für Element als JSON String zusammenbaue wie dargestellt? Die Laenge scheint ja unbegrenzt zu sein. Also Name des Elementes + String(Data.xyz).
1 | //First request will return 0 results unless you start scan from somewhere else (loop/setup)
|
2 | //Do not request more often than 3-5 seconds
|
3 | server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request){ |
4 | String json = "["; |
5 | int n = WiFi.scanComplete(); |
6 | if(n == -2){ |
7 | WiFi.scanNetworks(true); |
8 | } else if(n){ |
9 | for (int i = 0; i < n; ++i){ |
10 | if(i) json += ","; |
11 | json += "{"; |
12 | json += "\"rssi\":"+String(WiFi.RSSI(i)); |
13 | json += ",\"ssid\":\""+WiFi.SSID(i)+"\""; |
14 | json += ",\"bssid\":\""+WiFi.BSSIDstr(i)+"\""; |
15 | json += ",\"channel\":"+String(WiFi.channel(i)); |
16 | json += ",\"secure\":"+String(WiFi.encryptionType(i)); |
17 | json += ",\"hidden\":"+String(WiFi.isHidden(i)?"true":"false"); |
18 | json += "}"; |
19 | }
|
20 | WiFi.scanDelete(); |
21 | if(WiFi.scanComplete() == -2){ |
22 | WiFi.scanNetworks(true); |
23 | }
|
24 | }
|
25 | json += "]"; |
26 | request->send(200, "application/json", json); |
27 | json = String(); |
28 | });
|
Thorsten M. schrieb: > Da ich vom Web nichts verstehe, bzw fast nichts... ich will nur einen > struct voller Daten versenden von einem Server zu einem Client. Moeglicherweise bist du hier mit Websockets besser bedient. Es kursieren im Netz jede Menge Beispiele im Sourcecode fuer den ESP32. Oder einfach mit dem Arduino Library Manager eine Websocket Lib laden und die mitgelieferten Beispiele testen.
Thorsten M. schrieb: > In der > Liste steht immer ein ESP-xxxxxx und das nervt. > > Jemand eine Idee? Verrate uns, um welche "Liste" es hier geht. Das dürfte der Knackpunkt sein.
FromahschdiBrie schrieb: > Moeglicherweise bist du hier mit Websockets besser bedient. Du hast wohl recht, ich lese mich mal ein. Mein Server soll ja von sich aus tätig werden können und nicht nur auf Anfrage.
c-hater schrieb: > Verrate uns, um welche "Liste" es hier geht. Das dürfte der Knackpunkt > sein. Die Liste der Clients in der Fritz Box unter Heimnetz? :-)
Thorsten M. schrieb: > c-hater schrieb: >> Verrate uns, um welche "Liste" es hier geht. Das dürfte der Knackpunkt >> sein. > > Die Liste der Clients in der Fritz Box unter Heimnetz? :-) Aha. DHCP-Leases, eventuell sogar "reservierte". Einfach ESP ausmachen, Lease/Reservierung auf der Fitzbox löschen, ESP wieder anmachen. Dann muss er sich zwangsläufig ein neues Lease holen und wird dabei auf der FB seinen (dann hoffentlich korrekten) Hostnamen hinterlassen. Danach kann man das Teil auf der FB dann noch auf eine gewünschte Adresse zwingen und diese dauerhaft zuweisen. Danach ist dann wiederum der ESP neu zu starten, damit der das auch mitbekommt. So weit, wie es richtig wäre. Man kann aber auch pfuschen and das Ding in der Fritzbox-"Liste" stumpf umbenennen. Es spielt nämlich fast keine Rolle, was das Teil selber als Hostnamen an die FB meldet. Das tut es nur beim allerersten Bekanntwerden.
c-hater schrieb: > Dann > muss er sich zwangsläufig ein neues Lease holen und wird dabei auf der > FB seinen (dann hoffentlich korrekten) Hostnamen hinterlassen. Tja, das dachte ich mir auch :-) Nur so einfach ist es nicht. Ist aber auch wurscht, mir reicht die IP Adresse. Aber was anderes .... das Einzige was ich machen will ist einen Brief verschicken, Adresse draufschreiben und ihn in den Postkasten werfen. Und wie er zum Ziel kommt ist mir wurscht. Websockets sind viel mit "Web", grad quer gelesen. Brauche ich gar nicht, nicht mal einen Browser. Ein ESP32 bildet den AP, der andere den Client. Der Client kann so oft er will was anfordern. Und dazu ist das Beispiel WifiBasicClient wohl besser, denn mehr als client.print, .get, available brauche ich nicht! Wenn der String beliebig lang sein kann verwurste ich die Binärdaten des fetten Struct einfach in Buchstaben (z.b. MIME oder was eigenes mit 7-Bit) und decodiere sie drüben wieder in den gleichen struct. Um Checksummen und Sendewiederholungen muss ich mir hoffentlich eher keine Sorgen machen, die werden wohl in dem Framework mit drin sein.
1 | void loop() |
2 | {
|
3 | // const uint16_t port = 80;
|
4 | // const char * host = "192.168.1.1"; // ip or dns
|
5 | const uint16_t port = 1337; |
6 | const char * host = "192.168.1.10"; // ip or dns |
7 | |
8 | Serial.print("Connecting to "); |
9 | Serial.println(host); |
10 | |
11 | // Use WiFiClient class to create TCP connections
|
12 | WiFiClient client; |
13 | |
14 | if (!client.connect(host, port)) { |
15 | Serial.println("Connection failed."); |
16 | Serial.println("Waiting 5 seconds before retrying..."); |
17 | delay(5000); |
18 | return; |
19 | }
|
20 | |
21 | // This will send a request to the server
|
22 | //uncomment this line to send an arbitrary string to the server
|
23 | //client.print("Send this data to the server");
|
24 | //uncomment this line to send a basic document request to the server
|
25 | client.print("GET /index.html HTTP/1.1\n\n"); |
26 | |
27 | int maxloops = 0; |
28 | |
29 | //wait for the server's reply to become available
|
30 | while (!client.available() && maxloops < 1000) |
31 | {
|
32 | maxloops++; |
33 | delay(1); //delay 1 msec |
34 | }
|
35 | if (client.available() > 0) |
36 | {
|
37 | //read back one line from the server
|
38 | String line = client.readStringUntil('\r'); |
39 | Serial.println(line); |
40 | }
|
41 | else
|
42 | {
|
43 | Serial.println("client.available() timed out "); |
44 | }
|
45 | |
46 | Serial.println("Closing connection."); |
47 | client.stop(); |
48 | |
49 | Serial.println("Waiting 5 seconds before restarting..."); |
50 | delay(5000); |
:
Bearbeitet durch User
Genau das was ich suche: ESP-NOW Die haben sich was dabei gedacht, ohne Router usw. https://dronebotworkshop.com/esp-now/
1 | / Define data structure |
2 | typedef struct struct_message { |
3 | float a; |
4 | float b; |
5 | int c; |
6 | } struct_message; |
7 | |
8 | // Create structured data object
|
9 | struct_message myData; |
10 | |
11 | // Callback function
|
12 | void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) |
13 | {
|
14 | // Get incoming data
|
15 | memcpy(&myData, incomingData, sizeof(myData)); |
16 | |
17 | // Print to Serial Monitor
|
18 | Serial.print("Temp Sensor "); |
19 | Serial.print(myData.c); |
20 | Serial.print(": "); |
21 | Serial.println(myData.a); |
22 | |
23 | Serial.print("Humidity Sensor "); |
24 | Serial.print(myData.c); |
25 | Serial.print(": "); |
26 | Serial.println(myData.b); |
27 | |
28 | Serial.println(""); |
29 | }
|
:
Bearbeitet durch User
Die Kommunikation mit ESP-NOW ist nicht sehr stabil. Speziell wenn man ESP-NOW gleichzeitig mit normalem WLAN-Station-Betrieb kombiniert. Erst wenn der Send-Callback mit einem "ESP-OK" aufgerufen wurde, ist die Nachricht beim Empfänger wirklich angekommen. Bei mir braucht es bis zu 6 Wiederholungen, bis die Nachricht auf dem kombinierten WEB-Server/ESPNOW-Empfänger angekommen ist. Aber irgendwann kommt er immer durch. Bei Kombination ESP-NOW mit WLAN-Station-Betrieb ist es wichtig, dass Du die Channel-Verwaltung des WLAN-Station-Betriebes berücksichtigst, sonst kommen irgendwann gar keine Daten mehr durch.... LG JK
Johann K. schrieb: > Erst wenn der Send-Callback mit einem "ESP-OK" aufgerufen wurde, ist die > Nachricht beim Empfänger wirklich angekommen. Das habe ich auch schon bemerkt !!! Den muss man aber doch nicht manuell aufrufen, oder? Wird der nicht von allein aufgerufen als Quasi-Interrupt? Mit WLAN zusammen muss man Kanal 1 nehmen.
:
Bearbeitet durch User
> Wird der nicht von allein aufgerufen als Quasi-Interrupt? Ja, aber sehr oft mit einem "transmission delivery failed". In diesem Fall setzte ich mir ein Flag für eine Wiederholung und mit dem nächsten Loop-Cycle sende ich eine Wiederholung und warte ob ich im nächsten CallBack ein ESP_OK bekomme... Interessanterweise sind die Übertragungsprobleme höchstgradig in die Richtung des ESP, welcher WLAN_STA plus ESP-NOW fährt. In die andere Richtung - also den ESP, welcher nur ESP-NOW fährt - gibt es wesentlich weniger Übertragungsfehler... > Mit WLAN zusammen muss man Kanal 1 nehmen. NEIN, dem ist leider nicht so. Wenn Du auf den Kanal 1 schaltest und dein WLAN_STAtion-Mode aktiv wird, schaltet der ESP auf jenen Kanal um, welchen er vom WLAN-Accesspoint genannt bekommt. Da es nur EIN WLAN-Funk-Interface gibt, wird damit auch automatisch der Kanal für die ESP-NOW-Übertragung umgeschaltet. Ich löse es in der Weise, dass ich auf dem NUR-ESPNOW-ESP, per ScanWlan die SSID des Ziel-Netzwerkes suche und den für dieses WLAN propagierten Kanal für ESP-NOW verwende. Ist zwar umständlich, aber spätestens mit jedem Neustart des WLAN-Accesspoints kann es passieren, dass das WLAN einer SSID über einen anderen Kanal funkt. Da ist man mit fixen ESPNOW-Kanälen nicht so gut beraten.
Lösung: Hostname lässt sich NUR setzen, wenn WIFI_AP ausgewählt ist. Reicht einmal, danach ist er im Flash dauerhaft drin. Die Meldungen von ESP Now sind widersprüchlich... Die Sendefunktion liefert OK aber das Callback dann FAIL, weil ich grad keinen Slave habe. Allerdings gibt es unter den Events auch keines was besagt, dass es keine Antwort gab. Damit ich mit diesem mixed Mode gar keine Konflikte kriege frage ich den NTPm Server einmal ab vom Internet, schalte dann alles ab und disconnecte und starte wifi dann wieder neu als softAP für mein Now Netzwerk. Das gibt Kuddelmuddel, wenn man beides betreibt, wie Johann schon sagte weil die sich die gleichen Register der Hardware teilen. Ich kann alles bestätigen was er schreibt und so oft wie die Revs neu erscheinen wird da noch viel dran geschraubt. Als nächtes Problem wird anstehen ESP NOW nur fürs Senden in Betrieb zu nehmen und die stromhungrige wifi Schnittstelle zwischendurch ab zu schalten. Da nirgens dokuemntiert ist, was ein wifi.mode (OFF) alles anrichtet wird das noch lustig. Aber statt 80-200mA frisst er dann nur noch seine 20ma bei 160Mhz. esp_now_deinit() löscht jedenfalls alles an Config Tabellen, aber das tut esp_init() auch. wozu also deinit? Light Sleep kann ich leider nicht nutzen, da ich die LEDs per PWM abdimme., die leuchteten sehr ungleich, sah uncool aus und Nachts bekam man Augenkrebs. Bei einer grünen einen 2.7k (!) Vorwiderstand bei 3.3V und volle Helligkeit hatte ich auch noch nicht. 270-390 Ohm war das früher mal auf 5V aber die werden immer besser.
:
Bearbeitet durch User
Noch hinzugefügt: Jetzt habe ich auch wieder die SDK-API-Referenz von Espressif gefunden: https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf Wenn man unter "channel" sucht und auch im Appendix A4 ist das mit dem Kanalwechsel nachzulesen.
@Johann: Ich habe das Ganze jetzt am Laufen, auch einen mixed Mode mit Wifi Internet Zugriff. Und bisher habe ich im Haus 0 Transmit Fehler, da kommt alles an. Als Nächstes versuche ich noch OTA zu implementieren, ob das auch noch mit rein passt, weil da ein ständiges Lauschen am Netz erforderlich ist.
Hallo Thorsten!
> weil da ein ständiges Lauschen am Netz erforderlich ist
Da würde ich nochmals drüber nachdenken (aus Sicherheitsgründen).
Ich habe OTA bei mir immer so implementiert, dass ich an den ESP ein
Kommando sende und erst daraufhin geht der ESP ein Software-Update
laden.
Dadurch ist es nicht notwendig, dauernd am Netz zu lauschen und es kann
mir niemand ein OTA-Update so einfach unterjubeln....
Die Initiative eines Updates geht daher immer von meinem ESP aus,
niemals von außen.... Naja - schon ein wenig von außen, weil ich das
Kommando natürlich sende, aber da steht ein Login und eine
Kommando-Syntax davor...
LG
Johann
:
Bearbeitet durch User
Ich frage mich nur, warum du nicht gleich den ganzen Sketch gepostet hast. Naja, vielleicht wolltest du den Helfern nicht gleich die Gelegenheit geben das mal selbst auszuprobieren.
Joachim L. schrieb: > Ich frage mich nur, warum du nicht gleich den ganzen Sketch gepostet Bei mir ist dieser OTA-Teil in einem Sourcecode von mehr als 20.000 Zeilen eingebettet. Bevor ich jetzt beginne den OTA-Teil rauszukopieren wollte ich mal grundsätzlich mal das Risiko aufzeigen. Wenn er das nicht selbst findet, kann er mich fragen und dann setzte ich mich hin, um das rauszuschnibbeln... Die wesentlichsten Dinge sind:
1 | |
2 | #ifdef ESP32 // if we have an ESP32
|
3 | #include <ESP32httpUpdate.h> // on ESP32 for update from Webserver |
4 | #else // if we have an ESP8266
|
5 | #include<ESP8266httpUpdate.h> // necessary code for update |
6 | #endif // end if ESP32
|
7 | .....
|
8 | |
9 | #ifdef ESP32 // if we make code for an ESP32
|
10 | ret=ESPhttpUpdate.update( SketchURL,SketchVersion); |
11 | #else // if we make code for an ESP8266
|
12 | ret=ESPhttpUpdate.update(HttpSubClient, SketchURL,SketchVersion); |
13 | #endif // end if ESP32/ESP8266
|
Zusatzinfos hier: https://github.com/suculent/esp32-http-update https://www.arduino.cc/reference/en/libraries/esp32httpupdate/ https://www.instructables.com/Set-Up-an-ESP8266-Automatic-Update-Server/ P.S.: Bevor jetzt eine Diskussion wegen Source-Code mit 22.000 Zeilen losgetreten wird: Aus dem einen Code erzeuge ich Binaries für viele verschiedene Funktionalitäten und für ESP8266 und ESP32. Es kommt also vom Gesamtcode immer nur ein Kern plus jene Teile zum Einsatz, welche ich über Include-Schalter regle. Jedes Device hat ein eigenes Set an Funktions-Includes (z. B. Webserver, Web-Client, Telnet-Server, UDP, ESPNOW, Bluetooth, MQTT, IFTTT, GPS-Empfänger, Sensoren, OLED-Display, und einiges mehr..) Vielleicht bin ich auch ein bisschen crazy, aber nachdem ich einen Artikel vom CCC (Chaos Computer Club) gelesen habe, bei dem mittels Zerlegung einer Ph*l*ps-Hue-Lampe und Auslesen des EProms die Zugangsdaten zu einem Firmen-WLAN gehackt wurden, lege ich in meinen ESPs auch die WLAN-Informationen im EPROM verschlüsselt ab... Aber so hat eben jeder seine eigene (Vor)Sicht...
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.