Поиск по этому блогу

13 февр. 2020 г.

Черновик домашней метеостанции (DHT-22) c передачей на домашний MQTT



//  ========================================================================
  #include                                                           // Библиотека MQTT.
//#include
  #include
//#include
//Adafruit_BMP280 bmp;                                  // Работаем по шине I2C.
  #include
//  ========================================================================  
// Раскомментируйте одну из строк ниже для любого типа датчика DHT, который вы используете.
//#define DHTTYPE DHT11   // DHT 11.
//#define DHTTYPE DHT21   // DHT 21 (AM2301).
  #define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321.
  #define LED_BUILTIN 2      // LED.
//  ========================================================================   

// Указываем учетные данные ниже, чтобы ваш ESP8266 подключался к вашему маршрутизатору.
const char* ssid = "XXX";                          // Имя сети WiFi.
const char* password = "XXX";                  // Пароль к сети.
const char* mqtt_server = "192.168.0.1";    // Указываем IP-адрес роутера, чтобы он подключался к вашему брокеру MQTT.
const char* mqttUser = "XXX";                  // Пользователь MQTT.
const char* mqttPassword = "XXX";          // Пароль пользователя.
//  ========================================================================  
// Задаём mac и ip адреса в Локальной сети
byte mac[]    = { 0x2c, 0x3a, 0xe8, 0x07, 0xd9, 0x3f };// MAC Адрес ESP8266.
IPAddress ip{192, 168, 0, 58};                           // ip Адрес ESP8266.
IPAddress server{192, 168, 0, 1};                      // ip Адрес MQTT Брокера.
//  ========================================================================
// Указываем публикуемые топики.
const char* mqttTopicTemperature = "home/temperature";   // Температура.
const char* mqttTopicHumidity = "home/humidity";             // Влажность.
const char* mqttTopicLamp = "home/lamp";                          // LED.
const char* mqttTopicStatlamp = "home/statlamp";               // Статус LED.
const char* mqttTopicPower = "home/power";                       // Напряжение на аналоговом входе (А0).
//  ========================================================================  
const int DHTPin = 5;             // Датчик DHT - GPIO 5 = D1 на плате ESP8266.
const int Lamp = 4;                 // Светодиод - GPIO 4 = D2 на плате ESP8266.
int StatusLamp = false;           // Текущее состояние LED (включен/выключен).
int lamp;                                  // Переменные для вычислений с LED.
const int AnalogPin = A0;      // Ползунок потенциометра (средний вывод) подключен к аналоговому выводу A0.
float dc = 0;                             // Переменная для хранения считанного значения.  
float max_v = 4.25;                 // Максимальный заряд аккумулятора.
float min_v = 2.75;                  // Минимальный заряд аккумулятора.
float vout = 0.0;                       // Напряжение на выходе делителя.
float vin = 0.0;                         // Напряжение на входе делителя.
float R1 = 100000.0;               // Сопротивление в Омах R1 (100K).
float R2 = 10000.0;                 // Сопротивление в Омах R2 (10K).
//  ========================================================================   
// Таймеры вспомогательных переменных.
unsigned long now = millis();
unsigned long lastMeasure = 0;
unsigned long resendtime = 30000; //30sec
//  ========================================================================
// Инициализирует espClient. Вам следует изменить имя espClient, 
// если в вашей домашней системе автоматизации запущено несколько ESP.
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPin, DHTTYPE);     // Инициализируем датчик DHT.
//  ========================================================================
// Функция настройки устанавливает ваши ESP GPIO на выходы, запускает последовательную связь со скоростью 115200 бод.
// Устанавливает ваш брокер mqtt и устанавливает функцию обратного вызова.
// Функция обратного вызова - это то, что получает сообщения и фактически управляет светодиодами.
void setup() {
Serial.begin (115200);
dht.begin();
setup_wifi();
client.setServer(mqtt_server, 1883);
pinMode(LED_BUILTIN, OUTPUT); 
pinMode(lamp, OUTPUT);
client.setCallback(callback);

pinMode(AnalogPin, INPUT);
}
//  ========================================================================
// Не меняйте функцию ниже, эта функция подключает ваш ESP8266 к маршрутизатору.
void setup_wifi() {
Serial.print ("Подключение к ");
Serial.print(ssid);
delay(10);
// Начинаем с подключения к сети WiFi.
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Подключен.");
Serial.println("IP адрес: ");
Serial.println(WiFi.localIP());
}
//  ========================================================================
// Эта функция выполняется, когда какое-либо устройство публикует сообщение в теме, на которую подписан Ваш ESP8266. 
// Измените нижеприведенную функцию, чтобы добавить логику в вашу программу, поэтому, когда устройство публикует сообщение в теме, 
// на которую подписан Ваш ESP8266, вы можете что-то сделать.
// Включаем светодиод, если была получена 1 в качестве первого символа.
void callback(String topic, byte* message, unsigned int length){
String messageTemp; 
for (int i = 0; i < length; i++) {
messageTemp += (char)message[i];
}
// Не стесняемся добавлять больше операторов if для управления большим количеством GPIO с помощью MQTT.
// Если сообщение получено по теме mqttTopicLamp, вы проверяете, включено ли сообщение или нет. Включает лампу GPIO согласно сообщению.
if(topic==mqttTopicLamp){                     // Если топик называется lamp....
if(messageTemp == "1"){                         // И значение в топике равно 1....
digitalWrite(LED_BUILTIN, HIGH);      // Устанавливаем на пине высокий уровень, выключаем LED.
Serial.println ("LED Выкл.");                   // Выводим в Serial монитор.
client.publish(mqttTopicStatlamp, "1");    // Отсылаем в топик.
}
else if(messageTemp == "0"){                   // И значение в топике равно 0....
digitalWrite(LED_BUILTIN, LOW);        // Устанавливаем на пине низкий уровень, включаем LED.
Serial.println ("LED Вкл.");                      // Выводим в Serial монитор.
client.publish(mqttTopicStatlamp, "0");    // Отсылаем в топик.
}
}
}
//  ========================================================================
// Эта функция повторно подключает ваш ESP8266 к вашему брокеру MQTT.
// Измените функцию ниже, если вы хотите подписаться на другие темы с вашим ESP8266. 
void reconnect() {
// Цикл, пока мы не переподключимся.
while (!client.connected()) {
Serial.println ("Подключение к MQTT ...");
// Попытка подключения.
//ВАМ НЕОБХОДИМО ИЗМЕНИТЬ ЭТУ ЛИНИЮ, ЕСЛИ У ВАС ПРОБЛЕМЫ С МНОГОКРАТНЫМИ СОЕДИНЕНИЯМИ MQTT
//Чтобы изменить идентификатор устройства ESP, вам нужно будет присвоить ESP8266 новое имя.
//Вот как это выглядит:
//if (client.connect ("ESP8266Client")) {
//Вы можете сделать это так:
//if (client.connect ("ESP1_Office")) {
//Тогда для другого ESP:
//if (client.connect ("ESP2_Garage")) {
//Это должно решить вашу проблему с несколькими подключениями MQTT
//  ========================================================================
if (client.connect(WiFi.hostname().c_str(), mqttUser, mqttPassword)) {
Serial.println ( "Подключен.");
// Подписаться или пере подписаться на тему.
// Вы можете подписаться на другие темы (для управления большим количеством светодиодов в этом примере).
client.subscribe(mqttTopicLamp);          // Подписываемся на топик "home/lamp".
client.subscribe(mqttTopicPower);         // Подписываемся на топик "home/power".

else {
delay(5000);                                            // Ждем 5 секунд перед повторной попыткой.
}
}
}
//  ========================================================================  
// Для этого проекта вам не нужно ничего менять в функции цикла. 
// В основном это гарантирует, что ваш ESP подключен к вашему брокеру.
void loop() {
if (!client.connected()) {
reconnect(); 
}
//не знаю, что делает эта строка, но без нее LED не работает.
if(!client.loop())
client.connect("ESP8266Client");
now = millis();
// Публикуем новую температуру и влажность каждые 30 секунд
if (now - lastMeasure > resendtime) {
lastMeasure = now;
// Показания датчика также могут быть «старыми» до 2 секунд (это очень медленный датчик).
float h = dht.readHumidity();
// Считать температуру в градусах Цельсия (по умолчанию).
float t = dht.readTemperature();
// Считать температуру в градусах Фаренгейта (isFahrenheit = true).
float f = dht.readTemperature(true);
 // Проверим, не удалось ли выполнить какое-либо чтение, и завершим работу рано (повторим попытку).
if (isnan(h) || isnan(t) || isnan(f)) {
return;
}
//  ========================================================================
// Вычисляем значения температуры в градусах Цельсия.
float hic = dht.computeHeatIndex(t, h, false);
static char temperatureTemp[7];
dtostrf(hic, 6, 2, temperatureTemp);    
static char humidityTemp[7];
dtostrf(h, 6, 2, humidityTemp);
//Считываем значения с аналогового входа.
float dc = (analogRead(AnalogPin) * 1.1) / 1023;          // Считываем значения с аналогового входа.
float del = dc / (R2/(R1+R2));                            // R2/(R1+R2)  0.99кОм / (9.88кОм + 0.99кОм)
float Vin = dc / del;
int proc = ((Vin - min_v) / (max_v - min_v)) * 100;       // Уровень заряда в процентах.


//  ========================================================================
// Публикуем значения температуры, влажности и напряжения.
// Индикация передачи данных.
//digitalWrite(LED_BUILTIN, LOW);                                  // Зажигаем LED (моргает при публикации топиков).
//Serial.println("ON");                                                            // Выводим в Serial монитор.
client.publish(mqttTopicTemperature, temperatureTemp);    // Публикуем температуру.
client.publish(mqttTopicHumidity, humidityTemp);              // Публикуем влажность.
client.publish(mqttTopicPower, String(dc).c_str());               // Публикуем напряжение.
//  ========================================================================    
// Выводим в Serial монитор.
Serial.print("Влажность: ");
Serial.print(h);
Serial.print(" %\t Температура: ");
Serial.print(t);
Serial.print(" *C\t ");
Serial.print(f);
Serial.print(" *F\t Тепловой индекс: ");
Serial.print(hic);
Serial.print(" *C\t ");
Serial.print("ESP8266-(A0) ");
Serial.print(dc);
Serial.println(" V.");

Serial.print("Напряжение: ");                             
Serial.print(Vin);                                        
Serial.println("V");                                      
Serial.print("Осталось: ");                               
Serial.print(proc);                                       
Serial.println("% ");                                     
//  ========================================================================
  

// Индикация передачи данных.
//  digitalWrite(LED_BUILTIN, HIGH); // Гасим LED (моргает при публикации топиков).
//  Serial.println("OFF");                          // Выводим в Serial монитор.

//  ESP.deepSleep(30e6);                          // 30e6 это и есть deep-sleep. Засыпаем на 30 секунд,(перемычка между D0 и RST)!

    
}

Комментариев нет:

Отправить комментарий

Создайте свой комментарий.