[ESP8266 #1] Migamy diodą

Pozostałe układy mikrokontrolerów, układy peryferyjne i inne, nie mieszczące się w powyższych kategoriach.
Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

[ESP8266 #1] Migamy diodą

Postautor: inż.wielki » niedziela 03 kwie 2016, 22:33

Dzień Dobry, Hello, Guten Tag, доброе утро, dobrý den, おはよう.

Uff.. to najbardziej merytoryczną część tego artykułu mamy już za sobą, przejdźmy zatem do ulubionego zajęcia jednego zielonego łosia, czyli migania diodami :P
Potrzebować będziemy
  • jakieś Duino,
  • kubek kawy,
  • pare kabli
  • ESP8266
Jeżeli na Twoim Duino nie ma diody, to potrzebujesz też diody i opornika 220Ω.

Podłączenie

Wszystko łączymy dokładnie tak jak w ostatnim artykule, czyli tak:
Obrazek

W naszym przypadku linie RX i TX podłączamy do Arduino UNO R3, do pinów D2(RX) i D3(TX).
[WAŻNE]Poziom zasilania na pinach RX i TX typowego Arduino to 5V, przed podłączeniem sprawdź w dokumentacji jakie poziomy toleruje Twój układ i jeżeli potrzeba zastosuj konwerter poziomów [/WAŻNE]

Szybki test jak ostatnio, czyli:

Kod: Zaznacz cały

#include <SoftwareSerial.h>

SoftwareSerial ESPSerial(2,3);

void setup()
{
ESPSerial.begin(9600);
Serial.begin(9600);
while (!Serial);
}

void loop()
{
if (ESPSerial.available())
Serial.write(ESPSerial.read());
if (Serial.available())
ESPSerial.write(Serial.read());

}


Obrazek

Czyli gra gitara, moduł jest chętny i gotowy :D Na czerwono znów zaznaczyłem opcje które trzeba ustawić, to ważne przy pisaniu komend AT. Napiszmy sobie pierwszą stronę HTML.

WebServer na arduino

Kod: Zaznacz cały

   String     webpage =  "<html>"
                          "<body>"
                          "<form action=\"update.html\" method=\"get\">"
                          "<fieldset>"
                          "<legend>LED State</legend>"
                          "<input type=\"radio\" name=\"LedState\" value=\"Led_ON\"> ON"
                          "<input type=\"radio\" name=\"LedState\" value=\"Led_OFF\" checked=\"checked\"> OFF<br>"
                          "</fieldset>"
                          "<input type=\"submit\" value=\"Submit\">"
                          "</form>"
                          "</body>"
                          "</html>";


Generalnie korzystamy dalej z kodu z ostatniego artykułu, dodajemy tylko funkcjonalność ;) W kodzie powyżej mamy prosty formularz w HTML wysyłany metodą GET z 1 parametrem, czyli statusu naszej diody. No to lecimy dalej, kod pętli teraz będzie wyglądać tak:

Kod: Zaznacz cały

void loop()
{

  if (esp8266.available()) // check if the esp is sending a message
  {

    if (esp8266.find("+IPD,"))
    {

      String html;
     
      //delay(1000);
      int connectionId = esp8266.read() - 48;
      if (esp8266.find("update.html?LedState="))
      {
        int State = esp8266.read() - 48;
        if (!State)
        {
          digitalWrite(13, LOW);   // turn the LED on (HIGH is the voltage level)
          Serial.println("OFF");
        }
        else if (State)
        {
          Serial.println("ON");
          digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
        }

        html =  "<html>"
                   "<body>"
                   "<h1> Data Update</h1>"
                   "<a href=\"index.html\">powrot</a>"
                   "</body>"
                   "</html>";
      }
      else
      {
        html =  "<html>"
                   "<body>"
                   "<form action=\"update.html\" method=\"get\">"
                   "<fieldset>"
                   "<legend>LED State</legend>"
                   "<input type=\"radio\" name=\"LedState\" value=\"1\"checked=\"checked\"> ON"
                   "<input type=\"radio\" name=\"LedState\" value=\"0\"> OFF<br>"
                   "</fieldset>"
                   "<input type=\"submit\" value=\"Submit\">"
                   "</form>"
                   "</body>"
                   "</html>";
      }

      String SendCommand = "AT+CIPSEND=";
      SendCommand += connectionId;
      SendCommand += ",";
      SendCommand += html.length();
      SendCommand += "\r\n";
      sendData(SendCommand, 1000, DEBUG);
      sendData(html, 1000, DEBUG);

      delay(1000);
      String closeCommand = "AT+CIPCLOSE=";
      closeCommand += connectionId; // append connection id
      closeCommand += "\r\n";

      sendData(closeCommand, 3000, DEBUG);


    }
  }
}


Mamy tutaj 2 nowe rzeczy, a dokładniej warunki, sprawdzamy o którą stronę prosi nas przeglądarka. Mamy 2 możliwości, albo update.html, gdzie w adresie dostajemy informacje o statusie diody LED, oraz inne strony, każda inna strona spowoduje że dostaniemy się na stronę główną z "panelem sterowania" diodą. Myślę że teraz każdy już wie i widzi jak proste jest tworzenie bardziej zaawansowanych aplikacji z wykorzystaniem ESP i WWW.
A tutaj cały kod:

Kod: Zaznacz cały

#include <SoftwareSerial.h>

#define DEBUG true

SoftwareSerial esp8266(2, 3); // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
// This means that you need to connect the TX line from the esp to the Arduino's pin 2
// and the RX line from the esp to the Arduino's pin 3

void ESP8266_Init();

void setup()
{
  Serial.begin(9600);
  esp8266.begin(9600); // your esp's baud rate might be different

  ESP8266_Init();

  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
}

void loop()
{

  if (esp8266.available()) // check if the esp is sending a message
  {

    if (esp8266.find("+IPD,"))
    {

      String html;
     
      //delay(1000);
      int connectionId = esp8266.read() - 48;
      if (esp8266.find("update.html?LedState="))
      {
        int State = esp8266.read() - 48;
        if (!State)
        {
          digitalWrite(13, LOW);   // turn the LED on (HIGH is the voltage level)
          Serial.println("OFF");
        }
        else if (State)
        {
          Serial.println("ON");
          digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
        }

        html =  "<html>"
                   "<body>"
                   "<h1> Data Update</h1>"
                   "<a href=\"index.html\">powrot</a>"
                   "</body>"
                   "</html>";
      }
      else
      {
        html =  "<html>"
                   "<body>"
                   "<form action=\"update.html\" method=\"get\">"
                   "<fieldset>"
                   "<legend>LED State</legend>"
                   "<input type=\"radio\" name=\"LedState\" value=\"1\"checked=\"checked\"> ON"
                   "<input type=\"radio\" name=\"LedState\" value=\"0\"> OFF<br>"
                   "</fieldset>"
                   "<input type=\"submit\" value=\"Submit\">"
                   "</form>"
                   "</body>"
                   "</html>";
      }

      String SendCommand = "AT+CIPSEND=";
      SendCommand += connectionId;
      SendCommand += ",";
      SendCommand += html.length();
      SendCommand += "\r\n";
      sendData(SendCommand, 1000, DEBUG);
      sendData(html, 1000, DEBUG);

      delay(1000);
      String closeCommand = "AT+CIPCLOSE=";
      closeCommand += connectionId; // append connection id
      closeCommand += "\r\n";

      sendData(closeCommand, 3000, DEBUG);


    }
  }
}

void ESP8266_Init()
{

  sendData("AT+RST\r\n", 1000, DEBUG); // reset module
  delay(1000);

  sendData("AT+CWMODE_CUR=3\r\n", 1000, DEBUG); // configure as access point
  delay(1000);
  sendData("AT+CWJAP_CUR=\"UPC0045472\",\"AAAAAAQA\"\r\n", 1000, DEBUG); // get ip address
  while (1)
  {
    if (esp8266.available() && esp8266.find("OK"))
    {
      Serial.print("CONNECTED\n\r");
      break;
    }
  }

  sendData("AT+CIPMUX=1\r\n", 1000, DEBUG);

  sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); // turn on server on port 80
  delay(1000);
  sendData("AT+CIFSR\r\n", 1000, DEBUG); // turn on server on port 80
}

String sendData(String command, const int waitForResponse, boolean debug)
{
  String response = "";

  esp8266.print(command); // send the read character to the esp8266

  long int time = millis();

  while ( (time + waitForResponse) > millis())
  {
    while (esp8266.available())
    {

      char znak = esp8266.read();
      response += znak;
    }
  }

  if (debug)
  {
    Serial.print(response);
  }

  return response;
}


Ważne jest żeby akcje na stronie wykonywać w momencie kiedy w konsoli/monitorze zobaczymy:
AT+CIPCLOSE=0

0,CLOSED

Z racji tego że wykorzystujemy bardzo blokujący system debagowy oraz blokujemy procesor czekając na pakiety to wszystko odbywa się bardzo wolno. Następne kody postaram się pisać w bardziej zoptymalizowany sposób, jednak by dalej można było je łatwo zrozumieć :)

A tutaj efekt:
Obrazek

Po kliknięciu zmienia się stan diody, przetestowane :D Zabierzemy się teraz do tego co tygryski lubią najbardziej, czyli własny firmware :)

Zmiana softu w ESP8266

Najpierw zaczniemy od podstaw czyli znów migamy diodami, w sumie to diodą, jedną na razie :P
Software można pisać albo w języku LUA, Arduinowym oraz C. Na dzień dzisiejszy zajmiemy się pisaniem w Arduinowym IDE z racji tego że LUA nie znam, a czysty język C mógłby trochę zamieszać a chcę utrzymać jak najprostszy i najczytelniejszy poziom tego kursu.

Znów podłączamy nasz układ do przejściówki UART/USB, należy pamiętać o sygnale GND, o czym nie wspomniałem w ostatniej części, a pin GPIO0 do GND. Kiedy już to zrobimy to uruchamiamy arduino IDE zaczynamy od dodania nowego linku dla menedżera płytek.
Plik -> Preferencje

i w miejscu
Dodatkowe adresu URL dla menedżera płytek

Wpisujemy
http://arduino.esp8266.com/stable/package_esp8266com_index.json


Obrazek

Po zatwierdzeniu OK lecimy dodać płytkę.

Narzędzia -> Płytka: -> Menedżer płytek


Wyszukujemy i instalujemy esp8266 platform

Obrazek

Teraz wybieramy płytkę ESP

Narzędzia -> Płytka -> Generic ESP8266 Module


Obrazek

No to co, wszystko mamy skonfigurowane, czas na prostego BLINK'a!

Kod: Zaznacz cały

/*
 ESP8266 Blink by Simon Peter
 Blink the blue LED on the ESP-01 module
 This example code is in the public domain
 
 The blue LED on the ESP-01 module is connected to GPIO1
 (which is also the TXD pin; so we cannot use Serial.print() at the same time)
 
 Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
*/

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
                                    // but actually the LED is on; this is because
                                    // it is acive low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}


Ten kod jest przykładem który znajdziecie w Arduino IDE, jest tam też webserwer i pare innych więc polecam zajrzeć :P

Ustawiamy parametry tak jak na obrazku

Obrazek

I wgrywamy, w ten oto sposób zaprogramowaliśmy ESP żeby działał tak jak chcemy. W przypadku kiedy chcemy powrócić do komend AT trzeba wgrać firmware zgodnie z tym co opisałem w poprzedniej części. No to czas wyłączyć ESP i podłączyć spowrotem zasilanie, powinniśmy zaobserwować miganie LED. Z racji tego że na różnych modułach LED jest przypięty pod różnymi pinami trzeba doświadczalnie poszukać, u mnie okazało się że zamiast mrygać diodą to machałem pinem TX ;) UWAGA na piny GPIO0 GPIO2 i GPIO15 które obecnie mamy zwarte do zasilania/masy. Napiszemy sobie jeszcze jeden programik który będzie realizował to samo zadanie jak ten w Arduino. Wykorzystamy kod z przykładu: HELLOSERVER.
Po wgraniu, standardowo, zasilanie wyłączamy i włączamy ponownie, pewnie się zastanawiasz czemu nie ruszamy GPIO0, okazało się że GPIO0 po wgraniu swojego programu nie może być ściągnięty do GND i soft dalej działa. Odpalamy sobie jeszcze monitor albo konsolkę i tam obserwujemy coś takiego

Obrazek

sam kod prezentuje się tak:

Kod: Zaznacz cały

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "";
const char* password = "";

ESP8266WebServer server(80);

String webpage =  "<html>"
                  "<body>"
                  "<form action=\"/update\" method=\"GET\">"
                  "<fieldset>"
                  "<legend>LED State</legend>"
                  "<input type=\"radio\" name=\"LedState\" value=\"Led_ON\"> ON"
                  "<input type=\"radio\" name=\"LedState\" value=\"Led_OFF\" checked=\"checked\"> OFF<br>"
                  "</fieldset>"
                  "<input type=\"submit\" value=\"Submit\">"
                  "</form>"
                  "</body>"
                  "</html>";

const int led = 13;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/html", webpage);
  digitalWrite(led, 0);
}

void handleNotFound() {
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void) {
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/update", []() {

    if (server.hasArg("LedState"))
    {
      for (uint8_t i = 0; i < server.args(); i++)
      {
        if(server.argName(i) == "LedState")
        {
          if(server.arg(i) == "Led_ON")
          {
              digitalWrite(led, 0);
                server.send(200, "text/plain", "Led status: "+server.arg(i));
                break;
          }
          if(server.arg(i) == "Led_OFF")
          {
              digitalWrite(led, 1);
              server.send(200, "text/plain", "Led status: "+server.arg(i));
              break;
          }
        }
      }
    }

  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
}


Jest go więcej niż w wersji z Arduino, jednak ma większe możliwości i łatwiej się go używa, trzeba posiłkować się jakimiś przykładami w internecie ale idzie to zrozumieć. To by było na tyle. Następne odcinki będą już nastawione stricte na jakiś projekt, myślę że zrobimy sobie prostą stację pogodową z jednym czujnikiem zewnętrznym opartą o 2 ESP i arduino :) Do następnego.

StaryAnoda

Re: [ESP8266 #1] Migamy diodą

Postautor: StaryAnoda » poniedziałek 04 kwie 2016, 11:16

Noooo gratuluję świetnego artykułu !
Widać, że doświadczony konstruktor i programista, chyba pracuje w NASA !
Jeszcze raz gratulację i czekamy na więcej

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: [ESP8266 #1] Migamy diodą

Postautor: inż.wielki » poniedziałek 04 kwie 2016, 11:18

StaryAnoda pisze:Noooo gratuluję świetnego artykułu !
Widać, że doświadczony konstruktor i programista, chyba pracuje w NASA !
Jeszcze raz gratulację i czekamy na więcej

Cicho! To miała być tajemnica, teraz mnie wyrzucą :lol:
I dziękuje bardzo za słowa uznania ;)

Awatar użytkownika
matty24
User
User
Posty: 333
Rejestracja: sobota 31 paź 2015, 20:11
Lokalizacja: Małopolska

Re: [ESP8266 #1] Migamy diodą

Postautor: matty24 » wtorek 05 kwie 2016, 14:17

Działało Ci dobrze to mruganie diodą przez przeglądarkę? Bo u mnie tylko zaświeci ale już nie zgasi jej. Po restarcie jest domyślnie zgaszona, a potem co bym nie zaznaczył to się zapali i już jej nie zgasi.
Tak jakby zawsze był wykonywany warunek pierwszy:
if(data.indexOf("Led_ON")) digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
else if(data.indexOf("Led_OFF")) digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level)

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: [ESP8266 #1] Migamy diodą

Postautor: dambo » wtorek 05 kwie 2016, 18:57

Jakby ktoś chciał jakieś efekty proste na stronkę dodać to bez problemu można użyć tu np. jQuery
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: [ESP8266 #1] Migamy diodą

Postautor: inż.wielki » czwartek 07 kwie 2016, 12:49

matty24 pisze:Działało Ci dobrze to mruganie diodą przez przeglądarkę? Bo u mnie tylko zaświeci ale już nie zgasi jej. Po restarcie jest domyślnie zgaszona, a potem co bym nie zaznaczył to się zapali i już jej nie zgasi.


Racja, w kodzie był błąd a ja przy testowaniu spojrzałem nie na tą diodę, mój błąd, kod już jest zaktualizowany i teraz działa bez żadnych problemów :)

Awatar użytkownika
phill2k
User
User
Posty: 288
Rejestracja: niedziela 18 paź 2015, 00:12

Re: [ESP8266 #1] Migamy diodą

Postautor: phill2k » piątek 10 cze 2016, 10:48

Coś obrazki poszły w buraki ;) , prośba do autora może by je na forum załadować - tak na przyszłość żeby się znowu nie porozłaziły :D - wartościowy tekst, szkoda by było, a bez screen'ów to trochę takie kulawe jest. W części dot. wprowadzenia też występuje ten efekt - [ESP8266] Krótkie wprowadzenie - nie sprawdzałem inny poradników.


Wróć do „Inne mikroklocki, również peryferyjne”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości