ESP32 sethostname klappt nicht

Gast #7349635
Lesenswert?

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?

Gast #7349641
Lesenswert?

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
}
#7349679
Lesenswert?

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

Gast #7349730
Lesenswert?

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
    });
Gast #7349754
Lesenswert?

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
});
Gast #7349786
Lesenswert?

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.

Gast #7349869
Lesenswert?

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.

Gast #7349874
Lesenswert?

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);
Gast #7349876
Lesenswert?

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
}
(Firma: privat) #7350864
Lesenswert?

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

Gast #7350866
Lesenswert?

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.

(Firma: privat) #7351237
Lesenswert?

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.

Gast #7351238
Lesenswert?

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.

Gast #7355329
Lesenswert?

@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.

Angehängte Dateien:
(Firma: privat) #7356103
Lesenswert?

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

Gast #7356242
Lesenswert?

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.

(Firma: privat) #7356388
Lesenswert?

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 Phlps-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...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren