|
НиколаМастер
2019-05-16 13:14 #332
Привет! Поможете? Нужна помощь в написании кода. Мега+5100+2 DS18B20+3 датчика тока+ 1602 Мониторинг работы парогенератора Алгоритм работы системы я вижу так:
• Температурный датчик на паропроводе. • Температурный датчик на подающем трубопроводе. • Токовые датчики на 3 фазы. Алгоритм, система находится всегда в режиме мониторинга, даже при выключенном парогенераторе. При включении парогенератора по программе, контроллер парогенератора выдает команду на включение света, с него берем сигнал и активируется режим сравнения параметров датчиков с заданными константами (задержка 30 мин для выхода на режим). При нарушении условий, включается звуковое оповещение и система посылает e-mail сообщение. Мониторинг осуществляется посредством посещения веб странички в локальной сети и на экране 1602. Необходим одновременный доступ на страничку нескольких пользователей. реле и шим, оставить как в примере на будущее.
http://tehnopage.ru/ethernet-arduino-pwm-control
Профиль
|
|
|
NIk1990
2019-05-20 23:09 #333
Здравствуйте! Хочу сделать проект по освещению дома.Подскажите пожалуйста,что нужно изменить в коде файлов index.htm , my.css и прошивке ардуино ,чтобы оставить только часть '"Управление нагрузками" с четырьмя кнопками . Пытался многократно сам отредактировать index.htm ,но просто удаляя строчки с 51 по 74 теряется функция фиксации кнопки(зеленый цвет ,если кнопка активна).Вам скорее всего пять секунд нужно,чтобы удалить лишнее и отредактировать код,а я нуб,и неделю уже не могу методом тыка справиться. Буду Вам крайне признателен,если поможете!
Профиль
|
|
|
humaxoid
2021-03-18 08:56 #335
Попробуем встряхнуть форум после долгой спячки. Вдохновленный вашими проектами, решил сделать умную теплицу. В ардуинку всё не влезло. Посему прикупил ESP32 и реализовал проект на нем. Вэб интерфейс выглядит так:
Как видим датчик DHT22 измеряет наружную температуру и влажность, показания выводятся в вэб интерфейс. Второй датчик BME280 имеряет температуру, атмосферное давление, влажность внутри теплицы. Датчик света BH1750. Температуру почвы DS18B20. Емкостной датчик "Soil Moisture Sensor" измеряет влажность почвы.
Всё завелось и работает. Основываясь на указанные показатели, включаются реле открывания форточек и полива растений. В будующем собираюсь прикрутить дополнительное освещение. Для досветки растений при коротком световом дне.
А теперь самое главное. Хочу сделать так, чтобы кроме автоматики, можно было принудительно включать и отключать реле. Ваши куски кода внедрил в свой скетч. Но кнопки включения и отключения реле не срабатывают. Может подскажете, где напортачил? Скетч со всеми комментариями прилагаю:
Код // Импортируем необходимые библиотеки: #include <WiFi.h> #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #include <BH1750.h> #include <DHT.h> #include <OneWire.h>
//Датчик DTH22 #define DHTPIN 13 //Указываем номер цифрового pin для чтения данных #define DHTTYPE DHT22 //Указываем тип датчика DHT dht(DHTPIN, DHTTYPE);
//Датчик BH1750 BH1750 lightMeter;
//Датчик BME280 Adafruit_BME280 bme; // Подключаем датчик в режиме I2C
//Датчик DS18B20 OneWire ds(15); // Создаем объект OneWire для шины 1-Wire, с помощью которого будет осуществляться работа с датчиком
//Датчик Soil_Moisture_Sensor (влажность почвы) int moisture_pin = 36; // Указываем номер аналогового пина int output_value ;
// Задаем сетевые настройки const char* ssid = "SSID"; const char* password = "password"; IPAddress local_IP(192, 168, 66, 68); // Задаем статический IP-адрес: IPAddress gateway(192, 168, 66, 102); // Задаем IP-адрес сетевого шлюза: IPAddress subnet(255, 255, 255, 0); // Задаем маску сети: IPAddress primaryDNS(8, 8, 8, 8); // Основной ДНС (опционально) IPAddress secondaryDNS(8, 8, 4, 4); // Резервный ДНС (опционально) WiFiServer server(80); // Назначаем web серверу 80 порт String header; // Переменная для хранения HTTP-запроса
//=================================== Однократная загрузка ==============================================
void setup() { // инициализируем монитор порта Serial.begin(115200); // запас времени на открытие монитора порта — 2 секунды delay(2000);
// Объявляем пины для подключения блока реле pinMode(32, OUTPUT); // Объявляем выходной пин BME280 (верхние форточки) pinMode(33, OUTPUT); // Объявляем выходной пин BME280 (нижние форточки) pinMode(25, OUTPUT); // Объявляем выходной пин Soil_Moisture_Sensor (полив-1) pinMode(26, OUTPUT); // Объявляем выходной пин Soil_Moisture_Sensor (полив-2) pinMode(27, OUTPUT); // Объявляем выходной пин Soil_Moisture_Sensor (полив-3) pinMode(14, OUTPUT); // Объявляем выходной пин BH1750 (освещение)
//DTH22 Serial.println(F("запуск датчика DHT22...")); dht.begin(); // Датчик BH1750 Wire.begin(); lightMeter.begin(); Serial.println(F("запуск датчика BH1750...")); // Датчик BME280 Serial.println(F("запуск датчика BME280...")); if (!bme.begin(0x76)) { Serial.println("Не обнаружен датчик BME280, проверьте соеденение!"); while (1); }
//Датчик Soil_Moisture_Sensor Serial.println("запуск датчика влажности почвы... ");
// Настраиваем статический IP-адрес: if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) { Serial.println("Режим клиента не удалось настроить"); }
// Подключаемся к WiFi: WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(2000); Serial.println("Подключаемся к WiFi..."); }
// Отображаем локальный IP-адрес и запускаем веб-сервер: Serial.println(""); Serial.println("WiFi подключен."); Serial.println("IP адрес: "); Serial.println(WiFi.localIP()); server.begin(); Serial.println("Web сервер запущен."); }
//======================================== Циклическая загрузка =============================================
void loop() { // DTH22 Датчик температуры и влажности float IN2 = dht.readHumidity(); // Считывание влажности и создание переменной с именем IN2 float IN1 = dht.readTemperature(); // Считывание температуры и создание переменной с именем IN1 // Проверка, не удалось ли выполнить какое-либо чтение, и выйдите рано (чтобы повторить попытку). if (isnan(IN2) || isnan(IN1)) { Serial.println(F("Ошибка чтения с DHT датчика!")); return; } Serial.print(F("DTH22- Влажность: ")); // Вывод текста в монитор порта Serial.print(IN2); // Вывод влажности в последовательный монитор Serial.print(F(" % Температура: ")); // Вывод текста в монитор порта Serial.print(IN1); // Вывод температуры в последовательный монитор Serial.println(F(" °C ")); // Вывод текста в монитор порта delay(1000); // Пауза 1 сек.
//Датчик BH1750 float IN3 = lightMeter.readLightLevel(); // Считывание данных и создание переменной с именем IN3 Serial.print("Освещенность: "); // Вывод текста в монитор порта Serial.print(IN3); // Вывод показаний в последовательный монитор порта Serial.println(" люкс"); // Вывод текста в монитор порта if (IN3<=500) digitalWrite(15, LOW); // При достижении освещенности 500 люкс и выше, подать 0 на 15 пин. else digitalWrite(15, HIGH); // Сброс реле в исходное состояние delay(1000);
// ===================================== Универсальный датчик MBE280 ========================================
// температура float IN4 = (bme.readTemperature()-1.04); // Считывание данных и создание переменной с именем IN4, поправочный коэффициент -1.04 гр. Serial.print("BME280- Температура: "); // Вывод текста в монитор порта Serial.print(IN4); // Вывод показаний в последовательный монитор порта Serial.print(F(" °C ")); // Вывод текста в монитор порта // Автоматически открываем (закрываем) форточки. if (IN4>=28) digitalWrite(32, LOW); // При достижении температуры 24 гр. и выше, подать 0 на 32 пин. if (IN4<=26) digitalWrite(32, HIGH); // При понижении температуры до 20 гр. и ниже, подать 1 на 32 пин. if (IN4>=30) digitalWrite(33, LOW); // При достижении температуры 26 гр. и выше, подать 0 на 33 пин. else digitalWrite(33, HIGH); // Сброс реле в исходное состояние // давление float IN5 = (bme.readPressure()/133.3); // Считывание данных и создание переменной с именем IN5 Serial.print(" Давление: "); // Вывод текста в монитор порта Serial.print(IN5); // Вывод показаний в последовательный монитор порта Serial.print(" мм.рт.ст "); // Вывод текста в монитор порта // влажность float IN6 = (bme.readHumidity()); // Считывание данных и создание переменной с именем IN6 Serial.print(" Влажность: "); // Вывод текста в монитор порта Serial.print(IN6); // Вывод показаний в последовательный монитор порта Serial.println(" %"); // Вывод текста в монитор порта delay(1000); // Пауза 1 сек.
//Датчик DS18B20 byte data[2]; // Место для значения температуры ds.reset(); // Начинаем взаимодействие со сброса всех предыдущих команд и параметров ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру. Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память delay(1000); // Микросхема измеряет температуру, а мы ждем. ds.reset(); // Теперь готовимся получить значение измеренной температуры ds.write(0xCC); ds.write(0xBE); // Просим передать нам значение регистров со значением температуры
// Получаем и считываем ответ data[0] = ds.read(); // Читаем младший байт значения температуры data[1] = ds.read(); // А теперь старший
// Формируем итоговое значение: // - сперва "склеиваем" значение, // - затем умножаем его на коэффициент, соответсвующий разрешающей способности (для 12 бит по умолчанию - это 0,0625) float temperature = ((data[1] << 8) | data[0]) * 0.0625; float IN7 = ((temperature)+2.3); // Считывание данных и создание переменной с именем IN7, поправочный коэффициент +2,3 гр. Serial.print("DS18B20- Температура почвы: "); // Вывод текста в монитор порта Serial.print(IN7); // Вывод показаний в последовательный монитор порта Serial.println(" °C"); // Вывод текста в монитор порта
//Датчик Soil Moisture Sensor (Датчик влажности почвы) output_value = analogRead(moisture_pin); output_value = map(output_value, 4090, 2900, 0, 100); // Настроить, где: 4090=0% влажности, 2900=100% влажности. float IN8 = (output_value); // Считывание данных и создание переменной с именем IN8 Serial.print("Влажность почвы: "); Serial.print(IN8); // Вывод показаний в последовательный монитор порта Serial.println("%"); Serial.println(); if (IN8<=50) digitalWrite(25, LOW); // При понижении влажности до 50% и менее, подать 0 на 25 пин. (Огурцы) else digitalWrite(25, HIGH); // Сброс реле в исходное состояние if (IN8<=25) digitalWrite(26, LOW); // При понижении влажности до 25% и менее, подать 0 на 26 пин. (Перцы, зелень) else digitalWrite(26, HIGH); // Сброс реле в исходное состояние if (IN8<=15) digitalWrite(27, LOW); // При понижении влажности до 15% и менее, подать 0 на 27 пин. else digitalWrite(27, HIGH); // Сброс реле в исходное состояние delay(1000);
//========================================== Настройка вэб сервера ===================================================
WiFiClient client = server.available(); // Прослушивание входящих клиентов if (client) { // Если подключается новый клиент, Serial.println("Подключился новый клиент..."); // Выводим сообщение в последовательный порт. String currentLine = ""; // Создаем строку для хранения входящих данных от клиента while (client.connected()) { // цикл, пока клиент подключен if (client.available()) { // если есть байты для чтения с клиента, char c = client.read(); // читаем байт, тогда Serial.write(c); // выводим в последовательный монитор header += c; if (c == '\n') { // если байт является символом новой строки // если текущая строка пуста, у вас есть два символа новой строки подряд. // это конец клиентского HTTP-запроса, поэтому отпраляем ответ: if (currentLine.length() == 0) { // HTTP заголовки всегда начинаются с кода ответа (например HTTP/1.1 200 OK) // и тип контента, чтобы клиент знал, что будет дальше, а затем пустая строка: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // Отображаем HTML страницу. client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<meta charset=utf-8 http-equiv=refresh content=15>"); client.println("<link href=http://a.radikal.ru/a02/2103/16/d2882b4d2489.jpg rel=shortcut icon type=/x-icon>"); client.println("<title>Моя тепличка</title>"); client.println("<link rel=StyleSheet type=text/css>"); // CSS стиль таблицы client.println("<style>"); client.println("#gradient {"); client.println("-ms-filter: progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#589afc, endColorstr=#f0f5fc);"); client.println("background: -webkit-linear-gradient(to bottom, #589afc, #f0f5fc);"); client.println("background: -moz-linear-gradient(to bottom, #589afc, #f0f5fc);"); client.println("background: -o-linear-gradient(to bottom, #589afc, #f0f5fc);"); client.println("background: linear-gradient(to bottom, #589afc, #f0f5fc);"); client.println("}"); client.println(".wrapper{min-height: 87vh; display: flex; flex-direction: column;}"); client.println(".title{text-align: center;}"); client.println(".content{flex-grow: 1; display: flex; justify-content: center; align-items: center;}"); client.println(".img-block{max-width: 900px; position: relative;}"); client.println(".img-block img{max-width: 100%;} "); client.println(".txt-top, .txt-bottom{position: absolute;}"); client.println(".txt-top {top: font-size:1.3em; color:red}"); client.println("/* ============== Зададаем стили кнопок ===================== */"); client.println("td{color: #fff}"); client.println(" /*----------Стиль кнопки в отключенном состоянии------------*/"); client.println(".button_disabled {color: #fff; /* цвет текста белый */"); client.println(" background: rgb(212, 75, 56); /* фон кнопки красный */"); client.println(" border: none; /* не показывать границу */"); client.println(" border-radius:5px; /* закругление углов */"); client.println(" cursor: pointer /* ставим другой курсор */"); client.println(" }"); client.println(".button_disabled:hover {background: rgb(232, 95, 76);}/* при наведении курсора мышки */"); client.println(".button_disabled:active {background: rgb(152, 15, 0);}/* при нажатии */"); client.println(" /*----------Стиль кнопки во включенном состоянии------------*/"); client.println(".button_enabled {color: #000; /* цвет текста черный */"); client.println(" background: rgb(17,237,105); /* фон кнопки зеленный */"); client.println(" border: none; /* не показывать границу */"); client.println(" border-radius:5px; /* закругление углов */"); client.println(" cursor: pointer /* ставим другой курсор */"); client.println(" }"); client.println(".button_enabled:hover { background: rgb(94,242,153); } /* при наведении курсора мышки */"); client.println(".button_enabled:active { background: rgb(84,184,124); } /* при нажатии */"); client.println("</style>"); // Загружаем скрипт управления кнопками client.println(" <script>"); client.println("function GetFlameState() {"); client.println("nocache = &nocache= + Math.random() * 1000000;"); client.println("var request = new XMLHttpRequest();"); client.println("request.onreadystatechange = function() {"); client.println("if (this.readyState == 4) {"); client.println("if (this.status == 200) {"); client.println("if (this.responseText != null) {"); client.println("var arrayOfStrings = this.responseText.split(:);"); client.println("document.getElementById(flame_txt).innerHTML = arrayOfStrings[0];"); client.println("document.getElementById(temp_txt).innerHTML = arrayOfStrings[1];"); client.println("document.getElementById(humid_txt).innerHTML = arrayOfStrings[2];"); client.println("for(var i = 1 ; i < 5 ; i++)"); client.println("if(arrayOfStrings[2+i] == 1)"); client.println("document.getElementById(led_+i).setAttribute(class,button_enabled);"); client.println("else"); client.println("document.getElementById(led_+i).setAttribute(class,button_disabled);"); client.println("}"); client.println("}"); client.println("}"); client.println("}"); client.println("request.open(GET, ajax_flame + nocache, true);"); client.println("request.send(null);"); client.println("setTimeout('GetFlameState()', 1000);"); client.println("}"); client.println("function onClick(pin){"); client.println("var request = new XMLHttpRequest();"); //client.println("request.open(GET, \setpin?pin= + pin, false);"); //вываливается ошибка============================ client.println("request.send(null);"); client.println("}"); client.println("</script>"); // Заголовок веб страницы client.println("</head>"); client.println("<body id=gradient onload=startTime()>"); client.println("<div class=form>"); client.println("<center>"); client.println("<p><img alt=домик height=70 width=72 src=http://b.radikal.ru/b24/2103/fe/fc244b9baa45.png><font size=7 color=#FFFFFF> Контрольная панель - Умная теплица</font></p>"); client.println("</center>"); client.println("<div class=wrapper>"); client.println("<div class=title>"); client.println("<hr noshade size=3px>"); client.println("</div>"); client.println("<div class=content>"); client.println("<div class=img-block><img src=http://c.radikal.ru/c11/2103/8a/a37215234ef6.png alt=картинка>"); client.println("<div class=txt-top style='top:17px; left:700px;'><img src=http://a.radikal.ru/a23/2103/45/eebdf37707a9.gif height=142 width=172></div>");
client.print("<div class=txt-top style='top:20px; left:65px;'><img src=http://b.radikal.ru/b07/2103/c5/2f3c2bd305b7.png>"); client.print(" Температура: "); client.print("<b>"); client.print(IN1); client.print("</b>"); client.print(" °C"); client.println("</div>");
client.print("<div class=txt-top style='top:50px; left:65px;'><img src=http://c.radikal.ru/c11/2103/69/c266ed71cfda.png>"); client.print(" Влажность: "); client.print("<b>"); client.print(IN2); client.print("</b>"); client.print(" %"); client.println("</div>");
client.print("<div class=txt-top style='top:260px; left:570px;'><img src=http://b.radikal.ru/b05/2103/b4/fbce1a092bdb.png>"); client.print(" Освещенность: "); client.print("<b>"); client.print(IN3); client.print("</b>"); client.print(" люкс"); client.println("</div>");
client.print("<div class=txt-top style='top:290px; left:570px;'><img src=http://b.radikal.ru/b07/2103/c5/2f3c2bd305b7.png>"); client.print(" Температура: "); client.print("<b>"); client.print (IN4); client.print("</b>"); client.print(" °C"); client.println("</div>");
client.print("<div class=txt-top style='top:320px; left:570px;'><img src=http://a.radikal.ru/a27/2103/0a/df3356c53b7b.png>"); client.print(" Давление: "); client.print("<b>"); client.print(IN5); client.print("</b>"); client.print(" мм.рт.ст"); client.println("</div>");
client.print("<div class=txt-top style='top:350px; left:570px;'><img src=http://c.radikal.ru/c11/2103/69/c266ed71cfda.png>"); client.print(" Влажность: "); client.print("<b>"); client.print(IN6); client.print("</b>"); client.print(" %"); client.println("</div>");
client.print("<div class=txt-top style='top:485px; left:239px;'><img src=http://b.radikal.ru/b07/2103/c5/2f3c2bd305b7.png>"); client.print(" "); client.print("<b>"); client.print(IN7); client.print("</b>"); client.print(" °C"); client.println("</div>");
client.print("<div class=txt-top style='top:515px; left:239px;'><img src=http://c.radikal.ru/c11/2103/69/c266ed71cfda.png>"); client.print(" "); client.print("<b>"); client.print(IN8); client.print("</b>"); client.print(" %"); client.println("</div>");
client.println("<div class=txt-top style='top:235px; right:-150px;'>"); client.println("<button type=button id=led_1 class=button_disabled onClick=onClick(1)> Полив-1 </button>"); client.println("</div>"); client.println("<br>"); client.println("<br>");
client.println("<div class=txt-top style='top:265px; right:-150px;'>"); client.println("<button type=button id=led_2 class=button_disabled onClick=onClick(2)> Полив-2 </button>"); client.println("</div>"); client.println("<br>"); client.println("<br>");
client.println("<div class=txt-top style='top:295px; right:-150px;'>"); client.println("<button type=button id=led_3 class=button_disabled onClick=onClick(3)> Полив-3 </button>"); client.println("</div>"); client.println("<br>"); client.println("<br>");
client.println("<div class=txt-top style='top:325px; right:-150px;'>"); client.println("<button type=button id=led_4 class=button_disabled onClick=onClick(4)>Форточки верхние</button>"); client.println("</div>"); client.println("<br>"); client.println("<br>");
client.println("<div class=txt-top style='top:355px; right:-150px;'>"); client.println("<button type=button id=led_4 class=button_disabled onClick=onClick(4)>Форточки нижние</button>"); client.println("</div>");
client.println("</div>"); client.println("</div>"); client.println("</div>"); client.println("</body>"); client.println("</html>"); // HTTP ответ заканчивается еще одной пустой строкой client.println(); // Выход из цикла while break; } else { // если получили новую строку, то очищаем текущую строку currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // добавьте его в конец текущей строки } } } // Очищаем переменную заголовка header = ""; // Закрываем соеденение. client.stop(); Serial.println("Клиент отключен."); Serial.println(""); } }
В идеале конечно сделать переключатель управления "Авто - Ручное". Если переключатель в положение "Авто", кнопки реле хотелосьбы скрыть. Но тут у меня знаний не хватает. У кого есть соотвествующий багаж, можно дополнить. Спасибо!
Профиль
|
|