![Arduino, ESP8266, MQTT, DHT22, Бутони и Волтметър управление на релета и мониторинг на сензори](http://ardudevelop.eu/wp-content/uploads/2025/02/Arduino-ESP8266-MQTT-DHT22-Бутони-и-Волтметър-управление-на-релета-и-мониторинг-на-сензори.png)
Въведение
Този проект демонстрира как да използвате ESP8266 с Arduino за създаване на система за управление на четири релета и мониторинг на сензори чрез MQTT протокол. Системата включва DHT22 сензор за температура и влажност, бутони за ръчно управление на релетата и волтметър за измерване на напрежение. Проектът е идеален за домашна автоматизация, IoT приложения и образователни цели. Този проект сме го използвали за да демонстрираме как за едио хардуерно изделие можем да напишем код за управлението му на различни с различни протоколи. Може да разгледате другите ни статии:
- MicroPython и MQTT, управление на релета, изчитане на DHT сензор и напрежение: Компактен проект за интелигентен дом
- ESP8266 управление на релета през WEB или бутони и изчитане на DHT22 и напрежение – В тази статия ще намерите СХЕМИТЕ и снимка на ПЛАТКАТА на това устройство.
Хардуер
За реализацията на проекта са използвани следните компоненти:
![Arduino, ESP8266, MQTT, DHT22, Бутони и Волтметър управление на релета и мониторинг на сензори Устройство](http://ardudevelop.eu/wp-content/uploads/2024/12/ESP8266-управление-на-релета-през-WEB-или-бутони-и-изчитане-на-DHT22-и-напрежение.png)
- ESP8266 – Микроконтролер с WiFi възможности, използван за управление на релетата и сензорите.
- Релета – Четири релета, управлявани чрез цифрови изходи на ESP8266.
- Бутони – Четири бутона за ръчно управление на релетата.
- DHT22 сензор – Сензор за температура и влажност.
- Волтметър – Използва се аналогов вход за измерване на напрежение чрез делител на напрежение.
- Делител на напрежение – Състоящ се от два резистора (R1 = 120kΩ, R2 = 15.5kΩ) за измерване на напрежение.
Използвани библиотеки
ESP8266WiFi – Библиотека за управление на WiFi връзката на ESP8266. Включена е в стандартната инсталация на Arduino IDE за ESP8266. Ако все още не сте добавили този процесор във вашето Arduino IDE може да прочетете как става това в статията ни: Добавяне на ESP8266 в Arduino IDE: Стъпка по стъпка
![MQTT PubSubClient Arduino IDE Library Manager](http://ardudevelop.eu/wp-content/uploads/2025/02/PubSubClient-Arduino-IDE-Library-Manager.jpg)
Ако не знаете как да инсталирате и настройте свой собствен MQTT брокер, може да прочетете как става това в страниците ни:
- Инсталиране на Mosquitto MQTT Broker на Raspberry Pi 4
- Инсталиране Mosquitto MQTT Broker на Orange Pi Plus 2 и Armbian Linux
DHT – Библиотека за работа с DHT сензорите. Може да бъде намерена в GitHub или отново да я свалите директно с Arduino IDE Library Manager. Също така може да я свалите от тук.
![ESP8266 Arduino IDE Library Manager DHT Library](http://ardudevelop.eu/wp-content/uploads/2025/02/ESP8266-Arduino-IDE-Library-Manager-DHT-Library.jpg)
Код за управление на релета и мониторинг на сензори написан на Arduino IDE, и ESP8266 през MQTT
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// Настройка на пиновете за релета
#define RELAY1_PIN D0 // GPIO16
#define RELAY2_PIN D6 // GPIO12
#define RELAY3_PIN D7 // GPIO13
#define RELAY4_PIN D8 // GPIO15
// Настройка на пиновете за бутони
#define BUTTON1_PIN D3 // GPIO0
#define BUTTON2_PIN D4 // GPIO2
#define BUTTON3_PIN D2 // GPIO4
#define BUTTON4_PIN D1 // GPIO5
// Аналогов вход
#define ANALOG_INPUT A0
// DHT22 сензор
#define DHTPIN D5 // GPIO14
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Настройки за WiFi и MQTT
const char* ssid = "XXXXXXXX"; // Заменете с вашето WiFi SSID
const char* password = "XXXXXXXX"; // Заместете с вашата WiFi парола
const char* mqtt_server = "192.168.1.80"; // Заместете с IP на вашия MQTT сървър
const int mqtt_port = 1883; // Заменете с вашия порт на MQTT сървъра
const char* mqtt_user = "XXXXXXXX"; // Заместете с username на вашия MQTT сървър
const char* mqtt_password = "XXXXXXXX"; // Заместете с вашата MQTT парола
const char* mqtt_client_id = "ESP8266_proto_1";
// MQTT топици
const char* mqtt_topic_command = "esp8266/relays";
const char* mqtt_topic_dht_temp = "esp8266/DHTtemp";
const char* mqtt_topic_dht_hum = "esp8266/DHThum";
const char* mqtt_topic_analog_in = "esp8266/AnalogIN";
const char* mqtt_topic_relay1_state = "esp8266/relay1/state";
const char* mqtt_topic_relay2_state = "esp8266/relay2/state";
const char* mqtt_topic_relay3_state = "esp8266/relay3/state";
const char* mqtt_topic_relay4_state = "esp8266/relay4/state";
const char* mqtt_topic_status = "esp8266/status";
// MQTT клиент
WiFiClient espClient;
PubSubClient client(espClient);
// Делител на напрежение
const float R1 = 120000.0;
const float R2 = 15500.0;
// Променливи за състоянието на релетата
bool relay1_state = false;
bool relay2_state = false;
bool relay3_state = false;
bool relay4_state = false;
// Функция за свързване към WiFi
void connectToWiFi() {
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi");
}
// Функция за свързване към MQTT сървър
void connectToMQTT() {
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect(mqtt_client_id, mqtt_user, mqtt_password)) {
Serial.println("Connected to MQTT server");
client.subscribe(mqtt_topic_command);
client.publish(mqtt_topic_status, "online", true);
} else {
Serial.print("Failed to connect to MQTT, retrying in 5 seconds...");
delay(5000);
}
}
}
// Функция за обработка на MQTT съобщения
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message received on topic: ");
Serial.print(topic);
Serial.print(" - ");
Serial.println(message);
if (String(topic) == mqtt_topic_command) {
if (message == "R1on") {
digitalWrite(RELAY1_PIN, HIGH);
relay1_state = true;
publishRelayState(1);
} else if (message == "R1off") {
digitalWrite(RELAY1_PIN, LOW);
relay1_state = false;
publishRelayState(1);
} else if (message == "R2on") {
digitalWrite(RELAY2_PIN, HIGH);
relay2_state = true;
publishRelayState(2);
} else if (message == "R2off") {
digitalWrite(RELAY2_PIN, LOW);
relay2_state = false;
publishRelayState(2);
} else if (message == "R3on") {
digitalWrite(RELAY3_PIN, HIGH);
relay3_state = true;
publishRelayState(3);
} else if (message == "R3off") {
digitalWrite(RELAY3_PIN, LOW);
relay3_state = false;
publishRelayState(3);
} else if (message == "R4on") {
digitalWrite(RELAY4_PIN, HIGH);
relay4_state = true;
publishRelayState(4);
} else if (message == "R4off") {
digitalWrite(RELAY4_PIN, LOW);
relay4_state = false;
publishRelayState(4);
}
}
}
// Функция за публикуване на състоянието на релетата
void publishRelayState(int relay_number) {
String topic;
String state;
switch (relay_number) {
case 1:
topic = mqtt_topic_relay1_state;
state = relay1_state ? "ON" : "OFF";
break;
case 2:
topic = mqtt_topic_relay2_state;
state = relay2_state ? "ON" : "OFF";
break;
case 3:
topic = mqtt_topic_relay3_state;
state = relay3_state ? "ON" : "OFF";
break;
case 4:
topic = mqtt_topic_relay4_state;
state = relay4_state ? "ON" : "OFF";
break;
}
client.publish(topic.c_str(), state.c_str(), true);
}
// Функция за четене на DHT сензора
void readDHT() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (!isnan(temperature) && !isnan(humidity)) {
client.publish(mqtt_topic_dht_temp, String(temperature).c_str(), true);
client.publish(mqtt_topic_dht_hum, String(humidity).c_str(), true);
} else {
Serial.println("Failed to read DHT sensor");
}
}
// Функция за четене на аналоговия вход
void readAnalogInput() {
int analog_value = analogRead(ANALOG_INPUT);
float voltage_in = analog_value * (3.3 / 1024.0) * 10.0;
float volt = (voltage_in * (R1 / (R1 + R2))) - 0.14;
// Ако volt е по-малко от 0, задайте го на 0
if (volt < 0) {
volt = 0;
}
volt = round(volt * 100) / 100; // Закръгляне до 2 знака след десетичната запетая
client.publish(mqtt_topic_analog_in, String(volt).c_str(), true);
}
// Функция за обработка на бутоните
void handleButtons() {
if (digitalRead(BUTTON1_PIN) == LOW) {
relay1_state = !relay1_state;
digitalWrite(RELAY1_PIN, relay1_state ? HIGH : LOW);
publishRelayState(1);
delay(200); // Anti-bounce
}
if (digitalRead(BUTTON2_PIN) == LOW) {
relay2_state = !relay2_state;
digitalWrite(RELAY2_PIN, relay2_state ? HIGH : LOW);
publishRelayState(2);
delay(200);
}
if (digitalRead(BUTTON3_PIN) == LOW) {
relay3_state = !relay3_state;
digitalWrite(RELAY3_PIN, relay3_state ? HIGH : LOW);
publishRelayState(3);
delay(200);
}
if (digitalRead(BUTTON4_PIN) == LOW) {
relay4_state = !relay4_state;
digitalWrite(RELAY4_PIN, relay4_state ? HIGH : LOW);
publishRelayState(4);
delay(200);
}
}
// Настройка
void setup() {
Serial.begin(115200);
// Инициализация на пиновете
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
pinMode(RELAY4_PIN, OUTPUT);
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(BUTTON3_PIN, INPUT_PULLUP);
pinMode(BUTTON4_PIN, INPUT_PULLUP);
// Инициализация на DHT сензора
dht.begin();
// Свързване към WiFi
connectToWiFi();
// Настройка на MQTT клиента
client.setServer(mqtt_server, mqtt_port);
client.setCallback(mqttCallback);
}
// Главен цикъл
void loop() {
if (!client.connected()) {
connectToMQTT();
}
client.loop();
// Четене и публикуване на данни от сензорите
readDHT();
readAnalogInput();
// Обработка на бутоните
handleButtons();
delay(1000); // Изчакване преди следващия цикъл
}
Пълно описание на кода
Инициализация на пинове и библиотеки
В началото на кода се инициализират пиновете за релетата, бутоните, аналоговия вход и DHT сензора. Също така се включват необходимите библиотеки.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// Настройка на пиновете за релета
#define RELAY1_PIN D0 // GPIO16
#define RELAY2_PIN D6 // GPIO12
#define RELAY3_PIN D7 // GPIO13
#define RELAY4_PIN D8 // GPIO15
// Настройка на пиновете за бутони
#define BUTTON1_PIN D3 // GPIO0
#define BUTTON2_PIN D4 // GPIO2
#define BUTTON3_PIN D2 // GPIO4
#define BUTTON4_PIN D1 // GPIO5
// Аналогов вход
#define ANALOG_INPUT A0
// DHT22 сензор
#define DHTPIN D5 // GPIO14
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
Настройка на WiFi и MQTT
След инициализацията на пиновете, се задават настройките за WiFi и MQTT сървъра. Функциите connectToWiFi()
и connectToMQTT()
се използват за свързване към WiFi и MQTT сървъра.
// Настройки за WiFi и MQTT
const char* ssid = "XXXXXXXXX"; // Заменете с вашето WiFi SSID
const char* password = "XXXXXXXXX"; // Заместете с вашата WiFi парола
const char* mqtt_server = "192.168.1.80"; // Заместете с IP на вашия MQTT сървър
const int mqtt_port = 1883; // Заменете с вашия порт на MQTT сървъра
const char* mqtt_user = "XXXXXXXXX"; // Заместете с username на вашия MQTT сървър
const char* mqtt_password = "XXXXXXXXX"; // Заместете с вашата MQTT парола
const char* mqtt_client_id = "ESP8266_proto_1";
// MQTT топици
const char* mqtt_topic_command = "esp8266/relays";
const char* mqtt_topic_dht_temp = "esp8266/DHTtemp";
const char* mqtt_topic_dht_hum = "esp8266/DHThum";
const char* mqtt_topic_analog_in = "esp8266/AnalogIN";
const char* mqtt_topic_relay1_state = "esp8266/relay1/state";
const char* mqtt_topic_relay2_state = "esp8266/relay2/state";
const char* mqtt_topic_relay3_state = "esp8266/relay3/state";
const char* mqtt_topic_relay4_state = "esp8266/relay4/state";
const char* mqtt_topic_status = "esp8266/status";
// MQTT клиент
WiFiClient espClient;
PubSubClient client(espClient);
Функции за управление на релетата
Функцията mqttCallback()
се използва за обработка на MQTT съобщенията. Тя проверява командите и управлява релетата според получените команди.
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
if (String(topic) == mqtt_topic_command) {
if (message == "R1on") {
digitalWrite(RELAY1_PIN, HIGH);
relay1_state = true;
publishRelayState(1);
} else if (message == "R1off") {
digitalWrite(RELAY1_PIN, LOW);
relay1_state = false;
publishRelayState(1);
}
// Аналогично за R2, R3, R4
}
}
Функции за четене на сензорите
Функциите readDHT()
и readAnalogInput()
се използват за четене на данните от DHT сензора и аналоговия вход, и публикуването им в MQTT топици.
void readDHT() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (!isnan(temperature) && !isnan(humidity)) {
client.publish(mqtt_topic_dht_temp, String(temperature).c_str(), true);
client.publish(mqtt_topic_dht_hum, String(humidity).c_str(), true);
} else {
Serial.println("Failed to read DHT sensor");
}
}
void readAnalogInput() {
int analog_value = analogRead(ANALOG_INPUT);
float voltage_in = analog_value * (3.3 / 1024.0) * 10.0;
float volt = (voltage_in * (R1 / (R1 + R2))) - 0.14;
if (volt < 0) {
volt = 0;
}
volt = round(volt * 100) / 100; // Закръгляне до 2 знака след десетичната запетая
client.publish(mqtt_topic_analog_in, String(volt).c_str(), true);
}
Обработка на бутоните
Функцията handleButtons()
се използва за ръчно управление на релетата чрез бутоните.
void handleButtons() {
if (digitalRead(BUTTON1_PIN) == LOW) {
relay1_state = !relay1_state;
digitalWrite(RELAY1_PIN, relay1_state ? HIGH : LOW);
publishRelayState(1);
delay(200); // Anti-bounce
}
// Аналогично за BUTTON2_PIN, BUTTON3_PIN, BUTTON4_PIN
}
Топици и настройка на MQTT панел
MQTT топиците са основен елемент за комуникация между ESP8266 и MQTT сървъра. Те действат като канали, през които устройствата обменят информация. В този проект са дефинирани няколко ключови топика, които позволяват управление на релетата, мониторинг на сензорите и проследяване на състоянието на системата.
esp8266/relays
: Този топик се използва за изпращане на команди към релетата. Например, съобщения като “R1on” или “R1off” включват или изключват първото реле.esp8266/DHTtemp
: Тук се публикуват данните за температурата, получени от DHT22 сензора.esp8266/DHThum
: Този топик съдържа информация за влажността, измерена от DHT22.esp8266/AnalogIN
: Чрез този топик се изпращат данните от волтметъра, който измерва напрежението на аналоговия вход.esp8266/relay1/state
,esp8266/relay2/state
,esp8266/relay3/state
,esp8266/relay4/state
: Тези топици съдържат текущото състояние на всяко реле (ON или OFF).esp8266/status
: Този топик се използва за индикация на статуса на устройството, като “online” или “offline“.
Настройката на MQTT панела включва конфигуриране на сървъра, клиентски идентификатор и потребителски данни. Всички топици се абонират и публикуват автоматично, когато устройството се свърже към MQTT сървъра. Това позволява лесно интегриране на системата в съществуващи IoT платформи или мобилни приложения за управление.
Виде презентация на проекта
Заключение
Този проект демонстрира как може да се използва Arduino и ESP8266 за управление на релета и мониторинг на сензори чрез MQTT протокол. Системата включва DHT22 сензор за температура и влажност, бутони за ръчно управление и волтметър за измерване на напрежение. С правилната настройка на MQTT сървъра и клиенти, системата може да бъде интегрирана в по-големи проекти за управление на умни домове и индустриални системи.