Napravi semafor

Programiraj semafor sa četiri faze, tri LED diode i ciklusom od deset sekundi. Nauči tabelu stanja i mjerenje vremena pomoću millis().

Prvi koraci sa ESP32 i ArduinomPočetni nivo60 min

Ciljevi učenja

  • Povezati crvenu, žutu i zelenu LED na GPIO25, GPIO26 i GPIO33 sa zasebnim otpornicima.
  • Opisati četiri faze tabelom koja definiše sva tri izlaza i trajanje.
  • Objasniti kako millis() određuje trenutak prelaska u sljedeću fazu.
  • Provjeriti sekvencu crveno, crveno i žuto, zeleno, žuto.
  • Izračunati period ciklusa i predvidjeti posljedice promjene trajanja faze.

Prije početka

Potrebno je znanje iz kurseva 01 i 02: učitavanje programa i povezivanje LED sa otpornikom. Rad sa millis() iz kursa 03 je koristan.

Referentna postavka

Ploča u Arduino IDE-u
ESP32 Dev Module
Arduino-ESP32
3.3.12
Serial Monitor
115200 baud

Ovo je referentni profil, a ne identifikacija ploče sa fotografije. Za ESP32-C3/S2/S3 ili drugačije označenu ploču treba prilagoditi GPIO i provjeriti šemu prije spajanja.

Šta ćemo napraviti

Napravićemo demonstracioni semafor sa crvenom, žutom i zelenom LED diodom. Redoslijed je: crveno četiri sekunde, crveno i žuto zajedno jednu sekundu, zeleno četiri sekunde, zatim samo žuto jednu sekundu. Poslije toga ciklus počinje ponovo.

Ovaj model uvodi upravljanje kroz stanja: program u svakom trenutku zna koja je faza aktivna, koji izlazi joj pripadaju i kada treba preći u sljedeću. Isti način razmišljanja kasnije možeš primijeniti na tajmer, meni ili jednostavnu automatizaciju.

Šta ćeš naučiti

  • Povezati tri LED diode sa zasebnim otpornicima.
  • Predstaviti ponašanje uređaja tabelom stanja.
  • Odvojiti izbor izlaza od mjerenja trajanja faze.
  • Koristiti millis() za prelazak u sljedeće stanje bez višesekundne pauze.
  • Izračunati period ciklusa i provjeriti ga posmatranjem.

Predznanje

Potrebni su postupci iz kurseva 01 i 02: izbor ESP32 ploče i porta, učitavanje programa, prepoznavanje LED polariteta i uloga otpornika. Iskustvo sa millis() iz kursa 03 pomoći će, ali ćemo ovdje objasniti njegovu namjenu u sekvenci.

Potrebna oprema

KomponentaKoličinaSpecifikacija i napomene
ESP32 razvojna ploča sa klasičnim ESP32-WROOM-32 modulom1GPIO nazivi moraju odgovarati referentnom profilu; fizički položaj izvoda provjeriti na ploči.
USB kabl za podatke i napajanje1Priključak prilagoditi ploči; komplet na slici navodi Micro-USB.
Eksperimentalna ploča1Komplet navodi 830 kontaktnih tačaka. Provjeriti eventualni prekid naponskih vodova.
Crvena LED dioda1Anoda A i katoda K; provjeriti polaritet stvarne komponente.
Žuta LED dioda1Anoda A i katoda K.
Zelena LED dioda1Anoda A i katoda K.
Otpornik 220 Ω3Po jedan otpornik za svaku LED granu; 220 Ω iz kompleta.
Spojni kablovi7M-M ili F-M prema priključcima ploče.

Okvirna količina.

Ova šema koristi klasični ESP32/ESP32-WROOM-32. Prati GPIO25, GPIO26 i GPIO33 označene na tvojoj ploči. Ne određuj priključke brojanjem fizičkih pinova. Za ploče ESP32-C3, S2 ili S3 potreban je prilagođen raspored povezivanja.

Četiri stanja jednog uređaja

Stanje je imenovana faza rada sa unaprijed određenim izlazima. Ovdje postoje četiri stanja, iako koristimo tri LED diode: kombinacija crvenog i žutog predstavlja zasebnu fazu. Sljedeća tabela potpuno opisuje osnovno ponašanje.

FazaCrvenaŽutaZelenaTrajanje
CrvenoUključenaIsključenaIsključena4000 ms
Crveno i žutoUključenaUključenaIsključena1000 ms
ZelenoIsključenaIsključenaUključena4000 ms
ŽutoIsključenaUključenaIsključena1000 ms

Zbir trajanja je 10.000 ms, odnosno 10 sekundi. Za svaku fazu navodimo sva tri izlaza. Tako se, na primjer, žuto namjerno gasi pri prelasku na zeleno. Samo uključivanje sljedeće LED bez isključivanja prethodne ostavilo bi neželjenu kombinaciju.

millis() omogućava provjeru proteklog vremena, dok se glavna petlja nastavlja izvršavati. Arduino Blink Without Delay predstavlja ovaj princip na jednoj LED; ovdje ga primjenjujemo na faze različitog trajanja.

Šema i povezivanje

Šema povezivanja

Prikaz prikazuje električne veze po GPIO nazivima, a ne fizički raspored priključaka ploče. Napajanje ploče je preko USB kabla.

Šema povezivanja — električne veze navedene u tabeli ispod
Šema povezivanjaUvećajSVGPNG
Veze · Šema povezivanja
OdDoOpis veze
ESP32.GPIO25R1.1Upravljanje granom RED.
R1.2D1.AOtpornik 220 Ω prema anodi LED diode.
D1.KESP32.GNDKatoda prema zajedničkoj masi.
ESP32.GPIO26R2.1Upravljanje granom YELLOW.
R2.2D2.AOtpornik 220 Ω prema anodi LED diode.
D2.KESP32.GNDKatoda prema zajedničkoj masi.
ESP32.GPIO33R3.1Upravljanje granom GREEN.
R3.2D3.AOtpornik 220 Ω prema anodi LED diode.
D3.KESP32.GNDKatoda prema zajedničkoj masi.
  1. Odspoji USB. Postavi tri LED diode redom crvena, žuta, zelena, tako da lako pratiš njihova kola.
  2. Spoji GND ploče na zajedničku masu eksperimentalne ploče. Provjeri da li je izabrana sabirnica prekinuta na sredini; ako koristiš oba njena dijela, poveži ih.
  3. Spoji GPIO25 preko otpornika 220 Ω na anodu crvene LED.
  4. Spoji GPIO26 preko drugog otpornika 220 Ω na anodu žute LED.
  5. Spoji GPIO33 preko trećeg otpornika 220 Ω na anodu zelene LED.
  6. Katodu svake LED spoji na zajednički GND. Provjeri polaritet svake diode i da joj nožice nisu u istoj povezanoj grupi rupica.

Svaka LED ima svoj otpornik jer predstavlja zasebnu strujnu granu. Otpornik nema polaritet i može se okrenuti, ali mora ostati u seriji sa odgovarajućom LED. Sve tri katode smiju dijeliti masu. Ploču napajamo USB kablom; GPIO izlazi upravljaju ovim malim demonstracionim kolima i ne povezujemo ih na 5 V.

Priprema Arduino okruženja

Koristi Arduino IDE 2.x sa paketom esp32 by Espressif Systems, ciljna verzija 3.3.12. Izaberi ESP32 Dev Module i port povezane ploče. Uputstvo za instalaciju paketa nalazi se kod Espressifa. Dodatne biblioteke nisu potrebne.

Preuzmi Arduino primjer (.zip), raspakuj ga i otvori traffic_light/traffic_light.ino. U kompletnom paketu nalazi se pod arduino/. Zadrži odgovarajući naziv foldera. Podesi Serial Monitor na 115200 baud. Uporedi GPIO oznake u programu sa svojim povezivanjem.

Kompletan Arduino program

traffic_light.ino Arduino / C++
Preuzmi .ino

#include <Arduino.h>

constexpr uint8_t RED_PIN = 25;
constexpr uint8_t YELLOW_PIN = 26;
constexpr uint8_t GREEN_PIN = 33;
constexpr uint8_t PHASE_COUNT = 4;
const uint32_t PHASE_DURATION_MS[PHASE_COUNT] = {4000, 1000, 4000, 1000};
const char* PHASE_NAMES[PHASE_COUNT] = {"RED", "RED + YELLOW", "GREEN", "YELLOW"};

uint8_t phase = 0;
uint32_t phaseStartedMs = 0;

void showPhase() {
  // Set all outputs on every transition so no previous light remains on.
  digitalWrite(RED_PIN, (phase == 0 || phase == 1) ? HIGH : LOW);
  digitalWrite(YELLOW_PIN, (phase == 1 || phase == 3) ? HIGH : LOW);
  digitalWrite(GREEN_PIN, phase == 2 ? HIGH : LOW);
  Serial.print("Phase: ");
  Serial.println(PHASE_NAMES[phase]);
}

void setup() {
  Serial.begin(115200);
  pinMode(RED_PIN, OUTPUT);
  pinMode(YELLOW_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  phaseStartedMs = millis();
  showPhase();
}

void loop() {
  const uint32_t now = millis();

  if (now - phaseStartedMs >= PHASE_DURATION_MS[phase]) {
    phase = (phase + 1) % PHASE_COUNT;
    phaseStartedMs = now;
    showPhase();
  }
}

Koristi izvornu datoteku za prvo učitavanje. Vlastite izmjene sačuvaj odvojeno kako bi se mogao vratiti na zadatu sekvencu.

Prolazak kroz program

Početno stanje je crveno. phase čuva broj faze od 0 do 3, a PHASE_DURATION_MS četiri trajanja. Funkcija showPhase() postavlja sva tri digitalna izlaza. pinMode() podešava izlaze, a digitalWrite() određuje njihove nivoe; oba API-ja opisana su u Espressif GPIO dokumentaciji.

U svakom prolasku kroz loop() provjerava se koliko je vremena prošlo od početka faze. Dok zadato trajanje nije isteklo, faza ostaje ista. Kada istekne, program bira sljedeću fazu, postavlja njene izlaze i bilježi vrijeme njenog početka. Poslije posljednje faze vraća se na prvu.

Vrijeme provjeravamo oduzimanjem početne oznake od trenutne. Vremenske vrijednosti čuvamo u cjelobrojnom tipu bez predznaka koji odgovara brojaču milisekundi. Izlazi ostaju postavljeni između prolazaka petlje; za nastavak svijetljenja nije potrebno višesekundno čekanje. Serial Monitor prijavljuje faze, počevši od Phase: RED.

Pokretanje i očekivani rezultat

Klikni Verify, zatim Upload. Kada program krene, posmatraj crvenu LED. Resetuj uređaj ako želiš ponovljiv početak mjerenja. Sljedeća tabela koristi vrijeme od ulaska u početnu crvenu fazu.

Približno vrijemeOčekivano svjetlo
0–4 sSamo crveno.
4–5 sCrveno i žuto zajedno.
5–9 sSamo zeleno.
9–10 sSamo žuto.
Od 10 sNovi ciklus počinje crvenim.

Posmatraj tri cijela ciklusa. Mjeri od početka jednog crvenog do početka sljedećeg crvenog, jer je to ponavljanje istog događaja. Ručno mjerenje štopericom ima grešku reakcije: male razlike nisu razlog za promjenu programa. Zabilježi kompajliranje odvojeno od stvarne probe na ploči.

Najčešći problemi

SimptomProvjera i postupak
Jedna LED nikad ne svijetliProvjeri njen polaritet, otpornik, žicu i odgovarajući GPIO.
Boje rade pogrešnim redomUporedi povezivanje: crvena 25, žuta 26, zelena 33.
Zelena svijetli zajedno sa crvenomVrati izvorni program; provjeri da je svako stanje postavilo sva tri izlaza.
Sve LED ostaju ugašeneProvjeri zajednički GND, prekid sabirnice i da li je novi program učitan.
Faze djeluju prekratkoVrijednosti su u milisekundama: četiri sekunde su 4000, a ne 4.

Samostalni zadatak

Produži samo zelenu fazu na šest sekundi. Prije učitavanja izračunaj novi period. Zatim posmatraj dva ciklusa i uporedi trajanja sa predviđanjem. Dodatno izračunaj koliko ukupno vremena tokom jednog ciklusa svijetle crvena i žuta LED. Na kraju vrati zelenu fazu na četiri sekunde.

Pitanja za provjeru

  1. Zašto četiri faze zahtijevaju samo tri LED diode?
  2. Zašto zelena faza mora izričito ugasiti crvenu i žutu?
  3. Da li je zbir pojedinačnih vremena uključenosti svih LED uvijek jednak periodu ciklusa?

Smjernice i rješenje

U nizu PHASE_DURATION_MS promijeni treću vrijednost, sa 4000 na 6000 ms. To je indeks 2 jer brojanje počinje od nule. Novi period iznosi 4000 + 1000 + 6000 + 1000 = 12.000 ms. Crvena svijetli pet sekundi: četiri sama i jednu sa žutom. Žuta svijetli dvije: jednu sa crvenom i jednu sama.

Faza predstavlja kombinaciju izlaza, pa ne mora odgovarati jednoj LED. Izričito postavljanje svih izlaza uklanja preostala stanja. Zbir vremena uključenosti u osnovnom ciklusu je 5 + 2 + 4 = 11 sekundi, iako ciklus traje 10 sekundi: jednu sekundu dvije LED rade istovremeno.

Preuzimanja

Primarni izvori