Skip to main content

6.2 Upravljanje LED-icom preko Wi-Fija

U 6.1 Povezivanje i dohvat podataka pločica je bila ta koja pita: pridružila se tvojoj Wi-Fi mreži, zatražila stranicu s web sjedišta i ispisala odgovor. Ovaj primjer to prevrće. Pločica je sada ona koju se pita. Postaje mali web server za sebe, a stranica koju otvoriš na mobitelu ili računalu pali i gasi pravu LED-icu.

Ništa oko same LED-ice nije novo. To je ista LED-ica, isti otpornik od 330 Ω i isti digitalWrite() koje koristiš od 1.2 Blinkanje LED-ice. Novo je odakle uputa dolazi. Umjesto da je unaprijed upisana u skicu, dolazi preko mreže onog trenutka kada netko pritisne tipku.

U ovoj dokumentaciji naučit ćeš:

  • Razliku između klijenta i servera, i zašto je ovaj primjer obrnut od 6.1.
  • Što je obrađivač (handler), i kako server.on() spaja web adresu s funkcijom u tvojoj skici.
  • Kako mDNS pločici daje ime, pa možeš upisati nulamini.local umjesto reda brojeva.
  • Zašto server.handleClient() mora nastaviti raditi u loop(), i što se lomi ako prestane.
  • Kako nekoliko linija JavaScripta unutar stranice same drže liniju statusa svježom.

Potreban hardver:

  • 1x Soldered NULA MINI pločica
  • 1x Breadboard
  • 1x LED-ica (bilo koje boje)
  • 1x otpornik od 330 Ω
  • 3x Jumper žice
  • 1x USB-C kabel
  • Wi-Fi mreža, i mobitel ili računalo pridruženo njoj
ℹ️
Otpornik od 330 Ω nije neobavezan. LED-ica gotovo da nema vlastitog otpora, pa bez ičega što bi ograničilo struju vuče daleko više nego što su LED-ica ili pin građeni izdržati, i oboje se može oštetiti. Otpornik ide serijski s LED-icom, jedan za drugim u istom lancu, i nije važno kojim je krajem okrenut. Prstenovi mu se čitaju narančasti-narančasti-smeđi.
⚠️
Ovom primjeru ne treba veza s internetom. Za razliku od 6.1, ovdje ništa ne poseže prema web sjedištu. Pločica i uređaj s kojeg pregledavaš moraju biti samo na istoj lokalnoj mreži, razgovarajući međusobno preko tvog routera. Ta razlika je u praksi važna: gostinska mreža, ili bilo koja mreža s uključenom izolacijom klijenata, namjerno sprječava uređaje da vide jedan drugoga. Pločica će se povezati, Serial Monitor će prijaviti uspjeh, a stranica će se i dalje odbijati otvoriti. Ako se to dogodi, stavi oboje na običnu kućnu mrežu ili hotspot mobitela.

Spajanje komponenti

ℹ️
Ovaj primjer doseže samo dva pina na pločici: IO4 u redu 27 i GND u redu 30, oba na f–j strani. Tijelo pločice prekriva stupce f–i, pa su j27 i j30 rupice u koje stvarno možeš uvesti žicu. Sve ostalo odvija se dalje duž iste f–j strane, dobro odmaknuto od pločice.
⚠️
Red 27 postoji s obje strane pločice. Na f–j strani red 27 je IO4, a to je pin koji ovom primjeru treba. Na a–e strani taj isti red 27 je IO19, potpuno drugi pin. Nisu spojeni međusobno. Broji svoje redove na f–j strani, onoj gdje silkscreen piše IO2 IO3 IO4 IO5 3V3 GND.

1. Umetni NULA MINI pločicu na breadboard

ℹ️
Ovaj korak pretpostavlja da znaš kako je breadboard spojen iznutra i što su njegove naponske vodilice (power rails). Za uvod pogledaj stranicu dokumentacije Osnove breadboarda.

Utisni pločicu u jedan kraj breadboarda tako da njezina dva reda pinova sjednu s obje strane središnjeg kanala, s čipom okrenutim prema dolje. Zauzet će redove 25 do 30.

NULA MINI pločica postavljena na breadboard, zauzima redove 25 do 30
Korak 1: pločica postavljena na breadboard, s IO4 u redu 27 i GND u redu 30

2. Izvedi IO4 u slobodan red

IO4 je pin koji će pobuđivati LED-icu, a pločica prekriva cijeli red 27 osim krajnje rupice. Zato prva žica samo nosi taj pin nekamo gdje možeš raditi: jumper žica iz j27 duž do j19.

Plava jumper žica ide duž stupca j iz reda 27 u red 19
Korak 2: IO4 izveden iz j27 u j19

3. Dodaj otpornik od 330 Ω

Otpornik je sljedeći član lanca. Postavi ga tako da premosti red 19, red u koji je jumper žica upravo došla, i red 14, oba na f–j strani.

Otpornik od 330 ohma premošćuje redove 19 i 14 na strani f do j
Korak 3: otpornik od 330 Ω premošćuje redove 19 i 14
ℹ️
Važan je samo broj reda, a ne slovo. Svih pet rupica jednog reda na f–j strani su jedna jedina spojna točka unutar breadboarda. Zato fotografija pokazuje jumper žicu u j19 a otpornik u i19, različite rupice u istom redu, pa su već spojeni. Odaberi onu rupicu do koje nožice tvoje komponente ugodno dosežu.
ℹ️
Otpornik nema polaritet, pa nije važno kojim je krajem okrenut. Nožice su mu dugačke i lako se savijaju, i zato se izvijaju preko površine umjesto da idu ravno. To je u redu, dokle god je svaki kraj čvrsto utisnut u svoju rupicu.

4. Dodaj LED-icu

LED-ica nastavlja lanac: njezina duga nožica (anoda) u red 14, isti red u kojem otpornik završava, i njezina kratka nožica (katoda) u red 12.

LED-ica dodana, s jednom nožicom u redu 14 uz otpornik i drugom u redu 12
Korak 4: LED-ica na mjestu, duga nožica prema otporniku
⚠️
Postavi LED-icu na pravu stranu. LED-ica propušta struju samo u jednom smjeru. Duga nožica mora biti okrenuta prema otporniku i IO4; kratka nožica mora biti okrenuta prema masi. Okrenuta obrnuto, jednostavno se neće upaliti. Ništa se neće pokvariti, ali se ni ništa neće dogoditi. Ako nožice ne možeš razlikovati po dužini, potraži ravni zarez na rubu plastičnog tijela: nožica na toj strani je kratka.

5. Spoji LED-icu i pločicu na masu

Dvije jumper žice zaokružuju krug, i obje idu na plavu vodilicu, koja djeluje kao dijeljena linija mase:

  • Iz reda 12, gdje sjedi kratka nožica LED-ice, do plave vodilice.
  • Iz j30 (GND) do te iste vodilice.
Dvije narančaste jumper žice, jedna iz reda 12 i jedna iz j30, obje idu na negativnu vodilicu
Korak 5: LED-ica i GND pin pločice oboje vezani na plavu − vodilicu
ℹ️
Obje žice moraju ići u isti stupac vodilice, onaj koji ide uz plavu liniju. Vodilica uz ružičastu liniju je zaseban pojas i nije spojena s njom.

Krug je sada jedan neprekinut lanac: IO4 → red 19 → otpornik → red 14 → LED-ica → red 12 → vodilica → GND. Struja može teći samo kada skica dovede IO4 u visoko stanje, a to je točno ono što će tipka ON napraviti.

6. Spoji pločicu na računalo

Utisni USB-C kabel u pločicu i u računalo. PWR LED-ica na pločici odmah se upali, ali zelena LED-ica na breadboardu ostaje ugašena. Skica je namjerno gasi pri pokretanju, tako da se stranica i hardver poklapaju od prvog trenutka.

Gotov krug sa spojenim USB-C kabelom, upaljenom PWR LED-icom i ugašenom zelenom LED-icom
Korak 6: napojeno. PWR LED-ica je upaljena; zelena LED-ica je ugašena, kako skica i namjerava

Kako pločica postaje web server

U 6.1 pločica je bila klijent. Odabrala je web sjedište, zatražila stranicu i čekala odgovor. Sve je počelo od pločice.

Ovdje je server, što znači da radi obrnuto: sjedi i čeka, a razgovor pokreće nešto drugo. Kada u preglednik (engl. browser) upišeš adresu pločice, preglednik pošalje zahtjev a pločica odgovori. Pločica nikada ne odlučuje kada se to dogodi. Tvoj prst na tipki ON odlučuje.

Portovi i rute

Serveru treba port, koji možeš zamisliti kao numerirana vrata na pločici. Port 80 su standardna vrata za web stranice, i zato ti WebServer server(80); dopušta da jednostavno upišeš adresu a da nakon nje ništa ne dodaš. Preglednici po zadanom već pokušavaju vrata 80.

Za tim vratima pločica drži kratku listu adresa na koje zna odgovoriti. Svaki unos sparuje adresu s funkcijom, a te se funkcije nazivaju obrađivači:

AdresaObrađivačŠto radi
/handleRoot()šalje samu web stranicu
/led/onhandleLedOn()dovodi IO4 u visoko stanje i odgovara on
/led/offhandleLedOff()dovodi IO4 u nisko stanje i odgovara off
/led/statushandleLedStatus()čita IO4 i prijavljuje njegovo trenutno stanje

Linije server.on() u setup() su ono što tu listu gradi. To se naziva usmjeravanje (routing). Primijeti da se imena obrađivača predaju bez zagrada: server.on("/led/on", handleLedOn) predaje samu funkciju, da bi se pozvala kasnije, a ne da je poziva tu i sada.

Te četiri funkcije nikada nigdje u skici ne pozivaš. Server ih poziva za tebe, svaki put kada zahtjev dođe na odgovarajuću adresu.

Zašto loop() izgleda tako prazan

loop() sadrži jednu jedinu liniju, server.handleClient(), i ta linija radi sav posao. U svakom krugu provjeri je li preglednik bilo što poslao i, ako jest, izvrši odgovarajući obrađivač.

Zato petlja mora nastaviti slobodno kružiti. Stavi dugi delay() u nju i stranica postaje troma ili prestaje odgovarati sasvim, jer nitko ne provjerava vrata dok pločica čeka.

Stranica živi unutar skice

Cijela web stranica spremljena je u skici kao jedan dugačak dio teksta, omotan u R"rawliteral( ... )rawliteral". To omotavanje je C++ udobnost: dopušta tekstu da se proteže kroz mnogo linija i sadrži navodnike bez potrebe za znakom za izbjegavanje pred svakim.

PROGMEM zatim govori pločici da taj tekst drži u svojoj flash memoriji, a ne u svojoj mnogo manjoj radnoj memoriji. Stranica je HTML, isti jezik koji nam je web sjedište u 6.1 poslalo natrag. Sada je pločica ta koja ga šalje.

Unutar stranice je kratak dio JavaScripta, koji se izvršava u pregledniku a ne na pločici. On od /led/status traži trenutno stanje i upisuje ga u liniju statusa, pa to ponavlja svake dvije sekunde:

updateStatus();
setInterval(updateStatus, 2000);

Zato linija statusa ostaje iskrena i ako netko drugi pritisne tipku na drugom mobitelu, a i zato može zaostajati: stranica može biti do dvije sekunde iza LED-ice.

nulamini.local umjesto IP adrese

MDNS.begin("nulamini") zauzima ime na tvojoj lokalnoj mreži pomoću mDNS-a, ili Multicast DNS-a. Pločici to dopušta da odgovara na http://nulamini.local/, što je daleko lakše zapamtiti od adrese koju je router dodijelio.

Kao i begin() funkcije na senzorima u ranijim primjerima, vraća true pri uspjehu i false pri neuspjehu, pa skica provjerava rezultat i ispisuje poruku u svakom slučaju.

ℹ️
Ako se nulamini.local ne otvori, koristi IP adresu. mDNS nije podržan svugdje. Windows 10 i 11, macOS i iOS svi razrješavaju .local imena bez ikakvog namještanja, ali neke verzije Androida i neki routeri ne. Točno zato skica ispisuje IP address: u Serial Monitor. Upiši te brojeve u svoj preglednik i doći ćeš na istu stranicu. Ime je udobnost, a ne zahtjev.

Postavljanje Wi-Fi podataka

Prije prijenosa promijeni ove dvije linije da odgovaraju tvojoj mreži:

const char* ssid = "your ssid";
const char* password = "your password";
⚠️
Pobrini se da su ime mreže i lozinka napisani točno kako se pojavljuju, jer se razlikuju velika i mala slova.

Kod

Ispod je cijeli kod za ovaj primjer:

/**
**************************************************
*
* @file 6.2_Wi-Fi_LED_Control.ino
* @brief Primjer koji pokazuje kako upravljati LED-icom s web stranice. NULA pločica pridružuje se tvojoj Wi-Fi mreži i
* onda postaje mali web server za sebe, što znači da je možeš otvoriti u pregledniku svog mobitela
* ili računala. Stranica ima tipku ON i tipku OFF i prikazuje trenutno stanje LED-ice.
* U prethodnom primjeru pločica je od web sjedišta tražila podatke, ovdje je pločica ona koju se pita.
* Za detalje, shemu spajanja i više, pogledaj dokumentaciju primjera na: <link placeholder>
* @author Soldered
***************************************************
*/

/*
Biblioteka WiFi sadrži sve što je potrebno za pridruživanje Wi-Fi mreži.
*/
#include <WiFi.h>

/*
Biblioteka WebServer obavlja teški posao bivanja web serverom: sluša preglednike koji se žele povezati i
svaki zahtjev predaje funkciji koju smo napisali.
*/
#include <WebServer.h>

/*
Biblioteka ESPmDNS dopušta pločici da se na tvojoj mreži najavi pod prijateljskim imenom. Zahvaljujući njoj u pregledniku
možeš otvoriti http://nulamini.local/ umjesto da moraš pamtiti IP adresu.
*/
#include <ESPmDNS.h>

/*
Ove dvije varijable drže ime tvoje Wi-Fi mreže (SSID) i njezinu lozinku. Zamijeni tekst između
navodnika svojim mrežnim podacima. Tvoj mobitel ili računalo mora biti na istoj mreži kao pločica,
inače neće moći doći do stranice.
*/
const char* ssid = "your ssid";
const char* password = "your password";

/*
Ovo je varijabla kojoj predajemo broj pina na koji smo spojili LED-icu.
NULA pločica ima logiku imenovanja pinova ovako: IO4, gdje je 4 broj koji dajemo varijabli.
Ako želiš koristiti drugi pin, pobrini se da koristiš pin označen s IO__.

Zapamti da LED-ici treba otpornik od 330 ohma u seriji s njom. Taj otpornik ograničava koliko struje teče, a
bez njega LED-ica vuče više nego što su ona ili pin građeni izdržati, pa se oboje može oštetiti.
*/
const int LED_PIN = 4;

/*
Ovdje stvaramo naš objekt web servera, koji smo nazvali "server". Broj 80 je port na kojem sluša. Port je
kao broj vrata na pločici: port 80 su standardna vrata za web stranice, i zato ih preglednici po zadanom pokušavaju
i zato ih ne moramo upisivati u adresnu traku.
*/
WebServer server(80);

/*
Ovo je sama web stranica, napisana u HTML-u i spremljena kao jedan dugačak dio teksta. HTML je jezik koji
opisuje kako stranica izgleda, isti jezik koji nam je example.com poslao u prethodnom primjeru.
Omotavanje R"rawliteral( ... )rawliteral" je C++ trik koji nam dopušta da napišemo mnogo linija teksta, uključujući
navodnike, a da svaki od njih ne izbjegavamo.
PROGMEM govori pločici da ovaj tekst drži u svojoj flash memoriji, a ne u svojoj mnogo manjoj radnoj memoriji.
Stranica sadrži dvije tipke i mali dio JavaScripta, koda koji se izvršava unutar preglednika i koji od
pločice traži trenutno stanje LED-ice svake dvije sekunde, pa prikazani status sam ostaje svjež.
*/
const char htmlPage[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NULA MINI LED Control</title>
<style>
body { font-family: Arial; text-align: center; margin-top: 50px; }
button { padding: 15px 30px; margin: 10px; font-size: 20px; }
.status { font-size: 24px; margin-top: 20px; }
</style>
</head>
<body>
<h1>NULA MINI LED Control</h1>
<button onclick="fetch('/led/on').then(()=>updateStatus())">ON</button>
<button onclick="fetch('/led/off').then(()=>updateStatus())">OFF</button>
<div class="status" id="status">Loading status...</div>

<script>
// Function that requests LED status from the NULA MINI and updates the page
async function updateStatus() {
let res = await fetch('/led/status');
let text = await res.text();
document.getElementById('status').innerHTML = 'LED is ' + text.toUpperCase();
}

// Run immediately after page load and update every 2 seconds
updateStatus();
setInterval(updateStatus, 2000);
</script>
</body>
</html>
)rawliteral";

/*
Četiri funkcije ispod nazivaju se obrađivači. Obrađivač je funkcija koju server izvrši kada preglednik zatraži
jednu određenu adresu. Mi ih ovdje samo pišemo, nigdje ih u programu sami ne pozivamo: dalje ispod
u setup() serveru govorimo koja adresa pripada kojem obrađivaču, i od tada ih server poziva za nas.

Ovaj prvi obrađivač odgovara na korijensku adresu "/", a to je ono što preglednik zatraži kada jednostavno otvoriš
adresu pločice. Šalje natrag web stranicu koju smo pripremili iznad.
Tri broja i riječi u server.send() su kod odgovora (200 znači "izvoli"), tip sadržaja koji
šaljemo, i sam sadržaj.
*/
void handleRoot() {
server.send(200, "text/html", htmlPage);
}

/*
Ovaj obrađivač odgovara na adresu "/led/on". Pali LED-icu i odgovara kratkim tekstom "on", koji
JavaScript u stranici koristi za osvježavanje linije statusa.
*/
void handleLedOn() {
digitalWrite(LED_PIN, HIGH);
server.send(200, "text/plain", "on");
}

/*
Ovaj obrađivač odgovara na adresu "/led/off" i radi obrnuto: gasi LED-icu i odgovara s "off".
*/
void handleLedOff() {
digitalWrite(LED_PIN, LOW);
server.send(200, "text/plain", "off");
}

/*
Ovaj obrađivač odgovara na adresu "/led/status" i prijavljuje trenutno stanje LED-ice. digitalRead() nam daje
vrijednost koju pin trenutno ima, a znak pitanja je kratak način zapisa if izjave: ako je vrijednost HIGH
odgovaramo "on", inače odgovaramo "off".
*/
void handleLedStatus() {
String status = digitalRead(LED_PIN) ? "on" : "off";
server.send(200, "text/plain", status);
}

void setup() {

/*
Serial.begin() uspostavlja serijsku komunikaciju između tvoje pločice i tvog računala preko USB kabela. Ovdje ga koristimo
da pratimo proces povezivanja i da otkrijemo adresu pločice.
*/
Serial.begin(115200);

/*
pinMode() je funkcija koja konfigurira zadani pin da se ponaša ili kao ulaz ili u ovom slučaju kao izlaz.
Budući da naš pin mora upaliti LED-icu, pin ćemo staviti u OUTPUT mod. Odmah nakon toga u njega pišemo LOW, tako
da LED-ica počne ugašena a status prikazan na stranici odgovara stvarnosti.
*/
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);

/*
WiFi.begin() pokreće pokušaj povezivanja. Funkcija samo pokreće proces, ne čeka da se dovrši.
*/
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);

/*
Zbog toga na vezu čekamo sami. WiFi.status() nam kaže trenutno stanje a WL_CONNECTED je
vrijednost koju prijavljuje kada smo na mreži. Točke (".") pokazuju napredak u Serial Monitoru.
*/
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

/*
WiFi.localIP() vraća adresu koju je router dodijelio našoj pločici. Upisivanje te adrese u preglednik na
istoj mreži otvara stranicu koju smo pripremili iznad.
*/
Serial.println("\nWiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

/*
MDNS.begin() zauzima ime na lokalnoj mreži, u ovom slučaju "nulamini". Ako uspije, pločica se može
dosegnuti i na http://nulamini.local/, što je daleko lakše zapamtiti od reda brojeva. Kao begin() funkcije na
senzorima, vraća true pri uspjehu i false pri neuspjehu, pa provjeravamo rezultat i ispisujemo poruku u svakom slučaju.
*/
if(MDNS.begin("nulamini")){
Serial.println("mDNS responder started!");
Serial.println("Access the board in your browser at: http://nulamini.local/");
} else {
Serial.println("Error starting mDNS responder!");
}

/*
server.on() spaja adresu s jednom od funkcija obrađivača koje smo napisali iznad. To se naziva usmjeravanje. Odsad
server zna da na preglednik koji traži "/led/on" treba odgovoriti handleLedOn(), i tako dalje za ostale.
Primijeti da ime funkcije predajemo bez zagrada: predajemo samu funkciju, ne pozivamo
je upravo sada.
*/
server.on("/", handleRoot);
server.on("/led/on", handleLedOn);
server.on("/led/off", handleLedOff);
server.on("/led/status", handleLedStatus);

/*
server.begin() otvara vrata i počinje slušati preglednike.
*/
server.begin();
Serial.println("HTTP server started");
}

void loop() {

/*
server.handleClient() provjerava je li nam preglednik bilo što poslao i, ako jest, izvršava odgovarajuću funkciju
obrađivača. To je razlog zašto petlja mora nastaviti raditi: ako bismo prestali pozivati ovu funkciju, stranica bi prestala
odgovarati. Iz istog razloga izbjegavaj duge delay() pozive u ovoj petlji.
*/
server.handleClient();
}

Što bi trebao vidjeti

Otvori Serial Monitor na 115200 bauda odmah nakon prijenosa. Pločica prijavljuje cijeli svoj slijed pokretanja:

Serial Monitor prikazuje boot zapis, točke povezivanja, dodijeljenu IP adresu i poruke o pokretanju mDNS-a i servera
Cijeli slijed pokretanja, koji završava adresom koja ti treba

Čitajući to od vrha:

  • Prvih devet linija (ESP-ROM, Build, rst:0x1 i load: linije) nisu iz skice. Dolaze iz vlastitog ROM bootloadera čipa dok se budi i učitava tvoj program. Svaki primjer ih ispisuje; normalne su, i pojavljuju se prije nego je setup() izvršio i jednu liniju.
  • Connecting to WiFi... je prva poruka skice. Tri točke na njezinom kraju su samo interpunkcija, dio teksta.
  • Točke u sljedećoj liniji su pravi pokazatelj napretka. Svaka je jedan prolaz petlje čekanja, a svaki prolaz traje 500 ms, pa je red točaka štoperica. Četrnaest točaka ovdje znači oko sedam sekundi do pridruživanja mreži.
  • IP address: 192.168.75.75 je adresa koju je router dodijelio. Tvoja će biti drugačija. Zadrži je. To je tvoje rezervno rješenje ako se nulamini.local ne bude htio otvoriti.
  • mDNS responder started! potvrđuje da je prijateljsko ime zauzeto, a linija nakon njega daje ti adresu za upisivanje.
  • HTTP server started je posljednja linija. Odavde pločica sluša a loop() radi.
ℹ️
Petlja čekanja nema vremenskog ograničenja. Ako je ime mreže ili lozinka pogrešna, WiFi.status() nikada ne dosegne WL_CONNECTED, pa pločica ispisuje točke unedogled i nikada ne dođe do toga da prijavi grešku. Red točaka koji nastavlja rasti iznad dvadeset ili trideset nije spora mreža. To je gotovo uvijek tipfeler u podacima.

Otvaranje stranice

Kada pločica prijavi HTTP server started, otvori http://nulamini.local/ na bilo kojem mobitelu ili računalu na istoj mreži. Stranica je namjerno obična:

Preglednik prikazuje stranicu NULA MINI LED Control s tipkama ON i OFF i linijom statusa koja piše LED is OFF
Stranica kako se prvi put otvori. Linija statusa već odražava stvarnost: LED-ica je ugašena

Linija statusa nije nagađanje. Prije nego se stranica do kraja učitala, JavaScript je već pitao /led/status, a pločica je pročitala IO4 i odgovorila. LED is OFF je pravo mjerenje pravog pina, a breadboard se slaže:

Gotov krug s ugašenom zelenom LED-icom, što odgovara statusu LED is OFF prikazanom u pregledniku
Hardverska strana istog trenutka: zelena LED-ica je tamna, točno kako stranica prijavljuje

Sada pritisni ON:

Ista stranica nakon pritiska na ON, s linijom statusa koja piše LED is ON
Nakon pritiska na ON, linija statusa slijedi

I LED-ica na breadboardu se upali:

Zelena LED-ica na breadboardu upaljena nakon pritiska na tipku ON u pregledniku
Isti krug, nepromijenjen od koraka 6, sada s IO4 dovedenim u visoko stanje iz preglednika

Između tih dviju fotografija na spajanju se ništa nije pomaknulo. Jedina razlika je napon na IO4, a on je došao od pritiska tipke negdje drugdje na tvojoj mreži.

Pritisak putuje dugačak put za nešto što izgleda tako jednostavno. Tvoj prst pokrene fetch('/led/on') u pregledniku, koji pošalje HTTP zahtjev preko tvog routera do pločice. server.handleClient() ga uhvati, poklopi adresu s handleLedOn(), a ta funkcija pozove digitalWrite(LED_PIN, HIGH). Struja zatim teče iz IO4 kroz otpornik, kroz LED-icu i u vodilicu. Pritisak na OFF radi isto putovanje obrnuto.

ℹ️
Linija statusa može biti do dvije sekunde zastarjela. Osvježava se na dvosekundnom brojaču, pa ako pritisneš tipku na jednom mobitelu dok stranicu gledaš na drugom, drugi se sustiže pri svojem sljedećem propitivanju, a ne trenutno. Sama LED-ica mijenja se odmah. Samo tekst zaostaje.

Cijeli primjer

Pogledaj cijeli kod primjera na linku ispod:

6.2_Wi-Fi_LED_Control.ino

Primjer koji pokazuje kako upravljati LED-icom na NULA MINI s web stranice, koju pločica sama servira i koja je dostupna na nulamini.local.