Arduino: LED dioda, taster i semafor

Lekcija 2 od 28 · Arduino i ESP32

Posle prvog programa iz lekcije Uvod u Arduino pravimo prava mala kola na eksperimentalnoj ploči. Naučićemo kako se ispravno povezuje LED dioda, kako Arduino čita taster i kako od tri LED diode nastaje semafor – pa i semafor sa dugmetom za pešake.

Šta nam treba

  • Arduino Uno (ili klon) i USB kabl
  • eksperimentalna ploča (breadboard) i žice
  • tri LED diode: crvena, žuta i zelena
  • tri otpornika od 220 Ω (crveno-crveno-braon)
  • jedan taster sa četiri nožice

LED dioda i otpornik

LED dioda propušta struju samo u jednom smeru. Duža nožica je anoda (+) i vezuje se ka pinu Arduina, a kraća nožica je katoda (−) i vezuje se na GND. Ako je okreneš naopako, neće se ništa pokvariti – samo neće svetleti.

LED dioda se nikada ne vezuje bez otpornika. Bez njega kroz diodu bi potekla prevelika struja i pregorela bi i dioda i pin. Otpornik od 220 Ω ograničava struju na oko 13 mA: (5 V − 2 V) / 220 Ω ≈ 0,013 A. Otpornik može da stoji sa bilo koje strane diode.

LED dioda povezana na pin 7 Arduina preko otpornika od 220 oma
LED dioda: pin 7 → otpornik 220 Ω → duža nožica, kraća nožica → GND

Program 1: LED dioda na pinu 7

// Arduino – LED dioda na pinu 7 trepće
const int LED = 7;              // LED (duža nožica) preko otpornika 220 oma na pin 7

void setup() {
  pinMode(LED, OUTPUT);         // pin 7 je izlaz
}

void loop() {
  digitalWrite(LED, HIGH);      // upali: na pinu je 5 V
  delay(1000);                  // čekaj 1 sekundu
  digitalWrite(LED, LOW);       // ugasi: na pinu je 0 V
  delay(1000);
}

Funkcija pinMode(LED, OUTPUT) u setup() kaže da je pin izlaz. U loop() se smenjuju HIGH (5 V, LED svetli) i LOW (0 V, LED ne svetli), sa pauzom od 1000 ms između.

Taster i INPUT_PULLUP

Taster ima četiri nožice koje su unutra spojene u dva para. Postavi ga preko sredine eksperimentalne ploče, pa jednu nožicu poveži na pin 2, a dijagonalnu na GND.

Pin koji nije nigde povezan „pluta“ i čita slučajne vrednosti. Zato koristimo pinMode(TASTER, INPUT_PULLUP): unutar Arduina uključuje se otpornik koji pin drži na HIGH. Kada pritisnemo taster, pin se spaja sa GND i čita se LOW.

TasterŠta čita digitalRead()U Serial Monitoru
puštenHIGH1
pritisnutLOW0
Pazi: sa INPUT_PULLUP logika je „naopaka“ – pritisnut taster daje LOW. To je normalno i tako se taster najčešće povezuje.

Program 2: LED svetli dok držimo taster

// Arduino – LED svetli dok držimo taster
const int LED = 7;
const int TASTER = 2;           // taster između pina 2 i GND

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(TASTER, INPUT_PULLUP);   // unutrašnji otpornik drži pin na HIGH
  Serial.begin(9600);
}

void loop() {
  int stanje = digitalRead(TASTER);
  Serial.println(stanje);          // 1 = pušten, 0 = pritisnut
  if (stanje == LOW) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
  delay(50);
}

Otvori Serial Monitor (9600) i pritiskaj taster – videćeš kako se 1 menja u 0.

Program 3: taster kao prekidač

// Arduino – svaki pritisak tastera pali, odnosno gasi LED (kao prekidač za svetlo)
const int LED = 7;
const int TASTER = 2;

bool upaljena = false;
int prethodno = HIGH;           // stanje tastera u prošlom prolazu kroz loop()

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(TASTER, INPUT_PULLUP);
}

void loop() {
  int sada = digitalRead(TASTER);
  if (prethodno == HIGH && sada == LOW) {   // trenutak kada je taster pritisnut
    upaljena = !upaljena;                   // promeni stanje
    digitalWrite(LED, upaljena ? HIGH : LOW);
    delay(30);                              // čekamo da kontakt prestane da „poskakuje“
  }
  prethodno = sada;
}

Ovde ne gledamo da li je taster pritisnut, nego trenutak kada je pritisnut: prošli put je bio HIGH, a sada je LOW. Bez toga bi LED treperela sve dok držimo taster, jer se loop() ponavlja hiljadama puta u sekundi.

Kratka pauza od 30 ms rešava „poskakivanje“ kontakta: metalni kontakti u tasteru se pri pritisku nekoliko puta brzo dodirnu i razdvoje, pa bi Arduino jedan pritisak video kao više.

Semafor

Tri LED diode, svaka sa svojim otpornikom, vezujemo na pinove 12, 7 i 4. Katode (kraće nožice) idu na zajedničku liniju GND na ivici ploče.

Semafor: crvena LED na pinu 12, žuta na pinu 7, zelena na pinu 4, sve preko otpornika 220 oma
Semafor u Tinkercad-u: crvena – pin 12, žuta – pin 7, zelena – pin 4
SvetloPinTrajanje u programu
crveno125 s
crveno + žuto12 i 72 s
zeleno45 s, pa trepće 3 puta
žuto72 s
// Arduino – semafor: crveno, crveno + žuto, zeleno, trepćuće zeleno, žuto
const int CRVENA = 12;
const int ZUTA = 7;
const int ZELENA = 4;

// pomoćna funkcija: pali tačno one sijalice koje zadamo
void svetla(int c, int z, int g) {
  digitalWrite(CRVENA, c);
  digitalWrite(ZUTA, z);
  digitalWrite(ZELENA, g);
}

void setup() {
  pinMode(CRVENA, OUTPUT);
  pinMode(ZUTA, OUTPUT);
  pinMode(ZELENA, OUTPUT);
}

void loop() {
  svetla(HIGH, LOW, LOW);       // crveno
  delay(5000);
  svetla(HIGH, HIGH, LOW);      // crveno + žuto: pripremi se
  delay(2000);
  svetla(LOW, LOW, HIGH);       // zeleno
  delay(5000);
  for (int i = 0; i < 3; i++) { // zeleno trepće 3 puta
    svetla(LOW, LOW, LOW);
    delay(500);
    svetla(LOW, LOW, HIGH);
    delay(500);
  }
  svetla(LOW, HIGH, LOW);       // žuto
  delay(2000);
}

Funkcija svetla(c, z, g) skraćuje program: umesto tri reda digitalWrite pišemo jedan red. Takve pomoćne funkcije čine program preglednijim.

Semafor za pešake

Dodaj taster na pin 2 (druga nožica na GND). Automobili imaju zeleno sve dok pešak ne pritisne taster; tada se semafor prebacuje na crveno, pa se vraća na zeleno.

// Arduino – semafor sa tasterom za pešake
// Automobili imaju zeleno dok pešak ne pritisne taster.
const int CRVENA = 12;
const int ZUTA = 7;
const int ZELENA = 4;
const int TASTER = 2;

void svetla(int c, int z, int g) {
  digitalWrite(CRVENA, c);
  digitalWrite(ZUTA, z);
  digitalWrite(ZELENA, g);
}

void setup() {
  pinMode(CRVENA, OUTPUT);
  pinMode(ZUTA, OUTPUT);
  pinMode(ZELENA, OUTPUT);
  pinMode(TASTER, INPUT_PULLUP);
  svetla(LOW, LOW, HIGH);       // na početku: zeleno za automobile
}

void loop() {
  if (digitalRead(TASTER) == LOW) {   // pešak je pritisnuo taster
    delay(1000);                      // automobili ne staju u istom trenutku
    svetla(LOW, HIGH, LOW);           // žuto
    delay(2000);
    svetla(HIGH, LOW, LOW);           // crveno: pešaci prelaze
    delay(6000);
    svetla(HIGH, HIGH, LOW);          // crveno + žuto
    delay(2000);
    svetla(LOW, LOW, HIGH);           // ponovo zeleno
    delay(5000);                      // najmanje 5 s zeleno pre sledećeg pešaka
  }
}

Dok traje delay(), Arduino ne radi ništa drugo – ni ne čita taster. Zato pritisak tokom crvenog svetla nema efekta. U trećem zadatku ispod videćeš kako se to rešava funkcijom millis().

Česte greške

  • LED ne svetli: okrenuta je naopako ili nije u istom redu ploče kao otpornik i žica.
  • Taster „radi sam od sebe“: zaboravljen je INPUT_PULLUP, pa pin pluta.
  • Taster nikad ne radi: obe žice su na nožicama koje su već spojene – okreni taster za 90°.
  • Sve tri LED svetle slabo: zaboravljen je pinMode(..., OUTPUT) za te pinove.

Zadaci za vežbu

Pokušaj prvo sam da rešiš zadatak, pa tek onda otvori rešenje.

  1. Napravi „svetlo koje trči“: tri LED diode (pinovi 4, 7 i 12) pale se jedna po jedna, napred pa nazad.
  2. Broj pritiske tastera i ispisuj ih u Serial Monitoru. Posle petog pritiska LED na pinu 7 neka trepne 3 puta, a brojanje kreće ispočetka.
  3. Dodaj semaforu noćni režim: pritisak tastera prebacuje semafor na trepćuće žuto, a sledeći pritisak vraća normalan rad. Taster mora da reaguje odmah, čak i dok traje neko svetlo.
Rešenje 1: svetlo koje trči
// Zadatak – „svetlo koje trči“: tri LED diode pale se redom, napred i nazad
const int PINOVI[3] = { 4, 7, 12 };

void setup() {
  for (int i = 0; i < 3; i++) {
    pinMode(PINOVI[i], OUTPUT);
  }
}

void upaliSamo(int k) {
  for (int i = 0; i < 3; i++) {
    digitalWrite(PINOVI[i], i == k ? HIGH : LOW);
  }
}

void loop() {
  for (int k = 0; k < 3; k++) {     // napred
    upaliSamo(k);
    delay(200);
  }
  for (int k = 1; k >= 0; k--) {    // nazad (bez ponavljanja krajnje diode)
    upaliSamo(k);
    delay(200);
  }
}
Rešenje 2: brojač pritisaka
// Zadatak – brojač pritisaka: posle 5 pritisaka LED trepne 3 puta
const int LED = 7;
const int TASTER = 2;
int broj = 0;
int prethodno = HIGH;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(TASTER, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  int sada = digitalRead(TASTER);
  if (prethodno == HIGH && sada == LOW) {
    broj++;
    Serial.print("Pritisaka: ");
    Serial.println(broj);
    if (broj == 5) {
      for (int i = 0; i < 3; i++) {
        digitalWrite(LED, HIGH);
        delay(200);
        digitalWrite(LED, LOW);
        delay(200);
      }
      broj = 0;                   // brojimo ispočetka
    }
    delay(30);
  }
  prethodno = sada;
}
Rešenje 3: noćni režim sa millis()
// Zadatak – semafor sa noćnim režimom: taster prebacuje na trepćuće žuto i nazad
const int CRVENA = 12;
const int ZUTA = 7;
const int ZELENA = 4;
const int TASTER = 2;
bool nocni = false;

void svetla(int c, int z, int g) {
  digitalWrite(CRVENA, c);
  digitalWrite(ZUTA, z);
  digitalWrite(ZELENA, g);
}

// čeka zadato vreme, ali sve vreme proverava taster
void cekaj(unsigned long ms) {
  unsigned long pocetak = millis();
  while (millis() - pocetak < ms) {
    if (digitalRead(TASTER) == LOW) {
      nocni = !nocni;
      while (digitalRead(TASTER) == LOW) {
        delay(10);                // čekamo da se taster pusti
      }
      return;                     // odmah prelazimo na novi režim
    }
  }
}

void setup() {
  pinMode(CRVENA, OUTPUT);
  pinMode(ZUTA, OUTPUT);
  pinMode(ZELENA, OUTPUT);
  pinMode(TASTER, INPUT_PULLUP);
}

void loop() {
  if (nocni) {
    svetla(LOW, HIGH, LOW);
    cekaj(500);
    if (!nocni) return;
    svetla(LOW, LOW, LOW);
    cekaj(500);
  } else {
    svetla(HIGH, LOW, LOW);
    cekaj(5000);
    if (nocni) return;
    svetla(HIGH, HIGH, LOW);
    cekaj(2000);
    if (nocni) return;
    svetla(LOW, LOW, HIGH);
    cekaj(5000);
    if (nocni) return;
    svetla(LOW, HIGH, LOW);
    cekaj(2000);
  }
}

Proveri znanje

Otvori kviz

Kviz: LED dioda, taster i semafor

1. Koja nožica LED diode se vezuje ka pinu Arduina?




2. Zašto se uz LED diodu vezuje otpornik od 220 Ω?




3. Šta čita digitalRead() kada je taster sa INPUT_PULLUP pritisnut?




4. Zašto taster kao prekidač reaguje samo na promenu HIGH → LOW?