ESP8266 Konfiguration mit print-AT-Befehlen im Code möglich?

Hallo zusammen,

Ich möchte meine Arduino Projekte drahtlos mit meinem Smartphone überwachen über die serielle Schnittstelle bzw. später auch bei Bedarf steuern. Zur Auswahl habeich mich Bluetooth (HM-10 Derivat) und Wifi (ESP8266 ESP-01S Wifi Modul).
Beim Bluetooth-Modul funktioniert die Verbindung nur vom Arduino Richtung Smartphone, in die andere Richtung bekomme ich akutell noch kein Signal auf den Tx des Bluetooth-Moduls (mehrere Apps verwendet)... keine Ahnung warum, aber ich hab die Fehlersuche erstmal aufgegeben.

Deshalb Variante zwei: Wifi... Hier habe ich es schonmal geschafft eine Verbindung über die AT-Befehle aufzubauen. Aber natürlich will ich das ganze irgendwie automatisieren beim Setup. Allerdings gibt es nur Anleitungen wo ich direkt das Wifi-Modul flashen soll, was ich eigentlich nicht will. Lieber wäre es mir die Konfiguration im Code des Arduino vorzunehmen, wo das Modul angeschlossen ist.
Meine erste Idee war, die AT-Befehle über "Serial.Print" zu senden, aber da kommt keine Rückmeldung.

Gibt es eine Anleitung und Library, die direkt auf dem Arduino ausgeführt werden kann und z.B. über die AT-Befehle die Verbindung entsprechend aufbaut ohne dass ich manuell immer die AT Codezeilen senden muss?
Falls ich einmal das Modul Flashen muss wäre es ok, aber die SSID, Passwort, Port, etc. möchte ich für jeden Arduino selbst festlegen.

Edit.: Kann die Eingangsfrage jetzt selbst beantworten. Ich muss jedem AT-Befehl noch einen Zeilenumbruch mitschicken. Mit "println" komme ich der Sache schon näher.
Werde mich trotzdem anschließend in die Programmierung einarbeiten um die Vorteile zu verstehen.

Hallo,

schau dir das mal an link

aber du solltest Deine Entscheidung noch mal überdenken, Spass macht das AT Gedöhns wirklich nicht.

Du solltest eine zweite serielle Schnittstelle dazu nutzen (Softserial), um dich mit den AT befehlen vertraut machen. Fur den Arduino verwendest Du am besten erst mal einen Sketch der das was über Serial rein kommt auf Softserial ausgibt, und umgekehrt. dann kannst Du die Antwort des ESP sehen. Da gibts glaube ich was in den Beispielen.

such mal ESP8266 AT Instruction Set link

Dieses AT “Gedöns” funktioniert bereits, allerdings nur bei Eingabe im Serial Monitor und Übergabe an den Serial2. Die funktion Serial2.print(“AT”) geht nur nicht.
In den Links ist leider kein Beispiel-Code für AT Kommandos.

Werd mir dann doch mal am Steckboard provisorisch einen Flasher aufbauen und mit dem Blink Beispiel usw. ran tasten. Muss dann halt den Code abändern, wenn mein Arduino in einem anderen Haushalt rum fährt. Wenn ich den Code so programmiere, dass diese beiden Werte weiterhin über die serielle Schnittstelle übergeben werden, bevor die WLAN Verbindung aufgebaut wird, hätte ich gegenüber der AT-Firmware wohl kaum was gewonnen.

Warum ist AT eigentlich grundsätzlich eher negativ belastet? Läuft das Modul dadurch instabil oder nervt einfach nur das Einstellen über Serial? Nach dem lästigen Verbindungsaufbau hab ich bei ersten Tests eigentlich alle Daten gut hin und her senden können zwischen App und Arduino.
Aber wahrscheinlich gibt’s dann wohl auch mehr Möglichkeiten als einen einfachen UDP Server für Datenaustausch.

Hallo,

Leider hast Du nciht geschrieben was für einen Arduino du hast, ich gehe jetzt mal von einem UNO aus. Der hat nur eine Hadware Schnittstelle , die liegt auf Pin0 und pin1 . Für eine Software Schnitttstelle benotigst Du eine zus. Lib . Darin gibts ein Beispiel.

unter Beispiele/SoftwareSerial/SoftwareSerial Exampel findest Du das Beispiel um den ESP über den Monitor bedienen zu können. Wenn das zuverlässig funktioniert kanns Du an einen eigene Sketch gehen. Für die Hardware musst Du einen Spannnungsteiler verwenden, der ESP ist 3,3V der Uno 5V Vorschlag dazu findest du im angegeben Link oben.

ich hab da mal in meiner Wühlkiste gesucht und diese alte Beispiel meiner ersten Gehversuche gefunden, weiß aber nicht mehr ob es funktioniert, denke aber ja. Ich weiß auch nicht mehr wo das her ist, es ist auch sicher nicht der Renner und ich würde heute einiges anders machen. Es zeigt aber wie man das ( auch falsch :wink: ) machen kann. Das Beispiel geht davon aus das der ESP bereits ein Netztwerk kennt, die Daten dazu fest hinterlegt sind, und es sich beim starten automatisch mit dem Netzwerk verbindet. Dazu gibt spezielle AT Befehle. Link hatte ich ebenfalls bereits angegeben.

Grudsätzlich gibt es aber sowas auch im Netz zu finde, das Beispiel ist ja nicht auf meinem Mist gewachsen.

#include <SoftwareSerial.h>
#include <SimpleDHT.h>

SoftwareSerial esp(2, 3); // RX, TX

int pinDHT11 = 4;
SimpleDHT11 dht11;

// Variable

unsigned long altzeit = 0;
int cycle = 5000;
int count, conID, action;
float temperatur, humidity ;
boolean debug = true;

void setup() {

  Serial.begin(19200); // eventuell 9600 verwenden für beide hängt vom Modul ab.
  esp.begin(19200);
  esp_setup();


}

void loop() { // run over and over
  String answ;

  if (esp.available()) {

    if (esp.find("+IPD,")) {
      Serial.println("Anfrage agekommen");
      conID = esp.read() - 48;
      delay(300);
      if (esp.find("ACTION=")) {

        action = esp.read() - 48;
        Serial.print("Button Action");
        Serial.println(action);
        //IP_close();
      }
      else {
        create_htlm();
      }

    }
  }

  if (millis() > ( altzeit + cycle)) {
    read_temperatur();
    altzeit = millis();
  }

}

void read_temperatur() {
  byte temp = 0;
  byte hum = 0;
  byte data[40] = {0};
  if (dht11.read(pinDHT11, &temp, &hum, data)) {
    Serial.println("Read DHT11 failed");
    return;
  }

  // Nachkomma von Temperatur lesen bit 24-31
  byte dectemp = 0;
  for (int i = 31; i > 23; i--) {
    bitWrite(dectemp, 31 - i, int(data[i]));
  }
  // Nachkomma dazu addiern und 2 grad offset abziehen+
  temperatur = temp + float(dectemp) / 10 - 3.5;
  humidity = hum;
}


void esp_setup() {

  esp_senden("ATE0\r\n", 1000, debug);
  esp_senden("AT+CWMODE=1\r\n", 1000, debug);
  esp_senden("AT+CWJAP?\r\n", 1000, debug);
  esp_senden("AT+CIPMUX=1\r\n", 1000, debug);
  esp_senden("AT+CIPSERVER=1,80\r\n", 1000, debug);
  esp_senden("AT+CIPSTA?\r\n", 1000, debug);

}

void create_htlm() {
  String buf = "";
  String cmd = "";
  String answ = "";

  // htlm Seite bilden
  buf += "<!DOCTYPE html><html><head></head>";
  buf += "<body>";
  buf += "<h1>Temperatur und Luftfeuchte</h1>";
  buf += "<h1>";
  buf += "Temperatur ";
  buf += temperatur;
  buf += "&#x2103";
  buf += "
";
  buf += "Luftfeuchte  ";
  buf += humidity;
  buf += "%";
  buf += "</h1>";

  buf += "<form>";
  buf += "<button style= \"width:120px\" name=\"ACTION\" value=\"1\"";
  buf += ">Ein</button>";
buf+="  ";
  buf += "<button style= \"width:120px\" name=\"ACTION\" value=\"2\"";
  buf += ">Aus</button>";


  buf += "</form>
";
  buf += "</body></html>";



  // SendeAuftrag

  cmd += "AT+CIPSEND=";
  cmd += conID;
  cmd += ",";
  cmd += buf.length();
  cmd += "\r\n";

  answ = esp_senden(cmd, 2000, debug);// sende aufrag
  delay(50);
  answ = esp_senden(buf, 2000, debug);// Seite senden
  
  IP_close();

}
void IP_close() {
  // schließen
 delay(100);
 String cmd = "";
  cmd += "AT+CIPCLOSE=";
  cmd += conID;
  cmd += "\r\n";
  String answ = esp_senden(cmd, 2000, debug);
}

void Create_Header(){
String buff="";
buf+="HTTP/1.1 200\r\n";
//-------------------------------------------------------------------

  
}


String esp_senden(String daten, int timeout, boolean debug) {

  if (debug) {
    // Serial.println(daten);
  }
  String ecar = "";
  esp.print(daten);
  delay(50);
  unsigned long time = millis();
  while (time + timeout > millis()); {
    while (esp.available () ) {
      char z = (esp.read());
      ecar += z;
    }
  }
  if (debug) {
    Serial.println(ecar);
  }
  return ecar;
}

Um den ESP8266-01 direkt mit der Arduino IDE und einem eigenen Sketch betreiben zu können benötigst Du die Erweiterung für die IDE und einen USB/Serial Konverter. Für Anfänger ist das auch ein bischen umständlich und geht nicht ohne zus. Bastelei. Einfacher ist ein ESP8266 WemosD1 oder jedes andere Board mit einer USB Schnittstelle drauf. Der ESP8266 Lolin NodeMcu Vers.3 hat einen Nachteil. Er ist zu breit, passt zwar noch auf ein normales Steckbrett, aber Du bekommst links und recht keinen Draht mehr dazu gesteckt. Lösung zwei Bretter nebenainander.

Die Sache mit dem eignen Haushalt ! Na ja du kannst das letzlich so machen das er sich in einem bekannten Netztwerk einloggen will, Wenn er das nicht findet spannt er ein eigens Netztwerk mit eigenr feste IP Adresse auf und stellt eine Webseite zur Verfügung. Darin kannst Du z.B mit dem Handy die Zugangsdaten eingeben mit denen er sich normal verbinden soll.

ich finde die AT Funktionen ziemlich kompliziert, das geht direkt mit einen Sketch alles wesentlich einfacher und zuverlässiger. Zudem hat der Uno ziemlich wenig Speicher. Da ist man schnell am Ende angekommen. Mit einem ESP ist das Thema Speicher so schnell kein Problem. Nachteil gibts natürlich auch, alles ist für 3,3V . Einiges an Zubehör läuft jedoch auch mit beiden Spannungen. Ansonsten müsst Du bei den Arduino Teilen bleiben und Shield´s verwenden.

Heinz

@Renter:
Achso, du meinst, besser ist, das ganze Programm auf einen ESP8266 zu erstellen?
Ich habe einen 5V Adapter bereits mitbestellt, da wird der EPS8266 nur drauf gesteckt und gleich auf die 4 Pins 5V, GND und Rx/Tx reduziert.
Ich will eigentlich nur irgendwie zwischen einer APP und einem Arduino (UNO bzw. MEGA) Daten hin und her schaufeln, da die Arduino meine Haupt"spielzeuge" sind.

Ich hab auch mittlerweile eine kleine Bibliothek geschrieben, das meine Befehle auf einen Hardware-Serial (aktuell noch festem Serial2) sendet und die Antwort kommentiert. Rückgabewert ist "True" für erfolgreiche Rückmeldung oder "False" für Fehler oder Timeout. Ich habe hier eine eigens Timer-Objekt namens "WifiTimer", der aktuell auf 5s begrenzt ist.

ool AT_handshake(char ATstr[])
    {
      Serial2.println(ATstr);
      Serial.print("    >> Send *");
      Serial.print(ATstr);
      Serial.print("*  ...  ");
      String Str = "";
      WifiTimer.Start();
      while(true)
      {
        if(Serial2.available())
        {
          Str = Serial2.readString();
          if(Str.indexOf("OK")) 
          {
            Serial.println("OK");
            return true;
            break;
          }
          else if (Str.indexOf("ERROR"))
          {
            Serial.println("ERROR");
            return false;
            break;
          }
          else if(WifiTimer.Finished())
          {
            Serial.println("TIMEOUT");
            return false;
            break;
          }
        }
      }
    }

Was ich aber jetzt schon merke: Während des Sendens bremst es meine Loop imens ein. Ich habe hier mehrere Baustellen, die möglicherweise Schuld sind:

  • Eine Serial.ReadString() Funktion scheint mir mehr Zeit in Anspruch zu nehmen, warum auch immer.
    Ich werde dies mit Array, Forschleife und Serial.Read ersetzen.
  • String brauchen gefühlt länger, wenn ich diese mit den String-Operatoren zusammen baue.
  • Die ganzen Schleifen bremsen mein System sehr stark aus. Bin noch am überlegen ob ich das eleganter löse, da zwischen Senden von AT-Befehle und Rückmeldung aktuell nur warte. Leider muss der Befehl AT_CIPSEND zweimal ausgeführt werden, bevor die Daten geschickt werden.