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

