Arduino+ethernet+html
- Войдите на сайт для отправки комментариев
Ср, 19/11/2014 - 13:22
Добрый день,
Есть идея управления электрическим котлом.
С самой логикой разобрался. Работает вопросов нет, но вот с визуализацией и управлением возникли проблемы.
Я только начинаю с этим работать - прошу сильно не пинать )
Вопрос в следующем.
1. На html странице arduino необходимо два поле. Первое для ввода нужной температуры, второе для порога нижнего значения комфортной температуры с фиксацией этих значений.
2. Отображение состояния датчиков температуры по комнатам, среднее значение во всем доме и температуры теплоносителя в котле. Так же состояние насоса котла (вкл/выкл)
3. Управление внешним насосом
Можно ли в самой Arduino использовать CSS? или для этого необходимо внешний WEB - сервер?
1. Начните с каких-то более простых проектов. Вокруг же полно интересных задач. Когда набъете руку, переходите к проектам с управлением силовым оборудованием. Вам для нормальной реализации "html страницы" желательно хотя бы знание javascript
2. вот с работы с датчиками и начните, без всякого "управления котлами" и т.д.
3. китайские релюшки, которые обычно задействуют в ардуино-проектах, могут просто не потянуть приличный погружной насос. я даже примеров таких не видел.
Датчики опрашивать, получать инфу, управлять реле, выводить инфу в html arduino я научился, в вот дальше, что то стопор какой то.
Насос не мощьный, но можно поставить и магнитный пускатель после релюхи.
ну тогда реле на оптронах и магнитный пускатель.
а в чем проблема с отображением ? что и откуда ты хочешь отображать, не совсем понятно...
ардуина тем и хороша, что вариантов интерфейса может быть миллион. можно радиомодулями передавать на lcd-экранчик, а можно, например с gsm-модуля отправлять на сервер и рисовать страничку красивую.
и наоборот - управлять задачами можно нажимая на кнопочки на странице или на кнопки на модуле в котельной.
Сейчас схемку нарисую
Что то такое хочу получить на выходе
вообще это тема для другого форума. автоматическая подгрузка и отображение данных на хтмл-странице без перезагрузки самой страницы не самая тривиальная задча, обычно для этого задействуют javascript+ php+ ajax.
Хорошо.
А как организовать тогда хотя бы вот так?
установка температуры будет производиться одной кнопкой
CSS ? внешний WEB - сервер ? знание javascript ?
А что-то типа
bfill.emit_p(PSTR("<form>Параметр 01 ($D): <input type=text name=param1 size=3> <input type=submit value=Ok> </form><br>"),InputParam1);не проще ли будет ? (Вырвано из скетча, но, надеюсь, мысль моя понятна)
вам точно нужна именно интернет страница ? может быть processing (это просто отображение на компьютере с внешнего порта usb или serial) , или там, экранчик какой-нибудь ? если всё же html, посмотрите здесь
http://habrahabr.ru/post/171525/
Спасибо за статью.
У меня получилось следующее
client.println("<form method=get name=ptemp>"); client.println("<label>Верхний порог температуры</label><input maxlength=60 name=uptemp type=text value="">"); client.println("<label>Нижний порог температуры</label><input maxlength=60 name=downtemp type=text value="">"); client.println("<input type=submit value=OK>"); client.println("</form>");в мониторе порта вижу ответ на ввод значений
читай про String и char http://arduino.ru/Reference
можно например так : перебираем все символы, пока не встретится знак "=", после этого начинаем записвать в строковую переменную все символы, которые являются цифровыми, как только пошел нецифровой символ, значит переменную ты уже записал. то же самое повторяешь после второго найденного знака равенства. затем конвертируешь из строкового типа в целочисленный - профит. на самом деле это такая задача, в которой должно быть интересно разобраться самому.
Вот здесь http://arduino.ru/forum/programmirovanie/razbor-testovoi-stroki#comment-28095 уважаемый leshak делился в свое время функцией для разбора строк, по сей день пользуюсь. Поменяйте только символы в strtok().
int params[10]; // в этот массив будем сохранять наши парсенные параметры int parsedParams=0; // сколько параметров нам удалось напарсить ///////////////////////// void parseParams(char* inputString) { parsedParams = 0; char* buffer=strtok(inputString,"?"); if ( buffer != NULL ) { for ( buffer=strtok(NULL, "="); buffer != NULL; buffer = strtok(NULL, "=") ) { if( ( buffer = strtok(NULL,"&")) != NULL ) params[parsedParams] = parseInteger(buffer); else return; parsedParams++; } } } int parseInteger(char* inputStr) { int val = 0; while((*inputStr) >= '0' && (*inputStr) <= '9') { val = val * 10 + ((*inputStr++)-'0'); } return val; }Использование:
// /?nightbeginhour=23&nightbeginminute=30&nightendhour=5&nightendminute=30 else if (strstr(data, "/?nightbeginhour=") != 0) { parseParams(data); if ( parsedParams > 3 ) { NightBeginHour = params[0]; NightBeginMinute = params[1]; NightEndHour = params[2]; NightEndMinute = params[3]; } } // ?tvledsthresholdlevel=100 else if (strstr(data, "?tvledsthresholdlevel=") != 0) { parseParams(data); TVLEDsThresholdLevel = params[0]; }ну это в точности то, о чем я говорил.
сначала отловить "=", потом выбрать все знаки от 0 до 9 и конвертировать в число.
Именно. Самый простой и логичный алгоритм.
Подскажите в каком месте кода это должно обрабатываться?
//======================== Задаем необходимые библиотеки ========== #include "DHT.h" #include <OneWire.h> #include <SPI.h> #include <Ethernet.h> #include <DallasTemperature.h> //======================== Задаем данные сети ====================== byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192,168,1,241); byte subnet[] = { 255, 255, 255, 0 }; //маска подсети String readString = String(30); EthernetServer server(80); //========== Задаем пин шины 1-WARE ================= OneWire oneWire(2); //========== Активируем датчик DHT-11 ============= DHT dht; //========== Устанавливаем пины приборов =========== int ten1 = 4; // Тэн 3кВ int ten2 = 5; // Тэн 1,5 кВт int VodoNagrevatel = 6; // int PinPump = 7; // Пин помпы //=========== Активируем датчики температуры Dallas ============ DallasTemperature sensors(&oneWire); //=========== Присваиваем имена датчикам Dallas =============== DeviceAddress ulicaDeviceAddress; // переменная для хранения адреса датчика - УЛИЦА DeviceAddress spalnyDeviceAddress; //переменная для хранения адреса датчика - СПАЛЬНЯ DeviceAddress zalDeviceAddress; //второй информационный датчик - ЗАЛ //============ Устанавливаем значения по умолчанию ============= float ulica = 0; //переменная для текущего значения температуры - УЛИЦА float spalny = 0; //переменная для текущего значения температуры - СПАЛЬНЯ float zal = 0; //переменная для текущего значения температуры - ЗАЛ float AverageTemp = 0; // переменная хранения среднего значения температуры int setpoint = 0; // уставка нужной температуры boolean LEDON = false; boolean NAGREVATEL = false; //отключаем водонагреватель по умолчанию int params[10]; // в этот массив будем сохранять наши парсенные параметры int parsedParams=0; // сколько параметров нам удалось напарсить void setup() { Serial.begin(9600); //запускаем Ethernet Ethernet.begin(mac, ip, subnet); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); //====== Задаем значение пинов ==================== pinMode(ten1, OUTPUT); // установливаем пин как выход digitalWrite(ten1, HIGH); // включаем подтягивающий резистор pinMode(ten2, OUTPUT); // установливаем пин как выход digitalWrite(ten2, HIGH); // включаем подтягивающий резистор //========= Насос котла ====================== pinMode(PinPump, OUTPUT); // установливаем пин как выход digitalWrite(PinPump, HIGH); // включаем подтягивающий резистор //========= Водонагреватель ================== pinMode(VodoNagrevatel, OUTPUT); // установливаем пин как выход digitalWrite(VodoNagrevatel, HIGH); // включаем подтягивающий резистор sensors.begin(); //====== Подключаем датчит DHT-11 к пину 3 ======== dht.setup(3); //======тДатчикам температуры Dallas присваиваем имена ===== sensors.getAddress(spalnyDeviceAddress, 0); spalny = sensors.getTempC(spalnyDeviceAddress); sensors.getAddress(zalDeviceAddress, 1); zal = sensors.getTempC(zalDeviceAddress); sensors.getAddress(ulicaDeviceAddress, 2); ulica = sensors.getTempC(ulicaDeviceAddress); } void parseParams(char* inputString) { parsedParams = 0; char* buffer=strtok(inputString,"?"); if ( buffer != NULL ) { for ( buffer=strtok(NULL, "="); buffer != NULL; buffer = strtok(NULL, "=") ) { if( ( buffer = strtok(NULL,"&")) != NULL ) params[parsedParams] = parseInteger(buffer); else return; parsedParams++; } } } int parseInteger(char* inputStr) { int val = 0; while((*inputStr) >= '0' && (*inputStr) <= '9') { val = val * 10 + ((*inputStr++)-'0'); } return val; } void loop() { //======== Считывание значения температуры с датчика DHT-11и\\\\ delay(dht.getMinimumSamplingPeriod()); float humidity = dht.getHumidity(); float temperature = dht.getTemperature(); //======= Считывание значения температуры с датчиков Dallasи==== sensors.requestTemperatures(); sensors.getAddress(spalnyDeviceAddress, 0); spalny = sensors.getTempC(spalnyDeviceAddress); sensors.getAddress(zalDeviceAddress, 1); zal = sensors.getTempC(zalDeviceAddress); sensors.getAddress(ulicaDeviceAddress, 2); ulica = sensors.getTempC(ulicaDeviceAddress); //======= Расчитываем среднее значение теипературы в доме ===== AverageTemp = ((temperature + spalny + zal) / 3); //======= Выводим показания датчиков в консоль ========== Serial.print ("Humidity in kuhnya: "); Serial.println (humidity, 2); Serial.print ("Temperature in kuhnya: "); Serial.println (temperature, 2); Serial.print ("Temperature in spalny: "); Serial.println (spalny); Serial.print ("Temperature in zal: "); Serial.println (zal); Serial.println ("-------------------------"); Serial.print ("Average temperature: "); Serial.println (AverageTemp); Serial.println ("-------------------------"); //======= Управляем тэнами при нагреве помещения ================ if (AverageTemp >= 28){ // если средняя температура больше или ровна 29*С digitalWrite(ten1, HIGH); // выключаем тэн 3кВт digitalWrite(ten2, HIGH); // выключаем тэн 1,5кВт } else if (AverageTemp >= 27) { // если средняя температура больше или ровна 28*С digitalWrite(ten1, HIGH); // выключаем тэн 3кВт digitalWrite(ten2, LOW); // включаем тэн 1,5кВт } else if (AverageTemp < 27) { // если средняя температура меньше 28*С digitalWrite(ten1, LOW); // включаем тэн 3кВт digitalWrite(ten2, LOW); // включаем тэн 1,5кВт } // =============Создаем клиентское соединение==================== EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { char c = client.read(); //read char by char HTTP request if (readString.length() < 30) { //store characters to string readString.concat( c); } //output chars to serial port Serial.print( c); //if HTTP request has ended if (c == '\n') { //Проверяем включили ли водонагреватель? //NAGREVATEL=1 - включен //NAGREVATEL=0 - выключен if(readString.indexOf("Level=1") >=0) { //Включаем водонагреватель digitalWrite(VodoNagrevatel, LOW); // set the LED on NAGREVATEL = true; } else{ //Выключаем водонагреватель digitalWrite(VodoNagrevatel, HIGH); // set the LED OFF NAGREVATEL = false; } // =============Формируем HTML-страницу========================== client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); client.println("<head> "); client.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> "); client.println("<title> :: Упр.Arduino:: V1.1</title>"); client.println("</head> "); client.println("<body"); client.println("<hr />"); client.println("<h1>Управление отоплением на даче</h1>"); //==============Задаем температуру отопления====================== client.println("<h3>Управление температурой на даче</h3>"); client.println("<form method=get name=ptemp>"); client.println("<label>Верхний порог температуры</label><input maxlength=20 name=uptemp type=text value="">"); client.println("<br> "); //перенос на след. строчку client.println("<label>Нижний порог температуры</label><input maxlength=20 name=downtemp type=text value="">"); client.println("<br> "); //перенос на след. строчку client.println("<input type=submit value=OK>"); client.println("</form>"); //==============Управление водонагревателем====================== client.println("<h3>Управление водонагревателем на кухне</h3>"); if (NAGREVATEL){ client.println("<font size=’5′>Водонагреватель: "); client.println("<strong><font size=’5′>Включен</strong>"); client.println("<form method=get name=LED><input type=radio name=Level value=1 CHECKED>Включить<input type=radio name=Level value=0>Выключить<input type=submit value=OK></form>"); } else{ client.println("<font size=’5′>Водонагреватель: "); client.println("<strong><font size=’5′>Выключен</strong>"); client.println("<form method=get name=LED><input type=radio name=Level value=1>Включить<input type=radio name=Level value=0 CHECKED>Выключить<input type=submit value=OK></form>"); } //==============Вывод значений на web-страницу====================== client.println("<h3>Показания датчиков температуры</h3>"); client.println("Температура на улице = "); //Температура на улице client.println(ulica); client.println(" *С"); client.println("<br> "); //перенос на след. строчку client.println("<hr />");//линия===================================== client.println("Tемпература на кухне = "); //Температура с DHT 11 на кухне client.println(temperature); client.println(" *C"); client.println("<br> "); //перенос на след. строчку client.println("Влажность = "); //Влажность с DHT 11 client.println(humidity); client.println(" %\t"); client.println("<br> "); //перенос на след. строчку client.println("<hr />"); //линия===================================== client.println("Температура в спальне = "); //Температура в спальне client.println(spalny); client.println(" *С"); client.println("<br> "); //перенос на след. строчку client.println("<hr />"); //линия===================================== client.println("Температура в зале = "); //Температура в зале client.println(zal); client.println(" *С"); client.println("<br> "); //перенос на след. строчку client.println("<hr />"); //линия===================================== client.println("Tемпература внутреняя = ");//Средняя температура client.println(AverageTemp); client.println(" *C"); client.println("<br> "); //перенос на след. строчку client.println("<hr />"); //линия===================================== //============================================================== client.println("</body></html>"); //очищаем строку для следующего считывания //==============Останавливаем web-client=========================== readString=""; client.stop(); //============================================================== } } } } delay (1000); }Буду очень признателен за помощь
У Вас это String readString
У меня это char data
#define REQ_BUF_SZ 256
char data[REQ_BUF_SZ] = {0};
char req_index = 0;
Дальше у меня так:
client = server.available(); if (client) { // reset buffer index and all buffer elements to 0 req_index = 0; for (int iclear = 0; iclear < REQ_BUF_SZ; iclear++) { data[iclear] = 0; } while (client.connected()) { if (client.available()) { char c = client.read(); if (c != '\n' && c != '\r') { data[req_index] = c; req_index++; continue; } data[req_index] = 0; if (strstr(data, "GET /favicon.ico") != 0) { goto dataskip; } else if (strstr(data, "/?sendsms=") != 0) {} else if (strstr(data, "/?sendmail=") != 0)Ну и далее куча else if (strstr(data, "
Ну то есть Вам надо либо void parseParams(char* inputString) приводить к String, либо анализируемый String приводить к char.
Как я вижу, парсинг уже есть
if(readString.indexOf("Level=1") >=0) { //Включаем водонагреватель digitalWrite(VodoNagrevatel, LOW); // set the LED on NAGREVATEL = true; } else{ //Выключаем водонагреватель digitalWrite(VodoNagrevatel, HIGH); // set the LED OFF NAGREVATEL = false; }так как в мониторе порта я вижу строку типа
Вот тут все расписал же: http://arduino.ru/forum/programmirovanie/arduinoethernethtml#comment-88162. Ваша "/?uptemp=20&downtemp=18" ничем не отличается от моей "/?nightbeginhour=23&nightbeginminute=30&nightendhour=5&nightendminute=30", неужели этого недостаточно для понимания ?
Araris, можно помощи по skype попросит?
ramzes.ru
Простите, нет.
Сделал вот так
if (readString.indexOf("uptemp")>0){ uptemp = (readString.substring(readString.indexOf("uptemp")+7)); Serial.println(uptemp); } if (readString.indexOf("downtemp")>0){ downtemp = (readString.substring(readString.indexOf("downtemp")+9)); Serial.println(downtemp); }В сериал.принт отдает занчения, но почему то
значение uptemp выглядит 20&downtemp=18
а значение downtemp выглядит так как надо 18
как в значении uptemp отсечь вывод значения после 20?
С помощью какой функции строковое значение конвертировать в числовое?
Для string.substring есть еще второй параметр.
Синтаксис
string.substring(from)
string.substring(from, to)
Параметры
string: переменная типа String
from: индекс начала подстроки
to (опциональный): индекс перед которым должна закончится подстрока
Воспользуйтесь, тогда сможете отсечь &downtemp=18 от uptemp.
stuptemp = (readString.substring(readString.indexOf("uptemp")+7,readString.indexOf("&downtemp")));Вот так вот получилось.
А как теперь строкое значение конвертировать а числовое?
http://arduino.ru/Reference/IntCast
у класса String есть функция toInt() применять так:
Я бы конечно туда еще double конвертер дописал, что сделает еще жирнее клас String.
вообще это тема для другого форума. автоматическая подгрузка и отображение данных на хтмл-странице без перезагрузки самой страницы не самая тривиальная задча, обычно для этого задействуют javascript+ php+ ajax.
Знаете, не так и сложно оказалось.
Правда не понятно, зачем тут пхп, но яваскрипт очень даже реально заставить работать на w5100. Собственно задача сводится к написанию обработчика ХТТП-запросов. А яваскрипт все равно браузер выполняет.
Я даже свой любимый Рафаэль на ардуине запустил, другое дело, что учитывая скорость - это было бессмысленно...
у класса String есть функция toInt() применять так:
Я бы конечно туда еще double конвертер дописал, что сделает еще жирнее клас String.
Спасибо за совет, все получилось основная часть задумки заработала.
поделись пожалуйста скетчем,тоже появилась надобность вносить изменения в переменные через текстовое поле с html странички...
пиши на ramzes.ru@mail.ru
У Вас это String readString
У меня это char data
#define REQ_BUF_SZ 256
По поводу буфера, у меня что-то зависает на 256, на 128 нормально (MEGA 2560 & W5100).
В какую сторону рыть, не могу понять.
Хоть топик и стар, но всетаки внесу свою лепту.
Если не развая поделка, то стоит выделить компик, например на Intel ATOMе на который поставить Apache, PHP, MySQL и делать запросы к поделке из PHP или из тела страницы через AJAX.
Если поделка разовая, то все файлы HTML/CS/JS необходимо разместить на SD карте, а все комманды сделать через AJAX. Логика скетча будет такой: если запрашиваемый файл (GET /css/script.js) есть на SD карте, то "поливать" клиенту его, если файла нет то пробовать разобрать как комманду к самой ардуине (AJAX)... тут 2 группы: 1 запрос значения, 2 установка значения. В этой схеме можете поставить bootstrap на SD карту и спокойно ваять интерфейс. Единственный минус, что ардуина может выдавать только 1 файл в один момент времени а HTTP 1.1 подразумевает паралельную выдачу и будет казаться что все тормозит.
Доброго времени суток!
Сеня сидел вкуривал хтмл на ардуине))
получилась такая забавная штуковина:
Подскажем подсказку;)
https://youtu.be/5-Y1tt14xsA
Я думаю и на ардуинке такое взлетит если допилить немного. Оно здесь -
http://arduino.ru/forum/otvlechennye-temy/orange-pi-one-nuzhen-start?pag...