
За основу взят проект [1], добавлен модуль часов реального времени DS1302. Кроме показаний датчиков DS18B20 на веб-страницу выводятся дата и текущее время. Показания температуры меняются медленно и трудно судить, работает система или нет. Вывод текущего времени позволяет убедиться, что система работает.
Часы работают автономно без синхронизации с NTP серверами интернета.
Использовалась среда Arduino IDE 1.8.5 на Windows 10. Для платы NodeMCU v3 скачайте и установите драйвер CH340G. (установочный файл ch341ser_w.zip). Подробно процесс установки описан в [7]. В результате всех манипуляций у вас в списке должна появиться плата NodeMCU 1.0 (ESP-12E Module).

Соберите схему, сопротивление резистора 4.7 кОм. Не забудьте соединить проводом контакт GND NodeMCU v.3 с контактом GND модуля часов.
Так как Wi-Fi адаптер модуля потребляет довольно большой ток, понадобится достаточно мощный блок питания. У меня питается от USB хаба с внешним блоком питания на 2 А.
Схема соединений

В скетче автор предусмотрел опрос до 15 датчиков DS18B20. Данные выводятся в виде таблицы: в первой колонке идентификаторы датчиков, во второй - их температуры. Датчики опрашиваются с интервалом в 5 секунд (5000 мс), интервал в скетче можно изменить. Интервал измерения менее 1 секунды задавать не стоит, так как время преобразования температуры составляет 750 мс.
В скетче используются библиотеки OneWire.h и DallasTemperature.h, как их импортировать, описано в [8]. Также используется библиотека DS1302.h (версия 2.2 26 Jan 2012). Можете использовать готовые библиотеки из архива со скетчем.
Скетч time3_ds18b20_web
/*********
Руи Сантос (Rui Santos)
Более подробно о проекте на: http://randomnerdtutorials.com
*********/
// подключаем библиотеку «ESP8266WiFi»:
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DS1302.h>
//------------------------------------------
//DS18B20
#define ONE_WIRE_BUS D3 //Pin to which is attached a temperature sensor
#define ONE_WIRE_MAX_DEV 15 //The maximum number of devices
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
int numberOfDevices; //Number of temperature devices found
DeviceAddress devAddr[ONE_WIRE_MAX_DEV]; //An array device temperature sensors
float tempDev[ONE_WIRE_MAX_DEV]; //Saving the last measurement of temperature
float tempDevLast[ONE_WIRE_MAX_DEV]; //Previous temperature measurement
long lastTemp; //The last measurement
const int durationTemp = 5000; //The frequency of temperature measurement
// RST DS1302 GPIO 15 (D8)
// Data DS1302 GPIO 13 (D7)
// CLK DS1302 GPIO 12 (D6)
DS1302 rtc(15, 13, 12);
// вписываем здесь SSID и пароль для вашей WiFi-сети:
const char* ssid = "Xiaomi"; // название Wi-Fi сети
const char* password = "abcdef1234567"; // пароль сети
// веб-сервер на порте 80:
WiFiServer server(80);
//------------------------------------------
//Convert device id to String
String GetAddressToString(DeviceAddress deviceAddress) {
String str = "";
for (uint8_t i = 0; i < 8; i++) {
if ( deviceAddress[i] < 16 ) str += String(0, HEX);
str += String(deviceAddress[i], HEX);
}
return str;
}
//Setting the temperature sensor
void SetupDS18B20() {
DS18B20.begin();
Serial.print("Parasite power is: ");
if ( DS18B20.isParasitePowerMode() ) {
Serial.println("ON");
} else {
Serial.println("OFF");
}
numberOfDevices = DS18B20.getDeviceCount();
Serial.print( "Device count: " );
Serial.println( numberOfDevices );
lastTemp = millis();
DS18B20.requestTemperatures();
// Loop through each device, print out address
for (int i = 0; i < numberOfDevices; i++) {
// Search the wire for address
if ( DS18B20.getAddress(devAddr[i], i) ) {
//devAddr[i] = tempDeviceAddress;
Serial.print("Found device ");
Serial.print(i, DEC);
Serial.print(" with address: " + GetAddressToString(devAddr[i]));
Serial.println();
} else {
Serial.print("Found ghost device at ");
Serial.print(i, DEC);
Serial.print(" but could not detect address. Check power and cabling");
}
//Get resolution of DS18b20
Serial.print("Resolution: ");
Serial.print(DS18B20.getResolution( devAddr[i] ));
Serial.println();
//Read temperature from DS18b20
float tempC = DS18B20.getTempC( devAddr[i] );
Serial.print("Temp C: ");
Serial.println(tempC);
}
}
//Loop measuring the temperature
void TempLoop(long now) {
if ( now - lastTemp > durationTemp ) { //Take a measurement at a fixed time (durationTemp = 5000ms, 5s)
for (int i = 0; i < numberOfDevices; i++) {
float tempC = DS18B20.getTempC( devAddr[i] ); //Measuring temperature in Celsius
tempDev[i] = tempC; //Save the measured value to the array
}
DS18B20.setWaitForConversion(false); //No waiting for measurement
DS18B20.requestTemperatures(); //Initiate the temperature measurement
lastTemp = millis(); //Remember the last time measurement
}
}
// блок setup() запускается только один раз – при загрузке:
void setup() {
// инициализируем последовательный порт (для отладочных целей):
Serial.begin(115200);
delay(10);
rtc.halt(false);
rtc.writeProtect(false);
//rtc.setTime(15,31,0);
//rtc.setDate(24, 6, 2018);
// подключаемся к WiFi-сети:
Serial.println();
Serial.print("Connecting to "); // "Подключаемся к "
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected"); // "Подключение к WiFi выполнено"
// запускаем веб-сервер:
server.begin();
Serial.println("Web server running. Waiting for the ESP IP...");
// "Веб-сервер запущен. Ожидание IP-адреса ESP..."
delay(10000);
// печатаем IP-адрес ESP:
Serial.println(WiFi.localIP());
SetupDS18B20();
}
// блок loop() будет запускаться снова и снова:
void loop() {
// начинаем прослушку входящих клиентов:
WiFiClient client = server.available();
if (client) {
Serial.println("New client"); // "Новый клиент"
// создаем переменную типа «boolean»,
// чтобы определить конец HTTP-запроса:
boolean blank_line = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && blank_line) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
// веб-страница с данными о температуре:
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head></head><body><h1>ESP8266 - Temperature</h1>");
client.print("Date ");
client.print(rtc.getDateStr());
client.print(" Time ");
client.print(rtc.getTimeStr());
client.print("<h3>Number of devices: ");
client.print(numberOfDevices);
client.print("</h3>");
client.print("<table border='1' cellspacing=0>");
client.print("<tr><td>Device id</td><td>Temperature, *C</td></tr>");
float temp_C;
for (int i = 0; i < numberOfDevices; i++) {
client.print("<tr><td>");
client.print(" ");
client.print(GetAddressToString( devAddr[i] ));
client.print(" ");
client.print("</td>");
client.print("<td>");
client.print(" ");
temp_C = DS18B20.getTempC( devAddr[i] );
client.print(temp_C);
client.print("</td></tr>");
Serial.print( "Sending temperature: " );
Serial.println( temp_C );
}
client.print("</table>");
client.println("</body></html>");
break;
}
if (c == '\n') {
// если обнаружен переход на новую строку:
blank_line = true;
}
else if (c != '\r') {
// если в текущей строчке найден символ:
blank_line = false;
}
}
}
// закрываем соединение с клиентом:
delay(1);
client.stop();
Serial.println("Client disconnected.");
// "Клиент отключен."
}
long t = millis();
TempLoop( t );
}
Скачать скетч и библиотеки
Не забудьте в скетче исправить имя и пароль Wi-Fi сети на свои. Импортируйте библиотеки DS1302, OneWire и DallasTemperature. В меню пройдите Скетч ► Подключить библиотеку ► Добавить .ZIP библиотеку... и в окне выберите zip-архив библиотеки.
Раскомментируйте строку //rtc.setTime(15,31,0); и пропишите правильное время (час, минуты, секунды).
Раскомментируйте строку //rtc.setDate(24, 6, 2018); и пропишите правильную дату (день, месяц, год).
Скомпилируйте и запустите скетч. При подключении на монитор порта будет выдан IP адрес соединения.

Теперь в адресной строке браузера введите IP адрес, который роутер присвоил вашему модулю. У меня этот IP адрес, как можно видеть, — 192.168.31.190. Вы должны увидеть примерно следующее:

Для обновления показаний требуется перезагружать (обновлять) веб-страницу.
Если правильные дата и время установились, снова закомментируйте строки rtc.setTime и rtc.setDate и перезапустите скетч.
Если датчиков много или они подключены по длинному шлейфу, а также, если температура измеряется на краях диапазона, т.е. высокая или низкая, то рекомендуют внешнее питание для DS18B20. В качестве внешнего питания я использовал батарею из двух элементов 1,5 В [4]. Схема подключения внешнего питания:


При проблемах со считыванием показаний проверьте контакты, датчики можно припаять. Подберите резистор, минимальное сопротивление 1 кОм. Попробуйте разместить резистор около модуля NodeMCU v.3. Для снижения помех используйте "витую пару".
На данный момент у вас доступ к веб-странице только по локальной сети. Чтобы просматривать веб-страницу через интернет, в Wi-Fi роутере надо настроить для модуля статический IP адрес и сделать проброс портов (port forwarding). В настройках port forwarding укажите протокол TCP и порт 80. О настройках можно прочитать в статье Как получить доступ по интернету к датчикам в квартире.
Для резервирования статического IP адреса понадобится MAC адрес модуля, обычно его можно увидеть в настройках Wi-Fi роутера в списке устройств. Также MAC адрес (физический адрес) можно узнать, если в командной строке Windows дать команду arp -a <IP_адрес_модуля>.
Роутер может дать модулю название (device name) наподобие ESP_A53DF3 или FaryLink_A53DF3, где последние 6 символов - это последние 6 символов MAC адреса.
Но тут есть одна закавыка. DNS сервис предлагает установить утилиту, которая периодически посылает на сервис текущий IP адрес. Когда провайдер выдаст вашему роутеру другой IP адрес, утилита сообщит новый IP адрес на DNS сервис. Сервис заменит устаревший IP адрес на текущий на DNS серверах. Вашему домену (имени сайта) будет соответствовать уже новый IP адрес и ваше устройство снова будет доступно в интернете. На NodeMCU нет возможности установить такую утилиту, но если у вас в сети есть компьютер Windows или Linux (Raspberry Pi), то вы можете установить эту утилиту на один из этих компьютеров. Он должен быть практически постоянно включен. Проще всего использовать Raspberry Pi или подобный компьютер. Как настроить доступ из интернета на Raspberry Pi, также написано в статье Как получить доступ по интернету к датчикам в квартире.

Статья обновлена 20.09.2021
Использованные ресурсы
1. https://www.hackster.io/adachsoft_com/esp8266-temperature-sensors-ds18b20-with-http-server-5509ac?ref=similar&ref_id=36220&offset=2
2. http://wikihandbk.com/wiki/ESP8266:Примеры/Отображение_температуры_в_браузере_с_помощью_чипа_ESP8266_и_датчика_DS18B20
3. http://zgo.narod.ru/publ/arduino_meteorological_station_bmp180_dht11_lcd1602/1-1-0-91
4. http://mypractic.ru/ds18b20-datchik-temperatury-s-interfejsom-1-wire-opisanie-na-russkom-yazyke.html
5. http://ab57.ru/netcmd.html
6. http://zgo.narod.ru/publ/nodemcu_v3_vyvod_pokazanij_temperatury_i_vremeni_na_veb_stranicu/1-1-0-93
7. http://arduinonsk.ru/?id=127:arduino-ide-esp-install
8. https://randomnerdtutorials.com/esp8266-ds18b20-temperature-sensor-web-server-with-arduino-ide/
9. http://averel.ru/pdf/ds18b20-rus.pdf
|