WiFi Kochbuch mit ESP8266

Das WiFi-Modul ESP8266 ermöglicht es mit dem Arduino auf einfache Weise mit einem Partner im WLAN oder im Internet zu kommunizieren. Die einfache Handhabung und nicht zuletzt der niedrige Preis machen das Modul sehr attraktiv. Man bekommt die einfachste Version für weniger als 5 Euro.

ESP8266_01

Obwohl das Modul relativ neu auf dem Markt ist, gibt es im Internet viele Anleitungen für die erste Kontaktaufnahme mit dem Modul. Unter der Überschrift „Erste Schritte“ gehen diese Anleitungen jedoch nicht soweit, ein komplettes Anwendungsbeispiel zu zeigen.

Ich möchte hier einen Sketch vorstellen, der zeigt, wie man mit diesem Modul den Arduino steuern kann.

Hier wird einfach die LED an Port 13 ein- und ausgeschaltet oder zum Blinken gebracht. Die Pulsdauer für das Blinken kann verändert werden. Die Steuerung erfolgt mit einer HTML-Eingabemaske, die der Arduino erzeugt und an den Client sendet.

ESP5266_03

Das Beispiel kann leicht für andere Anwendungen angepasst und erweitert werden. Ein- und Ausgaben in Form von Beschriftungen, Eingabefeldern und Radiobuttons zeigen beispielhaft wie es funktioniert. Der gewünschte Zustand der Led wird im Parameter LED mit den Werten Ein, Aus oder Blk zurückgegeben. Die Pulsdauer im Parameter PULS. Dies ist 4-stelliger Zahlenwert.

Für das Modul habe ich mir ein Schild gebaut.

ESP5266_02

Hier die Beschaltung :

ESP5266_04

Das Modul kann kurzzeitig bis zu 200 mA Strom benötigen. Deshalb habe ich die vom Arduino gelieferte Versorgungsspannung mit einem Elko gestützt. Für große Entfern- ungen kann das jedoch nicht ausreichend sein, sodass eine eigene, leistungsfähige 3,3V Stromversorgung notwendig ist..

Um das Signal vom 5 V Ausgang des Arduino an den 3,3 V Eingang des Moduls anzupassen, ist  in der TX-Leitung des Arduino ein Spannungsteiler. In umgekehrter Richtung ist keine Signalanpassung notwendig; der Arduino erkennt auch Signale mit 3,3 V Spannung.

Update 22.12.2014 : Ich nun habe den Sketch umgeschrieben, sodaß die  Text-Konstanten weitgehend im Flash-Memory gespeichert werden. Das führt zu einer deutlichen Verringerung des belegten SRAMs : Bisher 1755 Byte (85%) jetzt nur noch 623 Byte (30 %).

Update 04.01.2015 : Im Beitrag einige Ergänzungen und Klarstellungen eingebaut, die sich aus den Komentaren ergeben haben. Im  Beispielsketch fehlte die Deklaration einer Routine. Dank an Andreas und Manfred für die Hinweise.

Hier das Coding meines Sketches (04.01.2015) : Dieser Seketch wurde mit FirmwareVersion 0901 und 0922 getestet.

//--------------------------------------------------------------------------
// Wifi Modul ESP8266 Beispiel Programm
//--------------------------------------------------------------------------
// Autor : Hubert Baumgarten
// Datum : 04.01.2015
//--------------------------------------------------------------------------
// Basis war das Beispiel von Ray Wang  http://rayshobby.net/?p=9734
//--------------------------------------------------------------------------

#include <avr/pgmspace.h>

#define WIFI_DEBUG

#define WIFI_Serial Serial
#define Debug_Serial mySerial

#ifdef WIFI_DEBUG
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,11); // RX, TX
#endif

#define WIFI_ERROR_NONE 0
#define WIFI_ERROR 1

//---------------------------------------------------------------------------
// HTML
int HTML_Content_Length;
int HTML_Header_Length;
int HTML_Temp_Length;
byte HTML_Sende_Mode;
int HTML_Counter = 0;

#define HTML_SENDE_MODE_PREPARE 0
#define HTML_SENDE_MODE_SEND 1

//---------------------------------------------------------------------------
// WIFI
char WIFI_Net[30];
char WIFI_IP_Adress[20];
#define PORT 80
char WIFI_Host[24];
int WIFI_CWMODE;
#define CWMODE_STATION 1
#define CWMODE_ACCESSPOINT 2
int WIFI_Setup_Error = 0;

//---------------------------------------------------------------------------
// Receive-Buffer
#define RECV_BUFFER_SIZE 100
char RECV_Buffer[RECV_BUFFER_SIZE];

//---------------------------------------------------------------------------
// LED Handling
#define LEDMODE_AUS 0
#define LEDMODE_EIN 1
#define LEDMODE_BLINK 2
#define LEDPIN 13
int led_value = LOW;
int led_mode = LEDMODE_AUS;
unsigned long led_nextpuls = 0;
int led_pulsdauer = 500;

//-----------------------------------------------------------------------
// Routinen deklarieren
int WIFI_Setup();
void RECV_Buffer_Clear();
void Led_Handling();
void Set_Led(int p);
void HTML_Page(int WIFI_Cannel);
void HTML_Make_Header();
void HTML_Make_Content();
void HTML_Send(char * c);
void HTML_Send_Int(int z);
void HTML_Send_PROGMEM(const __FlashStringHelper* tx);

//--------------------------------------------------------------------------------------
void setup() {
  pinMode(LEDPIN, OUTPUT);

  WIFI_Serial.begin(115200);
  WIFI_Serial.setTimeout(5000);

#ifdef WIFI_DEBUG
  Debug_Serial.begin(9600);
#endif
  //----------------------------------
  // 3 sec warten
  delay (3000);

  Set_Led(HIGH);

  WIFI_Setup_Error = WIFI_Setup();

#ifdef WIFI_DEBUG
  if (WIFI_Setup_Error) {
    Debug_Serial.println(F("Error"));
  }
#endif

  if (WIFI_Setup_Error) led_mode = LEDMODE_BLINK;
  else Set_Led(LOW);

  WIFI_Serial.setTimeout(20);
  WIFI_Host[0] = 0;
  RECV_Buffer_Clear();
}
//--------------------------------------------------------------------------
void loop() {

  int WIFI_Cannel, WIFI_Packet_Length;
  int i;
  char *buffer_pointer;
  byte len;

  // request: +IPD,ch,len:GET /?LED=xxx&PULS=nnnn ... Host: nnn.nnn.nnn.nnn:nnnn 0x0D ...

  if (WIFI_Serial.findUntil("+IPD,", "\r")) {

    WIFI_Cannel = WIFI_Serial.parseInt();
    WIFI_Serial.findUntil(",", "\r");
    WIFI_Packet_Length = WIFI_Serial.parseInt();

    if (WIFI_Serial.findUntil("GET /", "\r")) {

      WIFI_Serial.readBytesUntil(13, RECV_Buffer, RECV_BUFFER_SIZE);

      if (WIFI_Packet_Length > 0) {
        buffer_pointer = RECV_Buffer;
        if (strncmp(buffer_pointer, "?LED=", 5) == 0) {
          buffer_pointer += 5;
          if (strncmp(buffer_pointer, "Ein", 3) == 0) {
            led_mode = LEDMODE_EIN;
          }
          if (strncmp(buffer_pointer, "Aus", 3) == 0) {
            led_mode = LEDMODE_AUS;
          }
          if (strncmp(buffer_pointer, "Blk", 3) == 0) {
            led_mode = LEDMODE_BLINK;
          }
          buffer_pointer += 3;
          if (strncmp(buffer_pointer, "&PULS=", 6) == 0) {
            buffer_pointer += 6;
            for (i = 0; i < 5; i++) {
              if (buffer_pointer[i] < '0' || buffer_pointer[i] > '9') buffer_pointer[i] = 0;
            }
            led_pulsdauer = atoi(buffer_pointer);
          }
        }
        WIFI_Host[0] = 0;
        if (WIFI_Serial.find("Host: ")) {
          len = WIFI_Serial.readBytesUntil(13, WIFI_Host, 23);
          WIFI_Host[len] = 0;
        }
        HTML_Page(WIFI_Cannel);
      }
    }
    RECV_Buffer_Clear();
  }
  Led_Handling();
}



//----------------------------------------------------------------------
int WIFI_Setup() {
  byte len;

  RECV_Buffer_Clear();

  //-----------------------------------------------------------
  // start server

#ifdef WIFI_DEBUG
  Debug_Serial.println(F("AT+CIPMUX"));
#endif

  WIFI_Serial.println(F("AT+CIPMUX=1"));
  delay(10);
  // normale Antwort :
  //   "AT+CIPMUX=1" 0xD 0xD 0xA 0xD 0xA "OK" 0xD 0xA

  if (!WIFI_Serial.find("OK")) {
    return WIFI_ERROR;
  }
  RECV_Buffer_Clear();

  //-----------------------------------------------------------
  // TCP service aktivieren

#ifdef WIFI_DEBUG
  Debug_Serial.println(F("AT+CIPSERVER"));
#endif
  WIFI_Serial.print(F("AT+CIPSERVER=1,"));
  WIFI_Serial.println(PORT);
  delay(10);

  // normale Antwort :
  //   "AT+CIPSERVER=1,8080" 0xD 0xD 0xA 0xD 0xA "OK" 0xD 0xA

  if (!WIFI_Serial.find("OK")) {
    return WIFI_ERROR;
  }

  RECV_Buffer_Clear();

  //-------------------------------------------------------------------------
  // Timeout für automatisches Trennen der Verbindung setzen

#ifdef WIFI_DEBUG
  Debug_Serial.println(F("AT+CIPSTO"));
#endif

  WIFI_Serial.println(F("AT+CIPSTO=0"));
  delay(10);
  if (!WIFI_Serial.find("OK")) {
    return WIFI_ERROR;
  }

  //---------------------------------------------------------------------------
  // WiFi Modus ermitteln

  RECV_Buffer_Clear();
  WIFI_Net[0] = 0;

#ifdef WIFI_DEBUG
  Debug_Serial.println(F("AT+CWMODE?"));
#endif

  WIFI_Serial.println(F("AT+CWMODE?"));
  delay(10);
  // Normale Antwort AT+CWMODE? 0x0D 0x0D 0x0A+CWMODE:1 0x0D 0x0A 0x0D 0x0A OK 0x0D 0x0A

  WIFI_CWMODE = 0;
  if (WIFI_Serial.find("AT+CWMODE?\r\r\n+CWMODE:")) {
    WIFI_CWMODE = WIFI_Serial.parseInt();
  }

#ifdef WIFI_DEBUG
  Debug_Serial.print(F("CWMode:"));
  Debug_Serial.println(WIFI_CWMODE);
#endif

  if (WIFI_CWMODE == 0) {
    return WIFI_ERROR;
  }

  //---------------------------------------------------
  // Ich bin Station. In welchem Netz bin ich ?

  if (WIFI_CWMODE == CWMODE_STATION) {

#ifdef WIFI_DEBUG
    Debug_Serial.println(F("AT+CWJAP?"));
#endif

    WIFI_Serial.println(F("AT+CWJAP?"));
    delay(10);
    // Normale Antwort AT+CWJAP? 0x0D 0x0D 0x0A +CWJAP:"<SSID>" 0x0D 0x0A 0x0D 0x0A OK 0x0D 0x0A

    len = 0;
    WIFI_Net[0] = 0;
    if (WIFI_Serial.find("AT+CWJAP?\r\r\n+CWJAP:\"")) {
      len = WIFI_Serial.readBytesUntil('\"', WIFI_Net, 20);
      WIFI_Net[len] = 0;
    }

    if (len > 0) {
#ifdef WIFI_DEBUG
      Debug_Serial.println(F("Netzwerk:"));
      Debug_Serial.println(WIFI_Net);
#endif
    }
    else {
      return WIFI_ERROR;
    }
  }
  //------------------------------------------
  // Ich bin Accesspoint, wie heisse ich ?
  if (WIFI_CWMODE == CWMODE_ACCESSPOINT) {

#ifdef WIFI_DEBUG
    Debug_Serial.println(F("AT+CWSAP?"));
#endif

    WIFI_Serial.println(F("AT+CWSAP?"));
    delay(10);
    // Normale Antwort AT+CWSAP? 0x0D 0x0D 0x0A +CWSAP:"MyESP",
    //                 "12345678",8,3 0x0D 0x0A 0x0D 0x0A OK 0x0D 0x0A
    len = 0;
    WIFI_Net[0] = 0;
    if (WIFI_Serial.find("AT+CWSAP?\r\r\n+CWSAP:\"")) {
      len = WIFI_Serial.readBytesUntil('\"', WIFI_Net, 20);
      WIFI_Net[len] = 0;
    }

    if (len > 0) {
#ifdef WIFI_DEBUG
      Debug_Serial.println(F("Netzwerk:"));
      Debug_Serial.println(WIFI_Net);
#endif
    }
    else {
      return WIFI_ERROR;
    }
  }

  //-----------------------------------------------------------
  // Get IP Adress

#ifdef WIFI_DEBUG
  Debug_Serial.println(F("AT+CIFSR"));
#endif

  WIFI_Serial.println(F("AT+CIFSR"));
  delay(1000);

  // Normale Antwort z.B.
  // AT+CIFSR 0xD 0xD 0xA 192.168.178.26 0xD 0xA

  len = 0;
  WIFI_IP_Adress[0] = 0;
  if (WIFI_Serial.find("AT+CIFSR\r\r\n")) {
    len = WIFI_Serial.readBytesUntil('\r', WIFI_IP_Adress, 20);
    WIFI_IP_Adress[len] = 0;
  }
#ifdef WIFI_DEBUG
  if (len > 0) {
    Debug_Serial.println(F("IP"));
    Debug_Serial.println(WIFI_IP_Adress);
  }
#endif
  if (len == 0) {
    return WIFI_ERROR;
  }

#ifdef WIFI_DEBUG
  Debug_Serial.println(F("Setup okay"));
#endif

  return WIFI_ERROR_NONE;
}

//----------------------------------------------------------------------

void HTML_Page(int WIFI_Cannel) {

  HTML_Counter++;

#ifdef WIFI_DEBUG
  Debug_Serial.print(F("Zaehler: "));
  Debug_Serial.println(HTML_Counter);
#endif

  HTML_Sende_Mode = HTML_SENDE_MODE_PREPARE;

  HTML_Temp_Length = 0;
  HTML_Make_Content();
  HTML_Content_Length = HTML_Temp_Length;

  HTML_Temp_Length = 0;
  HTML_Make_Header();
  HTML_Header_Length = HTML_Temp_Length;

  WIFI_Serial.print(F("AT+CIPSEND="));
  WIFI_Serial.print(WIFI_Cannel);
  WIFI_Serial.print(F(","));
  WIFI_Serial.println(HTML_Header_Length + HTML_Content_Length);

  delay(20);

  RECV_Buffer_Clear();

  HTML_Sende_Mode = HTML_SENDE_MODE_SEND;
  HTML_Make_Header();
  HTML_Make_Content();

  delay(10);
}

//---------------------------------------------------------------------------
void HTML_Make_Header() {

  HTML_Send_PROGMEM(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n"));
  HTML_Send_PROGMEM(F("Content-Length:"));
  HTML_Send_Int(HTML_Content_Length);
  HTML_Send_PROGMEM(F("\r\n\r\n"));
}

//---------------------------------------------------------------------------
void HTML_Make_Content() {

  HTML_Send_PROGMEM(F("<HTML><HEAD> <title>Arduino Steuerung</title></HEAD>\n"));

  HTML_Send_PROGMEM(F("<BODY bgcolor=\"#ADCEDE\" text=\"#000000\">"));

  HTML_Send_PROGMEM(F("<FONT size=\"6\" FACE=\"Verdana\">Arduino Steuerung<BR/></FONT>"));

  HTML_Send_PROGMEM(F("<FONT size=\"3\" FACE=\"Verdana\">\n<BR/>Hubbie's Arduino Uno<BR/>"));

  HTML_Send_PROGMEM(F("Led : "));
  switch (led_mode)  {
    case LEDMODE_AUS:
      HTML_Send_PROGMEM(F("aus"));
      break;
    case LEDMODE_EIN:
      HTML_Send_PROGMEM(F("ein"));
      break;
    case LEDMODE_BLINK:
      HTML_Send_PROGMEM(F("blinkt"));
      break;
  }
  HTML_Send_PROGMEM(F("<BR/>\n"));

  //--------------------------------------
  // Aufrufzaehler
  HTML_Send_PROGMEM(F("Aufrufz&auml;hler = "));
  HTML_Send_Int(HTML_Counter);

  HTML_Send_PROGMEM(F("<BR/></font>"));

  HTML_Send_PROGMEM(F("<FORM ACTION=\"http://"));
  HTML_Send(WIFI_Host);
  HTML_Send_PROGMEM(F("\">"));

  HTML_Send_PROGMEM(F("<P><FONT size=\"3\" FACE=\"Verdana\">Led schalten :<BR/>"));

  if (led_mode == LEDMODE_EIN)  {
    HTML_Send_PROGMEM(F("<INPUT TYPE=\"RADIO\" NAME=\"LED\" VALUE=\"Ein\"> Einschalten<BR/>"));
    HTML_Send_PROGMEM(F("<INPUT TYPE=\"RADIO\" NAME=\"LED\" VALUE=\"Aus\" CHECKED> Ausschalten<BR/>"));
  }
  else
  {
    HTML_Send_PROGMEM(F("<INPUT TYPE=\"RADIO\" NAME=\"LED\" VALUE=\"Ein\" CHECKED> Einschalten<BR/>"));
    HTML_Send_PROGMEM(F("<INPUT TYPE=\"RADIO\" NAME=\"LED\" VALUE=\"Aus\"> Ausschalten<BR/>"));
  }

  HTML_Send_PROGMEM(F("<INPUT TYPE=\"RADIO\" NAME=\"LED\" VALUE=\"Blk\"> Blinken"));

  HTML_Send_PROGMEM(F("&emsp;&emsp;&emsp;&emsp;&emsp;Plusdauer:<INPUT NAME=\"PULS\" TYPE=\"TEXT\" size=\"4\" MAXLENGTH=\"4\" VALUE=\""));
  HTML_Send_Int(led_pulsdauer);
  HTML_Send_PROGMEM(F("\"> mSec<BR/>"));
  HTML_Send_PROGMEM(F("<BR/>"));

  //--------------------------------------
  // Absende-Knopf

  HTML_Send_PROGMEM(F("<INPUT TYPE=\"SUBMIT\" VALUE=\" Absenden \">"));
  HTML_Send_PROGMEM(F("</FONT></P>"));
  HTML_Send_PROGMEM(F("</BODY></HTML>"));
}

//---------------------------------------------------------------------------
void HTML_Send_Int(int p_int) {
  char tmp_text[8];
  itoa(p_int, tmp_text, 10);
  HTML_Send(tmp_text);
}

//---------------------------------------------------------------------------
void HTML_Send(char * p_text) {
  HTML_Temp_Length += strlen(p_text);
  if (HTML_Sende_Mode == HTML_SENDE_MODE_SEND) {
    WIFI_Serial.print(p_text);
  }
}

//---------------------------------------------------------------------------
void HTML_Send_PROGMEM(const __FlashStringHelper* p_text) {

  HTML_Temp_Length += strlen_P((const char*)p_text);
  if (HTML_Sende_Mode == HTML_SENDE_MODE_SEND) {
    WIFI_Serial.print(p_text);
  }
}


//------------------------------------------------------------
void RECV_Buffer_Clear() {
  for (int i = 0; i < RECV_BUFFER_SIZE; i++) RECV_Buffer[i] = 0;
  while (WIFI_Serial.available())WIFI_Serial.read();
}

//--------------------------------------------------------------------
void Led_Handling() {

  if (led_mode == LEDMODE_AUS && led_value != LOW) Set_Led(LOW);
  if (led_mode == LEDMODE_EIN && led_value != HIGH) Set_Led(HIGH);
  if (led_mode == LEDMODE_BLINK && millis() > led_nextpuls) {
    led_nextpuls = millis() + (unsigned long)led_pulsdauer;
    if (led_value == LOW) Set_Led(HIGH);
    else Set_Led(LOW);
  }
}

//--------------------------------------------------------------------
void Set_Led(int p) {
  led_value = p;
  digitalWrite(LEDPIN, led_value);
}

Die Sketche zum download:

Neuere FirmwareVersionen ermöglichen die Einstellung der Baudrate für die serielle Kommunikation. Dies führt zu einer Verlangsamung des Datenverkehrs, was wiederum zu Komplikationen führen kann. Ich empfehle daher, die Einstellung 115200 Baud zu belassen.

In meinem Sketch habe ich viele Routinen generell anders aufgebaut, als in den vielen Beispielen im Internet:

  •  Auslesen der empfangenen Daten
    Der Arduino hat einen Puffer von nur 64 Zeichen. Eine Nachricht vom Client kann jedoch über 400 Zeichen lang sein, weil viele Angaben zum verwendeten Internetbrowser, zum Betriebssystem, zum Gerätetyp usw. enthalten sind. Also muß man immer versuchen, die Daten schneller auszulesen als Daten empfangen werden. Dafür eignen sich treffsicher formulierte Befehle wie Find und ReadUntil.
  • Aufbau der Sendenachricht
    Das Protokoll sieht vor, dass am Anfang einer Nachricht die Gesamtlänge der Nachricht angegeben wird. Deshalb wird in vielen Beispielen zunächst die gesamte Nachricht zusammengebaut. Häufig wird sogar mit einer Stringvariablen gearbeitet. Das kostet jedoch sehr viel Arbeitsspeicher. Ich erzeuge eine relativ große HTML-Nachricht und baue deshalb die Nachricht Stück für Stück auf. Dabei nutze ich die Möglichkeit, die Texte im Flash-Memory zu speichern. Ich mache 2 Durchläufe. Im ersten Durchlauf wird nur die Länge der Nachricht ermittelt; erst im 2. Durchlauf wird die Nachricht gesendet.
  • Empfänger IP im Absendebutton
    Mit dem Absende-Button wird aus der HTMLSeite heraus an das ESP-Modul eine neue Nachricht erzeugt. Abhängig von der Arbeitsweise des Moduls ist die IP des Empfängers mal die lokale WLAN-IP, die globale IP des Routers oder die Server-IP des Moduls. Mein Sketch liest die richtige IP aus der eingehenden Nachricht. Der ausgewertete Parameter heißt HOST .

Das ESP8266-Modul hat 2 verschiedene Betriebsarten. Die Betriebart wird über das AT-Kommando CWMODE eingestellt.

  • Als Client im WLAN (Station)
    Hier müssen mit dem AT-Kommando CWJAP die Zugangsdaten (SSID und Passwort) eingestellt werden.
  • Als Router im selbst erzeugten WLAN (Accesspoint)
    Hier müssen mit dem AT-Kommando CWSAP die WLAN-Parameter (SSID, Passwort, WLAN-Kanal und Art der Verschlüsselung) eingestellt werden. Fabrikneue Module sind auf diese Betriebsart eingestellt, mit offenen WLAN-Netz. In diesem Arbeitsmodus hat das Modul die feste IP-Adresse 192.168.4.1. Es können bis zu 5 Clients gleichzeitig angemeldet sein. Die Clients können jedoch nicht untereinander kommunizieren.

Die o.g. Einstellungen müssen nur einmal gemacht werden. Sie bleiben nach dem Ausschalten erhalten. Mein Beispiel-Sketch setzt diese Einstellungen nicht. Das hat den Vorzug, dass er universeller einsetzbar ist. Im oben angegebenen ZIP-File sind Sketche enthalten, die diese Parameter setzen. In diesen Sktechen müssen die eigenen Parameterwerte eingetragen werden. Sie müssen nur einmalig ausgeführt werden.

Im Arbeitsmodus Client im WLAN bezieht das Modul vom Router die lokale IP-Adresse. Das kann bei jedem Programmstart eine andere sein. Es empfiehlt sich daher im Router (Speedport oder Fritzbox …) eine Einstellung vorzunehmen, die dafür sorgt, dass für das ESP-Modul immer die gleiche IP-Adresse vergeben wird. Diese Adresse muß man mit dem Internetbrowser aufrufen. Will man aus dem Internet auf das Modul zugreifen, muß man in seinem Router eine Weiterleitung Port an sein ESP-Mudul eintragen. Hat man nur einen Anwerndungsfall kann man Port 80 verwenden. Dies ist der Standard für HTTP und braucht dann nicht angegeben zu werden.
Um über das Internet zugreifen zu können, muß man die globale IP seines Routers kennen. Diese wechselt jedoch täglich. Ein Methode diese auch von ausserhalb zu erfahren ist, sich vom Router eine automatische Mail mit der aktuellen IP schicken zu lassen. Diese Mail muß man von ausserhalb lesen können. Viele Router bieten diese Möglichkeit an.

Abschliessend hier meine Beschreibung der wichtigsten AT-Kommandos. Die angegebenen Antowrten wurden mit der FirmwareVersion 0901 ermittelt. Mit anderen FirmwareVersionen können die Antworten anweichend sein.

AT Hallo bist Du da ?

Aufruf : AT
Antwort : AT OK

  • AT+RST    Reset

Aufruf :              AT+RST
Antwort :           AT+RST <cr> <crlf> <crlf> OK <crlf> <crlf> <space> ets <space> Jan <space> <space> 8 <space> 2013,rst <space> cause:4, <space> boot <space> mode:(3,5) <crlf> <crlf>wdt <space> reset <crlf>load <space> 0x40100000, <space> len <space> 244 <space> o1 <space> tl2 <lf> k00h0a2o <space> <cr> o <space> 3f0,e8 <space> ackmxldxf809o4 <cr> a <space> hu0d <lf> u0b <lf> rd <cr>

Anmerkung     Prüfen die Antwort auf “reset”. Der restliche Inhalt ist unerklärbar.

  • AT+CWMODE   WiFi Modus

Bedeutung:  

1 = Station (Server im vorhandenen WLAN),
2 = Accesspoint, (eigenes WLAN-Netzwerk),
3 = beides

Aktuellen Wert Abfragen :
Aufruf :              AT+CWMODE?
Antwort :           AT+CWMODE? <cr> <crlf>+CWMODE:2 <crlf> <crlf> OK <crlf>

Erlaubte Werte abfragen :
Aufruf :              AT+CWMODE=?
Antwort :           AT+CWMODE=? <cr> <crlf> +CWMODE:(1-3) <crlf> <crlf> OK <crlf>

Wert setzen :
Aufruf :              AT+CWMODE=1

Wenn der Modus bisher anders war :
Antwort :           AT+CWMODE=1 <cr> <crlf> <crlf> OK <crlf>

sonst :
Antwort :           AT+CWMODE=1 <cr> <crlf>no <space> change <crlf>

Der geänderte Wert wird er nach einem Reset wirksam; also anschiessend AT+RST schicken.

  • AT+CWLAP       Verfügbare Netze anzeigen

Aufruf :         AT+CWLAP
Antwort :      AT+CWLAP <cr> <crlf> +CWLAP:(0,““,0) <crlf> +CWLAP:(3,“Netzwerk1″,-66) <crlf> +CWLAP:(4,“Netzwerk2″,-44) <crlf> OK <crlf>

Jedes Netzwerk wird mit Art der Verschlüsselung, SSID und Signalstärke (in dB) ausgegeben,

  • AT+CWJAP       WLAN-Router setzen

Aktuellen Wert Abfragen :
Aufruf :         AT+CWJAP?
Antwort :      AT+CWJAP? <cr> <crlf> +CWJAP:“<SSID>“ <crlf> <crlf> OK <crlf>

Die <SSID> ist leer, wenn keine Verbindung besteht.

Wert setzen:
Aufruf :         AT+CWJAP=“<SSID>“,“<Passwort>“
Antwort :      AT+CWJAP=“<SSID>”,“<Passwort>“ <cr> <crlf> <crlf> OK <crlf>

Diese Einstellung wird erst nach dem nächsten PowerOn wirksam, sie bleibt auch nach dem Ausschalten erhalten.

  • AT+CIPSTATUS        Status abfragen

 Aufruf :         AT+CISPTATUS

Wenn nicht verbunden (Status 1)
Antwort :      AT+CIPSTATUS <cr> <crlf> STATUS:1 <crlf> <crlf> OK <crlf>

Wenn verbunden (Status 3) z.B.
Antwort :      AT+CIPSTATUS <cr> <crlf> STATUS:3 <crlf> +CIPSTATUS:0,“TCP“,“192.168.178.21″,50324,1 <crlf> <crlf> OK <crlf>

Es fehlt eine vollständige Liste aller Status und deren Bedeutung.

  • AT+CIFSR         Aktuelle IP-Adresse abfragen

 Aufruf :         AT+CIFSR

Wenn nicht verbunden
Antwort :      AT+CIFSR <cr> <crlf> <crlf> ERROR <crlf>

Wenn verbunden.
Antwort :      AT+CIFSR <cr> <crlf> 192.168.178.29 <crlf>

  • AT+CWQAP      Verbindung trennen

Aufruf :        AT+CWQAP
Antwort :      AT+CWQAP <cr> <crlf> <crlf> OK <crlf>

  • AT+CIPMUX      Einzel/Multi – Verbindungsmodus-Modus

Bedeutung: 0 = Einzel-Verbindung 1 = Multi-Verbindung

Wert abfragen
Aufruf :         AT+CIPMUX?
Antwort :      AT+CIPMUX? <cr> <crlf> +CIPMUX:0 <crlf> <crlf> OK <crlf>

Wert setzen
Aufruf :         AT+CIPMUX=1
Antwort :      AT+CIPMUX=1 <cr> <crlf> <crlf> OK <crlf>

  • AT+CWSAP       Accesspoint-Parameter setzen

Hier wird die eigene SSID, das Passwort ,der WLAN-Kanal und die Sicherungsart fgestgelegt. Die Verbindung läuft stabiler, wenn der gewählte WLAN-Kanal frei ist, also kein weiteres Netzwerk damit arbeitet.

Die Sicherungsart kann folgende Werte annehmen :

0 = offen, ohne Passwort
1 = WEB
2 = WPA_PSK
3 = WPA2_PSK
4 = WPA_WPA2_PSK

Wert abfragen
Aufruf :         AT+CWSAP?
Antwort :      AT+CWSAP? <cr> <crlf> +CWSAP:“Hubbie_ESP01″,“12345678″,8,3 <crlf> <crlf> OK <crlf>

Wert setzen
Aufruf :         AT+CWSAP=“ESP01″,“12345678″,8,3
Antwort :      AT+CWSAP=“ESP01″,“12345678″,8,3 <cr> <crlf> <crlf> OK <crlf>

Das ESP-Modul ist anschliessend im angegebenen Netz, unter der IP-Adresse 192.168.4.1 erreichbar.

Das Passwort muß mindestens 8 Stellen lang sein und muß auch bei Sicherungsart 0 (offener Zugang; ohne Passwort eingabe) angegeben werden.

Diese Einstellung wird erst nach dem nächsten PowerOn wirksam, sie bleibt auch nach dem Ausschalten erhalten.