Zápisník experimentátora
Hierarchy: ESP8266
Veľké množstvo príkladov pre ESP8266 používa prehliadač HTML len na zobrazenie statických stránok, ktoré vygeneroval mikrokontrolér. Takto ale fungoval Internet pred desiatimi rokmi. Dnes má v sebe každý prehliadač vysokovýkonné jadro, ktoré pomocou javascriptu dokáže premeniť statické stránky na dynamické. Musíte si uvedomiť, že v prehliadači máte k dispozícii vysoký výkon, ktorý je neporovnateľný s výkonom samotného ESP8266.
Preto si dnes ukážeme, ako tento výkon využiť a výslednú stránku z mikrokontroléra generovať až v prehliadači u užívateľa. ESP8266 bude iba dodávať podkladové údaje a výsledok sa bude zobrazovať pomocou AngularJS v prehliadači. Aby dnešný zdrojový kód nebol pre vás príliš zložitý, napísal som dva vzorové príklady, ktoré simulujú všetko pomocou súborového systému SPIFFS.
V článku využijeme niektoré technológie, ktoré som popisoval v predchádzajúcich článkoch.
Toto je jednoduchý projekt, preto nám bude stačiť niektorá doska s mikrokontrolérom ESP8266, ktorú je možné priamo pripojiť do USB. Aby ste sa vyhli prípadnému skratu, môžete dosku zastrčiť do breadboardu.
Na prvý príklad som si vybral niekoľko gitarových efektov od firmy Digitech. Majú zaujímavé mená (Nautila, Polara, Obscura) a majú aj tajomné obrázky na svojom povrchu. Ako výsledná HTML stránka vyzerá vidíte v nasledujúcom obrázku. Stránka sa skladá z nasledovných súborov.
Poďme si vysvetliť, ako sa vytvára AngularJS aplikácia pomocou tejto šablóny. Na začiatku sa toto načíta do prehliadača a aby sa AngularJS aplikácia spustila, sú potrebné tieto HTML značky. Na začiatku stránky vidíte niekoľko značiek <script>
. Tie sa starajú o to, aby sme si na stránku stiahli responzívny dizajn Bootstrap a AngularJS. Posledná značka <script src="single.js"></script>
načíta do prehliadača zdrojový kód programu. Na to, aby program vedel, kde má na stránke vytvoriť výslednú stránku, nám slúži značka <div ng-app="singleApp" ng-controller="singleCtrl">...</div>
. Takto sme označili miesto pre aplikáciu singleApp s grafickým kontrolérom singleCtrl. Ďalšie značky obsahujú atribúty, ktoré slúžia ako príkazy pre AngularJS. Sú to napríklad atribúty ng-repeat pre vytvorenie cyklu a značky {{xxx}}, ktoré slúžia na zobrazenie obsahu premennej v programe.
<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>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.js"></script>
<script src="single.js"></script>
<link rel="icon" type="image/png" href="favicon.png">
<title>HTTP Server ESP8266 - AngularJS single</title>
</head>
<body>
<div class="container" ng-app="singleApp" ng-controller="singleCtrl">
<h1>ESP8266 HTTP Server - AngularJS Singlepage Application</h1>
<div ng-repeat="x in data.pedals | orderBy: 'name'">
<h2 class="alert alert-info">{{x.name}}</h2>
<div class="row">
<div class="col-sm-4"><img class="img-responsive" src="{{x.image}}"></div>
<div class="col-sm-8">{{x.description}}</div>
</div>
</div>
<p>Copyright (C) 2019 <a href="https://www.arduinoslovakia.eu">Arduino Slovakia</a>.</p>
</div>
</body>
</html>
Asi som v texte zatiaľ nespomenul, že AngularJS bol navrhnutý tak, aby boli programy v ňom jednoduché. Toto je celý program. Vytvorí sa aplikácia singleApp a priradí sa do premennej app
. A do tejto aplikácie sa pridá kontrolér singleCtrl. Kontrolér po štarte zavolá funkciu downloadData()
, ktorá si stiahne obsah súboru data.json a uloží ho do premennej $scope.data
. A o viac sa nemusíte starať, pretože v šablóne sme nastavili, že data.pedals je pole, ktoré sa má postupne zobraziť a forma je určená vnorenými HTML značkami v tagu div, ktorý funguje ako cyklus.
var app = angular.module('singleApp', []);
app.controller('singleCtrl', ['$scope', '$http', function ($scope, $http) {
function downloadData() {
$http.get('data.json')
.then(function (response) {
$scope.data = response.data;
}, function (response) {
$scope.error = response.data.error;
});
}
downloadData();
}]);
Takto vyzerá vzorový JSON. Obsahuje tri objekty v poli pedals. Každý objekt má tri atribúty. Meno, popis a odkaz na obrázok.
{ "pedals": [ { "name": "Nautila", "description": "Sing a song of stormy oceans and float upon the calming seas with the Nautila Chorus/Flanger. Create never before heard tidal swirls or soothing rhythmic waves with the Voice and Drift controls. These controls allow you to add up to eight chorus or four flanger voices and then blend and morph the waveforms in real-time with the Drift knob. Alter the modulation speed in real-time by holding down the momentary footswitch and then release to continue on your voyage through the currents. Separate Speed, Depth, Emphasis, Voices and Mix controls shape your waves into clean curls or soupy foam. True Bypass, stereo inputs and outputs, silent switching, and rugged construction, make the Nautila as practical as it is creative. The Nautila uses a 9VDC power supply to easily integrate into your existing pedalboard.", "image": "nautila.jpg" }, { "name": "Polara", "description": "Featuring seven inspirational Lexicon® reverbs, the DigiTech® Polara will be the new architect of your soundscape, defining space and adding dimension to your playing. The Polara’s flexible reverbs cover a full spectrum, from the intimate warmth of “Room”, to the vast expansiveness of “Hall”, through time with the cosmic power of “Reverse”, and anchored by Lexicon’s revered “Modulated”, “Plate” and “Spring” reverbs. In addition to those classics, the Polara introduces the new “Halo” reverb. The “Halo” reverb with cascading octaves interspersed in the reverb decays will cast a heavenly glow over your tone. With its new, compact size and soft-touch vacuum-style footswitch, the Polara truly represents the latest evolution in DigiTech pedal design. We’ve put years of experience into every detail of its mechanical and sonic blueprint. The Polara offers independent Level, Liveliness, Decay and Type controls; Stereo Inputs and Outputs; a Soft Click Footswitch; and a Reverb Tails On/Off Toggle Switch. It is true bypass, and uses a 9V DC power supply to easily integrate into your existing pedalboard.", "image": "polara.jpg" }, { "name": "Obscura", "description": "The Obscura Altered Delay from DigiTech allows you to turn your delays upside down and inside out. The Obscura’s four delay types can be darkened, degraded and distorted on the fly with the stacked Tone and Degrade controls. Combine these controls with the Obscura’s Repeat/Hold feature and lose yourself in long, trippy, gurgling repeats or backwards-manipulated sonic mayhem. In addition to its Tone and Degrade controls, the Obscura features independent Level, Delay Mode and stacked Time and Repeats controls. Complimenting those versatile controls, the Obscura offers four excellent-sounding Analog, Tape, Lo-Fi, and Reverse types, Tap Tempo mode with Beat Divisions, Stereo Inputs/Outputs, a Delay Tails On/Off Switch and True Bypass circuitry. With its compact size and vacuum-style footswitch, the Obscura furthers DigiTech’s evolution in pedal design. We’ve put years of experience into every detail of its mechanical and sonic blueprint. The Obscura uses a 9V DC power supply to easily integrate into your existing pedalboard.", "image": "obscura.jpg" } ] }
Zdrojový kód pre ESP8266. Je to HTTP server, ktorý celý obsah dodáva zo SPIFFS. Ten obsah sa nachádza v adresári data a je potrebné ho do SPIFFS načítať pomocou príkazu Tools/ESP8266 Sketch Data Upload. SPIFFS je popísaný podrobne v samostatnom článku.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include "arduino_secret.h"
ESP8266WebServer server(80);
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: http://");
Serial.println(WiFi.localIP());
SPIFFS.begin();
server.serveStatic("/", SPIFFS, "/index.html");
server.serveStatic("/favicon.png", SPIFFS, "/favicon.png");
server.serveStatic("/single.js", SPIFFS, "/single.js");
server.serveStatic("/data.json", SPIFFS, "/data.json");
server.serveStatic("/nautila.jpg", SPIFFS, "/nautila.jpg");
server.serveStatic("/obscura.jpg", SPIFFS, "/obscura.jpg");
server.serveStatic("/polara.jpg", SPIFFS, "/polara.jpg");
server.onNotFound([]() {
server.send(404, "text/plain", "404: Not Found");
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
}
Druhý príklad je viac komplexnejší. Tento príklad sa hodí na situácie, keď chcete v rámci jednej webstránky vybudovať rozsiahlejšiu aplikáciu. Ak v nej budete zobrazovať informácie na viacerých stránkach, musíte si vytvoriť smerovaciu tabuľku medzi URL podstránkami a jednotlivými kontrolérmi, ktoré sa postarajú o zobrazenie obsahu na každej podstránke. Ja som vymyslel nasledovnú situáciu, ktorá sa pomerne často objavuje ako príklad pre ESP8266. Je to aplikácia, ktorá meria teplotu. Používa dve stránky:
Na vytvorenie príkladu používam opäť len statické údaje, ktoré sa nachádzajú v súborovom systéme SPIFFS, ale pre šikovnejšieho programátora nie je problém tieto údaje doplniť. Ak k nim nepatríte, tak si počkajte na niektoré z pokračovaní seriálu o ESP8266, kde vám celý príklad naprogramujem.
Stránka sa skladá z nasledovných súborov:
Poďme si vysvetliť, ako sa vytvára AngularJS aplikácia pomocou tejto šablóny. Na začiatku sa toto načíta do prehliadača a aby sa AngularJS aplikácia spustila, sú potrebné tieto HTML značky. Na začiatku stránky vidíte niekoľko značiek <script>
. Tie sa starajú o to, aby sme si na stránku stiahli responzívny dizajn Bootstrap a AngularJS. Posledná značka <script src="multiple.js"></script>
načíta do prehliadača zdrojový kód programu. Na to, aby program vedel, kde má na stránke vytvoriť výslednú stránku, nám slúži značka <div ng-app="multiple" ng-view></div>
. Takto sme označili miesto pre aplikáciu multipleApp s viac stránkami. Voči predchádzajúcej šablóne tu je zmena v atribúte ng-view. Tým nastavíme, že kdesi v zdrojovom kóde aplikácie bude tabuľka, ktorá priradí pre každú URL konkrétnu šablónu a kontrolér.
<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>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular-route.js"></script>
<script src="multiple.js"></script>
<link rel="icon" type="image/png" href="favicon.png">
<title>HTTP Server ESP8266 - AngularJS multiple</title>
</head>
<body>
<div class="container">
<h1>ESP8266 HTTP Server - AngularJS Multiplepage Application</h1>
<div ng-app="multipleApp" ng-view>
</div>
<p>Copyright (C) 2019 <a href="https://www.arduinoslovakia.eu">Arduino Slovakia</a>.</p>
</div>
</body>
</html>
Šablóna pre aktuálnu teplotu. Teplota sa zobrazí pomocou premennej {{data.temperature}}
.
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">ESP8266</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a href="/#!/">Temperature</a></li>
<li><a href="/#!/history">History</a></li>
</ul>
</div>
</nav>
<p>Temperature: <b>{{data.temperature}}</b></p>
Šablóna pre historické merania teploty. Je to tabuľka, do ktorej sa zobrazia údaje z premennej data.history
. Pretože v tej premennej je iba pole čísel, musel som doplniť parameter track by $index
. Keby to bola tabuľka objektov, toto nie je nutné.
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">ESP8266</a>
</div>
<ul class="nav navbar-nav">
<li><a href="/#!/">Temperature</a></li>
<li class="active"><a href="/#!/history">History</a></li>
</ul>
</div>
</nav>
<table class="table">
<tr>
<th>#</th>
<th>Temperature</th>
</tr>
<tr ng-repeat="x in data.history track by $index">
<td>{{$index+1}}</td>
<td>{{x}}</td>
</tr>
</table>
Tento zdrojový kód je len mierne odlišný. Funkciou config
si pridáme routovaciu tabuľku medzi URL, šablónou a kontrolérom. A kontroléry sa správajú rovnako ako v predchádzajúcom príklade. Stiahnu si JSON a nastavia si ho do premennej. O zvyšok sa postará AngularJS a vytvorí výsledné stránky v prehliadači.
var app = angular.module('multipleApp', ['ngRoute']);
app.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/', {
controller: 'mainCtrl',
templateUrl: '/page1.html',
});
$routeProvider.when('/history', {
controller: 'historyCtrl',
templateUrl: '/page2.html',
});
$routeProvider.otherwise({
redirectTo: '/'
});
});
app.controller('mainCtrl', ['$scope', '$http', function ($scope, $http) {
function downloadData() {
$http.get('data1.json')
.then(function (response) {
$scope.data = response.data;
}, function (response) {
$scope.error = response.data.error;
});
}
downloadData();
}]);
app.controller('historyCtrl', ['$scope', '$http', function ($scope, $http) {
function downloadData() {
$http.get('data2.json')
.then(function (response) {
$scope.data = response.data;
}, function (response) {
$scope.error = response.data.error;
});
}
downloadData();
}]);
Jediné číslo s aktuálnou hodnotou.
{ "temperature": 12.5 }
Pole čísiel, ktoré predstavujú meranú teplotu.
{ "history": [12, 13, 14, 13, 12, 11, 12, 13] }
Zdrojový kód pre ESP8266. Je to HTTP server, ktorý celý obsah dodáva zo SPIFFS. Ten obsah sa nachádza v adresári data a je potrebné ho do SPIFFS načítať pomocou príkazu Tools/ESP8266 Sketch Data Upload. SPIFFS je popísaný podrobne v samostatnom článku.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include "arduino_secret.h"
ESP8266WebServer server(80);
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: http://");
Serial.println(WiFi.localIP());
SPIFFS.begin();
server.serveStatic("/", SPIFFS, "/index.html");
server.serveStatic("/favicon.png", SPIFFS, "/favicon.png");
server.serveStatic("/multiple.js", SPIFFS, "/multiple.js");
server.serveStatic("/data1.json", SPIFFS, "/data1.json");
server.serveStatic("/data2.json", SPIFFS, "/data2.json");
server.serveStatic("/page1.html", SPIFFS, "/page1.html");
server.serveStatic("/page2.html", SPIFFS, "/page2.html");
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.
30.11.2019