NodeMCU, LED & static IP
Na mreži se može naći dosta tutorijala o tome kako programirati NodeMCU i
kako upravljati modulima preko web pregledača. Svi su uglavnom sa
dinamičkom IP adresom što kao tutorijal i nije loše ali za pravljenje
stand alone projekta nije dobro. Svakim resetovanjem rutera se u tom
slučaju IP adresa menja i dolazimo u situaciju da svaki put nakon
resetovanja teba da priključimo NodeMCU sa računarom da bi videli novu
IP adresu. Rešenje je u statičkoj IP adresi u okviru kućne mreže.
Sastojci za ovaj recept su:
NodeMCU v1.0
Dupont žice
Breadboard
LED
Povezivanje
prema šemi. Pinovi se, naravno mogu koristiti po želji. Ja sam
upotrebio D7 i D8, što će reći GPIO13 i GPIO15. Obratite samo pažnju
prilikom povezivanja LED. Anoda je duža (+) a katoda je kraća (-).
Na
redu je skeč. Standardno na početku dodajemo biblioteku za rad sa
ESP8266 modulom. Dalje popunjavamo SSID i lozinku naše kućne mreže.
Sledeće na redu su adrese. U prvom redu postavljamo statičnu IP adresu.
Prilikom odabira ove adrese treba imati na umu limite rutera i broj
priključenih wi-fi uređaja. Postavljamo gateway i subnet adrese prema
našem ruteru. Dalje je definisanje izlaznih pinova i promenljivih koje
će nam kasnije trebati. Na kraju pokrećemo WIfi server. U void setup sekciji postavljamo izlazne pinove na LOW, povezujemo modul na mrežu i sve to ispisujemo na serijal monitor. Serial.println(ip) bi morala da ispiše istu onu adresu koju smo postavili iznad. U void loop
sekciji osim ispisivanja trenutnog stanja modula na serijal monitoru
što je bitno za otklanjanje eventualnih grešaka, menjamo stanje izlaznih
pinova. U zavisnosti šta je poslato preko web pregledača, menjamo svaki
pin sa LOW na HIGH i obrnuto. Sledeće na redu je postavljanje html
stranice. Za to koristimo client.println funkciju. Stranica se može formatirati po želji ali se mora voditi računa o upotrebi navodnika (").
-----------------------------------------------
#include <ESP8266WiFi.h>
const char* ssid = "xxxxxxxxxxxxxxx"; // ssid
const char* password = "xxxxxxxxxxxxx";// password
IPAddress ip(192, 168, 0, 107); //set static ip
IPAddress gateway(192, 168, 0, 1); //set getteway
IPAddress subnet(255, 255, 255, 0);//set subnet
int led1 = 13; // GPIO13
int led2 = 15; // GPIO15
int stat1;
int stat2;
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
pinMode(led1, OUTPUT);
digitalWrite(led1, LOW);
pinMode(led2, OUTPUT);
digitalWrite(led2, LOW);
// Connection to wireless network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
server.begin();
Serial.println("Server started");
// Print the IP address in serial monitor. It must be the same we entered above
Serial.print("Type this address in URL to connect: ");
Serial.print("http://");
Serial.println(ip);
Serial.println("/");
}
void loop() {
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String request = client.readStringUntil('r');
Serial.println(request);
client.flush();
// engine
int stat1 = 0;
if (request.indexOf("/led1=on") != -1) {
digitalWrite(led1, HIGH);
stat1 = 1;
}
if (request.indexOf("/led1=off") != -1) {
digitalWrite(led1, LOW);
stat1 = 0;
}
int stat2 = 0;
if (request.indexOf("/led2=on") != -1) {
digitalWrite(led2, HIGH);
stat2 = 1;
}
if (request.indexOf("/led2=off") != -1) {
digitalWrite(led2, LOW);
stat2 = 0;
}
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("");
client.println("<!DOCTYPE HTML>");
client.println("<head>");
client.println("<meta charset='UTF-8'>");
client.println("<style>");
client.println(" a {background:#F44336; color:white; padding:25px;
text-decoration:none; display:inline-block; width:50%; margin: 20px;
text-align:center;}");
client.println("</style>");
client.println("</head>");
client.println("<html>");
client.println("<div align="center">");
/// led1 part. GUI, etc
client.print("LED je sada ");
if(stat1 == 1) {
client.print("upaljena");
} else {
client.print("ugašena");
}
client.println("<br><br>");
client.println("<a href="/led1=on" >Upali </a>");
client.println("<a href="/led1=off">Ugasi </a><br />");
client.println("<br><br>");
///led2 part. GUI, etc
client.print("LED je sada ");
//if(value == HIGH) {
if(stat2 == 1){
client.print("upaljena");
} else {
client.print("ugašena");
}
client.println("<br><br>");
client.println("<a href="/led2=on">Upali </a>");
client.println("<a href="/led2=off">Ugasi </a><br />");
client.println("</div>");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}
-----------------------------------------------
Kucanjem
IP adrese u URL web pregledača dolazimo do html stranice koju smo
napravili. Možemo joj pristupiti preko bilo kog računara, tableta,
mobilnog telefona... dokle god koriste isti ruter. Bez obzira da li će
se ruter iz nekog razloga restartovati, IP adresa će ostati ista.
Kao
što vidite, u pitanju je prost projekat sa dosta prostora za
proširivanje. Uz osnovno znanje web progamskih jezika se GUI može
napraviti po želji. Ja sam kao primer dodao osnovni CSS, podršku za UTF8
slova, ali u principu se stranica može formatirati kako god želite. Za
neki eventualni projekat koji će se koristiti na duže staze, trebalo bi
razmisliti o responsivnom templejtu zbog ekrana mobilnih uređaja. Moj
mali propust je ispisivanje stanja LED u okviru web pregledača, gde
postoji mali bag kada se nakon prve upali druga LED. To zahteva upotrebu
sesija i vreme za neophodno programiranje a moj dugo očekivani godišnji
odmor je konačno došao. Budite slobodni da korigujete skeč po volji i
da ispravke postavite ispod. Neću se ljutiti.
Toliko od mene do sledećeg skeča.