WebServer на ардуино 2560 и ethernet контроллере W5100
- Войдите на сайт для отправки комментариев
Здравствуйте, помогите пожалуйста разобраться. Задача сделать удаленное управление периферией, через web интерфейс (эта часть с небольшим трудом сделана). Но управление должно происходить в автоматическом или ручном режиме, в зависимости от первоначального выбора. Т.е. если я выбираю автоматический режим, то периферия управляется по определенному алгоритму. Если выбрал ручной режим - то управляется каждый элемент периферии отдельно.
За основу взял http://zelectro.cc/Ethernet_shield_W5100.
Убрал кнопку отправить, сделал отправление команды после установки галочки в checkbox.
Для красоты запихнул все в табличку и выровнял по левому краю.
Добавил checkbox для выбора автоматического режима. И столкнулся с проблемой того, что состояние выходов парсится и укладывается в массив, из которого потом считывается. Пробовал добавлять такое условие
char automan = client.read(); if (automan == 'm') pinState[0] = 1
но результата не дало.
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Мак адрес
byte ip[] = { 192, 168, 1, 198 }; // IP адрес (В броузере вводим 192.168.0.2)
EthernetServer server(80);
int numPins = 4;
int pins[] = { 3, 5, 7, 10 }; // Пины для реле
int pinState[] = {0, 0, 0, 0}; // Состояние пинов
bool mode= 0;
void setup()
{
// Изначально выключаем все реле
for (int i = 0; i < numPins; i++)
{
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], 1);
}
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
}
void loop()
{
EthernetClient client = server.available();
if (client)
{
// Проверяем подключен ли клиент к серверу
while (client.connected())
{
// Проверяем идет ли запрос к серверу
int dataCount = client.available();
if (dataCount > 0)
{
// Считываем данные передаваемые серверу с клиента (браузера)
for (int i = 0; i < dataCount; i++)
{
char ch = client.read();
// Если данные передаются, то они будут переданы POST запросом, который начинается с символа 'P'
if (i == 0 && ch != 'P')
break;
if (ch == '\n' && i < dataCount - 1)
{
// Находим строку, в которой содержатся передаваемые данные
char chNext = client.read();
// Формат строки r2=on&r3=on&r4=on (Пример если нужно включены 2,3,4 реле)
if (chNext == 'r')
{
// Выключаем все реле
pinState[0] = 0;
pinState[1] = 0;
pinState[2] = 0;
pinState[3] = 0;
// Считываем первый номер реле, который нужно включить
char relayNum = client.read();
pinState[relayNum-'0'] = 1;
Serial.write(relayNum);
// Считываем вспомогательную информацию (=on&)
relayNum = client.read();
relayNum = client.read();
relayNum = client.read();
relayNum = client.read();
// Пока есть данные об остальных реле, считываем и заносим в массив pinState
while (relayNum != -1)
{
relayNum = client.read();
relayNum = client.read();
pinState[relayNum-'0'] = 1;
Serial.write(relayNum);
relayNum = client.read();
relayNum = client.read();
relayNum = client.read();
relayNum = client.read();
}
} else
{
// Если не было передано данных, то выключаем все реле
pinState[0] = 0;
pinState[1] = 0;
pinState[2] = 0;
pinState[3] = 0;
}
}
}
}
// В соответствие с переданными данными включаем реле
for (int i = 0; i < 4; i++)
{
digitalWrite(pins[i], pinState[i]);
}
// Выводим HTML страницу, на которой пользователь может включить или выключить нужные ему реле
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<head>");
//client.println("<meta http-equiv= Refresh content=15; >");
client.println("<title>Управление аквариумом</title>");
client.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> ");
client.println("</head>");
client.println("<body>");
//client.println("<h3>Zelectro. Relay + Ethernet shield.</h3>");
client.println("<table align='left' border=0 cellpadding=1 cellspacing=1 style='width:190px'>");
client.println("<tbody>");
client.println("<tr>");
client.println("<td>");
client.println("<form method='post'>");
client.print("<div> Авто/Ручной режим");
client.println("</td>");
client.println("<td>");
client.println("<input type='checkbox' onClick='this.form.submit()' "); //<input type="checkbox" onClick="this.form.submit()" name="test" value="test" />
if (mode == true)
client.print("checked"); //client.print("onClick='this.form.submit()'");
client.println(" name='m0'></div>");
client.println("</td>");
client.println("</tr>");
client.println("<tr>");
client.println("<td>");
client.println("<form method='post'>");
client.print("<div> Свет");
client.println("</td>");
client.println("<td>");
client.println("<input type='checkbox' onClick='this.form.submit()' "); //<input type="checkbox" onClick="this.form.submit()" name="test" value="test" />
if (pinState[0] == 1)
client.print("checked"); //client.print("onClick='this.form.submit()'");
client.println(" name='r0'></div>");
client.println("</td>");
client.println("</tr>");
client.println("<tr>");
client.println("<td>");
client.print("<div>Фильтр");
client.println("</td>");
client.println("<td>");
client.println(" <input type='checkbox' onClick='this.form.submit()' ");
if (pinState[1] == 1) // client.print("onClick='this.form.submit()'");
client.print("checked");
client.println(" name='r1'></div>");
client.println("</td>");
client.println("<tr>");
client.println("<td>");
client.print("<div>Компрессор");
client.println("</td>");
client.println("<td>");
client.println(" <input type='checkbox' onClick='this.form.submit()' ");
if (pinState[2] == 1) // client.print("onClick='this.form.submit()'");
client.print("checked");
client.println(" name='r2'></div>");
client.println("</td>");
client.println("<tr>");
client.println("<td>");
client.print("<div>Обогрев");
client.println("</td>");
client.println("<td>");
client.println(" <input type='checkbox' onClick='this.form.submit()' ");
if (pinState[3] == 1) // client.print("onClick='this.form.submit()'");
client.print("checked");
client.println(" name='r3'></div>");
client.println("</td>");
client.println("</tbody>");
client.println("</table>");
//client.println("<input type='submit' value='Refresh'>");
client.println("</form>");
client.println("</body>");
client.println("</html>");
client.stop();
}
}
}
Создайте еще одну переменную, которая будет переключать режимы и все... Вы должны понимать, что, к примеру, в строках 145, 157, 168, 179 содержатся имена отправляемых релюшек... Тобишь поставив галочку напротив всех реле получите строку вида r1=on&r2=on&r3=on&r4=on... Я сам начинал разбираться с этого примера и могу сказать, что посимвольный парсинг для новичков не самый простой вариант... Проще использовать String и парсить через indexOf(), хоть это и съедает побольше ресурсов..
Спасибо за ответ, все что вы написали я прекрасно понимаю, вы процитировали 51 строку. Если не сложно, ткните в инфу, где можно по подробнее почитать про post запрос и посимвольный парсинг именно в ардуино. Или если не сложно, объясните пожалуйста на пальцах.
Фух... ща попытаюсь...Вам нужно понять принцип работы всей этой штуковины... строка 047 подходит как раз к переданным командам POST-запроса...После нее можно создать строку типа String и зафигачить в нее все передаваемые данные... К примеру так в 049:
String X=""; //создаем пустую строку while (chNext!=-1){ //пока строка не наткнулась на пустой символ - он же конец передаваемых данных chNext=client.read();//cчитываем байт X+=chNext; // зафигачиваем в строку все что пришло... }int index_r1=X.indexOf("r1=");
if (index_r1!=-1) { //если такая совокупность символов найдена в строке Х
//делаем любое нам нужное действие... Почитайте тут про indexOf();
}
Ужасная реализация генератора html кода. Я бы сделал так:
const char PROGMEM buf[]={"\ <html>\ <head>\ <title>Управление аквариумом</title>\ </head>\ <body>\ <input type='checkbox' %a> //%a сюда нужно подставить значение переменной </body>\ </html>\ "}; //в коде for (i=0; i<buflen; i++) { char c = buf[i]; if (c=='%') { if ((c=buf[++i])=='a') client.print("checked"); i++; } client.print(c); }Спасибо за ответы, попробую переварить и покажу на ваш суд, что получилось.
Сделал как вы говорили, но проблема в том, что X - string, а chNext - char. И одно в пихнуть другое напрямую нельзя.
Нужен какой-то костыль.
Попробовал сделать так:
String data = client.read(); String indexmode=""; while (data!=-1);{ data= client.read(); indexmode+=data; } mode = indexmode.indexOf("m"); if (mode != -1){ pinState[0] = 1; statemode=true; }else{ pinState[0] = 0; statemode=false; }Та же проблема в string нельзя запихнуть int
Нужен какой-то костыль.
int однозначно нужно превращать в строку itoa, print и т.п. функции в помощь.
нашел вот такой вариант с переводом char в String, но все ровно считать не получилось ничего. Судя по монитору порта, я подозреваю, что вхожу в цикл while и из него уже не выхожу, т.к. после установки галочки, страница уходит в долгую перезагрузку и в ответ "m" не приходит.
String indexmode=""; while (chNext!=-1);{ chNext= client.read(); indexmode+=String (chNext); } mode = indexmode.indexOf("m"); if (mode != -1){ pinState[0] = 1; statemode=true; }else{ pinState[0] = 0; statemode=false; }Цикл while(chNext != -1); обречен быть бесконечным из-за ; после while. По логике вещей цикл должен выглядеть так:
String indexmode; char chNext; while (client.available())) { chNext = client.read(); if (chNext != -1) indexmode += chNext; ... }Или я что-то не понимаю или одно из двух. Этот вариант то же не работает.
/*ВНИМАНИЕ! Выводы 10, 11, 12 и 13 зарезервированы для сопряжения с модулем Ethernet и не могут использоваться никак иначе. Таким образом, число доступных выводов уменьшается до 9, 4 из которых могут использоваться как выходы ШИМ. */ #include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Мак адрес byte ip[] = { 192, 168, 1, 198 }; // IP адрес (В броузере вводим 192.168.0.2) EthernetServer server(80); int numPins = 4; int pins[] = { 3, 5, 7, 9 }; // Пины для реле int pinState[] = {0, 0, 0, 0}; // Состояние пинов int mode; bool statemode=false; void setup() { // Изначально выключаем все реле for (int i = 0; i < numPins; i++) { pinMode(pins[i], OUTPUT); digitalWrite(pins[i], 1); } Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); } void loop() { EthernetClient client = server.available(); if (client) { // Проверяем подключен ли клиент к серверу while (client.connected()) { // Проверяем идет ли запрос к серверу int dataCount = client.available(); if (dataCount > 0) { // Считываем данные передаваемые серверу с клиента (браузера) for (int i = 0; i < dataCount; i++) { char ch = client.read(); // Если данные передаются, то они будут переданы POST запросом, который начинается с символа 'P' if (i == 0 && ch != 'P') break; if (ch == '\n' && i < dataCount - 1) { // Находим строку, в которой содержатся передаваемые данные char chNext = client.read(); // Формат строки r2=on&r3=on&r4=on (Пример если нужно включены 2,3,4 реле) if (chNext == 'r') { // Выключаем все реле pinState[0] = 0; pinState[1] = 0; pinState[2] = 0; pinState[3] = 0; // Считываем первый номер реле, который нужно включить char relayNum = client.read(); pinState[relayNum-'0'] = 1; Serial.write(relayNum); // Считываем вспомогательную информацию (=on&) relayNum = client.read(); relayNum = client.read(); relayNum = client.read(); relayNum = client.read(); // Пока есть данные об остальных реле, считываем и заносим в массив pinState while (relayNum != -1) { relayNum = client.read(); relayNum = client.read(); pinState[relayNum-'0'] = 1; Serial.write(relayNum); relayNum = client.read(); relayNum = client.read(); relayNum = client.read(); relayNum = client.read(); } } else { // Если не было передано данных, то выключаем все реле pinState[0] = 0; pinState[1] = 0; pinState[2] = 0; pinState[3] = 0; } String indexmode; // char chNext; while (client.available()){ chNext= client.read(); if (chNext != -1) indexmode+=String (chNext); mode = indexmode.indexOf("m"); if (mode != -1){ pinState[0] = 1; statemode=true; }else{ pinState[0] = 0; statemode=false; } } } } } // В соответствие с переданными данными включаем реле for (int i = 0; i < 4; i++) { digitalWrite(pins[i], pinState[i]); } // Выводим HTML страницу, на которой пользователь может включить или выключить нужные ему реле client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); client.println("<html>"); client.println("<head>"); //client.println("<meta http-equiv= Refresh content=15; >"); client.println("<title>Управление аквариумом</title>"); client.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> "); client.println("</head>"); client.println("<body>"); //client.println("<h3>Zelectro. Relay + Ethernet shield.</h3>"); client.println("<table align='left' border=0 cellpadding=1 cellspacing=1 style='width:190px'>"); client.println("<tbody>"); client.println("<tr>"); client.println("<td>"); client.println("<form method='post'>"); client.print("<div> Авто/Ручной режим"); client.println("</td>"); client.println("<td>"); client.println("<input type='checkbox' onClick='this.form.submit()' "); //<input type="checkbox" onClick="this.form.submit()" name="test" value="test" /> if (statemode=true) client.print("checked"); //client.print("onClick='this.form.submit()'"); client.println(" name='m'></div>"); client.println("</td>"); client.println("</tr>"); client.println("<tr>"); client.println("<td>"); client.println("<form method='post'>"); client.print("<div> Свет"); client.println("</td>"); client.println("<td>"); client.println("<input type='checkbox' onClick='this.form.submit()' "); //<input type="checkbox" onClick="this.form.submit()" name="test" value="test" /> if (pinState[0] == 1) client.print("checked"); //client.print("onClick='this.form.submit()'"); client.println(" name='r0'></div>"); client.println("</td>"); client.println("</tr>"); client.println("<tr>"); client.println("<td>"); client.print("<div>Фильтр"); client.println("</td>"); client.println("<td>"); client.println(" <input type='checkbox' onClick='this.form.submit()' "); if (pinState[1] == 1) // client.print("onClick='this.form.submit()'"); client.print("checked"); client.println(" name='r1'></div>"); client.println("</td>"); client.println("<tr>"); client.println("<td>"); client.print("<div>Компрессор"); client.println("</td>"); client.println("<td>"); client.println(" <input type='checkbox' onClick='this.form.submit()' "); if (pinState[2] == 1) // client.print("onClick='this.form.submit()'"); client.print("checked"); client.println(" name='r2'></div>"); client.println("</td>"); client.println("<tr>"); client.println("<td>"); client.print("<div>Обогрев"); client.println("</td>"); client.println("<td>"); client.println(" <input type='checkbox' onClick='this.form.submit()' "); if (pinState[3] == 1) // client.print("onClick='this.form.submit()'"); client.print("checked"); client.println(" name='r3'></div>"); client.println("</td>"); client.println("</tbody>"); client.println("</table>"); //client.println("<input type='submit' value='Refresh'>"); client.println("</form>"); client.println("</body>"); client.println("</html>"); client.stop(); } } }По поводу ; после цикла - мой промах. Но что-то не пойму. Сначала мы определили типы данных для indexmode и chNext, проверили что соединение есть и все в порядке, записали в chNext символ, проверили что строка не кончилась и переписали тип данных char в String?
Слушай, ты замутил цикл for от 0 до количества символов в буфере, а пытаешься прочитать больше чем есть.
relayNum = client.read(); relayNum = client.read(); relayNum = client.read(); relayNum = client.read();Этот код приведет к тому, что в буфере не останется принятых символов и очередная функция client.read() будет ждать пока не поступит сообщение в приемник. Функцию cient.read() надо вызывать столько раз сколько там реально есть символов.
А вообще я тебе изначально предлагал уйти от этой пурги:
... client.println("<tr>"); client.println("<td>"); client.println("<form method='post'>"); client.print("<div> Авто/Ручной режим"); client.println("</td>"); client.println("<td>"); client.println("<input type='checkbox' onClick='this.form.submit()' "); //<input type="checkbox" onClick="this.form.submit()" name="test" value="test" /> if (statemode=true) client.print("checked"); //client.print("onClick='this.form.submit()'"); client.println(" name='m'></div>"); client.println("</td>"); client.println("</tr>"); client.println("<tr>"); client.println("<td>"); client.println("<form method='post'>"); client.print("<div> Свет"); client.println("</td>"); client.println("<td>"); client.println("<input type='checkbox' onClick='this.form.submit()' "); //<input type="checkbox" onClick="this.form.submit()" name="test" value="test" /> if (pinState[0] == 1) client.print("checked"); //client.print("onClick='this.form.submit()'"); client.println(" name='r0'></div>"); client.println("</td>"); client.println("</tr>"); ...Но ты меня на разбор POST запросов подписал :)
POST запрос выглядит таким образом:
POST /login.php HTTP/1.1 User-Agent: Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.229 Version/11.62 Host: yourhost.ru Accept: */* Accept-Language: ru-RU,en Connection: Close Content-Length: 25 Content-Type: application/x-www-form-urlencoded название_поля1=значение&название_поля2=значение&...Размер заголовка может меняться, твоя задача убедиться что это POST запрос, найти в запросе пустую строку \r\n\r\n и после неё уже разбирать твой запрос. название_поля1=значение&название_поля2=значение&
Цикл может выглядеть так
String str, s=""; while (client.available()) s+=client.read(); //в строке s весь запрос полностью if (s.indexOf("POST")==0) { int i = s.indexOf("\r\n\r\n"); if (i != -1) { str = s.substring(i); //в str твой запрос, ищи в нем i=str.indexOf("название_поля1="); .... } }Если вы мне поможете, то попробую все переделать:
/*ВНИМАНИЕ! Выводы 10, 11, 12 и 13 зарезервированы для сопряжения с модулем Ethernet и не могут использоваться никак иначе. Таким образом, число доступных выводов уменьшается до 9, 4 из которых могут использоваться как выходы ШИМ. */ #include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Мак адрес byte ip[] = { 192, 168, 1, 198 }; // IP адрес (В броузере вводим 192.168.0.2) EthernetServer server(80); int pins (3); // Пины для реле int mode; bool statemode = false; String str; String s; int i; void setup() { // Изначально выключаем все реле for (int i = 0; i < 1; i++) { pinMode(3, OUTPUT); digitalWrite(3, LOW); } Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); } void loop() { EthernetClient client = server.available(); if (client) { // Проверяем подключен ли клиент к серверу while (client.connected()) { if (client.available()) s += client.read(); if (s.indexOf("POST") == 0) { i = s.indexOf("\r\n\r\n"); if (i != -1) { str = s.substring(i); //в str твой запрос, ищи в нем i = str.indexOf("m"); statemode = true; } } const char PROGMEM buf[]={" client.println("<html>"); client.println("<head>"); client.println("<title>"); client.println("Управление аквариумом"); client.println("</title>"); client.println("</head>"); client.println("<body>"); client.println("<input type='checkbox' %a>"); //%a сюда нужно подставить значение переменной client.println("</body>"); client.println("</html>"); "}; //в коде for (i=0; i<buflen; i++) { char c = buf[i]; if (c=='%') { if ((c=buf[++i])=='a') client.print("checked"); i++; } client.print(c); } client.stop(); } } } Примерно должно так получиться?Не вопрос, только давай так, идеи за мной, отладка за тобой. Насколько я понимаю за основу взят библиотечный пример WebServer. Теперь к нему надо прикрутить парсер запросов и нормальный генератор html кода. Моя идея хранить в буфере html страничку целиком, и выводить её целиком в цикле
, а не кусочками, как в примере при помощи тыщи команд
client.print("<html>"); client.print("<head>"); client.print("<title>"); ...Но поскольку страничка должна меняться время от времени, я предлагаю в нужных местах поместить свои теги, а во время вывода странички эти теги подменять значениями переменных.
Есть одна засада, компиляторы не умеют инициализировать буфер из файла, поэтому предлагаю такой выход из ситуации: весь html код вынести в файл html.h, а в проект вставить при помощи директивы
В файле html.h мы просто объявим буфер и проинициализируем чистым html кодом твоей странички. Давай сначала эту фишку реализуем. С тебя нужен чистый html код твоей странички.
#include <SPI.h> #include <Ethernet.h> #include "html.h" // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192, 168, 1, 177); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); void setup() { Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); } const char PROGMEM header[]={"\ HTTP/1.1 200 OK\n\ Content-Type: text/html\n\ Connection: close\n\ \n\ "}; void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { client.print(header); // send a standard http response header 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); // give the web browser time to receive the data client.stop(); // close the connection: } }Или я что-то не понимаю или одно из двух. Этот вариант то же не работает.
Изучите этот материал http://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/
Тут все подробно изложено, причем от простого к сложному.
Изучите этот материал http://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/
Тут все подробно изложено, причем от простого к сложному.
Тогда, по вашему, проект известный как Arduino Mega Server http://majordomo.smartliving.ru/forum/viewtopic.php?f=4&t=2347&sid=941635f1d7a7edbd3938e3e51bab724e , за основу которого взят тот самый цикл статей - это говносервер? Тогда покажите миру что-то свое, гораздо более эффективное. Или расскажите, почему это говнопример?
alexvs, не указывай, что мне делать, и я не стану указывать, куда тебе идти.
Я не указываю, а прошу объяснить, почему цикл статей, на который я дал ссылку - это говнопример.
Этот генератор html кода хороший пример "как не надо делать".
// send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // send web page client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Arduino Web Page</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Hello from Arduino!</h1>"); client.println("<p>A web page from the Arduino server</p>"); client.println("</body>"); client.println("</html>");А это не парсер запросов, а кусок овна
if (c == '\n' && currentLineIsBlank) { ... // every line of text received from the client ends with \r\n if (c == '\n') { // last character on line of received text // starting new line with next character read currentLineIsBlank = true; } else if (c != '\r') { // a text character was received from clientВзамен этого я и предлагаю написать нормальный генератор html кода (без SD карты) и по человечески разобрать пару запросов.
Про первое - согласен, не очень правильно, но на этапе изучения возможностей - вполне сойдет, только надо в каждой строке добавить F,
client.println(F("HTTP/1.1 200 OK"));, что бы зря не забивать оперативку. Далее, в статьях, предлагается исходный код HTML вообще хранить в файлах на SD Card и загружать странички прямо из файлов - что вообще самое правильное, на мой взгляд.Ну и если не трудно, можно пример адекватного парсера?
http://arduino.ru/forum/proekty/web-server-na-arduino-s-kontrollerom-temperatury
Посмотрите там мой 40 пост. Может это то что нужно?
Работает и в ручном режиме и в автоматическом.
Можно свои датчики подключить.
Вся web морда на sd карте
GraninDm спасибо за ссылку. Но хотелось бы поочередно разобарться как что формируется, особенно запросы и как это парсится.
Andy вот html странички, для начала. Приношу извинения за долгий ответ, но работа прежде всего.
<!DOCTYPE html> <html> <head> <style> #manauto {display: none;} [for="manauto"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="manauto"]:before { content: "MAN"; position: absolute; right: 15px; color: #FF0000; } [for="manauto"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #manauto:checked ~ [for="manauto"]:after { left: 65px; } #light {display: none;} [for="light"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="light"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="light"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #light:checked ~ [for="light"]:after { left: 65px; } #filter {display: none;} [for="filter"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="filter"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="filter"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #filter:checked ~ [for="filter"]:after { left: 65px; } #air {display: none;} [for="air"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="air"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="air"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #air:checked ~ [for="air"]:after { left: 65px; } #hiter {display: none;} [for="hiter"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="hiter"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="hiter"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #hiter:checked ~ [for="hiter"]:after { left: 65px; } </style> </head> <body> <table align=left border=0 cellpadding=5 cellspacing=1 width="auto"> <tbody> <tr> <td>Режим работы</td> <td><input type="checkbox" id="manauto" /><label for="manauto">AUTO</label></td> <td>Feedback</td> </tr> <tr> <td>Свет</td> <td><input type="checkbox" id="light"/><label for="light">ON</label></td> <td>Feedback</td> </tr> <tr> <td>Фильтр</td> <td><input type="checkbox" id="filter"/><label for="filter">ON</label></td> <td>Feedback</td> </tr> <tr> <td>Компрессор</td> <td><input type="checkbox" id="air"/><label for="air">ON</label></td> <td>Feedback</td> </tr> <tr> <td>Нагреватель</td> <td><input type="checkbox" id="hiter"/><label for="hiter">ON</label></td> <td>Feedback</td> </tr> </tbody> </table> </body> </html>Получилось вот так:
#include <SPI.h> #include <Ethernet.h> #include "HTML.h" #include "request.h" Crequest request; const char PROGMEM ok[]={\ "HTTP/1.1 200 OK\r\n"\ "Content-Type: text/html\r\n"\ "\r\n"\ }; // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192, 168, 1, 177); EthernetServer server(80); void setup() { //Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); request.init(); } void loop() { EthernetClient client = server.available();// listen for incoming clients if (client) { while (client.connected()) { if (client.available() && request.received(client.read())) { switch (request.type()) { case GET: client.print(ok); client.print(html); break; case POST: client.print(ok); break; default: break; } break; } } client.stop(); request.init(); } }Это HTML.h
const char PROGMEM html[]={\ "<!DOCTYPE html>"\ "<html>"\ "<head>"\ "<style>"\ "#manauto {display: none;}"\ "[for='manauto'] {"\ " position: relative;"\ " display: block;"\ " width: 95px;"\ " height: 10px;"\ " padding: 15px;"\ " border-radius: 50px;"\ " line-height: 10px;"\ " color: #00FF22;"\ " text-shadow: 1px 1px 0px rgba(255,255,255,.15);"\ " background: rgb(71, 71, 71);"\ " box-shadow:"\ " 0 1px 0 rgba(255,255,255,.2),"\ " inset 0 0 0 5px rgb(60, 60, 60),"\ " inset 0 6px 6px rgba(0,0,0,.5),"\ " inset 0 -6px 1px rgba(255,255,255,.2);"\ " cursor: pointer;"\ "}"\ "[for='manauto']:before {"\ " content: 'MAN';"\ " position: absolute;"\ " right: 15px;"\ " color: #FF0000;"\ "}"\ "[for='manauto']:after {"\ " content: '';"\ " position: absolute;"\ " left: 5px; top: 5px;"\ " display: block;"\ " width: 55px;"\ " height: 30px;"\ " border-radius: 50px;"\ " background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%);"\ " transition: .5s;"\ "}"\ "#manauto:checked ~ [for='manauto']:after {"\ " left: 65px;"\ "}"\ "#light {display: none;}"\ "[for='light'] {"\ " position: relative;"\ " display: block;"\ " width: 95px;"\ " height: 10px;"\ " padding: 15px;"\ " border-radius: 50px;"\ " line-height: 10px;"\ " color: #00FF22;"\ " text-shadow: 1px 1px 0px rgba(255,255,255,.15);"\ " background: rgb(71, 71, 71);"\ " box-shadow:"\ " 0 1px 0 rgba(255,255,255,.2),"\ " inset 0 0 0 5px rgb(60, 60, 60),"\ " inset 0 6px 6px rgba(0,0,0,.5),"\ " inset 0 -6px 1px rgba(255,255,255,.2);"\ " cursor: pointer;"\ "}"\ "[for='light']:before {"\ " content: 'OFF';"\ " position: absolute;"\ " right: 15px;"\ " color: #FF0000;"\ "}"\ "[for='light']:after {"\ " content: '';"\ " position: absolute;"\ " left: 5px; top: 5px;"\ " display: block;"\ " width: 55px;"\ " height: 30px;"\ " border-radius: 50px;"\ " background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%);"\ " transition: .5s;"\ "}"\ "#light:checked ~ [for='light']:after {"\ " left: 65px;"\ "}"\ "#filter {display: none;}"\ "[for='filter'] {"\ " position: relative;"\ " display: block;"\ " width: 95px;"\ " height: 10px;"\ " padding: 15px;"\ " border-radius: 50px;"\ " line-height: 10px;"\ " color: #00FF22;"\ " text-shadow: 1px 1px 0px rgba(255,255,255,.15);"\ " background: rgb(71, 71, 71);"\ " box-shadow:"\ " 0 1px 0 rgba(255,255,255,.2),"\ " inset 0 0 0 5px rgb(60, 60, 60),"\ " inset 0 6px 6px rgba(0,0,0,.5),"\ " inset 0 -6px 1px rgba(255,255,255,.2);"\ " cursor: pointer;"\ "}"\ "[for='filter']:before {"\ " content: 'OFF';"\ " position: absolute;"\ " right: 15px;"\ " color: #FF0000;"\ "}"\ "[for='filter']:after {"\ " content: '';"\ " position: absolute;"\ " left: 5px; top: 5px;"\ " display: block;"\ " width: 55px;"\ " height: 30px;"\ " border-radius: 50px;"\ " background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%);"\ " transition: .5s;"\ "}"\ "#filter:checked ~ [for='filter']:after {"\ " left: 65px;"\ "}"\ "#air {display: none;}"\ "[for='air'] {"\ " position: relative;"\ " display: block;"\ " width: 95px;"\ " height: 10px;"\ " padding: 15px;"\ " border-radius: 50px;"\ " line-height: 10px;"\ " color: #00FF22;"\ " text-shadow: 1px 1px 0px rgba(255,255,255,.15);"\ " background: rgb(71, 71, 71);"\ " box-shadow:"\ " 0 1px 0 rgba(255,255,255,.2),"\ " inset 0 0 0 5px rgb(60, 60, 60),"\ " inset 0 6px 6px rgba(0,0,0,.5),"\ " inset 0 -6px 1px rgba(255,255,255,.2);"\ " cursor: pointer;"\ "}"\ "[for='air']:before {"\ " content: 'OFF';"\ " position: absolute;"\ " right: 15px;"\ " color: #FF0000;"\ "}"\ "[for='air']:after {"\ " content: '';"\ " position: absolute;"\ " left: 5px; top: 5px;"\ " display: block;"\ " width: 55px;"\ " height: 30px;"\ " border-radius: 50px;"\ " background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%);"\ " transition: .5s;"\ "}"\ "#air:checked ~ [for='air']:after {"\ " left: 65px;"\ "}"\ "#hiter {display: none;}"\ "[for='hiter'] {"\ " position: relative;"\ " display: block;"\ " width: 95px;"\ " height: 10px;"\ " padding: 15px;"\ " border-radius: 50px;"\ " line-height: 10px;"\ " color: #00FF22;"\ " text-shadow: 1px 1px 0px rgba(255,255,255,.15);"\ " background: rgb(71, 71, 71);"\ " box-shadow:"\ " 0 1px 0 rgba(255,255,255,.2),"\ " inset 0 0 0 5px rgb(60, 60, 60),"\ " inset 0 6px 6px rgba(0,0,0,.5),"\ " inset 0 -6px 1px rgba(255,255,255,.2);"\ " cursor: pointer;"\ "}"\ "[for='hiter']:before {"\ " content: 'OFF';"\ " position: absolute;"\ " right: 15px;"\ " color: #FF0000;"\ "}"\ "[for='hiter']:after {"\ " content: '';"\ " position: absolute;"\ " left: 5px; top: 5px;"\ " display: block;"\ " width: 55px;"\ " height: 30px;"\ " border-radius: 50px;"\ " background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%);"\ " transition: .5s;"\ "}"\ "#hiter:checked ~ [for='hiter']:after {"\ " left: 65px;"\ "}"\ "</style>"\ "</head>"\ "<body>"\ "<table align=left border=0 cellpadding=5 cellspacing=1 width='auto'>"\ "<tbody>"\ "<tr>"\ "<td>Режим работы</td>"\ "<td><input type='checkbox' id='manauto' /><label for='manauto'>AUTO</label></td>"\ "<td>Feedback</td>"\ "</tr>"\ "<tr>"\ "<td>Свет</td>"\ "<td><input type='checkbox' id='light'/><label for='light'>ON</label></td>"\ "<td>Feedback</td>"\ "</tr>"\ "<tr>"\ "<td>Фильтр</td>"\ "<td><input type='checkbox' id='filter'/><label for='filter'>ON</label></td>"\ "<td>Feedback</td>"\ "</tr>"\ "<tr>"\ "<td>Компрессор</td>"\ "<td><input type='checkbox' id='air'/><label for='air'>ON</label></td>"\ "<td>Feedback</td>"\ "</tr>"\ "<tr>"\ "<td>Нагреватель</td>"\ "<td><input type='checkbox' id='hiter'/><label for='hiter'>ON</label></td>"\ "<td>Feedback</td>"\ "</tr>"\ "</tbody>"\ "</table>"\ "</body>"\ "</html>"\ };Это request.h
#define GET 0 #define POST 1 class Crequest { protected: String s; byte st; int i, dataLen; boolean bGet, bPost; public: void init() {s=""; st=0; bGet=false; bPost=false; dataLen=0;} byte type(){if (bGet) return GET; if (bPost) return POST; return -1;} void LookForKeyWord() { if (s.indexOf("GET / ")!=-1) bGet=true; else if (s.indexOf("POST /")!=-1) bPost=true; else if (s.indexOf("Content-Length: ")!=-1) dataLen = s.substring(15).toInt(); s=""; } bool received(char c) { s+=c; //Собираю символы в строку switch(st) { case 0: if(c=='\r') st=1; break; case 1: if(c=='\n') {st=2; LookForKeyWord();} break;//получена строка запроса case 2: if(c=='\r') st=3; else st=0; break; case 3: if(c=='\n') {if (bGet) return true; st=4; s=""; i=0;} break;//получен заголовок запроса case 4: if (++i>=dataLen) return true; break;//Получены данные POST запроса } } }; /* Так выглядит GET запрос. Пустая строка это конец запроса ------------------------------------------------------------------------------------------ GET / HTTP/1.1\r\n Host: 10.0.0.20\r\n User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*;q=0.8\r\n Accept-Language: en-ZA,en-GB;q=0.8,en-US;q=0.5,en;q=0.3\r\n Accept-Encoding: gzip, deflate\r\n Connection: keep-alive\r\n \r\n ------------------------------------------------------------------------------------------ Так выглядит POST запрос. Между заголовком и данными пустая строка. Content-Length: это длина данных. ------------------------------------------------------------------------------------------ POST /login.php HTTP/1.1\r\n User-Agent: Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.229 Version/11.62\r\n Host: yourhost.ru\r\n Accept: *\r\n Accept-Language: ru-RU,en\r\n Connection: Close\r\n Content-Length: 25\r\n Content-Type: application/x-www-form-urlencoded\r\n \r\n name=value&name=value&... ------------------------------------------------------------------------------------------ На любой запрос отвечаем Ok. Ответ тоже заканчивается пустой строкой ------------------------------------------------------------------------------------------ HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n \r\n ------------------------------------------------------------------------------------------ */Давай отладим это. Модификацию html и разбор данных POST запроса добавим позже.
Ошибок нет, но страничка не грузится. "Во время загрузки страницы соединение с сервером было сброшено."
Нашел одну ошибку, в request.h между строками 30 и 31 нужно вставить return false;
исправил - ничего не изменилось
подключай Serial.print();
Для PROGMEM рекомендуют #include <avr/pgmspace.h>, попробуй добавить.
Попробуй вместо client.print(ok); client.print(html); вызвать функцию:
void func() { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // send web page client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Arduino Web Page</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Hello from Arduino!</h1>"); client.println("<p>A web page from the Arduino server</p>"); client.println("</body>"); client.println("</html>"); }В общем надо отлаживать код. Если в коде что-то непонятно спрашивай.
client.print(html) - не выводит. Подозреваю, что нужно каким-то другим методом выводить содержимое html.
Судя по этой статье http://easyelectronics.ru/avr-uchebnyj-kurs-programmirovanie-na-si-rabota-s-pamyatyu-adresa-i-ukazateli.html мы не так выводим из памяти html. Наверное нужно что-то типа pgm_read_word, а потом уже запихивать это в printline.
Давай попробуем так. Добавь к массивам Ок и html символ \0 в самом конце.
const char PROGMEM ok[]={\ "HTTP/1.1 200 OK\r\n"\ "Content-Type: text/html\r\n"\ "\r\n\0"\ };В html:
Замени вызовы: client.print(Ok); на send(Ok); а clien.print(html); на send(html);
добавь функцию send
void send(char *ptr) { char c; while(c=pgm_read_byte(ptr++)) client.print(c); }Эта функция нам потом все равно понадобится, при выводе htm кода будем налету подменять значения.
подключай Serial.print();
Для PROGMEM рекомендуют #include <avr/pgmspace.h>, попробуй добавить.
Попробуй вместо client.print(ok); client.print(html); вызвать функцию:
void func() { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // send web page client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Arduino Web Page</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Hello from Arduino!</h1>"); client.println("<p>A web page from the Arduino server</p>"); client.println("</body>"); client.println("</html>"); }В общем надо отлаживать код. Если в коде что-то непонятно спрашивай.
А на несколько постов ранее......
Этот генератор html кода хороший пример "как не надо делать".
// send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // send web page client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Arduino Web Page</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Hello from Arduino!</h1>"); client.println("<p>A web page from the Arduino server</p>"); client.println("</body>"); client.println("</html>");Для alexvs. Функция func() предлагалась мне временно, для вычисления места до которого у меня работает код. Это пока для меня единственный меттод для определения места возникновения проблемы. Правда сегодня пол ночи потратил, что бы нормально прикрутить к atmes studia 6.2 Visual Micro, но уйти от ошибки при компиляции об отсутствии cor.a так и не смог.
Давай попробуем так. Добавь к массивам Ок и html символ \0 в самом конце.
const char PROGMEM ok[]={\ "HTTP/1.1 200 OK\r\n"\ "Content-Type: text/html\r\n"\ "\r\n\0"\ };В html:
Ничего не изменилось.
Ругается на 32 строчку exit status 1'client' was not declared in this scope
#include <SPI.h> #include <Ethernet.h> #include <HTML.h> #include <request.h> #include <avr/pgmspace.h> Crequest request; const char PROGMEM ok[]={\ "HTTP/1.1 200 OK\r\n"\ "Content-Type: text/html\r\n"\ "\r\n\0"\ }; // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192, 168, 1, 198); EthernetServer server(80); void setup() { //Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); request.init(); } void send(char *ptr) { char c; while(c=pgm_read_byte(ptr++)) client.print(c); } void loop() { EthernetClient client = server.available();// listen for incoming clients if (client) { while (client.connected()) { if (client.available() && request.received(client.read())) { switch (request.type()) { case GET: send(Ok); send(html); break; case POST: send(Ok); break; default: break; } break; } } client.stop(); request.init(); } }Ставил void send(char *ptr) после void loop(), ругался на 47 строчку exit status 1'Ok' was not declared in this scope
Зачем ты полез в такие дебри если ты путаешься с областью видимости переменных?
Где у тебя объявлена переменная client? Правильно, в loop(), так с какого перепугу ты ее пытаешься заюзать в send()? Или объявляй ее как глобальную, или передавай в send().
Я тебе дал ссылку на прекрасный материал, котрый проведет тебя от простого к сложному в области создания веб-сервера на Ардуино, но ты упорно бьешься над своими ошибками, не понимя, что делаешь.
Вот так без ошибок
#include <SPI.h> #include <Ethernet.h> #include "HTML.h" #include "request.h" #include <avr/pgmspace.h> Crequest request; const char PROGMEM Ok[]={\ "HTTP/1.1 200 OK\r\n"\ "Content-Type: text/html\r\n"\ "\r\n\0"\ }; // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192, 168, 1, 198); EthernetServer server(80); EthernetClient client; void setup() { //Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); request.init(); } void send(const char *ptr) { char c; while(c=pgm_read_byte(ptr++)) client.print(c); } void loop() { client = server.available();// listen for incoming clients if (client) { while (client.connected()) { if (client.available() && request.received(client.read())) { switch (request.type()) { case GET: send(Ok); send(html); break; case POST: send(Ok); break; default: break; } break; } } client.stop(); request.init(); } }Все заработало!
Отлично! Теперь нам надо, что бы html страничка отображала значения переменных. Есть несколько вариантов:
1. Менять html код налету, во время вывода. В браузере требуется обновление всей странички, решается при помощи refresh. Можно обойтись без скриптов. В html коде размещаем ключевые символы, которые при выводе подменяем значениями переменных. С точки зрения повторения проекта другими - это не очень наглядный способ.
2. Использовать скрипты: <script type=" text/javascript" src="URL"></script> где URL будет указывать на наш скрипт с переменными. Скрипт достаточно простой, можно создавать во время вывода. В браузере требуется обновление всей странички, решается при помощи refresh или скриптов. В коде html размещаем идентификаторы id='sensor1'. В скрипте создаем запись типа document.getElementById('sensor1').value = 123; Потребуется разбор GET запроса. С точки зрения повторения проекта другими - это более наглядный способ.
3. Использовать iframe. В браузере обновлять можно только iframe при помощи скриптов. Потребуется разбор GET запросов. С точки зрения повторения проекта другими - достаточно наглядный способ.
Какой вариант тебе больше нравится?
2 вариант
Вот как это будет выглядеть
Это твой html с небольшими изменениями:
<!DOCTYPE html> <html> <head> <style> #manauto {display: none;} [for="manauto"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="manauto"]:before { content: "MAN"; position: absolute; right: 15px; color: #FF0000; } [for="manauto"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #manauto:checked ~ [for="manauto"]:after { left: 65px; } #light {display: none;} [for="light"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="light"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="light"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #light:checked ~ [for="light"]:after { left: 65px; } #filter {display: none;} [for="filter"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="filter"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="filter"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #filter:checked ~ [for="filter"]:after { left: 65px; } #air {display: none;} [for="air"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="air"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="air"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #air:checked ~ [for="air"]:after { left: 65px; } #hiter {display: none;} [for="hiter"] { position: relative; display: block; width: 95px; height: 10px; padding: 15px; border-radius: 50px; line-height: 10px; color: #00FF22; text-shadow: 1px 1px 0px rgba(255,255,255,.15); background: rgb(71, 71, 71); box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 0 0 5px rgb(60, 60, 60), inset 0 6px 6px rgba(0,0,0,.5), inset 0 -6px 1px rgba(255,255,255,.2); cursor: pointer; } [for="hiter"]:before { content: "OFF"; position: absolute; right: 15px; color: #FF0000; } [for="hiter"]:after { content: ""; position: absolute; left: 5px; top: 5px; display: block; width: 55px; height: 30px; border-radius: 50px; background: #ccc linear-gradient(#fcfff4 0%, #dfe5d7 40%, #b3bead 100%); transition: .5s; } #hiter:checked ~ [for="hiter"]:after { left: 65px; } </style> <script type="text/javascript" src="script.js"></script> </head> <body onload="setVars();"> <table align=left border=0 cellpadding=5 cellspacing=1 width="auto"> <tbody> <tr> <td>Режим работы</td> <td><input type="checkbox" id="manauto" /><label for="manauto">AUTO</label></td> <td>Feedback</td> </tr> <tr> <td>Свет</td> <td><input type="checkbox" id="light"/><label for="light">ON</label></td> <td>Feedback</td> </tr> <tr> <td>Фильтр</td> <td><input type="checkbox" id="filter"/><label for="filter">ON</label></td> <td>Feedback</td> </tr> <tr> <td>Компрессор</td> <td><input type="checkbox" id="air"/><label for="air">ON</label></td> <td>Feedback</td> </tr> <tr> <td>Нагреватель</td> <td><input type="checkbox" id="hiter"/><label for="hiter">ON</label></td> <td>Feedback</td> </tr> </tbody> </table> </body> </html>Это скрипт, который мы будем создавать во время вывода:
function setVars() { document.getElementById('manauto').checked='true'; document.getElementById('light').checked='true'; document.getElementById('filter').checked='true'; document.getElementById('air').checked='true'; document.getElementById('hiter').checked='true'; }чего-то я ничего не понял.
1. Мы уже не используем PROGMEM html[]?
2. script.js - это function set()?
3. onload="setVars() - у нас вроде нигде не используется setVars?
1.Используем, это я выложил чистый код html, его можно в браузере открыть. Код для ардуины я выложу чуть позже.
2.Опечаточка произошла: script.js - это function setVars(). Она же вызывается по onload в body.
Вопрос такой: у тебя 5 переменных. В html коде нет ни одной формы. Будем делать 5 форм (по одной на каждую переменную) или одну форму на все?
Хмм.. А про Ajax почитать ?
http://www.ibm.com/developerworks/ru/views/xml/libraryview.jsp?search_by=Ajax+master
и куча ссылок по запросу "arduino ajax" с работающими примерами
Хмм.. А про Ajax почитать ?
http://www.ibm.com/developerworks/ru/views/xml/libraryview.jsp?search_by=Ajax+master
и куча ссылок по запросу "arduino ajax" с работающими примерами
Да я предлогал ТС данный материал для изучения, но Andy отговорил его, сказав, что это говнопример.
У меня все в табличку впихнуто. По логике, если будет всю страничку обновлять, то смысл тогда делать отдельные формы. Но я в дальнейшем планирую еще температуру выводить, обратную связь от реле.
Хмм.. А про Ajax почитать ?
http://www.ibm.com/developerworks/ru/views/xml/libraryview.jsp?search_by=Ajax+master
и куча ссылок по запросу "arduino ajax" с работающими примерами
Да я предлогал ТС данный материал для изучения, но Andy отговорил его, сказав, что это говнопример.
Я по мере наличия времени изучаю любезно скинутые вами ссылки и возможно в дальнейшем где-нибудь применю.