OK

Při poskytování služeb nám pomáhají soubory cookie. Používáním našich služeb vyjadřujete souhlas s naším používáním souborů cookie. Více informací

Úvodní stránka » Aktuální články » Mini webserver NodeMCU s teploměrem DS18B20

Mini webserver NodeMCU s teploměrem DS18B20

V minulém článku jsme se seznámili s velmi zajímavým modulem NodeMCU a ukázali jsme si, jak jej uchopit pro praktické projekty. Dneska si ukážeme, jak jednoduše vytvořit malý webový server, který nám bude ukazovat teploty doma a venku.

HW s NodeMCU

Pro měření teploty použijeme známá čidla Dallas 18B20 a budeme potřebovat ještě jeden rezistor 4k7 jako pullup na OneWire sběrnici. Zde je velmi výhodné použít rezistor v pouzdru SMD 0805, protože se dá pohodlně zapájet mezi pin D4 a 3.3V, který je hned vedle přímo na modul NodeMCU. Na piny NodeMCU tak zbývá pouze připojit samotný teploměr nebo teploměry. HW je patrný z níže uvedeného obrázku:

Sketch

Sketch vychází z examplu jednoduchého serveru, který jsem doplnil o podporu sběrnice OneWire a knihovnou proobsluhu DS18B20 tak, aby implementace byla co nejjednodušší. Ve skutečnosti je sketch poměrně náročný, ale naštěstí je vše hezky zabaleno v dost dobře funkčních knihovnách ESP8266WiFi, WiFiClient, ESP8266WebServer a ESP8266mDNS, takže spoustu starostí odpadne. Tyto knihovny jsou součástí balíků, který jsme instalovali podle předešlého článku.

Snad jen drobné upozornění - ve stávajícím prostředí Arduina máte jistě knohovnu OneWire - tu bude potřeba přepsat nově dodanou knihovnou, která je rovněž součásti implementačního balíku, jinak kompilér nebude znát OneWire proNodeMCU. Stačí přepsat soubory .h a .cpp v tomto případě.

Pojďme rozebrat jednotlivé pasáže.


Nejprve provedeme základní definice a nalinkování potřebných knihoven.


#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <OneWire.h> 
#include <DallasTemperature.h>

//pro teploměr
#define ONE_WIRE_BUS D4
#define TEMPERATURE_PRECISION 9 

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer, outsideThermometer;
float teplota;
String termOUT;
String termIN;


#define SCKLED 5


Zde zadejte SSID a heslo ke svému WiFi routeru

const char *ssid = "SSID";
const char *password = "*************";
MDNSResponder mdns;

ESP8266WebServer server(80);
const int led = 13;

Funkce pro zobrazení stránky HTML na ESP8266. Jedná se vlastně o vytištění HTML kódu na serverový pool ESP8266. Data pro HTML stránku lze buď natvrdo nakódovat přímo ve sketchi nebo vymyslet jiný způsob, jak ji do serveru vytisknout - načtením z SD karty, případně externího souboru.


//pro server
void handleRoot()
{
	digitalWrite(SCKLED, 1);
	char temp[450];
	int sec = millis() / 1000;
	int min = sec / 60;
	int hr = min / 60;
	uint8 index = termOUT.indexOf('.');
	int restOUT = termOUT.substring(index+1).toInt();
	int temperatureOUT = termOUT.toInt();
	index = termIN.indexOf('.');
	int restIN = termIN.substring(index + 1).toInt();
	int temperatureIN = termIN.toInt();


	snprintf(temp, 450,

		"<html>\
  <head>\
    <meta http-equiv='refresh' content='5'/>\
    <title>ESP8266 Demo</title>\
    <style>\
      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
    </style>\
  </head>\
  <body>\
    <h1>Teplota v Kuncicich pod Ondrejnikem</h1>\
    <p>Uptime: %02d:%02d:%02d</p>\
	<p>Teplota venku: %02d.%01d&deg;C</p>\
	<p>Teplota doma: %02d.%01d&deg;C</p>\
  </body>\
</html>",

hr, min % 60, sec % 60, temperatureOUT,restOUT,temperatureIN,restIN
);
	server.send(200, "text/html", temp);
	digitalWrite(led, 0);
}

void handleNotFound() {
	digitalWrite(led, 1);
	String message = "File Not Found\n\n";
	message += "URI: ";
	message += server.uri();
	message += "\nMethod: ";
	message += (server.method() == HTTP_GET) ? "GET" : "POST";
	message += "\nArguments: ";
	message += server.args();
	message += "\n";

	for (uint8_t i = 0; i < server.args(); i++) {
		message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
	}

	server.send(404, "text/plain", message);
	digitalWrite(led, 0);
}

Provedeme nějaké úvodní nastvovačky - LEDka na modulu ESP8266 nám bude později indikovat chod sketche, aktivujeme sériový port na rychlosti 9600 b/s, pokusíme se připojit na WiFi router s patřičným nastavením viz. výše, vypíšeme IP adresu, kterou jsme od routeru obdrželi, abychom věděli, kam budeme sahat browserem pro zobrazení stránky. Nakonec ošéfujeme teploměry - jeden jsem označil jako vnitřní a jeden jako vnější, pokusím se je najít na sběrnici a vypsat jejich aktuální teplotu.


void setup(void) 
{
	
	pinMode(led, OUTPUT);
	pinMode(SCKLED,OUTPUT);
	digitalWrite(SCKLED,LOW);
	digitalWrite(led, 0);
	Serial.begin(9600);
	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());

	if (mdns.begin("esp8266", WiFi.localIP())) {
		Serial.println("MDNS responder started");
	}

	server.on("/", handleRoot);
	server.on("/inline", []() {
		server.send(200, "text/plain", "this works as well");
	});
	server.onNotFound(handleNotFound);
	server.begin();
	Serial.println("HTTP server started");
	//digitalWrite(SCKLED, HIGH);

	//teploměry
	sensors.begin();
	Serial.println("***************************************************");
	Serial.print("Pocet teplomeru: ");
	Serial.println(sensors.getDeviceCount(), DEC);
	//zjisti adresy
	oneWire.reset_search();
	if (!oneWire.search(insideThermometer)) Serial.println("Vnitrni teplomer nenalezen!");
	if (!oneWire.search(outsideThermometer)) Serial.println("Vnejsi teplomer nenalezen!");
	Serial.print("Adresa teplomeru 1: ");
	printAddress(insideThermometer);
	Serial.println();

	Serial.print("Adresa teplomeru 2: ");
	printAddress(outsideThermometer);
	Serial.println();

	//nastav rozlišení
	sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
	sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);

	//načti všechny teploměry
	sensors.requestTemperatures();

	//vytiskni data na seriák
	printData(insideThermometer);
	printData(outsideThermometer);

}


Hlavní smyčka je celkem primitivní - neustále dookola sbírá teploty a updatuje webovou stránku, mezi čtením vnitřního a vnějšího teploměru pak blikne LEDkou.


void loop(void) 
{
	digitalWrite(led, LOW);
	mdns.update();
	server.handleClient();
	sensors.requestTemperatures();
	teplota = sensors.getTempC(insideThermometer);
	digitalWrite(led, HIGH);
	termOUT = String(teplota, 1);
	teplota = sensors.getTempC(outsideThermometer);
	termIN = String(teplota, 1);
	digitalWrite(led, LOW);

}

//pro teploměry
void printAddress(DeviceAddress deviceAddress)
{
	for (uint8_t i = 0; i < 8; i++)
	{
		// zero pad the address if necessary
		if (deviceAddress[i] < 16) Serial.print("0");
		Serial.print(deviceAddress[i], HEX);
	}
}


Zde ještě pár nezbytností pro obsluhu teploměrů


void printData(DeviceAddress deviceAddress)
{
	Serial.print("Adresa teplomeru ");
	printAddress(deviceAddress);
	Serial.print(":");
	printTemperature(deviceAddress);
}

void printTemperature(DeviceAddress deviceAddress)
{
	float tempC = sensors.getTempC(deviceAddress);
	Serial.print("Teplota: ");
	Serial.print(tempC);
	Serial.write(176);
	Serial.println("C");
}


Pokud se Vám povedla kompilace, zaveďte sketch do NodeMCU a otevřete sériový kanál na rychosti 9600 b/s. Pokud vše proběhlo jak mělo, pak na sériovém kanálu uvidíte vypisování symbolu tečky(.), což znamená, že se ESP8266 snaží asociovat s Vaším WiFi routerem. V momentě, kdy je asociace úspěšná se vypíše následující:

...
Connected to TESTER2
IP address: 192.168.1.111
MDNS responder started
HTTP server started
***************************************************
Pocet teplomeru: 2
Adresa teplomeru 1: 28789A68000000A1
Adresa teplomeru 2: 28F55A6800000023
Adresa teplomeru 28789A68000000A1:Teplota: 21.50°C
Adresa teplomeru 28F55A6800000023:Teplota: 22.50°C

A nyní se můžeme podívat na www stránku přes libovolný browser...

Sketch je ke stažení zde. Z veřejného internetu je webová stranka dostupná zde - pakliže zrovna nějak s tímto nelaboruji a nemám jej v jiném, než on-line režimu nebo pokud se nezmění veřejná adresa u poskytovatele.

NodeMCU je dostupné v našem e-shopu v zatím omezeném množství, od konce listopadu 2015 by mělo být již standardně dostupné a více kusů skladem. NodeMCu je beze sporu významnou komponentou pro podporu IoT a budu této desce o velikosti 48x26mm věnovat patřičnou pozornost. Podobné řešení existuje ještě ve formě ala Arduino UNO - tedy v konstrukci, která umožňuje přímo využít stávající Arduino shieldy - tedy alespoň některé.

 

 

PF

 

Přidat komentář

Zvýrazněné položky jsou povinné.

Přehled komentářů

  1. error: 'printAddress' was not declared in this scope (garf, 11.12.2015 20:37:49) Odpovědět

    Veľmi pekný návod, mám však problém, pri kompilácií mi vyskočia hlášky:

    NodeMCU_DS18B20:134: error: 'printAddress' was not declared in this scope

    printAddress(insideThermometer);

    Podobné ešte na riadku 149 a 185. Vie mi niekto poradiť. Ďakujem.

  2. arduino ide 1.6.6 (garf, 11.12.2015 23:11:39) Odpovědět

    Hore uvedený problém sa týka len ide 1.6.6 po inštalácií staršej verzie 1.6.5 kompilácia prebehne bez chyby.

    Admin:
    Trochu jsem to podrobil analýze a vypadá to takto - není to ani tak závislé na verzi Arduino IDE, ale objevil jsem takový zvláštní jev - podotýkám používám pro vývoj Visual Studio for Comunities 2015 a plugin VisualMicro - tak tedy, samotné Arduino IDE mi v obou verzích kompilovalo OK, jakmile jsem totéž zkusil ve VS, pak jsem obdržel hlášku, kterou popisujete. Vzal jsem tedy veškeré funkce, které byly napsány za hlavní smyčkou loop() a pouze je přemístil před setup(). Zjevně je někde chyba v kopiléru, resp. Visual micro pluginu. Jakmile se toto přemístění udělalo, pak se již sketch kompiluje bez chyby.

  3. esp (Ivan, 21.2.2016 10:03:56) Odpovědět

    Perfektné. Mám ale otázku: Ako môžem dosiahnúť to, aby bola stránka dostupná z verejného internetu, teda to čo máte v predposlednom odstavci? Vopred ďakujem za odpoveď

    Admin:
    Dobrý den,
    Musíte mít veřejnou adresu od Vašeho poskytovatele a pak si patřičným způsobem nastavit forward portu ve Vašem routeru. Protože routerů existuje mnoho, pak univerzální postup nelze popsat, princip ano - port forward a povolit si ho také na firewallu, pokud Váš router firewall má a máte ho zapnutý. Pak z vneku napíšete veřejnou IP adresu:portxy a ten portxy budete mít směrován na vnitřní adresu, kterou Vám dhcp přidělilo pro NodeMCU. Směruji většinou portxy na port 80, tam defaultně běží vnitřní web ESPčka.

    PF

  4. Data a napajeni (Michal, 1.3.2016 13:49:57) Odpovědět

    Dobrý den,
    poběží to i při napajení tužkovými bateriemi vydrží to nejakou slušnou dobu?

    Admin:
    Dobrý den!
    Ano, pokud budete slušně zacházet se spotřebou - tedy deep sleep, vzbudit, změřit, poslat data, pak pojedete na lithiovku 3V/3000mAh (CR123a) cca půl roku. Ale chce to fakt hoooodně šetřit a trochu si nastudovat Low Power záležitosti. Pokud ale hledáte něco, kde budete sypat data, počkejte ještě chvilku (2 měsíce max.) na LoRa nebo Sigfox sítě pro IoT, viz. mé články o IoT.

    http://www.arduinotech.cz/inpage/lpwan-lorawan-sigfox-vitejte-v-iot-107/


    PF

  5. re (Leo, 28.10.2016 9:54:46) Odpovědět

    Kdybych chtěl nastavít penou IP?
    Da se vypsat na ser.monitor sila wifi signalu?

  6. knihovna OneWire (Boss, 2.12.2016 10:42:38) Odpovědět

    Zdravím, nějak nemůžu najít tu správnou knihovnu pro OneWire.
    S tou kterou mám mi to hází error

    Zdravím,
    doporučoval bych používat ty knihovny, které se stáhnou s ESP8266 packem. Je totho celkem dost na netu, těžko říct, co funguje a co ne. Zkuste si přeinstalovat celé to ESP8266 repository.
    PF
    #define ONE_WIRE_BUS D4
    'D4' was not declared in this scope

    Děkuji za pomoc

  7. Dík (Adam, 10.1.2017 11:26:33) Odpovědět

    Funguje parádně, díky!

  8. Zapojeni s Dallas (Jiří Kačmařík, 16.1.2017 17:52:28) Odpovědět

    Dobrý den,
    podařilo se mi rozběhnout Arduino s Dallasem, dokonce s port forwarding, Mám ověřeno z Číny a Irska, že stránka teploměru je přístupná. Zjistil jsem, že je dobré dát za svou veřejnou adresu v cizině ještě číslo portu http://A.A.A.A:80, třeba můj Zyxel to potřebuje, bez toho stránku neotevře, i když v NAT má nastaveno www = č.p. 80.
    Ale na některé věci jsem krátky,
    1. letošní zima má i mínusové telploty ty se však na www nezobrazují, jedině seriový monitor napsal -0.50 ale na www je 00.0°C přitom venku je -3. Je to Dallasem nebo knihovnou? Oba Dallasy byli venku a svorně ukazovali na www 00.0
    2. Zakomentoval jsem všechny blikaci místa ř. 156, 161, 165, 122
    //pinMode(led, OUTPUT);
    //pinMode(SCKLED,OUTPUT);
    //digitalWrite(SCKLED,LOW);
    //digitalWrite(led, 0);
    //digitalWrite(led, HIGH);
    //digitalWrite(SCKLED, HIGH);

    a stejně Arduino vesele bliká dále. Frekvence blikání je otravná a powerbanka nevydrží ani den.
    Máte někdo s tím zkušenosti?

  9. Zapojeni s Dallas 2 (Jiří Kačmařík, 16.1.2017 18:54:07) Odpovědět

    Asi jsem na to přišel
    dal jssem Dallas na port D1 podle
    https://github.com/RuiSantosdotme/Random-Nerd-Tutorials/blob/master/Projects/DS18B20__ESP8266_web_server.ino
    opravil řádek 9
    #define ONE_WIRE_BUS D1
    a přestalo to blikat a měří i pod nulou
    ----------------------------------------
    Teplota venku: -1.0°C
    Teplota doma: 22.5°C
    ------------------------------------
    sice mi to moc nesedí neb venku je -1.9
    ale aspoň nějaký pokrok, možná je to jen nastaveným rozlišením Dallasu (skáče po 0.5)

  10. Zapojení s Dallas 3 (Jiří Kačmařík, 17.1.2017 14:41:02) Odpovědět

    Ještě jedna informace k TEMPERATURE_PRECISION

    // Mode Resol Conversion time
    //#define TEMPERATURE_PRECISION 9 // 9 bits 0.5°C 93.75 ms
    //#define TEMPERATURE_PRECISION 10 // 10 bits 0.25°C 187.5 m
    //#define TEMPERATURE_PRECISION 11 // 11 bits 0.125°C 375 ms
    #define TEMPERATURE_PRECISION 12 // 12 bits 0.0625°C 750 ms

  11. Chyba kompilace (Jirka, 27.1.2017 20:15:15) Odpovědět

    Dobrý den, pořád mi vyskakuje tato hláška:

    NodeMCU-DS18B20.ino:6:31: fatal error: DallasTemperature.h: No such file or directory
    compilation terminated.
    Chyba kompilace.

  12. 3 čidla? (reddy, 27.3.2017 14:00:28) Odpovědět

    snažím je tento případ pochopi zpětně, jak by vypadal kód se 3 čidly prosím?


TOP produkty

Kontakt

Ing. Petr Foltýn
Kunčice pod Ondřejníkem 814, 73913
TOPlist