Zvučna poruka: aktivni buzzer i tranzistor

Pokreni obrazac od dva kratka i jednog dugog tona jednim pritiskom tastera. Poveži tranzistorski drajver i organizuj zvuk pomoću millis().

Zvuk, releji i interaktivni projektiPočetni nivo75 min

Ciljevi učenja

  • Razlikovati aktivni buzzer od spoljašnje pobude pasivnog elementa.
  • Povezati PN2222A, otpornike i zaštitnu diodu prema funkcijama priključaka.
  • Pokrenuti jedan vremenski obrazac stabilnim pritiskom tastera.
  • Objasniti ignorisanje novih zahtjeva tokom obrasca i početno isključeno stanje.

Prije početka

Kurs 03: taster, INPUT_PULLUP i stabilizacija pritiska. Kurs 07: pouzdano čitanje digitalnog signala. Potrebno je znati poslati program na klasični ESP32.

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 pravimo?

Pravimo zvučni signal koji se oglašava poslije jednog pritiska tastera: dva kratka tona, zatim jedan duži. ESP32 upravlja vremenom uključivanja, a aktivni buzzer sam stvara ton. Ovakav obrazac može označiti završetak mjerenja ili potvrdu radnje u narednim projektima.

Program je organizovan tako da tokom oglašavanja nastavlja čitati taster i slati stanje računaru. Pritisak dok je obrazac već aktivan se zanemaruje. Kada završi, izlaz ostaje isključen do novog pritiska.

Ciljevi i predznanje

Potrebno je da znaš poslati Arduino program na ESP32 i povezati taster sa internim pull-up otpornikom, kao u kursu 03. Kurs 07 pomaže da razumiješ stabilizaciju digitalnog signala.

Na kraju ćeš moći objasniti razliku između aktivnog i pasivnog zvučnog elementa, povezati tranzistor kao prekidač, prepoznati polaritet zaštitne diode i napraviti vremenski obrazac pomoću millis(). Predviđeno vrijeme radionice je oko 75 minuta.

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.
Aktivni buzzer — referenca 5 V, do 20 mA1Fotografija navodi aktivni buzzer, ali ne potvrđuje njegov napon i struju. Za ovu šemu izaberi dokumentovani 5 V model sa najviše 20 mA radne struje.
Dodatni NPN tranzistor PN2222A1Obavezno dodatno — nije na slici kompletaDODATNO, nije naveden u kompletu. Identifikuj B/C/E prema tačnom proizvođaču; PN2222A i P2N2222A mogu imati različit raspored.

DODATNO: tranzistor nije naveden na fotografiji kompleta.

Dodatna zaštitna dioda 1N41481Obavezno dodatno — nije na slici kompletaDODATNO, nije navedena u kompletu. Prsten označava katodu K. U buzzer krugu katoda ide prema +5 V.

DODATNO: dioda nije navedena na fotografiji kompleta.

Otpornik 1 kΩ1Otpornik baze; u kursu 14 i paralelni otpornik piezo elementa. Količina ove vrijednosti u kompletu nije potvrđena.
Otpornik 10 kΩ1R2 je pull-down od baze Q1 prema GND; baza ostaje nisko dok GPIO ne upravlja.
Trenutni taster1Koristiti par priključaka koji se spaja pritiskom; ista strana četvoronožnog tastera može već biti spojena.
Spojni kablovi10M-M ili F-M prema priključcima ploče.

Okvirna količina; zavisi od fizičkog rasporeda.

Uz dijelove iz kompleta obavezno su potrebni PN2222A NPN tranzistor i dioda 1N4148; oni nisu prikazani u fotografisanom kompletu. Referentna zujalica je dvopriključni aktivni element za 5 V, sa deklarisanom radnom strujom najviše 20 mA. To je uslov izbora, a ne identifikacija elementa sa fotografije.

Prije povezivanja provjeri oznaku, napajanje i struju svog primjerka. Za element drugačijeg napona ili veće struje potreban je odgovarajući drugi pogonski sklop.

Aktivni buzzer i put struje

Aktivni buzzer ima unutrašnji oscilator. Kada dobije odgovarajuće napajanje, proizvodi svoj ton. Naš program određuje kada se taj ton čuje. Promjena trajanja impulsa od 150 ms mijenja ritam, a ne postavlja muzičku frekvenciju unutrašnjeg oscilatora. Proizvođački pregled pobudnih sklopova objašnjava razliku unutrašnje i spoljašnje pobude.

Kada je GPIO26 HIGH, mala struja kroz otpornik R1 uključuje Q1. Glavna struja tada teče od 5 V, kroz buzzer, kolektor i emiter tranzistora do mase. Kada je GPIO26 LOW, Q1 prekida taj put.

Zašto koristimo tranzistor i diodu?

R1 od 1 kΩ ograničava struju baze, a R2 od 10 kΩ povezuje bazu sa masom i održava isključeno stanje dok upravljački izlaz nije aktivan. Uz približno 0,7 V na spoju baza–emiter, kroz R1 teče oko (3,3 − 0,7)/1000 = 2,6 mA. To je procjena za objašnjenje sklopa, a ne izmjerena vrijednost.

Dioda je normalno neprovodna: njena katoda, označena prstenom, ide na plus napajanja. Ona ograničava odgovarajući naponski impuls pri isključivanju. Uobičajenu radnu struju nosi tranzistor, a napajanje buzzera ne dolazi iz GPIO pina.

Šema i provjera priključaka

Šema povezivanja

Q1 i D1 su dodatne komponente. Koristi aktivni buzzer potvrđen za 5 V i najviše 20 mA radne struje. Prsten diode ide na +5 V; Q1 B/C/E identifikuj prema stvarnom datasheet-u. USB5V je provjereni funkcionalni vod ploče, ne GPIO.

Šema povezivanja — električne veze navedene u tabeli ispod
Šema povezivanjaUvećajSVGPNG
Veze · Šema povezivanja
OdDoOpis veze
ESP32.GPIO26R1.1Otpornik R1 od 1 kΩ ograničava struju baze.
R1.2Q1.BBaza dodatnog PN2222A tranzistora.
Q1.BR2.1R2 od 10 kΩ drži bazu nisko dok GPIO ne upravlja.
R2.2ESP32.GNDDrugi kraj pull-down otpornika.
Q1.EESP32.GNDEmiter prema zajedničkoj masi; provjeriti stvarni B/C/E raspored.
ESP32.USB5VBZ1.PLUSProvjereni USB vod 5 V prema pozitivnom izvodu buzzera.
D1.KESP32.USB5VKatoda zaštitne 1N4148, označena prstenom, prema +5 V.
BZ1.MINUSQ1.CKolektor prekida struju aktivnog buzzera.
D1.ABZ1.MINUSAnoda diode prema negativnom izvodu buzzera i kolektoru.
ESP32.GPIO27SW1.CONTACT_ATaster na ulaz sa INPUT_PULLUP.
SW1.CONTACT_BESP32.GNDDrugi izvod odabranog para kontakata, koji se spaja pritiskom.

Šema prikazuje funkcije priključaka B, C i E. Njihov fizički raspored utvrdi iz tehničkog lista tačnog proizvođača i kućišta. Sličan naziv iz porodice 2222 ne garantuje isti raspored. Koristi PN2222A tehnički list i odgovarajući crtež kućišta svog dijela.

Ploča se napaja USB kablom. Za buzzer koristi samo priključak za koji dokumentacija konkretne ESP32 ploče potvrđuje da daje USB napajanje od 5 V. Ne spajaj dodatni izvor 5 V paralelno sa USB-om. Provjeri raspoloživu struju napajanja i ploče; svi upravljački GPIO signali ostaju 3,3 V.

Spajanje korak po korak

  1. Isključi USB i postavi tranzistor tako da su B, C i E u različitim redovima breadboarda.
  2. Poveži ESP32 GND sa zajedničkom masom, a emiter Q1 sa tom masom.
  3. Poveži GPIO26 preko R1 od 1 kΩ sa bazom Q1. Dodaj R2 od 10 kΩ između baze i mase.
  4. Poveži minus BZ1 na kolektor Q1, a plus BZ1 na potvrđeni USB 5 V priključak.
  5. Postavi D1 paralelno sa buzzerom: anoda na minus/kolektor, katoda sa prstenom na plus/5 V.
  6. Poveži GPIO27 preko prekidačkog para tastera sa GND. Kod tastera sa četiri izvoda provjeri koji se par zaista spaja pritiskom.
  7. Uporedi svaki spoj sa tabelom. Posebno provjeri da 5 V nije povezano sa GPIO26 ili GPIO27, pa priključi USB.

Priprema Arduino okruženja

Izaberi Arduino IDE 2.x, paket esp32 by Espressif Systems 3.3.12, ploču ESP32 Dev Module i odgovarajući port. Referenca je klasični ESP32/WROOM-32, a ne automatski svaka ESP32 varijanta. Serial Monitor podesi na 115200 baud.

Dodatne Arduino biblioteke nisu potrebne. Otvori active_buzzer.ino iz istoimenog direktorijuma, provjeri izbor ploče i pošalji program. Poslije pokretanja buzzer treba da bude isključen.

Kompletan program

active_buzzer.ino Arduino / C++
Preuzmi .ino

#include <Arduino.h>

constexpr uint8_t BUZZER_PIN = 26;
constexpr uint8_t BUTTON_PIN = 27;
constexpr uint32_t DEBOUNCE_MS = 30;
constexpr uint32_t REPORT_MS = 500;
constexpr uint32_t STEP_MS[] = {150, 150, 150, 150, 600};
constexpr uint8_t STEP_COUNT = sizeof(STEP_MS) / sizeof(STEP_MS[0]);
// Each event is accepted once after 30 ms of stable input.
// If held during reset, a stable release is required before the first press.
struct DebouncedButton {
  bool rawHigh = true;
  bool stableHigh = true;
  bool armed = true;
  bool pressed = false;
  bool released = false;
  uint32_t rawChangedAt = 0;
  uint32_t pressStartedAt = 0;
  void begin(uint32_t now) {
    rawHigh = stableHigh = digitalRead(BUTTON_PIN) == HIGH;
    armed = rawHigh;
    rawChangedAt = now;
    pressed = released = false;
  }
  void update(uint32_t now) {
    pressed = released = false;
    const bool readingHigh = digitalRead(BUTTON_PIN) == HIGH;
    if (readingHigh != rawHigh) {
      rawHigh = readingHigh;
      rawChangedAt = now;
    }
    if (rawHigh != stableHigh && static_cast<uint32_t>(now - rawChangedAt) >= DEBOUNCE_MS) {
      stableHigh = rawHigh;
      if (stableHigh) {
        armed = true;
        released = true;
      } else if (armed) {
        pressed = true;
        pressStartedAt = rawChangedAt;
      }
    }
  }
};
DebouncedButton button;

bool patternActive = false;
uint8_t patternStep = 0;
uint32_t stepStartedAt = 0;
uint32_t lastReportAt = 0;

void startPattern(uint32_t now) {
  patternActive = true;
  patternStep = 0;
  stepStartedAt = now;
  digitalWrite(BUZZER_PIN, HIGH);
}

void updatePattern(uint32_t now) {
  while (patternActive && static_cast<uint32_t>(now - stepStartedAt) >= STEP_MS[patternStep]) {
    stepStartedAt += STEP_MS[patternStep];
    ++patternStep;
    if (patternStep >= STEP_COUNT) {
      patternActive = false;
      digitalWrite(BUZZER_PIN, LOW);
    } else {
      digitalWrite(BUZZER_PIN, (patternStep % 2 == 0) ? HIGH : LOW);
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  button.begin(millis());
  lastReportAt = millis();
  Serial.println("Active buzzer: press for one 1.2 s pattern; presses during the pattern are ignored.");
}

void loop() {
  const uint32_t now = millis();
  button.update(now);
  if (button.pressed && !patternActive) startPattern(now);
  updatePattern(now);
  if (static_cast<uint32_t>(now - lastReportAt) >= REPORT_MS) {
    lastReportAt = now;
    Serial.print("Pattern="); Serial.println(patternActive ? "PLAYING" : "IDLE");
  }
}

Prvo pokreni originalni program. Tako će kasnije promjene ritma imati jasnu početnu tačku za poređenje.

Kako program organizuje vrijeme?

Taster koristi INPUT_PULLUP: otpušten je HIGH, pritisnut LOW. Promjena mora ostati stabilna 30 ms da bi je program prihvatio. Ako držiš taster tokom resetovanja, najprije ga otpusti, pa ponovo pritisni; početno zatečeno LOW stanje ne pokreće zvuk.

Niz STEP_MS sadrži pet trajanja, a patternStep određuje trenutni segment. startPattern() pokreće obrazac; updatePattern() poredi proteklo vrijeme sa trajanjem i prelazi na sljedeći segment. patternActive razlikuje rad od mirovanja. Oduzimanje vremenskih oznaka bez predznaka omogućava rad i preko preliva brojača millis(). Nema blokirajućeg delay() između segmenata.

SegmentBuzzerTrajanjeUkupno od početka
1Uključen150 ms150 ms
2Isključen150 ms300 ms
3Uključen150 ms450 ms
4Isključen150 ms600 ms
5Uključen600 ms1200 ms

Pokretanje i očekivano ponašanje

Pritisni i otpusti taster. Treba da čuješ dva kratka i jedan duži ton, nakon čega nastupa tišina. Novi pritisak tokom obrasca ne produžava ga i ne dodaje naredni obrazac u red čekanja.

Serial izvještaj stiže približno svakih 500 ms. On pomaže da razlikuješ mirovanje i aktivan obrazac, ali može preskočiti cijeli segment od 150 ms. Iz takvog ispisa ne možeš precizno izmjeriti trajanje svakog tona. Navedena opažanja su očekivani rezultati koje treba potvrditi na svojoj ploči.

Eksperimenti

PostupakOčekivani rezultatŠta provjeravaš
Jednom kratko pritisni tasterJedan obrazac, zatim tišinaPokretanje događajem
Drži taster tri sekundeObrazac se ne ponavljaRazliku stanja i pritiska
Pritisni ponovo dok sviraNema dodatnog obrascaZanemarivanje zauzetog ulaza
Drži taster i resetuj pločuTišina do otpuštanja i novog pritiskaPočetno stanje

Zabilježi rezultat svakog pokušaja. Kod provjere novog pritiska jasno otpusti taster dovoljno dugo da i otpuštanje bude stabilno.

Najčešći problemi

ProblemProvjera i ispravka
Serial radi, zvuka nemaProvjeri aktivni tip, polaritet BZ1, USB 5 V, zajedničku masu i tačan B/C/E raspored.
Čuje se samo klikProvjeri da slučajno nije korišćen pasivni element koji zahtijeva spoljašnju pobudu.
Buzzer stalno sviraIsključi napajanje; provjeri da minus nije direktno na masi i da Q1 nije pogrešno povezan.
Pritisak nema efektaProvjeri prekidački par tastera, GPIO27 i uslov otpuštanja nakon resetovanja.
Ploča se resetuje pri zvukuProvjeri kratke spojeve, struju buzzera, USB kabl i mogućnost napajanja ploče.

Samostalni zadatak i odgovori

U nizu STEP_MS promijeni samo posljednji ton sa 600 na 300 ms. Prije slanja koda izračunaj ukupno trajanje i predvidi ponašanje kada držiš taster.

Rješenje je 150 + 150 + 150 + 150 + 300 = 900 ms. Prva četiri segmenta ostaju ista. Zadržan pritisak i dalje proizvodi samo jedan obrazac jer nisi promijenio obradu događaja.

Zašto kraći segment ne podiže visinu tona? Mijenjaš vrijeme napajanja aktivnog oscilatora, a ne njegovu frekvenciju. Zašto se koristi R2? On određuje stanje baze kada GPIO još ne upravlja sklopom. Zašto dodatni pritisci ne čekaju na red? Program ih obrađuje dok je zauzet i namjerno ne pamti zahtjev za novi ciklus.

Izvori za dalji rad