Forum: Mikrocontroller und Digitale Elektronik ESP32 sethostname klappt nicht


von Thorsten M. (Gast)


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?

von Thorsten M. (cortex_user)


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
}

von Jim M. (turboj)


Lesenswert?

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.

von Sebastian (Gast)


Lesenswert?

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

von Thorsten M. (cortex_user)


Lesenswert?

esp8266 klappt alles, ist aber ne ganz andere Kiste, andere befehle usw.

von Thorsten M. (cortex_user)


Lesenswert?

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.

von Werner P. (werner4096)


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

von Thorsten M. (cortex_user)


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
    });

: Bearbeitet durch User
von PROGRAMINO (Gast)


Lesenswert?

Hi,

// Costum Hostname
const char* hostname = "WiFi-Thorsten"; (global).

Router neu starten!

von Thorsten M. (cortex_user)


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
});

von FromahschdiBrie (Gast)


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.

von c-hater (Gast)


Lesenswert?

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.

von Thorsten M. (cortex_user)


Lesenswert?

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.

von Thorsten M. (cortex_user)


Lesenswert?

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? :-)

von c-hater (Gast)


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.

von Thorsten M. (cortex_user)


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);

: Bearbeitet durch User
von Thorsten M. (cortex_user)


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
}

: Bearbeitet durch User
von Johann K. (Firma: privat) (johnboyk)


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

von Thorsten M. (cortex_user)


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.

: Bearbeitet durch User
von Johann K. (Firma: privat) (johnboyk)


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.

von Thorsten M. (cortex_user)


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.

: Bearbeitet durch User
von Johann K. (Firma: privat) (johnboyk)


Lesenswert?

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.

von Thorsten M. (cortex_user)


Angehängte Dateien:

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.

von Johann K. (Firma: privat) (johnboyk)


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

: Bearbeitet durch User
von 🕵︎ Joachim L. (Gast)


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.

von Johann K. (Firma: privat) (johnboyk)


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 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
Noch kein Account? Hier anmelden.