Мгновенная реакция на нажатие кнопки в Веб-сервере W5100
- Войдите на сайт для отправки комментариев
Пнд, 19/03/2018 - 14:52
Доброго времени суток, уважаемые форумчане!
Перед мной возникла задача организации управления электронным блоком котлов через интернет
Решено было использовать Arduino UNO +W5100 и блок реле 4шт.
С сетевыми делами все ясно, но только не могу понять как сделать так, чтобы нажатие на кнопку в веб браузере мнговенно включало реле.
скетч
#include <SPI.h> #include <Ethernet.h> #include <OneWire.h> #include <DallasTemperature.h> #define MQ_PIN A0 float mqValue; float mqPercents; #define PIN_RELAY1 4 // пин, используемый для подключения реле #define PIN_RELAY2 5 // пин, используемый для подключения реле #define PIN_RELAY3 6 // пин, используемый для подключения реле #define PIN_RELAY4 7 // пин, используемый для подключения реле OneWire oneWire(2); // вход датчиков 18b20 DallasTemperature ds(&oneWire); DeviceAddress sensor1 = {0x28, 0xFF, 0x82, 0x1C, 0x02, 0x17, 0x05, 0xD8}; DeviceAddress sensor2 = {0x28, 0xFF, 0x6E, 0x09, 0x03, 0x17, 0x04, 0x6F}; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address Ethernet шилда IPAddress ip(192, 168, 171, 17); // IP address Ethernet шилда byte gateway[] = { 192, 168, 171, 14 }; // Адрес основного шлюза (роутера локальной сети) Смотреть в настройках роутера. byte subnet[] = { 255, 255, 255, 0 }; // Маска подсети. В локальной сети можно на любом компе зайти в центр упр. сет. -> параметры адаптера. EthernetServer server(80); // create a server at port 80 void setup() { { pinMode(PIN_RELAY1, OUTPUT);// Объявляем пин реле как выход pinMode(PIN_RELAY2, OUTPUT); pinMode(PIN_RELAY3, OUTPUT); pinMode(PIN_RELAY4, OUTPUT); digitalWrite(PIN_RELAY1, LOW); // Выключаем реле - digitalWrite(PIN_RELAY2, LOW); digitalWrite(PIN_RELAY3, LOW); digitalWrite(PIN_RELAY4, LOW); } Serial.begin(9600); while (!Serial) ; Ethernet.begin(mac, ip); server.begin(); Serial.println(Ethernet.localIP()); ds.begin(); } void loop() { mqValue = analogRead(MQ_PIN); mqPercents = mqValue/1024*100; ds.requestTemperatures(); // считываем температуру с датчиков float t1=ds.getTempC(sensor1); float t2=ds.getTempC(sensor2); // Serial.print("Sensor 1: "); // Serial.print(ds.getTempC(sensor1)); // отправляем температуру // Serial.println("C"); // Serial.print("Sensor 2: "); // Serial.print(ds.getTempC(sensor2)); // Serial.println("C"); // Serial.println(); Serial.print(t1); Serial.print(t2); delay(1000); EthernetClient client = server.available(); if (client) { Serial.println("new client"); boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html;charset=utf-8"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<meta http-equiv=\"refresh\" content=\"3\">"); client.println("<html><head><title>Карла Маркса. Корпус №7</title> </head>"); client.println("<body><CENTER><H2>Температура котлов Navien, корпус №7</H2></BR><H1>"); client.println("<body><H2>Уровень загазованности помещения:</H2><H1>"); client.println(mqPercents); client.println("%, "); client.println(mqValue); client.println("ppm."); client.println("<body><H2>Температура котла №1:</H2><H1>"); client.println(t1); client.println("C"); client.println("<input type=submit value=\"+1 градус\"></form>"); if (client.print("<input type=hidden name=cmd>")); { digitalWrite(PIN_RELAY1, HIGH); delay(500); digitalWrite(PIN_RELAY1, LOW); } client.println("<input type=submit value=\"-1 градус\"></form>"); if (client.print("<input type=hidden name=cmd>")); { digitalWrite(PIN_RELAY2, HIGH); delay(500); digitalWrite(PIN_RELAY2, LOW); } client.println("<body><H2>Температура котла №2:</H2><H1>"); client.println(t2); client.println("C"); client.println("<input type=submit value=\"+1 градус\"></form>"); if (client.print("<input type=hidden name=cmd value=1>")); { digitalWrite(PIN_RELAY3, HIGH); delay(500); digitalWrite(PIN_RELAY3, LOW); } client.println("<input type=submit value=\"-1 градус\"></form>"); if plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=1>")); { digitalWrite(PIN_RELAY4, HIGH); delay(500); digitalWrite(PIN_RELAY4, LOW); } client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } delay(1); client.stop(); Serial.println("client disonnected"); } }
Как сделать рабочие кнопки в веб сервере
Кнопки должны срабатывать мгновенно - включать реле на 500 мсекунд
Буду очень признателен за советы
никак.
WEB-протокол не предназаначен для Реал-Тайм систем.
Мгновенно, кстати, это сколько в секундах/миллисекундах/наносекундах?
Наверное я неверно выразился, под словом "мгновенно" я имел ввиду чтобы при нажатии кнопки с веб сервера сразу уходила команда на включение реле.
В примерах управления реле через веб-интерфейс, что мне попадались, надо было поставить галочку, потом нажать выполнить и тд.
Можно ли сделать так чтобы достаточно было только нажатия на кнопку?
И вообще как програмируются кнопки на веб сервере, точнее их функциональные возможности при срабатывании????
Можно-то можно, сделайте эту кнопку "сабмитом для формы", запрос на сервер будет уходить сразу. Только о какой мгновенности Вы говорите, если у Вас в loop торчат блокирующие функции (стр. 57-58), которые вместе работают целых полторы секунды?
ШTopo, странный какой-то у вас HTML. Он хоть что-то делает?
Температуру и загазованость показывает нормально, а кнопки ничего не делают - в этом то и главная проблема
Реле срабатывают поочередно и все(((
Под словом "мгновенно" имелось ввиду срабатываение кнопки только при нажатии на нее,
А можно по подробнее как использовать Submit???
client.println("<input type=submit value=\"-1 градус\"></form>");
Написал я что то с эти словом, но реле срабатывают сами по себе поочередно, без нажатия
Читайте вот здесь, начиная с фразы "Для отправки данных на сервер предназначена специальная кнопка Submit".
Но, лучше, читайте всё - пользы будет больше.
Что то я не пойму, как сказать Ардуине, что кнопка на веб сервере нажата?
Ну, как сказать... Попробуйте заорать на ардуину - может дойдет до нее.
Сабмит постит поля формы на вебсервер. Т.е. на ардуину прилетает строка с именами полей и их значениями. Ваше задание - распарсить эту строку и сделать ардуиной красиво, если прилетевшее поле равно чему-то нужному. Можете сделать что-то вроде <input hidden> и тогда это поле не будет показано в браузере, но при сабмите его значение полетит на ардуину.
Вы прочитали про HTML? Так прочитайте! Ну, поймите Вы, нельзя делать что-то в среде, о которой ничего не знаете!
Пишете в тэге form адрес Вашей ардуины, а запрос сам на неё пойдёт, когда submit Нажмёте
Разумеется, адрес правильный укажите в аттибуте action
Разумеется, адрес правильный укажите в аттибуте action
да бесполезно - следующий вопрос будет "А где мне взять адрес?"
Правильно сказал Дракула (вроде?) - "Ардуина, это игрушка. Но игрушка для программистов."
ТС, пока вы не станете программистом, хотя бы на любительском уровне - ничего дельного у вас с ардуиной не выйдет. Так что приготовтесь много учиться. Либо забросьте эту затею.
ПОшел немного другим путем.
Решил использовать гиперссылки
Вроде все заработало, но есть один маленкий и неприятный момент - при обновлении страницы реле самопроизвольно начинабт включатся, то первое, то 4-е
вот код
В чем может быть причина???
А что в монитор порта печатается?
Можно протокол монитора порта скопипастить и чётко написать что именно включалось в моменты обновлений?
Включал поочередно 1 реле, затем 2, 3, 4
после нажал обновил страницу и сразу включилось 4-е реле (2 раза обновлял и 2 раза включалось реле)
Как будто думает что я кнопку нажимаю
вот данные с монитора порта:
видимо после обновления страницы он повторно отсылает последний запрос. как эт этого избавится то?
Это нормальное поведение браузера. Можно сделать редирект страницы на саму себя если пришли данные методом GET.
Это нормальное поведение браузера. Можно сделать редирект страницы на саму себя если пришли данные методом GET.
Или добавить свою кнопку обновить на страницу, которая будет ссылаться на саму страницу/
Включал поочередно 1 реле, затем 2, 3, 4
после нажал обновил страницу и сразу включилось 4-е реле (2 раза обновлял и 2 раза включалось реле)
Вот это то, чего я хотел услышать. А то раньше Вы писали другое
при обновлении страницы реле самопроизвольно начинабт включатся, то первое, то 4-е
Понимаете, то что влкючается не какое попало, а то, которое Вы последним включали, это правильно, так и должно быть.
Более того, Вы же печатаете лог, чего ж Вы в него не смотрите? (кстати, вставляйте с номерами строк, ну что вы - новички все такие). Вот смотрите
Строки 1-2 - это Ваш первый запрос на button1on.
Строки 3-4 - это Ваш второй запрос на button2on.
Строки 5-6 - это Ваш третий запрос на button3on.
Строки 7-8 - это Ваш четвёртый запрос на button4on.
А вот теперь два Ваших обновления - строки 9-10 и 11-12. Они тоже просят button4on - смотрите это написано в строках 9 и 11! Вы читайте то, что сами же печатаете!
Т.е. это совершенно нормальное поведение. Если ничего не предпринимать, то "по умолчанию" так и должно быть.
Теперь увидел - в дискуссии рождается истина)
Если ничего не предпринимать, то "по умолчанию" так и должно быть.
Что можно предпринять???
Можно ли сделать условия о отмене всех запросов при обновлении страницы?
Страницу необходимо обновлять каждые 10 секунд, для получения актуальных данных
Что можно предпринять???
Вам уже сказали в постах №№ #17 и #18.
Это нормальное поведение браузера. Можно сделать редирект страницы на саму себя если пришли данные методом GET.
Или добавить свою кнопку обновить на страницу, которая будет ссылаться на саму страницу/
Что такое редирект? Я чайник и сленг програмистов нихт ферштейн))
Кнопку делать мне не надо. Все равно при нажатии будет срабатывать одна из релюшек.
Тем более у мен страница должна обновлятся каждые 10 сек для получения актуальных данных о температуре и загазованности.
Как сделать редирект страницы на саму себя если пришли данные методом GET.
Где прочесть про это?
https://ru.wikipedia.org/wiki/HTTP
сленг програмистов нихт ферштейн))
И в гугле тоже забанирен! Достаточно набрать в гугле: редирект html
Как первый же результат будет - http://ab-w.net/HTML-guide/HTML-redirect.php
редирект результатов не принес
все равно последний запрос обрабатывается при обновлении страницы.
В редиректе указал ссылку на ip адресс ардуины.
Проверил работоспособность - вел другой Ip-шник по истечении 10 сек браизер переходил на него.
Однако при указании ссылки на ip адресс ардуины при обновлении срабатывает последнее нажатая ссылка.
Возникли следующие мысли.
ПРи обработке гиперссылок используется переменные:
?button1on
?button2on
?button3on
?button4on
При нажатии они становятся >0
можно ли их насильно после выполнения сделать =0??
Т.е. при обновлении страницы и запуске цикла все переменные будут =0, т.е типа не нажатые?
редирект результатов не принес
Код и лог печати в студию, иначе - кофейная гуща.
Решил все таки вернутся к использованию кнопок
Sadman писал о "Т.е. на ардуину прилетает строка с именами полей и их значениями. Ваше задание - распарсить эту строку и сделать ардуиной красиво, если прилетевшее поле равно чему-то нужному. Можете сделать что-то вроде <input hidden> и тогда это поле не будет показано в браузере, но при сабмите его значение полетит на ардуину."
Как распарсить строку?
Я использовал код:
Сначало объявил переменную cmd как число
затем на веб сервер выводим кнопку и скрытий элемент, при нажатии переменная cmd принимает значени 1 (если я правильно оформил все по синтаксу):
Затем задаем условие:
Но ничего не работает.
Господа форумчане, что я делаю не так то?
В строках №№ 111, 114, 120, 123 вижу закрывающие тэги "</form>", но что-то не нашёл к ним открывающих. Вы как вообще это делали и где именно указывали адрес Вашей страницы?
А в строке 97 необходимо явно указать URL, иначе она так и будет рефрешить с последним параметром (как у Вас и раньше было).
Про кривой HTML код, Вам уже неоднократно писали.
Затем задаем условие:
Что же этот if(), по-вашему, должен делать?
Что же этот if(), по-вашему, должен делать?
Провеярть действительно ли cmd=1 имеет тип byte. Угадал?
Что же этот if(), по-вашему, должен делать?
Провеярть действительно ли cmd=1 имеет тип byte. Угадал?
Может проверяет удалось ли в принципе создать переменную?
Может проверяет удалось ли в принципе создать переменную?
а какая, кстати, у нее будет область видимости? до закрывающей скобки условия или больше?
Таки
до закрывающей скобки условия