Meine Erfahrungen mit dem ESP8266 in der Arduino IDE und wlan routern

Hier finden Sie kurze Informationen ueber meine Erfahrungen mit dem ESP8266. Ich moechte hier nicht grossartig Fakten, die man im Internet findet, wiederholen, sondern nur das erwaehnen, was man sonst so nicht findet.
Viel Spass beim Lesen.


ESP8266 : EEPROM : Ist nicht wirklich ein eeprom.
ESP8266 : WiFi : Wie es funktioniert.
ESP8266 : WiFi : Wie es auch mit neueren WLAN routern funktioniert.
ESP8266 : Programmier Adapter : Auch nach dem seriellen Programmieren geht ESP.reset(), ... .
ESP8266 : Reset : ESP.reset, ESP.restart, ... : Eine Alternative.
ESP8266 : Timer : Ein kleiner Timer(dual oder chain).

EEPROM : Ist nicht wirklich ein eeprom.

Der ESP8266 benutzt einen Teil des Flash-Speichers als EEPROM. Dieser kann nur begrenzt oft beschrieben werden. EEPROMs koennen ca. 1000000 mal beschrieben werden. Der Flash-Speicher nicht. Meine Empfehlung wenn der Chip lange halten soll:
Nur Daten zur Konfiguration dort ablegen. Keine Messwerte.
Beispiel code:
	
#include <EEPROM.h>
// structure in EEPROM
struct eepromdata {
char bla;
char bla1;
};

static struct eepromdata *eepromstr;           // pointer to eeprom ram data

setup()
{

  	// read the content of the eeprom space to internal memory
	EEPROM.begin(sizeof(struct eepromdata)); 
  	// get pointer to the internal memory (set dirty flag internal)
  	eepromstr = (struct eepromdata *)(EEPROM.getDataPtr());

	eepromstr->bla = xyz;

	// write data to the flash memory and clear dirty flag internal
	EEPROM.commit();
}


WiFi : Wie es funktioniert.

Wird ESP8266WiFi.h im code includiert, so hat man sofort ein AP (access point). Wird irgend wann WiFi.mode(WIFI_STA) und WiFi.begin(...,...) aufgerufen, so wird der AP geloescht und der Chip geht in den station-mode. WiFi.begin() schreibt jedes mal die Daten in den Flash-Speicher ! Bein hochfahren des ESP8266 wird, ohne das nochmals WiFi.begin() aufgerufen wird, der station-mode mit den letzten Werten erzeugt. Hier ein Beispiel code, der natuerlich nur das Prinzip veranschaulicht. Irgend wo muss natuerlich ein WiFi.begin() erstmalig aufgerufen werden.
Beispiel code:
	
#include <ESP8266WiFi.h>

setup()
{
	if (WiFi.status() != WL_CONNECTED) 
		{
		Serial.print ( "start wifi " );

		WiFi.mode(WIFI_STA); 
		WiFi.begin(  "mynet",  "mypw" );
		}
	else
		{
		Serial.print ( "Wifi already connected ... " );
		if ( strcmp ( WiFi.SSID().c_str(), "mynet" )  != 0 ||
		     strcmp ( WiFi.psk().c_str(), "mypw" )  != 0)
			{
			WiFi.persistent(true);
			Serial.print ( "Run Wifi disconnect\n" );
			WiFi.disconnect(true);
			delay ( 1000 );
			WiFi.mode(WIFI_STA); 
			Serial.print ( "Run Wifi connect ... " );
			WiFi.begin(  "mynet",  "mypw" );
			delay ( 1000 );
			WiFi.persistent(false);
			}
		}
	for ( count = 0 ; count != 20 ; count++ )
		{
		delay ( 1000 );
		if (WiFi.status() != WL_CONNECTED) 
			{
			Serial.print ( "." );
			}
		else
			{
			break;
			}
			
		}
	if (WiFi.status() != WL_CONNECTED) 
		{
		Serial.print("error\n");
		}
	else
		{
		Serial.print("ok\n");

		Serial.print("SSID:");
		Serial.print(WiFi.SSID());
		Serial.print ( "\n" );
		Serial.print("password:");
		Serial.print(WiFi.psk());
		Serial.print ( "\n" );
		Serial.print("RSSI:");
		Serial.print(WiFi.RSSI());
		Serial.print ( "dBm\n" );
		Serial.print("IP Addresse:");
		Serial.print(WiFi.localIP());
		Serial.print ( "\n" );
		Serial.print("IP netmask:");
		Serial.print(WiFi.subnetMask());
		Serial.print ( "\n" );
		Serial.print("IP gateway:");
		Serial.print(WiFi.gatewayIP());
		Serial.print ( "\n" );
		}
}


WiFi : Wie es auch mit neueren WLAN routern funktioniert.

Das obere Beispiel hat mit einem easybox 602 wlan DSL router funktioniert. Oktober 2024 wurde mir ein neuer wlan DSL router geliefert. Das war die easybox 805.
Damit ging nichts mehr. Nur sporadisch connects zwischen dem router und den esp8266. Nach ca. 3 Minuten ging dann wieder nichts mehr. Es war nicht zu gebrauchen.

Die Frage war also : warum geht es mit der easybox 602 und mit der 805 nicht mehr ?
Ergebnis nach tagelangen Untersuchungen und lesen von Dokumentationen:
- Der esp8266 kann nur WLAN 802.11b, auch wenn er sich selbst mit einem anderem phy. layer verbindet.
- Die easybox 602 kann WLAN 802.11b.
- Die easybox 805 kann WLAN 802.11b nicht.

Beide (esp8266 + easybox 805) verbinden sich mit WLAN 802.11g, was nur humpelt, aber nicht laeuft.

Es musste ein neuer router her, der WLAN 802.11b kann. Ich habe den tp-link Archer VR2100v gekauft. Nun muss nur noch dem esp8266 beigebracht werden, dass er sich mit WLAN 802.11b verbindet. Dazu hier ein Auszug meiner setup software. Zu beachten ist, dass der esp8266 immer erst DHCP benutzt. Wer static IP hat, muss dies jedesmal aendern. Die Werte dazu scheinen nicht im flash zu landen. Also vorsicht und nicht jedesmal der flash Speicher beschreiben.

static WiFiPhyMode_t wifiPhyMode;

                int reconnect, wrongIP;
                IPAddress ipaddr;
                String ipaddrS;
.
.
.
		basis Initialisierung nach der Eingabe der Parameter: (wird nicht beim normalem booten ausgefuehrt)

                        WiFi.persistent(true);// WiFi.begin schreibt parameter ins flash

                        if (WiFi.status() == WL_CONNECTED)
                                {
                                Serial.print ( "Run Wifi disconnect\n" );
                                WiFi.disconnect(true);
                                delay ( 1000 );
                                }
                        WiFi.hostname ( &eepromstr->name[0] );
                        WiFi.setOutputPower ( atof (&eepromstr->wifi_tx_power[0])  );
                        WiFi.mode(WIFI_STA);
                        WiFi.setAutoReconnect ( true );

                        if ( eepromstr->static_ip[0] != 0 &&
                             eepromstr->static_gateway[0] != 0 &&
                             eepromstr->static_subnet[0] != 0 )
                                {
                                Serial.print ( " (setup static network address) " );
                                WiFi.config ( eepromstr->static_ip_IP,
                                              eepromstr->static_gateway_IP,
                                              eepromstr->static_subnet_IP );
                                }
                        WiFi.setPhyMode(WIFI_PHY_MODE_11B);
                        WiFi.begin(&eepromstr->wifi_network[0], &eepromstr->wifi_password[0]);
.
.
.
		Initialisierung bei jedem boot:

                if (WiFi.status() != WL_CONNECTED)
                        {
                        Serial.print ( "start wifi, using tx power of " );
                        Serial.print ( atof (&eepromstr->wifi_tx_power[0]) );
                        Serial.print ( " dBm ... " );

                        WiFi.persistent(false); // WiFi.begin schreibt parameter nur ins data memory

                        WiFi.hostname ( &eepromstr->name[0] );
                        WiFi.setOutputPower ( atof (&eepromstr->wifi_tx_power[0])  );
                        WiFi.mode(WIFI_STA);
                        WiFi.setAutoReconnect ( true );

                        if ( eepromstr->static_ip[0] != 0 &&
                             eepromstr->static_gateway[0] != 0 &&
                             eepromstr->static_subnet[0] != 0 )
                                {
                                Serial.print ( " (setup static network Address) " );
                                WiFi.config ( eepromstr->static_ip_IP,
                                              eepromstr->static_gateway_IP,
                                              eepromstr->static_subnet_IP );
                                }
                        WiFi.setPhyMode(WIFI_PHY_MODE_11B);
                        WiFi.begin(&eepromstr->wifi_network[0], &eepromstr->wifi_password[0]);
                        }
                else
                        {
                        Serial.print ( "Wifi already connected ... " );
                        reconnect = 0;
                        wrongIP = 0;

                        if ( strcmp ( WiFi.SSID().c_str(), &eepromstr->wifi_network[0] )  != 0 ||
                             strcmp ( WiFi.psk().c_str(), &eepromstr->wifi_password[0] )  != 0 )
                                {
                                Serial.print ( "Run Wifi disconnect (wrong SSID)\n" );
                                reconnect = 1;
                                }
                        if ( eepromstr->static_ip[0] != 0 && eepromstr->static_gateway[0] != 0 &&
                               eepromstr->static_subnet[0] != 0 )
                                {
                                /* static IP configuration, check IPs */

                                ipaddr = WiFi.localIP();
                                ipaddrS = ipaddr.toString();
                                if ( strcmp ( ipaddrS.c_str(), &eepromstr->static_ip[0] ) != 0 )
                                        {
                                        Serial.print ( "Local IP Address: " );
                                        Serial.print ( ipaddrS.c_str());
                                        Serial.print ( "\n" );
                                        Serial.print ( "Run Wifi disconnect (wrong IP address)\n" );
                                        wrongIP = 1;
                                        }
                                ipaddr = WiFi.gatewayIP();
                                ipaddrS = ipaddr.toString();
                                if ( strcmp ( ipaddrS.c_str(), &eepromstr->static_gateway[0] ) != 0 )
                                        {
                                        Serial.print ( "Run Wifi disconnect (wrong gateway)\n" );
                                        wrongIP = 1;
                                        }
                                ipaddr = WiFi.subnetMask();
                                ipaddrS = ipaddr.toString();
                                if ( strcmp ( ipaddrS.c_str(), &eepromstr->static_subnet[0] ) != 0 )
                                        {
                                        Serial.print ( "Run Wifi disconnect (wrong subnet)\n" );
                                        wrongIP = 1;
                                        }
                                }
                        wifiPhyMode = WiFi.getPhyMode();
                        if (wifiPhyMode != WIFI_PHY_MODE_11B)
                                {
                                Serial.print ( "Run Wifi disconnect (wrong physical layer)\n" );
                                reconnect = 1;
                                }

                        if ( reconnect == 1 )
                                {
                                WiFi.persistent(true); // WiFi.begin schreibt parameter ins flash
                                delay ( 1000 );

                                Serial.print ( "Run Wifi disconnect now\n" );
                                WiFi.disconnect(true);
                                delay ( 1000 );
                                WiFi.hostname ( &eepromstr->name[0] );
                                WiFi.setOutputPower ( atof (&eepromstr->wifi_tx_power[0])  );
                                WiFi.mode(WIFI_STA);
                                Serial.print ( "Run Wifi connect ... " );
                                WiFi.setAutoReconnect ( true );
                                if ( eepromstr->static_ip[0] != 0 &&
                                     eepromstr->static_gateway[0] != 0 &&
                                     eepromstr->static_subnet[0] != 0 )
                                        {
                                        Serial.print ( " (setup static Network address) " );
                                        WiFi.config ( eepromstr->static_ip_IP,
                                                      eepromstr->static_gateway_IP,
                                                      // eepromstr->static_gateway_IP,
                                                      eepromstr->static_subnet_IP );
                                        }
                                WiFi.setPhyMode(WIFI_PHY_MODE_11B);
                                WiFi.begin(&eepromstr->wifi_network[0], &eepromstr->wifi_password[0]);

                                delay ( 1000 );
                                WiFi.persistent(false);
                                }

                        if ( wrongIP == 1 )
                                {
                                WiFi.persistent(false); // WiFi.begin schreibt parameter nur ins data memory
                                delay ( 1000 );

                                Serial.print ( "Run Wifi disconnect now\n" );
                                WiFi.disconnect(true);
                                delay ( 1000 );
                                WiFi.hostname ( &eepromstr->name[0] );
                                WiFi.setOutputPower ( atof (&eepromstr->wifi_tx_power[0])  );
                                WiFi.mode(WIFI_STA);
                                Serial.print ( "Run Wifi connect ... " );
                                WiFi.setAutoReconnect ( true );
                                if ( eepromstr->static_ip[0] != 0 &&
                                     eepromstr->static_gateway[0] != 0 &&
                                     eepromstr->static_subnet[0] != 0 )
                                        {
                                        Serial.print ( " (setup static Network address) " );
                                        WiFi.config ( eepromstr->static_ip_IP,
                                                      eepromstr->static_gateway_IP,
                                                      // eepromstr->static_gateway_IP,
                                                      eepromstr->static_subnet_IP );
                                        }
                                WiFi.setPhyMode(WIFI_PHY_MODE_11B);
                                WiFi.begin(&eepromstr->wifi_network[0], &eepromstr->wifi_password[0]);

                                delay ( 1000 );
                                WiFi.persistent(false);
                                }
                        }
                for ( count = 0 ; count != 20 ; count++ )
                        {
                        delay ( 1000 );
                        if (WiFi.status() != WL_CONNECTED)
                                {
                                Serial.print ( "." );
                                }
                        else
                                {
                                break;
                                }
                        }
                if (WiFi.status() != WL_CONNECTED)
                        {
                        Serial.print("error\n");
                        }
                else
                        {
                        Serial.print("ok\n");

                        Serial.print("SSID:");
                        Serial.print(WiFi.SSID());
                        Serial.print ( "\n" );
                        Serial.print("password:");
                        Serial.print(WiFi.psk());
                        Serial.print ( "\n" );
                        Serial.print("RSSI:");
                        Serial.print(WiFi.RSSI());
                        Serial.print ( "dBm\n" );
                        Serial.print("IP Addresse:");
                        Serial.print(WiFi.localIP());
                        Serial.print ( "\n" );
                        Serial.print("IP netmask:");
                        Serial.print(WiFi.subnetMask());
                        Serial.print ( "\n" );
                        Serial.print("IP gateway:");
                        Serial.print(WiFi.gatewayIP());
                        Serial.print ( "\n" );
                        Serial.print("PhyMode:");
                        wifiPhyMode = WiFi.getPhyMode();
                        if (wifiPhyMode == WIFI_PHY_MODE_11B)
                                Serial.print("11b");
                        else if (wifiPhyMode == WIFI_PHY_MODE_11G)
                                Serial.print("11g");
                        else if (wifiPhyMode == WIFI_PHY_MODE_11N)
                                Serial.print("11n");
                        Serial.print ( "\n" );
                        }









Programmier Adapter : Auch nach dem seriellen Programmieren geht ESP.reset(), ... .

Wer den ESP8266 auf ein eigenes board setzen will, wird sich Gedanken machen muessen, wie die Programme geladen werden sollen und wie dazu einige GPIOs beschaltet sein muessen. Stichwort : boot mode. Es wird oft eine Schaltung mit zwei Transistoren beschrieben, die eine XOR logik darstellen. Diese habe ich etwas veraendert, damit nach dem seriellen Hochladen ein ESP.reset() oder aehnliches geht auch wenn der Programmieradapter noch mit dem board verbunden ist. Ebenso kann in der Arduino IDE als reset mode nodemcu angegeben werden. Damit braucht man keine Tasten druecken.
Benoetigte Teile : USB-Serial Adapter, 9 Pol und ein paar Bauteile.

Schaltung vom programmier Adapter:
Unterschied zu dem, was man im Internet findet : Die Dioden sind unerlaesslich.

Programmier Adapter oben:

Programmier Adapter unten:

Beschaltung ESP8266 (Auszug) :
Unterschied zu dem, was man im Internet findet : Widerstand zwischen GPIO16 und Reset.

Update (ohne neues Bild):
Aenderung der Schaltung auf dem Board, auf dem sich der ESP8266 befindet.
- Reset funktioniert nicht : Der Widerstand R24, 2 kOhm ist zu hoch. Auf 1 kOhm reduzieren.
- Schutzwiderstaende fehlen : An der Stiftleiste K16, an Pin 1 und 2, einen Schutzwiderstand in die Leiterbahn von 100 Ohm einbauen.


ESP.reset, ESP.restart, ... : Eine Alternative.

Die Beschreibung im Internet fuer ESP.reset und ESP.restart sind meiner Meinung nach stark gelungen. Wenn ich einen reset haben will, so soll das auch ein reset sein. Der code zeigt eine Alternative. Funktioniert sogar mit angeschlossenem programmier Adapter. Siehe oben.
	
void restart_sys()
{
	Serial.print ( "+++++++++ Restart Chip +++++++++\n" );
	delay ( 100 );
	pinMode( 16, OUTPUT);
	digitalWrite( 16, LOW); 
	delay ( 100 );
	Serial.print ( "+++++++++ Restart Chip failed +++++++++\n" );
}
Den Text "+++++++++ Restart Chip failed +++++++++" habe ich nie gesehen. Wird vorher nicht 100ms gewartet, so sieht man noch "+++++++++ Restar". Das sind wahrscheinlich die paar bytes, die der Chip in hardware noch rausschreibt bis auch da der reset angekommen ist. Baudrate 115200.


Ein kleiner Timer(dual oder chain).

Hier wird mit dem ESP8266, oder genauer mit dem board ESP12-F, ein 2 Kanal Timer aufgebaut.

Ausgaenge:
- 2 mal open Drain, ca 2A kurzzeitig
- 1 mal open Drain mit pullup

Eingaenge:
- 2 mal Kurzschlusseingaenge

Interne Eingaenge:
- 2 mal Kontrolleingaenge fuer die beiden open Drain Ausgaenge

Spannungsversorgung:
5,8V - 8V

So sieht es aus:

Ich nutze den Timer fuer ein anderes Hobby ( hier ).
Hier sollte der Timer zum ersten Mal eingesetzt werden. Durch einen Fehler musste der Vorgang abgebrochen
werden. Der Timer wird hier benutzt um zwei Brueckenzuender zu betreiben. Der open Drain mit pullup
schaltet ueber einen externem npn Transistor ein Kontrollrelais. Dies ist ein 2*um Modell, mit dem
der Zuender fuer den Motor kurzgeschlossen wird. Erst wenn die Startfreigabe erfolgt (der Ausgang geschaltet
wird) wird der Zuender fuer den Motor mit dem Zuendkabel verbunden. Erst jetzt kann durch das
Zuendkabel das Modell gestartet werden. Ein Eingang ist der Abreisskontakt fuer den Startvorgang.
Der andere Eingang dient im chain mode als Steuereingang fuer den zweiten Zuenderausgang.
Mit den internen Eingaengen werden die Zuender ueberwacht.

Die software wurde unter Arduino entwickelt. Der ESP12-F arbeitet im Station mode. Braucht also ein
wlan um sich zu verbinden. Ein Smartphone im Hotspot mode kann dies. Mit dem Browser kann man sich
dann mit dem Timer verbinden. Hier koennen einige Parameter ueberwacht und eingestellt werden. Nach
der Startfreigabe muss dann nach wie vor mit einem Zuendkabel das Modell gestartet werden.
Hier die beider wichtigsten html Seiten vom Timer:




Impressum: 
Frank Salomon
Mattenbuder Pfad 29
13503 Berlin
info@franksalomon.de




Haftung für Inhalte

Die Inhalte meiner Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte kann ich jedoch keine Gewähr übernehmen.

Als Diensteanbieter bin ich gemäß § 6 Abs.1 MDStV und § 8 Abs.1 TDG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Diensteanbieter sind jedoch nicht verpflichtet, die von ihnen übermittelten oder gespeicherten fremden Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei bekannt werden von entsprechenden Rechtsverletzungen werde ich diese Inhalte umgehend entfernen.

Haftung für Links

Mein Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte ich keinen Einfluss haben. Deshalb kann ich für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich.
Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei bekannt werden von Rechtsverletzungen werde ich derartige Links umgehend entfernen.

Urheberrecht

Die Betreiber der Seiten sind bemüht, stets die Urheberrechte anderer zu beachten bzw. auf selbst erstellte sowie lizenzfreie Werke zurückzugreifen.

Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Beiträge Dritter sind als solche gekennzeichnet. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet und dürfen nicht veröffentlicht werden..

Datenschutz

Soweit auf meinen Seiten personenbezogene Daten (beispielsweise Name, Anschrift oder eMail-Adressen) erhoben werden, erfolgt dies soweit möglich stets auf freiwilliger Basis. Die Nutzung der Angebote und Dienste ist, soweit möglich, stets ohne Angabe personenbezogener Daten möglich.

Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.

Quelle: Haftungsausschluss von eRecht24 - Portal zum Internetrecht