/* Применялось
2 датчика DH22 - Как датчик температуры/влажности почвы и воздуха
1 Photoresistor (LDR) для управлении освещенности через ТГ бот и автоматически.
2 Relay Module (Один как Подогреватель, другой как Увлажнитель)
1 Servo (Проветривание) */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*
cred:
Junior Developer K.Kriv
Information Specialist (Captain) - A.Fir
------------------------------------------------------------- НОК 🧡 ----------------------------------------------------------------------------------------
*//*------------------------------------------------------- Библиотеки ----------------------------------------------------------------------------------------*/
#include <WiFi.h>
#include <DHTesp.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h> // Universal Telegram Bot Library written by Brian Lough: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
#include <ArduinoJson.h>
#include <FastLED.h> // конфигурация матрицы // LED matrix configuration
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <ESP32Servo.h>
/* ---------------------------------------------- define, int, const, bool и прочее --------------------------------------------------------------------------------------------------------- */
#define NUM_LEDS 17 // количество светодиодов в матрице // number of LEDs
#define LED_PIN 13 // пин к которому подключена матрица // matrix pin
#define PHOTO_PIN 33 // Подключение фоторезистора
int brightness = 0; // Переменная для определения текущей яркости светодиодов
int mapBrightness(int lightValue) {
return map(lightValue, 0, 1023, 0, 255); // Функция для конвертации значения освещенности в диапазон яркости FastLED
}
int isLightTurned = 0;
const int LIGHT_THRESHOLD = 500; // Указываем пороговое значение освещенности для включения/выключения света
CRGB leds[NUM_LEDS];
#define DHT_PIN1 23 // Подключение пинов датчиков
#define DHT_PIN2 15
DHTesp dht1;
DHTesp dht2;
Servo servo;
const int relayPin2 = 14;
const int relayPin = 12;
//const int trig = 32;
//const int echo = 33;
const char* SSID = "Wokwi-GUEST";
const char* password = "";
#define BOTtoken "6807265753:AAHLnxfS9JFHgO4zKWl1PEOENM7qt9s_ILM"
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
int botRequestDelay = 500;
unsigned long lastTimeBotRan;
bool humidifierOn = false;
int statusCode;
/*------------------------------------------------------ Иницилизации --------------------------------------------------------------------------------------*/
void setup(void){
dht1.setup(DHT_PIN1, DHTesp::DHT22); //Инициалиазация DHT1 DHT2 датчиков
dht2.setup(DHT_PIN2, DHTesp::DHT22);
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);
servo.attach(27);
pinMode(relayPin, OUTPUT);
pinMode(relayPin2, OUTPUT);
servo.write(90); // Устанавливаем сервопривод в исходное положение
Serial.begin(9600);
Serial.begin(9500);
//pinMode(trig, OUTPUT);
//pinMode(echo, INPUT);
Serial.println();
Serial.println("Иницилизация системы...");
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, password);
client.setCACert(TELEGRAM_CERTIFICATE_ROOT);
Serial.print("Подключение к WI-FI..");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println();
Serial.println("Подключен");
}
/*-------------------------------------------- Паблик реакции на команды/кнопки ТГ бота ---------------------------------------------------------------------- */
void handleNewMessages(int numNewMessages) {
for (int i = 0; i < numNewMessages; i++)
{
String chat_id = String(bot.messages[i].chat_id); // Импортируем мессадж ид, для того чтобы одним сообщением обновлялся сообщение
int message_id = bot.messages[i].message_id;
if (bot.messages[i].type == "callback_query")
{
String text = bot.messages[i].text;
String chat_id = String(bot.messages[i].chat_id);
Serial.print("Кнопка: ");
Serial.println(text);
if (text == "BACK") // Возвращение
{
String text = "Привет! 👋🏻" "\n";
text += "Это бот управления умной теплицой от ОГАПОУ «Новооскольский колледж» 🏠" "\n";
text += "С помощью него вы можете управлять умной теплицой 🎛️" "\n";
text += "Выберите необходимое действие 👨🌾:" "\n";
String keyboardJson = "[[{ \"text\" : \"🔧 Ручное управление теплицей\", \"callback_data\" : \"TEPLISA\" }], [{ \"text\" : \"⏏️ Режимы освещенности\", \"callback_data\" : \"COLORLAMP\" }], [{ \"text\" : \"🪴 Узнать состояние теплицы\", \"callback_data\" : \"INFODHT22\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, text, "", keyboardJson, message_id);
}
if (text == "TEPLISA") // вручная работа теплицей
{
String keyboardJson = "[[{ \"text\" : \"💡Включить/выключить освещение\", \"callback_data\" : \"LAMP\" }], [{ \"text\" : \"💧 Включить/выключить контроль влажности\", \"callback_data\" : \"HUMIDIFER\" }], [{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"BACK\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "Выберите команды для управления теплицей", "", keyboardJson, message_id);
}
if (text == ("LAMP")){ // Команды от кнопки (Включение/выключение)
if (isLightTurned == 0){
fill_solid( leds, NUM_LEDS, CRGB(255, 255, 255));
isLightTurned = 1;
FastLED.show();
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"TEPLISA\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "⚪ Освещение включено", "", keyboardJson, message_id);
}
else if (isLightTurned == 1) {
fill_solid( leds, NUM_LEDS, CRGB(0, 0, 0));
isLightTurned = 0;
FastLED.show();
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"TEPLISA\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "⚫ Освещение выключено", "", keyboardJson, message_id);
}
}
if (text == ("COLORLAMP")){ // на изменение спектров
String keyboardJson = "[[{ \"text\" : \"🔵 Спектр вегетации\", \"callback_data\" : \"BLUECOLOR\" }], [{ \"text\" : \"🔴 Спектр цветение\", \"callback_data\" : \"REDCOLOR\" }], [{ \"text\" : \"⚪ Исходный спектр\", \"callback_data\" : \"BACKCOLOR\" }], [{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"BACK\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "Выберите спектра для изменение освещения", "", keyboardJson, message_id);
}
if (text == ("REDCOLOR")){ // кмд на спектр цветение
if (isLightTurned == 1){
fill_solid ( leds, NUM_LEDS, CRGB(255,0,0));
FastLED.show();
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"COLORLAMP\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "🔴 Включен спектр цветение", "", keyboardJson, message_id);
}else{
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"COLORLAMP\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "⚫ Освещение выключено, необходимо включить освещение, дабы включить спектр", "", keyboardJson, message_id);
}
}
if (text == ("BLUECOLOR")){ // кмд на спектр вегетации
if (isLightTurned == 1){
fill_solid ( leds, NUM_LEDS, CRGB(0,77,255));
FastLED.show();
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"COLORLAMP\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "🔵 Включен спектр вегетации", "", keyboardJson, message_id);
}else{
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"COLORLAMP\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "⚫ Освещение выключено, необходимо включить освещение, дабы включить спектр", "", keyboardJson, message_id);
}
}
if(text == ("BACKCOLOR")){ // кмд на исход спектр
if (isLightTurned == 1){
fill_solid ( leds, NUM_LEDS, CRGB(255,255,255));
FastLED.show();
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"COLORLAMP\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "⚪ Включен в исходный спектр", "", keyboardJson, message_id);
}else{
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"COLORLAMP\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "⚫ Освещение выключено, необходимо включить освещение, дабы включить спектр", "", keyboardJson, message_id);
}
}
if (text == ("HUMIDIFER")){ // кмд на влага
if (!humidifierOn){
digitalWrite(relayPin2, HIGH);
humidifierOn = true;
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"TEPLISA\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "✅ Увлажнитель включен", "", keyboardJson, message_id);
}else{
digitalWrite(relayPin2, LOW);
humidifierOn = false;
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"TEPLISA\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, "❌ Увлажнитель выключен", "", keyboardJson, message_id);
}
}
if (text == ("INFODHT22")){ //Информация с датчика DHT22
float temperature1 = dht1.getTemperature();
float humidity1 = dht1.getHumidity();
float temperature2 = dht2.getTemperature();
float humidity2 = dht2.getHumidity();
int lightValue = analogRead(PHOTO_PIN); // Считываем значения с фоторезистора
brightness = mapBrightness(lightValue); // Конвертируем значение освещенности в диапазон яркости FastLED
String info = "🌡 Температура воздуха: " + String(temperature1) + " °C" + ".\n";
info += "💧 Влажность воздуха: " + String(humidity1) + " %" "\n";
info += "🌱 Температура почвы: " + String(temperature2) + " °C" "\n";
info += "🌱 Влажность почвы: " + String(humidity2) + " %" "\n";
info += "💡 Уровень освещенности: " + String(brightness) + " LUX" "\n";
String keyboardJson = "[[{ \"text\" : \"⏪ Назад\", \"callback_data\" : \"BACK\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, info, "", keyboardJson, message_id);
}
} else {
String chat_id = bot.messages[i].chat_id;
String text = bot.messages[i].text;
String from_name = bot.messages[i].from_name;
if (from_name == "")
from_name = "Guest";
if (text == "/start")
{
String text = "Привет! 👋🏻" "\n";
text += "Это бот управления умной теплицой от ОГАПОУ «Новооскольский колледж» 🏠" "\n";
text += "С помощью него вы можете управлять умной теплицой 🎛️" "\n";
text += "Выберите необходимое действие 👨🌾:" "\n";
String keyboardJson = "[[{ \"text\" : \"🔧 Ручное управление теплицей\", \"callback_data\" : \"TEPLISA\" }], [{ \"text\" : \"⏏️ Режимы освещенности\", \"callback_data\" : \"COLORLAMP\" }], [{ \"text\" : \"🪴 Узнать состояние теплицы\", \"callback_data\" : \"INFODHT22\" }]]";
bot.sendMessageWithInlineKeyboard(chat_id, text, "", keyboardJson);
}
}
}
}
/*---------------------------------------------------------- Паблик повтора ----------------------------------------------------------------------------------*/
void loop(){
int lightValue = analogRead(PHOTO_PIN); // Считываем значения с фоторезистора
brightness = mapBrightness(lightValue); // Конвертируем значение освещенности в диапазон яркости FastLED
FastLED.setBrightness(brightness); // Применяем яркость ко всем светодиодам
FastLED.show(); // Обновляем состояние светодиодов
delay(100);
if (millis() - lastTimeBotRan > botRequestDelay){
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
Serial.println("Новое сообщение : " + String(numNewMessages));
while(numNewMessages) {
Serial.println("получил ответ");
handleNewMessages(numNewMessages);
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
}
lastTimeBotRan = millis();
}
/*-------------------------------------------------- Отдельные задачи от автоматики датчиков -----------------------------------------------------------------------*/
//Необходимые компоненты
int i = i++;
String chat_id = String(bot.messages[i].chat_id); // импортирую чат_ид, дабы не было триггера со стороны комплектации
/*-------------------------------------------------- Увлажнитель ------------------------------------------------------------------------------------------------------------------*/
float humidity1 = dht2.getHumidity();
float humidity2 = dht2.getHumidity();
if (humidity1 <= 20 && humidity2 <= 20) {
//humidifierOn = true; (в рарзработке момент с вручным вырубление/врубление)
digitalWrite(relayPin2, HIGH); // Включение увлажнителя
bot.sendMessage(chat_id, "Влажность почвы ниже или равна 20%. Увлажнитель включен.");
delay(5000); // Включаем увлажнитель на 5 секунд
digitalWrite(relayPin2, LOW); // Выключаем увлажнитель
}
else if (humidity1 >= 40 && humidity2 >= 40 && humidifierOn == true){
digitalWrite(relayPin2, LOW); // Выключение увлажнителя
humidifierOn = false;
bot.sendMessage(chat_id, "Влажность почвы выше 40%. Увлажнитель выключен.");
}
delay(5000); // Интервал 5 секунд перед включением проветр/подогрев
/*-------------------------------------------------- Проветривание/Подогрев ----------------------------------------------------------------------------------------------------*/
float temperature_1 = dht1.getTemperature();
float temperature_2 = dht2.getTemperature();
if (temperature_1 <= 25 && temperature_2 <= 25) {
digitalWrite(relayPin, HIGH); // Включаем нагрев
bot.sendMessage(chat_id, "Температура воздуха/почвы ниже или равна 25 °C. Подогреватель включен.");
servo.write(0); // Поворачиваем сервопривод в одну сторону
delay(5000); // Включаем нагрев на 5 секунд
digitalWrite(relayPin, LOW); // Выключаем нагрев
servo.write(90); // Возвращаем сервопривод в исходное положение
}
else if (temperature_1 >= 29 && temperature_2 >= 29){
digitalWrite(relayPin, HIGH); // Включаем проветривание
bot.sendMessage(chat_id, "Температура воздуха/почвы выше или равна 29 °C. Проветривание включена.");
servo.write(180); // Поворачиваем сервопривод в другую сторону
delay(5000); // Включаем проветривание на 5 секунд
digitalWrite(relayPin, LOW); // Выключаем проветривание
servo.write(90); // Возвращаем сервопривод в исходное положение
}
}
/*--------------------------------------------- Концовка loop ---------------------------------------------------------------------------------------------------------------*/
/* Вроде все */