32ESP32 Akadémia
Interaktív magyar tananyag

Kicsi lapka.Nagy rendszerek.

Tanuld meg az ESP32-t az első GPIO jeltől a Wi-Fi hálózatokon és szenzorokon át a valódi, kétmagos FreeRTOS alkalmazásokig.

12fejezet
12részletes kódminta
3projektlépcső
A teljes útvonal

Három szint. Egy működő rendszer.

Minden blokk az előzőre épül. Először megtanulod irányítani a hardvert, aztán összekötöd a világgal, végül feladatokra bontod és párhuzamosan futtatod.

01—04 / ALAPOZÁS

Értsd meg

Hardver, toolchain, GPIO és időzítés. Stabil mentális modell, veszélyes vakfoltok nélkül.

05—08 / KAPCSOLAT

Kösd össze

Szenzorbuszok, analóg jelek, Wi‑Fi, HTTP, MQTT és biztonságos konfiguráció.

09—12 / RENDSZER

Skálázd fel

Energia, hibakeresés, FreeRTOS feladatok, két mag és egy komplett záróprojekt.

01

Az ESP32 térképe

Egy mikrovezérlő nem miniatűr PC: közvetlenül érintkezik a fizikai világgal, determinisztikusan reagál, és szűk erőforrásokból gazdálkodik.

Mit kapsz egy lapkán?

  • Két, akár 240 MHz-es Xtensa LX6 magot a klasszikus ESP32-ben
  • 2,4 GHz-es Wi‑Fi-t és Bluetooth/BLE-t
  • GPIO, ADC, DAC, PWM, UART, SPI, I²C, I²S perifériákat
  • RTC alrendszert, hardveres időzítőket és watchdogokat

Család ≠ egyetlen chip

Az „ESP32” egész család: ESP32, S2, S3, C3, C6, H2. Eltérhet a processzormag, a magok száma, az USB, a Bluetooth és a rádió. Mindig a pontos modul adatlapja a mérvadó.

Szabály: a klasszikus ESP32 többmagos példái nem vihetők át változtatás nélkül egy egymagos C3-ra.

A program útja

forráskód
.ino / .cpp
fordító + linker
firmware.bin
flash memória
program + konstansok
CPU + RAM
futó rendszer
TerületSzerepTipikus hiba
FlashProgram és tartós adatokTúl nagy firmware
SRAMStack, heap, változókElfogyó heap / stack overflow
NVSKulcs–érték konfigurációTúl gyakori írás, kopás

Gyors ellenőrzés

Miért kell tudnod a pontos ESP32 variánst?

SZINT · ALAP
02

Nyelvek és fejlesztőkörnyezetek

Az ESP32 több nyelven programozható, de nem minden nyelv ad azonos sebességet, hardverhozzáférést vagy könyvtárkínálatot. A választás a projekt céljától függ.

Először: nyelv, keretrendszer vagy szerkesztő?

C, C++, Python és Rust programozási nyelvek. Az Arduino Core és az ESP-IDF keretrendszerek/SDK-k. Az Arduino IDE, a VS Code és a PlatformIO fejlesztőeszközök. Például C++ kódot írhatsz Arduino IDE-ben vagy PlatformIO-ban, Arduino Core-ral vagy közvetlenül ESP-IDF-fel.

Gyakorlati ajánlás: első projekthez Arduino C++, gyors kísérlethez MicroPython, hosszú életű termékhez ESP-IDF C/C++, memóriabiztonság-központú új rendszerhez Rust.

Nyelvek részletes összehasonlítása

Nyelv / környezetElőnyHátrányMikor válaszd?
C + ESP-IDFMaximális kontroll, kis overhead, teljes Espressif API, kiváló hibakeresés és dokumentációMutatók és kézi erőforrás-kezelés miatt könnyebb memóriabugot írni; meredekebb tanulásTermék, alacsony késleltetés, speciális periféria, secure boot/OTA
C++ + Arduino CoreNagyon sok könyvtár, rövid kód, könnyű kezdés, közben elérhető a FreeRTOS és sok ESP-IDF APIA könyvtárak minősége vegyes; absztrakciók elrejthetik az időzítést és memóriahasználatotTanulás, hobbi, prototípus és kis-közepes eszköz
C++ + ESP-IDFNatív kontroll RAII-val, típusokkal és osztályokkal; C API-val jól együttműködikBonyolultabb build és hibakép; kivételek/RTTI gyakran tiltott vagy költségesNagyobb, moduláris firmware, tapasztalt C++ csapat
MicroPythonREPL, gyors kipróbálás, olvasható kód, nincs hosszú fordítási ciklusLassabb, jóval több RAM-ot használ, időzítése kevésbé determinisztikus, kisebb driverkészletOktatás, szenzorprototípus, automatizálás, rövid fejlesztési idő
CircuitPythonNagyon kezdőbarát; az eszköz USB-meghajtóként jelenhet meg; erős Adafruit ökoszisztémaESP32 boardtámogatása és hálózati képessége variánsonként eltér; teljesítmény/RAM korlátozottOktatás, maker projektek, támogatott S2/S3/C3/C6 panelek
RustFordításkor kiszűrt memóriakezelési és konkurenciahibák; modern típusosság; natív sebességMeredek tanulás, hosszabb build, kisebb ökoszisztéma; chipenként eltérő támogatási érettségBiztonságkritikusabb, hosszú életű vagy nagy párhuzamos rendszer
Lua / NodeMCUEgyszerű scriptelés, interaktív fejlesztés, kis forráskódMa kisebb közösség és kevesebb friss könyvtár; RAM- és sebességkorlátRégi NodeMCU rendszer karbantartása, nagyon kis script
JavaScript / EspruinoWebfejlesztőknek ismerős, REPL-es kísérletezésNem minden ESP32 variáns támogatott, szűkebb periféria-ökoszisztéma, interpreter-overheadGyors IoT demonstráció, meglévő JS tudás

Melyiket válaszd?

  • Most kezded: Arduino C++.
  • Pythonban gondolkodsz: MicroPython.
  • Gyorsan próbálnál szenzort: MicroPython/CircuitPython.
  • Valós idejű vagy ipari termék: ESP-IDF C/C++.
  • Memóriabiztonság fontos: Rust.
  • Meglévő NodeMCU/Espruino projekt: Lua/JavaScript.

IDE és build választás

EszközErősség
Arduino IDELeggyorsabb első feltöltés
PlatformIOReprodukálható függőségek, több környezet, tesztek
ESP-IDF CLINatív konfiguráció, monitor és debug
ThonnyEgyszerű MicroPython REPL és fájlkezelés
cargo-espRust build és flash eszköztár

Ugyanaz a LED három nyelven

A példák ugyanazt az elvet mutatják. A különbség nem csak szintaxis: eltér a futtatási modell, az indítás, a driver API és a hardver feletti kontroll.

Arduino C++ · blink.ino
constexpr int LED = 2;
void setup() { pinMode(LED, OUTPUT); }
void loop() {
  digitalWrite(LED, !digitalRead(LED));
  delay(500);
}
MicroPython · main.py
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
while True:
    led.value(not led.value())
    sleep(0.5)
Rust · esp-hal (egyszerűsített)
// no_std firmware; a pontos inicializálás chip/crate verziófüggő
let mut led = Output::new(peripherals.GPIO2, Level::Low);
loop {
    led.toggle();
    delay.delay_millis(500);
}

Feltöltési lánc

  1. Adatképes USB-kábel és megfelelő soros port
  2. A pontos board és flash beállítás kiválasztása
  3. Fordítás vagy interpreter firmware, majd flash írás
  4. Soros monitor/REPL: jellemzően 115200 baud

Nem csatlakozik? Tartsd nyomva a BOOT gombot az írás indulásakor; ellenőrizd a kábelt és a port jogosultságát.

Teljesítmény és valós idő

A natív C/C++ és Rust gépi kódra fordul. A MicroPython, CircuitPython, Lua és JavaScript interpretert futtat, ezért kényelmesebb, de lassabb és kevésbé kiszámítható. Kemény időzítésű GPIO-t, motorvezérlést vagy nagy adatsebességet natív kóddal érdemes megoldani.

Hello, soros világ — Arduino C++

hello.ino
void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(10); }
  Serial.println("ESP32 elindult");
}

void loop() {
  Serial.printf("Uptime: %lu ms, szabad heap: %u byte\n",
                millis(), ESP.getFreeHeap());
  delay(1000);
}
SZINT · ALAP
03

GPIO: a fizikai világ kapcsolói

A lábak villamos pontok, nem absztrakt változók. A 3,3 V-os határ, az áramkorlát és a boot-strapping pinek ismerete megóvja a panelt.

Biztonságos alapszabályok

  • Soha ne adj 5 V-ot közvetlenül GPIO-ra.
  • LED-hez használj 220–1000 Ω soros ellenállást.
  • GPIO 34–39 csak bemenet a klasszikus ESP32-n.
  • GPIO 6–11 tipikusan a flashhez foglalt.
  • Boot pineknél (0, 2, 5, 12, 15) a külső szint indítási hibát okozhat.

Gyakori lábkiosztás

21 / 22I²C SDA / SCL
16 / 17UART2 RX / TX
18 / 19 / 23SPI SCK/MISO/MOSI
25 / 26DAC kimenet

A kiosztás boardonként változhat; ellenőrizd a panel rajzát.

LED és gomb — blokkolásmentesen

gpio.ino
constexpr uint8_t LED = 2;
constexpr uint8_t BUTTON = 27;
uint32_t lastToggle = 0;
bool ledState = false;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP); // gomb a GND felé
}

void loop() {
  uint32_t now = millis();
  if (now - lastToggle >= 500) { // túlcsordulásbiztos
    lastToggle = now;
    ledState = !ledState;
    digitalWrite(LED, ledState);
  }
  if (digitalRead(BUTTON) == LOW) { /* esemény */ }
}

Gyors ellenőrzés

Mekkora logikai feszültségre készültek az ESP32 GPIO-k?

SZINT · ALAP
04

Időzítés, PWM és megszakítások

A jó firmware nem várakozik: eseményekre reagál. A delay() helyett állapotgépek, hardveres időzítők és rövid ISR-ek dolgoznak.

PWM / LEDC

A PWM gyors ki-be kapcsolással állít elő átlagos teljesítményt LEDhez vagy motorvezérlőhöz. A frekvencia és felbontás kompromisszum: több bithez alacsonyabb maximális frekvencia társul.

pwm.ino
const int pwmPin = 25;
void setup() {
  ledcAttach(pwmPin, 5000, 8);
  ledcWrite(pwmPin, 128); // kb. 50%
}

ISR szabálykönyv

  • Legyen rendkívül rövid és nem blokkoló.
  • Ne használj benne delay()-t vagy hálózatot.
  • Megosztott jelző legyen volatile.
  • ISR-ből FreeRTOS ...FromISR API-t használj.
  • A valódi feldolgozást bízd a loop()-ra vagy taskra.

Eseményvezérelt gondolkodás

GPIO / timer ISR
jelzést ad
queue / flag
átadja
task
feldolgozza
SZINT · ALAP+
05

Szenzorok és adatbuszok

A perifériák nyelve négy alapmintára szűkíthető: analóg mérés, kétvezetékes címzett busz, gyors szinkron busz és soros adatfolyam.

Buszválasztó

BuszVezetékJellemző
I²C2 + GNDSok címzett eszköz, pull-up kell
SPI3 + CS/eszközNagy sebesség, kijelző/SD
UARTTX/RXPont–pont, GPS/modem
ADCjel + GNDAnalóg, zajos és nem tökéletesen lineáris

ADC csapda Wi‑Fi mellett

A klasszikus ESP32 ADC2 csatornáit a Wi‑Fi alrendszer is használja. Aktív Wi‑Fi mellett analóg méréshez válassz ADC1 lábat. Átlagolj több mintát, és valódi feszültséghez kalibrálj.

I²C: a SDA/SCL vonal nyitott drain, ezért felhúzóellenállás kell; sok modulon már van.

I²C busz felderítése

i2c_scanner.ino
#include <Wire.h>
void setup() {
  Serial.begin(115200); Wire.begin(21, 22);
  for (uint8_t address = 1; address < 127; ++address) {
    Wire.beginTransmission(address);
    if (Wire.endTransmission() == 0)
      Serial.printf("Eszköz: 0x%02X\n", address);
  }
}
void loop() {}
SZINT · KÖZÉP
06

Wi‑Fi, amely újra is csatlakozik

A hálózat nem állapot, hanem folyamat. Egy terméknek kezelnie kell a kimaradást, az újracsatlakozást és a konfiguráció változását.

STA, AP és AP+STA

  • STA: az ESP32 egy meglévő routerhez kapcsolódik.
  • AP: saját hálózatot hoz létre, jó első konfigurációhoz.
  • AP+STA: mindkettő egyszerre, de több memória és rádióidő.

Hitelesítő adatok

Ne tedd a jelszót publikus forráskódba. Fejlesztéskor külön, gitignore-olt konfigurációt; termékben provisioninget és NVS-t használj. TLS nélkül a rádiós hálózat nem jelent alkalmazásszintű titkosítást.

Időkorlátos kapcsolódás

wifi.ino
#include <WiFi.h>
void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  uint32_t started = millis();
  while (WiFi.status() != WL_CONNECTED &&
         millis() - started < 15000) {
    delay(100);
  }
  if (WiFi.status() == WL_CONNECTED)
    Serial.println(WiFi.localIP());
  else Serial.println("Offline mód");
}

Gyors ellenőrzés

Melyik megoldás a robusztus?

SZINT · KÖZÉP
07

Web, REST, MQTT és OTA

Az ESP32 lehet kliens, webszerver és üzenetküldő végpont. A protokollt az adat ritmusa és a rendszer felelőssége alapján válaszd.

Protokollmátrix

MegoldásJó választás
HTTP/RESTRitka kérés–válasz, konfiguráció
WebSocketÉlő böngészős kétirányú adat
MQTTSok eszköz, publish/subscribe telemetria
OTAFirmware-frissítés kábel nélkül

Biztonsági minimum

  • TLS tanúsítvány-ellenőrzéssel
  • Hitelesítés minden állapotmódosító végponton
  • Bemenet méret- és tartalomellenőrzése
  • Aláírt firmware és rollback OTA esetén
  • Titkok nem kerülnek logba vagy Gitbe

Egyszerű REST végpont

webserver.ino
#include <WebServer.h>
WebServer server(80);

void setupRoutes() {
  server.on("/api/status", HTTP_GET, []() {
    String json = "{\"uptime\":" + String(millis()) + "}";
    server.send(200, "application/json", json);
  });
  server.onNotFound([](){ server.send(404, "text/plain", "Not found"); });
  server.begin();
}
// loop(): server.handleClient(); — ne legyen hosszú blokkolás mellette
SZINT · KÖZÉP
08

Bluetooth Low Energy

A BLE nem „vezeték nélküli soros port”: szolgáltatásokból, karakterisztikákból és szabályozott adatcseréből álló GATT modellt használ.

GATT mentális modell

Peripheral
ESP32
Service
pl. környezet
Characteristic
hőmérséklet

Adatmozgások

  • Read: kliens lekérdezi az értéket
  • Write: kliens konfigurál
  • Notify: eszköz változáskor küld
  • Indicate: nyugtázott értesítés

A rövid advertising csomag segít felfedezni az eszközt; a kapcsolat több energiát kér.

Tervezési döntések

Használj szabványos service UUID-t, ha létezik. Saját UUID esetén dokumentáld a byte-sorrendet, skálázást, mértékegységet és verziót. A BLE titkosítás nem helyettesíti automatikusan a jogosultságkezelést: érzékeny íráshoz párosítás és alkalmazásszintű ellenőrzés kell.

SZINT · KÖZÉP+
09

Adattárolás és energiamenedzsment

A tartós rendszer tudja, mit érdemes megőrizni és mikor érdemes elaludni. A flash írás véges, az akkumulátor energiája még inkább.

Tárolóválasztás

  • Preferences/NVS: kis konfigurációs kulcs–érték párok
  • LittleFS: fájlok, webes assetek, naplórészletek
  • SD: nagy mérési adatsorok
  • RTC memória: kis állapot deep sleep ciklusok között

Energiabüdzsé

Az üzemidőt az átlagáram határozza meg: aktív mérés + rádiós adás + alvás súlyozott összege. A Wi‑Fi rövid áramcsúcsai miatt a stabil táp és a pufferkondenzátor kritikus.

Gyakori hiba: breadboardon működik, akkumulátorról resetel — a táp pillanatnyi áramot nem tud biztosítani.

Időzített deep sleep

sleep.ino
constexpr uint64_t SECOND_US = 1000000ULL;
void setup() {
  Serial.begin(115200);
  // mérés → mentés → küldés, majd:
  esp_sleep_enable_timer_wakeup(60 * SECOND_US);
  Serial.flush();
  esp_deep_sleep_start();
}
void loop() {}
SZINT · HALADÓ
10

Hibakeresés és megbízhatóság

A soros log csak a kezdet. A reset ok, heap trend, stack vízjel és dekódolt backtrace együtt mondja el, mi történt.

Hibatípus → nyom

TünetElső ellenőrzés
Brownout resetTápfeszültség és áramcsúcs
Guru MeditationBacktrace, null pointer, tömbhatár
WatchdogBlokkoló ciklus, task starvation
Random fagyásHeap, stack, race condition

Figyeld a rendszert

health.cpp
Serial.printf(
  "heap=%u minHeap=%u core=%d reset=%d\n",
  ESP.getFreeHeap(),
  ESP.getMinFreeHeap(),
  xPortGetCoreID(),
  esp_reset_reason()
);

Robusztussági ellenőrzőlista

TimeoutMinden külső várakozáson
RetryExponenciális backoffal
BoundsMinden bemeneten
RecoveryIsmert biztonságos állapot
SZINT · HALADÓ
11

FreeRTOS és a két mag

A párhuzamosság célja nem az, hogy mindenből task legyen. Feladatokra bontjuk a felelősséget, üzenetekkel kommunikálunk, és mérhetően tartjuk a határidőket.

Alapfogalmak

  • Task: saját stackkel rendelkező futási egység
  • Scheduler: prioritás alapján oszt CPU-időt
  • Queue: biztonságos, másolt üzenetátadás
  • Mutex: közös erőforrás kizárólagos védelme
  • Semaphore: esemény vagy kapacitás jelzése
  • Notification: könnyű, gyors task-jelzés

Core 0 és Core 1

A klasszikus Arduino-ESP32 környezetben a rádiós rendszerfeladatok jellemzően a 0. magon, az Arduino setup/loop pedig az 1. magon fut. Ez implementációs részlet lehet; mérd és ellenőrizd a használt core verzióban.

Ne pinelj reflexből. Az xTaskCreate() szabad ütemezése sokszor jobb. Maghoz rögzítés csak mérhető indokkal.

Producer–consumer queue két magon

dual_core.ino
#include <Arduino.h>
struct Sample { uint32_t at; float value; };
QueueHandle_t samples;

void sensorTask(void*) {
  TickType_t last = xTaskGetTickCount();
  for (;;) {
    Sample s{millis(), analogReadMilliVolts(34) / 1000.0f};
    xQueueOverwrite(samples, &s); // queue hossza 1
    vTaskDelayUntil(&last, pdMS_TO_TICKS(100));
  }
}

void networkTask(void*) {
  Sample s;
  for (;;) {
    if (xQueueReceive(samples, &s, portMAX_DELAY) == pdTRUE)
      Serial.printf("t=%lu V=%.3f core=%d\n", s.at, s.value, xPortGetCoreID());
  }
}

void setup() {
  Serial.begin(115200);
  samples = xQueueCreate(1, sizeof(Sample));
  xTaskCreatePinnedToCore(sensorTask, "sensor", 3072, nullptr, 2, nullptr, 1);
  xTaskCreatePinnedToCore(networkTask, "network", 4096, nullptr, 1, nullptr, 0);
}
void loop() { vTaskDelay(portMAX_DELAY); }

Race condition

Két task egyszerre olvas és ír közös adatot; az eredmény az időzítéstől függ. Első választásként tulajdonost és queue-t tervezz. Mutexet rövid kritikus szakaszra használj, és soha ne tartsd hálózati várakozás alatt.

Stack és prioritás

Az ESP32 FreeRTOS stackméretei bájtban értendők az Arduino környezet gyakori API-jainál. Mérj uxTaskGetStackHighWaterMark()-kal. A túl magas prioritás kiéheztetheti a rendszerfeladatokat és watchdog resetet okozhat.

Gyors ellenőrzés

Mi a legjobb alapminta taskok közti szenzoradat-átadáshoz?

SZINT · HALADÓ++
12

Záróprojekt: kapcsolt mérőállomás

Építs környezeti állomást szenzorral, helyi kijelzővel, MQTT telemetriával, webes állapotoldallal és biztonságos frissítéssel.

Referenciaarchitektúra

Sensor task
100 ms / Core 1
queue →
State owner
szűrés + snapshot
Network task
MQTT / Core 0
Button ISR
notification
UI task
kijelző
NVS config
verziózott

Mérföldkövek

  1. Szenzor stabil olvasása és kalibráció
  2. Blokkolásmentes helyi kijelzés
  3. Queue-alapú task szétválasztás
  4. Wi‑Fi reconnect + MQTT backoff
  5. Konfiguráció és deep sleep mód
  6. Aláírt OTA + rollback próba

Elfogadási kritériumok

  • 24 órás futás reset és növekvő heap-vesztés nélkül
  • Router-kiesés után automatikus helyreállás
  • Szenzorhiba jelzett, nem hamis adat
  • Stack vízjelek dokumentálva
  • GPIO és táp bekötési rajz rögzítve
  • Firmware-verzió látható a diagnosztikában

Továbbhaladás

Ha ez stabil, lépj ESP-IDF-re: komponensek, Kconfig, event loop, esp_timer, native HTTP/MQTT kliensek, secure boot, flash encryption, particionálás és Unity-alapú egységtesztek. A professzionális fejlődés kulcsa nem az újabb library, hanem a mérhető követelmény, tiszta felelősség és reprodukálható build.

Zárókérdés

Mitől lesz „kész” egy beágyazott projekt?

SZINT · RENDSZERÉPÍTŐ
13

Projektlabor: gyalogos jelzőlámpa

Három LED, egy nyomógomb és egy blokkolásmentes állapotgép. A projekt megtanítja, hogyan kezeld az időt delay() nélkül.

Alkatrészek

  • 1× ESP32 DevKit V1
  • 1× piros, 1× sárga, 1× zöld LED
  • 3× 330 Ω ellenállás
  • 1× nyomógomb
  • Breadboard és jumper vezetékek

Bekötés

ESP32AlkatrészMásik pont
GPIO 25Piros LED anódKatód → 330 Ω → GND
GPIO 26Sárga LED anódKatód → 330 Ω → GND
GPIO 27Zöld LED anódKatód → 330 Ω → GND
GPIO 32Nyomógomb egyik lábaMásik láb → GND

Miért nincs külső gombellenállás? Az INPUT_PULLUP bekapcsolja a belső felhúzást, így megnyomva LOW értéket olvasunk.

Teljes program

traffic_light.ino
constexpr uint8_t RED=25, YELLOW=26, GREEN=27, BUTTON=32;
enum class State { CarsGo, Prepare, Pedestrians };
State state = State::CarsGo;
uint32_t changedAt = 0, lastPress = 0;

void show(bool r, bool y, bool g) {
  digitalWrite(RED,r); digitalWrite(YELLOW,y); digitalWrite(GREEN,g);
}
void setup() {
  for (uint8_t pin : {RED,YELLOW,GREEN}) pinMode(pin,OUTPUT);
  pinMode(BUTTON,INPUT_PULLUP); show(0,0,1);
}
void loop() {
  uint32_t now=millis();
  if (state==State::CarsGo && !digitalRead(BUTTON) && now-lastPress>250) {
    lastPress=now; state=State::Prepare; changedAt=now; show(0,1,0);
  }
  if (state==State::Prepare && now-changedAt>=1500) {
    state=State::Pedestrians; changedAt=now; show(1,0,0);
  }
  if (state==State::Pedestrians && now-changedAt>=5000) {
    state=State::CarsGo; changedAt=now; show(0,0,1);
  }
}

Próba

  1. Bekapcsoláskor csak a zöld világít.
  2. Nyomd meg a gombot: 1,5 s sárga következik.
  3. A piros 5 s-ig világít, majd visszatér a zöld.
  4. Nyomogasd gyorsan: a 250 ms debounce kiszűri a pattogást.

Továbbfejlesztés

Adj hozzá gyalogos zöld/piros LED-et és csipogót. Készíts külön enterState() függvényt, és a soros monitorra írd ki az állapotváltásokat.

PROJEKT · KEZDŐ · 35 PERC
14

Projektlabor: DHT22 + OLED állomás

Mérj hőmérsékletet és páratartalmat, majd jelenítsd meg egy 0,96″-os I²C OLED kijelzőn, hibás szenzorértékek kezelésével.

Alkatrészek és könyvtárak

  • ESP32 DevKit V1, DHT22 modul
  • SSD1306 128×64 I²C OLED
  • 10 kΩ felhúzó, ha a DHT22 nem modul
  • Arduino Library Manager: DHT sensor library, Adafruit Unified Sensor, Adafruit SSD1306, Adafruit GFX

Bekötés

ModulESP32Megjegyzés
DHT22 VCC3V3Ne 5 V-ról add az adatjelet
DHT22 DATAGPIO 410 kΩ DATA–3V3, ha csupasz szenzor
DHT22 GNDGNDKözös föld
OLED VCC / GND3V3 / GNDModul adatlapját ellenőrizd
OLED SDA / SCLGPIO 21 / 22Tipikus I²C cím: 0x3C

Teljes program

dht_oled.ino
#include <Wire.h>
#include <DHT.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

constexpr uint8_t DHT_PIN=4;
DHT dht(DHT_PIN,DHT22);
Adafruit_SSD1306 display(128,64,&Wire,-1);

void setup() {
  Serial.begin(115200); dht.begin(); Wire.begin(21,22);
  if (!display.begin(SSD1306_SWITCHCAPVCC,0x3C)) {
    Serial.println("OLED nem található"); while(true) delay(1000);
  }
  display.setTextColor(SSD1306_WHITE);
}
void loop() {
  float humidity=dht.readHumidity(), temperature=dht.readTemperature();
  display.clearDisplay(); display.setCursor(0,0); display.setTextSize(2);
  if (isnan(humidity) || isnan(temperature)) {
    display.println("Szenzorhiba"); Serial.println("DHT olvasasi hiba");
  } else {
    display.printf("%.1f C\n%.1f %%",temperature,humidity);
    Serial.printf("T=%.1f C RH=%.1f %%\n",temperature,humidity);
  }
  display.display(); delay(2000); // DHT22-t ne olvasd túl gyorsan
}

Ha üres a kijelző

  • Futtasd az I²C scannert: 0x3C vagy 0x3D?
  • Ellenőrizd az SDA/SCL sorrendet és a közös GND-t.
  • SH1106 vezérlős kijelzőhöz más könyvtár kellhet.

Mérési ellenőrzés

Ne közvetlenül az ESP32 vagy tápegység fölé tedd a DHT22-t, mert a saját hőjük torzít. Hasonlítsd referencia-hőmérőhöz, és dokumentáld az eltérést.

PROJEKT · KÖZÉP · 60 PERC
15

Projektlabor: Wi‑Fi relévezérlő

Kapcsolj kisfeszültségű terhelést telefonról, helyi weboldallal. Megtanulod a relémodul bekötését, az állapotvégpontot és a biztonságos alapállapotot.

Alkatrészek

  • ESP32 DevKit V1
  • 3,3 V logikával biztosan vezérelhető, optocsatolt relémodul
  • Kisfeszültségű próbalámpa vagy LED-modul
  • Külön, megfelelő terhelhetőségű modul-táp szükség szerint

Biztonság: ez a labor kizárólag érintésvédelmileg biztonságos kisfeszültséghez készült. Hálózati 230 V bekötését csak szakképzett villanyszerelő végezheti megfelelő házban és védelemmel.

Bekötés

RelémodulESP32 / terhelés
INGPIO 26
VCCA modul előírt tápja; 3V3 csak ha támogatott
GNDESP32 GND (közös referencia)
COMKisfeszültségű táp pozitív ága
NOTerhelés pozitív pontja
Terhelés másik pontjaKisfeszültségű táp negatív ága

Sok modul aktív LOW. A példában ezt a RELAY_ON konstans kezeli.

Teljes program

wifi_relay.ino
#include <WiFi.h>
#include <WebServer.h>
constexpr uint8_t RELAY=26, RELAY_ON=LOW, RELAY_OFF=HIGH;
const char* SSID="HALOZAT_NEVE"; const char* PASS="JELSZO";
WebServer server(80); bool relayOn=false;

void setRelay(bool on) { relayOn=on; digitalWrite(RELAY,on?RELAY_ON:RELAY_OFF); }
void sendPage() {
  String html="<!doctype html><meta name='viewport' content='width=device-width'>"
    "<h1>ESP32 rele</h1><p>Allapot: " + String(relayOn?"BE":"KI") +
    "</p><p><a href='/on'>BE</a> | <a href='/off'>KI</a></p>";
  server.send(200,"text/html; charset=utf-8",html);
}
void setup() {
  Serial.begin(115200); pinMode(RELAY,OUTPUT); setRelay(false);
  WiFi.begin(SSID,PASS); uint32_t started=millis();
  while (WiFi.status()!=WL_CONNECTED && millis()-started<15000) delay(100);
  if (WiFi.status()!=WL_CONNECTED) { Serial.println("Wi-Fi hiba"); return; }
  Serial.println(WiFi.localIP());
  server.on("/",sendPage);
  server.on("/on",[]{setRelay(true); server.sendHeader("Location","/"); server.send(303);});
  server.on("/off",[]{setRelay(false); server.sendHeader("Location","/"); server.send(303);});
  server.begin();
}
void loop() { server.handleClient(); delay(2); }

Használat

  1. Írd át az SSID-t és jelszót, majd töltsd fel.
  2. A soros monitoron keresd meg az IP-címet.
  3. Ugyanarról a Wi‑Fi-ről nyisd meg telefonon.
  4. Reset közben ellenőrizd: a relé maradjon biztonságos KI állapotban.

Termék előtt kötelező

A példa csak helyi, megbízható hálózatra való. Éles rendszerhez hitelesítés, CSRF-védelem, TLS vagy biztonságos átjáró, konfigurációs provisioning és watchdog szükséges.

PROJEKT · KÖZÉP · 75 PERC
16

Projektlabor: kétmagos MQTT szenzor

A mérés az 1. magon, a hálózati kommunikáció a 0. magon fut. Queue választja szét a felelősségeket, a Wi‑Fi és MQTT pedig megszakadás után újracsatlakozik.

Hardver és függőségek

  • ESP32 DevKit V1 + DHT22
  • DHT22 VCC → 3V3, DATA → GPIO 4, GND → GND
  • 10 kΩ DATA–3V3 felhúzó csupasz szenzornál
  • Library Manager: DHT sensor library, Adafruit Unified Sensor, PubSubClient
  • Elérhető MQTT broker a helyi hálózaton

Adatút

DHT22
GPIO 4
sensorTask
Core 1 / 2 s
queue →
mqttTask
Core 0

A queue hossza 1 és xQueueOverwrite() mindig a legfrissebb mintát tartja meg. Lassú hálózat nem torlaszolja fel a régi méréseket.

Teljes program

dual_core_mqtt.ino
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
const char* SSID="HALOZAT"; const char* PASS="JELSZO";
const char* BROKER="192.168.1.10";
DHT dht(4,DHT22); WiFiClient tcp; PubSubClient mqtt(tcp); QueueHandle_t samples;
struct Sample { float temperature,humidity; uint32_t at; };

void sensorTask(void*) {
  TickType_t last=xTaskGetTickCount();
  for(;;) {
    Sample s{dht.readTemperature(),dht.readHumidity(),millis()};
    if(!isnan(s.temperature) && !isnan(s.humidity)) xQueueOverwrite(samples,&s);
    vTaskDelayUntil(&last,pdMS_TO_TICKS(2000));
  }
}
bool ensureNetwork() {
  if(WiFi.status()!=WL_CONNECTED) {
    WiFi.begin(SSID,PASS); for(int i=0;i<50 && WiFi.status()!=WL_CONNECTED;i++) vTaskDelay(pdMS_TO_TICKS(100));
  }
  if(WiFi.status()!=WL_CONNECTED) return false;
  if(!mqtt.connected()) mqtt.connect("esp32-lab");
  return mqtt.connected();
}
void mqttTask(void*) {
  Sample s; char payload[96]; mqtt.setServer(BROKER,1883);
  for(;;) {
    if(ensureNetwork()) { mqtt.loop();
      if(xQueueReceive(samples,&s,pdMS_TO_TICKS(100))==pdTRUE) {
        snprintf(payload,sizeof(payload),"{\"temperature\":%.1f,\"humidity\":%.1f,\"uptime\":%lu}",s.temperature,s.humidity,s.at);
        mqtt.publish("lab/esp32/environment",payload,true);
      }
    } else vTaskDelay(pdMS_TO_TICKS(2000));
  }
}
void setup() {
  Serial.begin(115200); dht.begin(); WiFi.mode(WIFI_STA);
  samples=xQueueCreate(1,sizeof(Sample)); if(!samples) ESP.restart();
  xTaskCreatePinnedToCore(sensorTask,"sensor",3072,nullptr,2,nullptr,1);
  xTaskCreatePinnedToCore(mqttTask,"mqtt",6144,nullptr,1,nullptr,0);
}
void loop() { vTaskDelay(portMAX_DELAY); }

Próba és megfigyelés

  1. Állítsd be a Wi‑Fi-t és a broker IP-jét.
  2. Iratkozz fel: mosquitto_sub -h BROKER_IP -t lab/esp32/environment -v.
  3. Kapcsold ki 20 másodpercre a routert, majd vissza.
  4. Figyeld, hogy a mérés folytatódik és a publikálás helyreáll.

Termékesítés előtt

Adj hozzá MQTT felhasználót/jelszót, TLS tanúsítvány-ellenőrzést, véletlenített exponenciális backoffot, egyedi kliensazonosítót és Last Will üzenetet. A Wi‑Fi stack feladataival való versengést mérd, ne csak feltételezd.

Projektellenőrzés

Miért használunk egyetlen elemű queue-t ebben a telemetria-projektben?

PROJEKT · HALADÓ · 120 PERC