Zápisník experimentátora
Hierarchy: ESP8266
V predchádzajúcich článkoch sme sa naučili vytvoriť HTTP server pomocou mikrokontroléra ESP8266. Doteraz sme zobrazovali statické stránky. Postupne sme sa naučili zobraziť stránky, ktoré boli v zdrojovom kóde programu, alebo boli uložené v súborovom systéme SPIFFS. Dnes sa posunieme o kus ďalej. Statickú stránku nahradíme dynamickou stránkou, ktorá bude zobrazovať teplotu. Teplotu budeme merať pomocou integrovaného obvodu DS18B20.
V ESP8266 je nahraný program, ktorý zobrazuje jedinú stránku. Na stránke je zobrazená aktuálna teplota v miestnosti. HTML kód stránky je vytvorený pomocou knižnice Bootstrap, ktorá zabezpečuje responzívny dizajn. Stránka zobrazuje dva stavy:
Program funguje tak, že si zo súborového systému SPIFFS stiahne šablónu HTML stránky a v nej nahradí premennú skutočnou teplotou. Potom výslednú stránku odošle do prehliadača. Toto je jeden možný spôsob, ako sa dá vytvoriť výsledná stránka v prehliadači. Pokiaľ potrebujete meranú teplotu zobraziť v prehliadači len občas a netrápi vás, či neprenášate pri každej obnove stránky príliš veľa informácií, ktoré sa nikdy nemenia, potom je tento spôsob na to vhodný. V pokračovaní tohto seriálu si ukážeme, že sa to dá urobiť aj inak a ukážeme si, ako sa dá oddeliť grafika od prenášaných údajov.
Budeme potrebovať tieto súčiastky:
Súčiastky sú zapojené podľa tejto schémy. Na pine D6 musí byť zapojený pull-up rezistor. Senzor teploty je zapojený normálne na GND a 3,3 V. Ak máte originálne senzory teploty, môžete ho zapojiť aj v parazitickom napájaní.
Tento príklad bude fungovať iba vtedy, ak si zdrojový kód stiahnete z GitHub a obsah adresára data prenesiete do SPIFFS pomocou príkazu Tools/ESP8266 Sketch Data Upload
.
Šablóna HTML stránky sa nachádza v súbore index.html. Je to jednoduchý kód pre responzívny dizajn pomocou knižnice Bootstrap. Dôležitá je iba premenná {TEMPERATURE}
, ktorá je vo výslednej stránke nahradená meranou teplotou.
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link rel="icon" type="image/png" href="favicon.png">
<title>HTTP Server ESP8266 - DS18B20</title>
</head>
<body>
<div class="container">
<h1>ESP8266 HTTP Server</h1>
<p>Temperature: <b>{TEMPERATURE}</b></p>
<p>Copyright (C) 2019 <a href="https://www.arduinoslovakia.eu">Arduino Slovakia</a>.</p>
</div>
</body>
</html>
Takto vyzerá zdrojový kód programu. Základom programu je HTTP server, ktorý počúva na porte 80. Teplota je meraná pomocou senzora teploty DS18B20. Použité knižnice možno rozdeliť na dve skupiny.
Pretože výsledkom programu je jediná stránka, v programe ju vytvára funkcia handleRoot
. Táto stránka je ale v skutočnosti zložená z dvoch častí. Jednou je samotný vygenerovaný HTML kód. Druhou je malá ikona, ktorá sa zobrazuje na záložke v prehliadači. Ikona je malý PNG súbor favicon.png, na ktorý je odkaz v zdrojovom kóde HTML stránky. Prehliadač si tento obrázok vyžiada a pretože pri ňom nemusíme robiť žiadne úpravy, môžeme ho staticky poskytnúť priamo zo SPIFFS.
Funkcia handleRoot najprv overí, či máme v SPIFFS uložený súbor index.html. Potom si obsah súboru uloží do premennej body
. Nasleduje meranie teploty, ktoré môže mať dva výsledky.
Výsledok sa nahradí v šablóne HTML stránky namiesto reťazca {TEMPERATURE}
. Aby výsledok dobre vyzeral, je použité formátovanie pomocou Bootstrap CSS štýlov alert-danger a alert-info.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include "arduino_secret.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D6
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
ESP8266WebServer server(80);
void handleRoot() {
Serial.println("GET /");
File f = SPIFFS.open("/index.html", "r");
if (!f) {
Serial.println("File '/index.html' open failed.");
server.send(500, "text/plain", "500: File '/index.html' open failed.");
}
else {
String body = f.readString();
if (sensors.getDS18Count() == 0) {
body.replace("{TEMPERATURE}", "<div class=\"alert alert-danger\">ERROR</div>");
}
else {
sensors.requestTemperatures();
double temp = sensors.getTempCByIndex(0);
Serial.println(temp);
String tempt = "<div class=\"alert alert-info\">" + String(temp) + " °C</div>";
body.replace("{TEMPERATURE}", tempt);
}
server.send(200, "text/html", body);
f.close();
}
}
void setup(void) {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
sensors.begin();
SPIFFS.begin();
server.serveStatic("/favicon.png", SPIFFS, "/favicon.png");
server.on("/", handleRoot);
server.onNotFound([]() {
server.send(404, "text/plain", "404: Not Found");
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
}
Zdrojový kód sa nachádza na serveri GitHub.
13.08.2019