В этой статье объясняется, как считывать данные с трех датчиков температуры и влажности — DHT11, DHT22 и SHTC3 — с использованием платы NodeMcu и отправлять их через последовательный порт. Для каждого датчика я предоставил примеры кода как с использованием сторонних библиотек, так и без них.
Инструкция по настройке среды разработки ESP8266: https://blog.zeruns.com/archives/526.html
Ссылки на покупку датчиков, используемых в статье, находятся в конце текста.
DHT11
DHT11 — это датчик температуры и влажности с калиброванным цифровым выходом. Точность: влажность ±5% RH, температура ±2°C. Диапазон измерений: влажность 20–90% RH, температура 0–50°C. Точность невысокая, но цена низкая. DHT11 использует однопроводную шину для связи. Напряжение питания: 3,3–5 В.
Использование библиотеки DHT
Используйте библиотеку DHT sensor library (необходимо установить вручную; инструкция по установке приведена в вышеупомянутом Руководстве по настройке среды разработки ESP8266) для прямого считывания данных с DHT11.
#include ```<DHT.h> // Подключение библиотеки DHT
DHT dht(D1, DHT11); // Настройка пина данных и типа датчика
void setup(){ // Функция инициализации, выполняется только один раз при запуске программы
Serial.begin(115200); // Настройка скорости последовательного порта
dht.begin();
}
//https://blog.zeruns.com
void loop() {
delay(1000); // Задержка 1000 миллисекунд
float RH = dht.readHumidity(); // Чтение данных влажности
float T = dht.readTemperature();// Чтение данных температуры
Serial.print("Humidity:"); // Вывод "Humidity:" в последовательный порт
Serial.print(RH); // Вывод данных влажности
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); // Вывод данных температуры
Serial.println("C");
Serial.println("https://blog.zeruns.com");
}
Без использования библиотеки
Чтение данных DHT11 путем написания собственной программы с использованием данных из даташита.
Даташит DHT11: http://go.zeruns.com/G
#define data D1 // Пин Data (2Pin) DHT11 подключен к пину D1 платы NodeMcu
unsigned char i; // Беззнаковая 8-битная целочисленная переменная
float RH,T; // Одинарная точность с плавающей запятой (32 бита)
byte RH_H,RH_L,T_H,T_L,sum,check; // Байтовые переменные, двоичные числа
void setup() { // Функция инициализации, выполняется только один раз при запуске
Serial.begin(115200); // Настройка скорости последовательного порта
}
void loop() { // Циклическая функция, выполняется постоянно после инициализации
delay(1000); // Задержка 1000 миллисекунд
DHT11(); // Получение данных температуры и влажности
Serial.print("Humidity:"); // Вывод "Humidity:" в последовательный порт
Serial.print(RH); // Вывод данных влажности
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); // Вывод данных температуры
Serial.println("C");
Serial.println("https://blog.zeruns.com");
}
void DHT11()
{
RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
pinMode(data,OUTPUT); // Настройка пина как выход
digitalWrite(data,1); // Установка высокого уровня на пине
delay(10); // Задержка 10 миллисекунд
digitalWrite(data,0); // Установка низкого уровня на пине
delay(25); // Задержка 25 миллисекунд
digitalWrite(data,1); // Установка высокого уровня на пине
pinMode(data,INPUT); // Настройка пина как вход
delayMicroseconds(30); // Задержка 30 микросекунд
if(!digitalRead(data)) // Проверка, является ли входной уровень низким
{//https://blog.zeruns.com
while(!digitalRead(data)); // Ожидание перехода в высокий уровень
while(digitalRead(data)); // Ожидание перехода в низкий уровень
for(i=0;i<8;i++) // Повторить 8 раз
{
while(!digitalRead(data));// Ожидание перехода в высокий уровень
delayMicroseconds(28); // Задержка 28 микросекунд
if(digitalRead(data)){ // Проверка, является ли входной уровень высоким
bitWrite(RH_H, 7-i, 1); // Записать 1 в бит 7-i (считая справа) переменной RH_H
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(RH_L, 7-i, 1);
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(T_H, 7-i, 1);
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(T_L, 7-i, 1);
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(check, 7-i, 1);
while(digitalRead(data));
}
}
}
sum=RH_H + RH_L + T_H + T_L;
byte sum_temp=0;
// Чтение младших 8 бит sum и запись в sum_temp
for(i=0;i<8;i++){
bitWrite(sum_temp,i,bitRead(sum,i));
}//https://blog.zeruns.com
if(check==sum_temp){ // Проверка данных
RH=RH_H+float(RH_L)/10;
T=T_H+float(T_L)/10;
}
}
Результат
DHT22 (AM2302)
DHT22 (AM2302) — это датчик температуры и влажности с цифровым сигналом, предварительно откалиброванным. Точность: влажность ±2% RH, температура ±0.5°C, диапазон: влажность 0–100% RH, температура –40–80°C, разрешение — 0.1. Высокая точность при невысокой цене. DHT22 использует однопроводную шину. Напряжение питания: 3.3–5 В.
Использование библиотеки DHT
Использование библиотеки DHT sensor library для прямого чтения данных DHT22.
#include <DHT.h> // Подключение библиотеки DHT
DHT dht(D1, DHT22); // Настройка пина данных и типа датчика
void setup(){ // Функция инициализации, выполняется только один раз при запуске программы
Serial.begin(115200); // Настройка скорости последовательного порта
dht.begin();
}
//https://blog.zeruns.com
void loop() {
delay(1000); // Задержка 1000 миллисекунд
float RH = dht.readHumidity(); // Чтение данных влажности
float T = dht.readTemperature();// Чтение данных температуры
Serial.print("Humidity:"); // Вывод "Humidity:" в последовательный порт
Serial.print(RH); // Вывод данных влажности
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); // Вывод данных температуры
Serial.println("C");
Serial.println("https://blog.zeruns.com");
}
Без использования библиотеки
Чтение данных DHT22 путем написания собственной программы с использованием данных из даташита.
Даташит DHT22: http://go.zeruns.com/H
#define data D1 // Пин Data (2Pin) DHT22 подключен к пину D1 платы NodeMcu
unsigned char i; // Беззнаковая 8-битная целочисленная переменная
float RH,T; // Одинарная точность с плавающей запятой (32 бита)
byte RH_H,RH_L,T_H,T_L,sum,check; // Байтовые переменные, двоичные числа
void setup() { // Функция инициализации, выполняется только один раз при запуске
Serial.begin(115200); // Настройка скорости последовательного порта
}
void loop() { // Циклическая функция, выполняется постоянно после инициализации
delay(1000); // Задержка 1000 миллисекунд
DHT11(); // Получение данных температуры и влажности
Serial.print("Humidity:"); // Вывод "Humidity:" в последовательный порт
Serial.print(RH); // Вывод данных влажности
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); // Вывод данных температуры
Serial.println("C");
Serial.println("https://blog.zeruns.com");
}
void DHT11()
{
RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
pinMode(data,OUTPUT); // Настройка пина как выход
digitalWrite(data,1); // Установка высокого уровня на пине
delay(10); // Задержка 10 миллисекунд
digitalWrite(data,0); // Установка низкого уровня на пине
delay(25); // Задержка 25 миллисекунд
digitalWrite(data,1); // Установка высокого уровня на пине
pinMode(data,INPUT); // Настройка пина как вход
delayMicroseconds(30); // Задержка 30 микросекунд
if(!digitalRead(data)) // Проверка, является ли входной уровень низким
{//https://blog.zeruns.com
while(!digitalRead(data)); // Ожидание перехода в высокий уровень
while(digitalRead(data)); // Ожидание перехода в низкий уровень
for(i=0;i<8;i++) // Повторить 8 раз
{
while(!digitalRead(data));// Ожидание перехода в высокий уровень
delayMicroseconds(28); // Задержка 28 микросекунд
if(digitalRead(data)){ // Проверка, является ли входной уровень высоким
bitWrite(RH_H, 7-i, 1); // Записать 1 в бит 7-i (считая справа) переменной RH_H
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(RH_L, 7-i, 1);
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(T_H, 7-i, 1);
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(T_L, 7-i, 1);
while(digitalRead(data));
}
}
for(i=0;i<8;i++)
{
while(!digitalRead(data));
delayMicroseconds(28);
if(digitalRead(data)){
bitWrite(check, 7-i, 1);
while(digitalRead(data));
}
}
}
sum=RH_H + RH_L + T_H + T_L;
byte sum_temp=0;
// Чтение младших 8 бит sum и запись в sum_temp
for(i=0;i<8;i++){
bitWrite(sum_temp,i,bitRead(sum,i));
}//https://blog.zeruns.com
if(check==sum_temp){
if(bitRead(RH_H,7)==1){ // Проверка, отрицательная ли температура
T=-(float(T_H<<8)+float(T_L))/10;
}else{
T=(float(T_H<<8)+float(T_L))/10;
}
RH=(float(RH_H<<8)+float(RH_L))/10;
}
}
Результат
SHTC3
SHTC3 — это датчик температуры и влажности с цифровым сигналом, предварительно откалиброванным. Точность: влажность ±2% RH, температура ±0.2°C, диапазон: влажность 0–100% RH, температура –40–125°C, разрешение — 0.01. Высокая точность и относительно низкая цена, но мало информации. SHTC3 использует интерфейс I2C (IIC). Напряжение питания: 1.62–3.6 В.
Даташит SHTC3: http://go.zeruns.com/I
Использование библиотеки Wire (I2C)
Использование библиотеки Wire для обмена данными с SHTC3 и чтения данных.c
/* https://blog.zeruns.com
- Подключение
- SHTC3 Плата разработки
- SCL SCL (на плате NodeMcu — D1)
- SDA SDA (на плате NodeMcu — D2)
*/
#include <Wire.h>
#define SHTC3_ADDRESS 0x70 // Определить I2C-адрес устройства SHTC3 как 0x70
float T, RH;
void setup() { // Функция инициализации, выполняется только один раз при запуске программы
Serial.begin(115200); // Установить скорость последовательного порта
Wire.begin(); // Инициализировать как I2C-хост
}
void loop() { // Циклическая функция, выполняется постоянно после завершения функции инициализации
delay(1000); // Задержка на 1000 миллисекунд
SHTC3(); // Получить данные температуры и влажности
Serial.print(“Humidity:”); // Вывести Humidity: на последовательный порт
Serial.print(RH); // Вывести данные влажности на последовательный порт
Serial.print(“%”);
Serial.print(" Temperature:");
Serial.print(T); // Вывести данные температуры на последовательный порт
Serial.println(“C”);
Serial.println(“https://blog.zeruns.com”);
}
void SHTC3(){ // Получить данные температуры и влажности
Wire.beginTransmission(SHTC3_ADDRESS); // Начать передачу на I2C-устройство по адресу 0x70.
Wire.write(byte(0xE0)); // Отправить команду записи
Wire.endTransmission(); // Завершить передачу на устройство
Wire.beginTransmission(SHTC3_ADDRESS);
Wire.write(byte(0x35)); // Отправить старший байт команды пробуждения
Wire.write(byte(0x17)); // Отправить младший байт команды пробуждения
Wire.endTransmission();
delayMicroseconds(300); // Задержка на 300 микросекунд
Wire.beginTransmission(SHTC3_ADDRESS);
Wire.write(byte(0xE0));
Wire.endTransmission();
Wire.beginTransmission(SHTC3_ADDRESS);
Wire.write(byte(0x7C)); // Отправить старший байт команды измерения
Wire.write(byte(0xA2)); // Отправить младший байт команды измерения
Wire.endTransmission();
Wire.beginTransmission(SHTC3_ADDRESS);
Wire.write(byte(0xE1)); // Отправить команду чтения
Wire.endTransmission();
Wire.requestFrom(SHTC3_ADDRESS,6); // Запросить данные от устройства
uint16_t T_temp, RH_temp, T_CRC, RH_CRC;
if (2 <= Wire.available()) {
T_temp = Wire.read(); // Принять старший байт температуры
T_temp = T_temp << 8; // Сдвинуть влево на 8 бит
T_temp |= Wire.read(); // Выполнить побитовую операцию ИЛИ между старшим байтом (после сдвига) и младшим байтом температуры
T_CRC = Wire.read(); // Принять код CRC
if(SHTC3_CRC_CHECK(T_temp,T_CRC)){ // Проверить данные
T = float(T_temp) * 175 / 65536 - 45; // Рассчитать температуру
}
}//https://blog.zeruns.com
if (2 <= Wire.available()) {
RH_temp = Wire.read(); // Принять старший байт влажности
RH_temp = RH_temp << 8; // Сдвинуть влево на 8 бит
RH_temp |= Wire.read(); // Выполнить побитовую операцию ИЛИ между старшим байтом (после сдвига) и младшим байтом влажности
RH_CRC = Wire.read();
if(SHTC3_CRC_CHECK(RH_temp,RH_CRC)){
RH = float(RH_temp) * 100 / 65536;
}
}
}
//https://blog.zeruns.com
uint8_t SHTC3_CRC_CHECK(uint16_t DAT, uint8_t CRC_DAT) // CRC-проверка SHTC3
{
uint8_t i, t, temp;
uint8_t CRC_BYTE;
CRC_BYTE = 0xFF;
temp = (DAT >> 8) & 0xFF;
for(t = 0; t < 2; t ++)
{
CRC_BYTE ^= temp;
for(i = 0; i < 8; i ++)
{
if(CRC_BYTE & 0x80)
{
CRC_BYTE <<= 1;
CRC_BYTE ^= 0x31;
}else{
CRC_BYTE <<= 1;
}
}
if(t == 0)
{
temp = DAT & 0xFF;
}
}//https://blog.zeruns.com
if(CRC_BYTE == CRC_DAT)
{
temp = 1;
}else{
temp = 0;
}
return temp;
}
Использование библиотеки SHTC3
Сначала установите библиотеку SparkFun SHTC3.
/* https://blog.zeruns.com
* Подключение
* SHTC3 Плата разработки
* SCL SCL (на плате NodeMcu — D1)
* SDA SDA (на плате NodeMcu — D2)
*/
#include <SparkFun_SHTC3.h>
SHTC3 mySHTC3;
void setup(){ // Функция инициализации, выполняется только один раз при запуске программы
Serial.begin(115200); // Установить скорость последовательного порта
while(Serial == false){}; // Ожидать запуска последовательного соединения
Wire.begin(); // Инициализировать библиотеку Wire (I2C)
unsigned char i=0;
errorDecoder(mySHTC3.begin());// Для запуска датчика необходимо вызвать "begin()", по умолчанию используется Wire (стандартный I2C-порт Arduino)
}
//https://blog.zeruns.com
void loop() {
float RH, T;
delay(1000); // Задержка на 1000 миллисекунд
SHTC3_Status_TypeDef result = mySHTC3.update();
if(mySHTC3.lastStatus == SHTC3_Status_Nominal) // Проверить, нормален ли статус SHTC3
{
RH = mySHTC3.toPercent(); // Прочитать данные влажности
T = mySHTC3.toDegC(); // Прочитать данные температуры
}else{
Serial.print("Update failed, error: ");
errorDecoder(mySHTC3.lastStatus); // Вывести причину ошибки
Serial.println();
}
Serial.print("Humidity:"); // Вывести Humidity: на последовательный порт
Serial.print(RH); // Вывести данные влажности на последовательный порт
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); // Вывести данные температуры на последовательный порт
Serial.println("C");
Serial.println("https://blog.zeruns.com");
}
void errorDecoder(SHTC3_Status_TypeDef message) // Функция errorDecoder выводит результаты "SHTC3_Status_TypeDef" в удобочитаемом виде
{
switch(message)
{
case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
case SHTC3_Status_Error : Serial.print("Error"); break;
case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
default : Serial.print("Unknown return code"); break;
}
}
Пример результата
Покупка датчиков
DHT11: Скопируйте $Lk3h1Mx8UTO$, чтобы открыть Taobao и сразу заказать
DHT22: Скопируйте $kr2T1MxkUKY$, чтобы открыть Taobao и сразу заказать
SHTC3: Скопируйте $UD4D1Mx6N3R$, чтобы открыть Taobao и сразу заказать
Рекомендуем прочитать:
- Рекомендации по недорогим и выгодным VPS/облачным серверам: https://blog.zeruns.com/archives/383.html
- Настройка сервера для проброса внутренней сети с веб-панелью: https://blog.zeruns.com/archives/397.html
- Создание собственного облачного хранилища с Cloudreve: https://blog.zeruns.com/archives/515.html
- Как создать личный блог: https://blog.zeruns.com/archives/218.html
- Полный список студенческих льгот: https://blog.zeruns.com/archives/321.html
- Поделюсь с вами небольшой игрой, которая может принести доход: https://blog.zeruns.com/archives/472.html





