blog

ESP32 WiFi-projekti: Lämpötilan etäseuranta verkossa

Haluatko rakentaa oman IoT-laitteen, jolla voit seurata lämpötilaa mistä tahansa kotiverkkosi laitteelta – puhelimella, tabletilla tai tietokoneella? Tässä artikkelissa rakennamme askel askeleelta ESP32 wifi projektin, jossa ESP32-mikrokontrolleri toimii web-palvelimena ja näyttää lämpötilatiedot tyylikkäällä verkkosivulla – reaaliaikaisella Chart.js-kuvaajalla höystettynä. Tarvitset vain ESP32-kehitysalustan ja USB-kaapelin, ja noin 15 minuutissa sinulla on toimiva lämpötilan etäseurantajärjestelmä.

Tämä on erinomainen IoT-projekti aloittelijoille, sillä hyödynnämme ESP32-C6:n sisäistä lämpötila-anturia. Ulkoista sensoria ei tarvita alkuun pääsemiseksi! Artikkelin lopussa näytämme myös, miten projektin voi päivittää ulkoisella DHT11/DHT22-anturilla tarkempaa mittausta varten.

Mitä tarvitset tähän ESP32 wifi projektiin?

Tämän projektin hienous on sen minimaalinen komponenttilista. Perusprojektiin tarvitset ainoastaan:

  • ESP32 DevKitC – ESP32-C6-pohjainen kehitysalusta, jossa on sisäänrakennettu Wi-Fi 6, Bluetooth 5.3 ja lämpötila-anturi
  • USB-C-kaapeli – virransyöttöön ja ohjelmointiin
  • Tietokone – Arduino IDE:llä ja samassa Wi-Fi-verkossa
ESP32 DevKitC (WROOM-32)
ESP32 DevKitC (WROOM-32) – tämän projektin ydin. Sisäänrakennettu Wi-Fi 6 ja lämpötila-anturi tekevät siitä täydellisen IoT-alustan.

Jos haluat myöhemmin mitata ympäristön lämpötilaa tarkasti, tarvitset lisäksi DHT11- tai DHT22-anturin sekä Dupont-hyppylankoja kytkentää varten.

Näin projekti toimii

Projektin arkkitehtuuri on yksinkertainen mutta tehokas. Käymme läpi kolme keskeistä konseptia:

ESP32 web server – mikrokontrolleri palvelimena

ESP32 yhdistää kotiverkkosi Wi-Fi-tukiasemaan (STA-tila eli Station Mode) ja saa oman IP-osoitteen. Tämän jälkeen se kuuntelee porttia 80 HTTP-pyyntöjä varten – aivan kuten tavallinen web-palvelin. Mikä tahansa samassa verkossa oleva laite (puhelin, tabletti, tietokone) voi avata ESP32:n IP-osoitteen selaimessa ja nähdä lämpötilatiedot.

AJAX – sivun päivitys ilman uudelleenlatausta

AJAX (Asynchronous JavaScript and XML) mahdollistaa verkkosivun osittaisen päivittämisen ilman koko sivun uudelleenlatausta. Selain lähettää taustalla HTTP-pyynnön ESP32:lle ja päivittää vain lämpötila-arvon. Käytämme modernia fetch-rajapintaa, joka on selkeä ja helppolukuinen.

Chart.js – reaaliaikainen kuvaaja

Chart.js on ilmainen JavaScript-kirjasto, joka ladataan CDN:stä (Content Delivery Network). Se piirtää responsiivisen viivakaavion lämpötilahistoriasta suoraan selaimeen. Huomaa, että Chart.js ladataan asiakaspäässä – eli puhelimesi tai tietokoneesi tarvitsee internet-yhteyden, vaikka ESP32 toimii vain paikallisverkossa.

Arduino IDE:n valmistelu

Ennen koodin lataamista ESP32-C6:lle tarvitset Arduino IDE:n oikeat asetukset:

  1. Avaa Arduino IDE (versio 2.x suositeltava)
  2. Mene File → Preferences ja lisää ”Additional Board Manager URLs” -kenttään:
    https://espressif.github.io/arduino-esp32/package_esp32_index.json
  3. Avaa Tools → Board → Boards Manager, etsi ”esp32” ja asenna esp32 by Espressif Systems (versio 3.x)
  4. Valitse Tools → Board → esp32 → ESP32C6 Dev Module
  5. Valitse oikea portti: Tools → Port (esim. COM3 Windowsissa tai /dev/ttyUSB0 Linuxissa)
  6. Aseta USB CDC On Boot: Enabled – tämä mahdollistaa Serial-tulostuksen USB:n kautta

Nyt ympäristö on valmis ESP32 wifi projektin koodia varten!

Valmis Arduino-koodi

Alla on koko projektin koodi yhdessä tiedostossa. Kopioi se Arduino IDE:hen ja muuta Wi-Fi-tunnukset omiksi. Koodi sisältää HTML-sivun, CSS-tyylit, JavaScript-logiikan ja Chart.js-kuvaajan – kaikki PROGMEM-muistissa.

#include <WiFi.h>
#include <WebServer.h>

// Vaihda oman Wi-Fi-verkkosi tiedot
const char* ssid = "OMAN_VERKON_NIMI";
const char* password = "OMAN_VERKON_SALASANA";

WebServer server(80);

// Lue ESP32-C6:n sisäinen lämpötila-anturi
float readTemperature() {
  return temperatureRead();
}

// HTML-sivu tallennetaan flash-muistiin (PROGMEM)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="fi">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ESP32 Lämpötilaseuranta</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      background: #1a1a2e;
      color: #eee;
      margin: 0;
      padding: 20px;
    }
    .card {
      background: #16213e;
      border-radius: 12px;
      padding: 20px;
      max-width: 600px;
      margin: 20px auto;
      box-shadow: 0 4px 15px rgba(0,0,0,0.3);
    }
    h1 { color: #e94560; }
    .temp-value {
      font-size: 3em;
      color: #0f3460;
      font-weight: bold;
    }
    canvas { max-width: 100%; }
  </style>
</head>
<body>
  <h1>🌡 ESP32 Lämpötilaseuranta</h1>
  <div class="card">
    <p>Nykyinen lämpötila:</p>
    <p class="temp-value"><span id="temp">--</span> °C</p>
  </div>
  <div class="card">
    <canvas id="tempChart"></canvas>
  </div>
  <script>
    const ctx = document.getElementById('tempChart').getContext('2d');
    const tempData = [];
    const timeLabels = [];
    const chart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: timeLabels,
        datasets: [{
          label: 'Lämpötila (°C)',
          data: tempData,
          borderColor: '#e94560',
          backgroundColor: 'rgba(233,69,96,0.1)',
          fill: true,
          tension: 0.3
        }]
      },
      options: {
        responsive: true,
        scales: {
          y: { title: { display: true, text: '°C' } },
          x: { title: { display: true, text: 'Aika' } }
        }
      }
    });

    async function updateTemp() {
      try {
        const response = await fetch('/temperature');
        const temp = await response.text();
        document.getElementById('temp').innerText =
          parseFloat(temp).toFixed(1);

        const now = new Date();
        timeLabels.push(now.toLocaleTimeString('fi-FI'));
        tempData.push(parseFloat(temp));
        if (tempData.length > 30) {
          tempData.shift();
          timeLabels.shift();
        }
        chart.update();
      } catch(e) {
        console.error('Virhe:', e);
      }
    }

    updateTemp();
    setInterval(updateTemp, 5000);
  </script>
</body>
</html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  delay(1000);

  // Yhdistä Wi-Fi-verkkoon
  Serial.println("Yhdistetään Wi-Fi-verkkoon...");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.print("Yhdistetty! IP-osoite: ");
  Serial.println(WiFi.localIP());

  // Määritä reitit
  server.on("/", []() {
    server.send(200, "text/html", index_html);
  });

  server.on("/temperature", []() {
    float temp = readTemperature();
    server.send(200, "text/plain", String(temp));
  });

  server.begin();
  Serial.println("Web-palvelin käynnistetty!");
}

void loop() {
  server.handleClient();
}

Lataus ja testaus

Kun koodi on valmis, seuraa näitä askeleita:

  1. Muuta Wi-Fi-tiedot – korvaa OMAN_VERKON_NIMI ja OMAN_VERKON_SALASANA oman verkkosi tiedoilla
  2. Lataa koodi – paina Arduino IDE:n Upload-nappia (nuoli oikealle)
  3. Avaa Serial Monitor – valitse baudinopeus 115200. Näet yhdistämispisteet ja lopulta IP-osoitteen, esimerkiksi 192.168.1.105
  4. Avaa selain – kirjoita IP-osoite selaimen osoiteriville samassa Wi-Fi-verkossa olevalla laitteella
  5. Seuraa lämpötilaa – sivu näyttää nykyisen lämpötilan ja piirtää kuvaajaa automaattisesti 5 sekunnin välein

Huomio: ESP32-C6:n sisäinen lämpötila-anturi mittaa sirun lämpötilaa, ei ympäristön lämpötilaa. Lukema voi poiketa huoneenlämmöstä merkittävästi – erityisesti Wi-Fi-toiminta nostaa sirun lämpötilaa. Tämä on täysin normaalia ja riittää hyvin projektin demonstrointiin!

Koodin läpikäynti

Käydään läpi koodin tärkeimmät osat, jotta ymmärrät miten ESP32 web server ja ESP32 etäseuranta toimivat käytännössä.

Wi-Fi-yhteyden muodostaminen

WiFi.begin(ssid, password) käynnistää yhteyden muodostamisen. ESP32 toimii STA-tilassa (Station Mode), eli se liittyy olemassa olevaan verkkoon. Vaihtoehtoinen AP-tila (Access Point) loisi oman verkon, mutta STA-tila on käytännöllisempi, koska kaikki kodin laitteet ovat jo samassa verkossa.

Reittien määrittely

server.on("/") määrittää juurireitin, joka palauttaa HTML-sivun. server.on("/temperature") palauttaa pelkän lämpötila-arvon tekstinä. Tämä kahden reitin malli on AJAX-päivityksen ydin: selain lataa HTML-sivun kerran ja pyytää sen jälkeen vain lämpötila-dataa.

PROGMEM ja muistinhallinta

PROGMEM-avainsana tallentaa HTML-merkkijonon flash-muistiin RAM-muistin sijaan. Tämä on tärkeää, koska ESP32-C6:ssa on 512 KB SRAM-muistia – pitkä HTML-sivu veisi siitä merkittävän osan. Flash-muistia on 8 MB, joten sinne mahtuu helposti.

JavaScript ja fetch-rajapinta

setInterval(updateTemp, 5000) kutsuu updateTemp-funktiota 5 sekunnin välein. Funktio käyttää fetch('/temperature')-kutsua hakemaan uuden lämpötila-arvon ESP32:lta ja päivittää sekä numeronäytön että Chart.js-kuvaajan. Kuvaaja säilyttää viimeiset 30 mittauspistettä (2,5 minuutin historia).

Päivitys: ulkoinen lämpötila-anturi

Kun haluat mitata todellista ympäristön lämpötilaa, sisäinen anturi ei riitä. DHT11 tai DHT22 ovat edullisia ja helppokäyttöisiä vaihtoehtoja. Tässä ohjeet päivitykseen:

Kytkentä

  • DHT11 VCC → ESP32 3.3V
  • DHT11 GND → ESP32 GND
  • DHT11 DATA → ESP32 GPIO4 (tai mikä tahansa digitaalinen GPIO)
  • 10 kΩ ylösvetovastus VCC:n ja DATA:n väliin (monissa moduuleissa sisäänrakennettu)

Kytkentään sopivat erinomaisesti Dupont-hyppylangat (uros-naaras), joilla anturin saa kytkettyä suoraan ESP32:n pinneihin.

Dupont-hyppylanka 10cm (20kpl) uros-naaras
Dupont-hyppylangat (uros-naaras) – kätevät kytkentälangat DHT-anturin liittämiseen ESP32:een.

Koodimuutokset

Asenna ensin Arduino IDE:n Library Managerista kirjastot DHT sensor library (Adafruit) ja Adafruit Unified Sensor. Muuta sitten koodin alkuun:

#include <DHT.h>

#define DHTPIN 4
#define DHTTYPE DHT11  // tai DHT22 tarkemmalle anturille

DHT dht(DHTPIN, DHTTYPE);

float readTemperature() {
  float t = dht.readTemperature();
  if (isnan(t)) {
    Serial.println("Virhe: anturin luku epäonnistui!");
    return -999.0;
  }
  return t;
}

Lisää myös dht.begin(); setup-funktion alkuun ennen Wi-Fi-yhdistämistä. Muu koodi pysyy täysin samana – tämä on modulaarisen suunnittelun etu!

DHT11 vs. DHT22 – kumpi valita?

DHT11 on edullisempi ja riittää useimpiin harrastusprojekteihin. Se mittaa lämpötilaa 0–50 °C alueella ±2 °C tarkkuudella ja kosteutta 20–80 % alueella. DHT22 (tunnetaan myös nimellä AM2302) tarjoaa laajemman mittausalueen (−40–80 °C) ja paremman tarkkuuden (±0,5 °C). Jos rakennat esimerkiksi kasvihuoneen tai saunan seurantaa, DHT22 on parempi valinta.

Ideoita jatkokehitykseen

Tämä ESP32 wifi projekti on loistava pohja monenlaisille laajennuksille. Tässä muutamia ideoita seuraaviksi askeliksi:

  • Useita antureita – lisää kosteus-, ilmanpaine- tai valoanturi ja näytä kaikki samalla sivulla
  • MQTT-protokolla – lähetä data MQTT-brokerille (esim. Mosquitto) ja yhdistä Home Assistantiin tai Node-RED:iin
  • Datan tallennus – tallenna mittaukset LittleFS-tiedostojärjestelmään ESP32:n flash-muistiin tai SD-kortille
  • Hälytykset – lähetä sähköposti- tai Terewe-ilmoitus, kun lämpötila ylittää raja-arvon
  • Access Point -tila – luo ESP32:lla oma Wi-Fi-verkko, jolloin erillistä reititintä ei tarvita
  • OTA-päivitykset – päivitä ESP32:n koodi langattomasti ilman USB-kaapelia
  • Syvä uni (Deep Sleep) – paristokäyttöä varten ESP32 voi herätä mittaamaan vain tietyin väliajoin

ESP32-C6:n tuki Zigbeelle ja Threadille avaa myös mahdollisuuksia Matter-älykodin protokollaan – mutta se on jo oma projektinsa!

Hanki tarvikkeet projektiin

Kaikki tämän ESP32 wifi projektin tarvikkeet löydät Protocachen verkkokaupasta:

Yhteenveto

Tässä artikkelissa rakensimme toimivan ESP32-lämpötilan etäseurantajärjestelmän, joka näyttää reaaliaikaisen lämpötilan ja kuvaajan web-selaimessa. Projekti demonstroi ESP32:n käyttöä web-palvelimena, AJAX-pohjaista datan päivitystä ja Chart.js-visualisointia. ESP32 DevKitC Protocachesta on täydellinen alusta tämänkaltaisille IoT-projekteille – sisäänrakennettu Wi-Fi 6 ja lämpötila-anturi tekevät alkuun pääsemisestä helppoa ilman ylimääräisiä komponentteja.

Kokeile projektia itse ja kerro kommenteissa, miten laajennat sitä! Tutustu ESP32 DevKitC -kehitysalustaan ja aloita oma IoT-projektisi jo tänään. Löydät kaikki tarvitsemasi komponentit Protocachen verkkokaupasta.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *