[ESP8266 #1] Migamy diodą
: 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
Potrzebować będziemy
Podłączenie
Wszystko łączymy dokładnie tak jak w ostatnim artykule, czyli tak:

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:

Czyli gra gitara, moduł jest chętny i gotowy
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
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:
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:
Ważne jest żeby akcje na stronie wykonywać w momencie kiedy w konsoli/monitorze zobaczymy:
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:

Po kliknięciu zmienia się stan diody, przetestowane
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
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.
i w miejscu
Wpisujemy

Po zatwierdzeniu OK lecimy dodać płytkę.
Wyszukujemy i instalujemy esp8266 platform

Teraz wybieramy płytkę ESP

No to co, wszystko mamy skonfigurowane, czas na prostego BLINK'a!
Ten kod jest przykładem który znajdziecie w Arduino IDE, jest tam też webserwer i pare innych więc polecam zajrzeć
Ustawiamy parametry tak jak na obrazku

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

sam kod prezentuje się tak:
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.
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
Potrzebować będziemy
- jakieś Duino,
- kubek kawy,
- pare kabli
- ESP8266
Podłączenie
Wszystko łączymy dokładnie tak jak w ostatnim artykule, czyli tak:

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());
}
Czyli gra gitara, moduł jest chętny i gotowy
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ść
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:

Po kliknięciu zmienia się stan diody, przetestowane
Zmiana softu w ESP8266
Najpierw zaczniemy od podstaw czyli znów migamy diodami, w sumie to diodą, jedną na razie
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

Po zatwierdzeniu OK lecimy dodać płytkę.
Narzędzia -> Płytka: -> Menedżer płytek
Wyszukujemy i instalujemy esp8266 platform

Teraz wybieramy płytkę ESP
Narzędzia -> Płytka -> Generic ESP8266 Module

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ć
Ustawiamy parametry tak jak na obrazku

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

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