w5100 web сервер обновление страници и повторное выполнение команды
- Войдите на сайт для отправки комментариев
Вс, 05/02/2017 - 20:47
Проблему не сразу заметил, при нажатии кнопке отравляется запрос http://192.168.0.203/$1 выполняется команда и при обновлении через заданное время опять отправляется повторно запрос http://192.168.0.203/$1 и выполняется та же команда, не знаю как отправить пустой запрос при обновлении страници, так чтобы небыло повторной отправки команды при обновлении и вернуть в строку http://192.168.0.203
и в библиотеке не могу найти в описании. и с опытом тяжело
#include <SPI.h> //библиотека для работы с SPI
#include <Ethernet.h> //библиотека для работы с Ethernet
boolean newInfo = 0;
//boolean newInfo1 = 0; //переменная для новой информации
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };
IPAddress ip(192,168,0,203);
//инифиализация библиотеки Ethernet server library
EthernetServer server(80);
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
Ethernet.begin(mac, ip);
server.begin();
Serial.begin(9600);
}
void loop()
{
//принимаем данные, посылаемые клиентом
EthernetClient client = server.available();
if(client){ //если запрос оканчивается пустой строкой
boolean currentLineIsBlank = true; //ставим метку об окончании запроса (дословно: текущая линия чиста)
while (client.connected()) { //пока есть соединение с клиентом
if (client.available()) { //если клиент активен
char c = client.read(); //считываем посылаемую информацию в переменную "с"
if(newInfo && c == ' '){ //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке
newInfo = 0; //то обнуляем переменную поступления новой информации
}
if(c == '$'){
newInfo = 1;
}
//if(newInfo1 && c == ' '){
// newInfo1 = 0;
//}
// if(c == '&'){
// newInfo1 = 1;
// }
/************************************************************************************************
Примечание:
Символ $ используется как обычный символ, который разделяет 1 от 2
На практике применяют символ &, который разделяет новые переменные от последующих
Это использьуется, например, в GET-запросах, которые выглядят подобным образом:
client.print("GET /controlbar/wp-content/data.php?uid=" + ID + "&type=" + type + "&value=" + value);
как видите, знак & разделяет значение переменной - ID и переменную type
***************************************************************************************************/
//Проверяем содержание URL - присутствует $1 или $2
if(newInfo == 1){ //если есть новая информация
if(c == '1'){ //Line 1 ON OFF
digitalWrite(2, HIGH); delay(1000); digitalWrite(2, LOW);
}
if(c == '2'){ //Line 2 ON OFF
digitalWrite(3, HIGH); delay(1000); digitalWrite(3, LOW);
}
if(c == '3'){ //Line 3 ON OFF
digitalWrite(5, HIGH); delay(1000); digitalWrite(5, LOW);
}
if(c == '4'){ //Line 4 ON OFF
digitalWrite(6, HIGH); delay(1000); digitalWrite(6, LOW);
}
}
// if(newInfo1 == 1){
// if(c == '1'){
// Serial.println("OFF");
// digitalWrite(7, HIGH);
// }
//}
if (c == '\n') { //если "с" равен символу новой строки
currentLineIsBlank = true; //то начинаем новую строку
}
else if (c != '\r') { //иначе, если "с" не равен символу возврата курсора на начало строки
currentLineIsBlank = false; //то получаем символ на текущей строке
}
if (c == '\n' && currentLineIsBlank) { //выводим HTML страницу
client.println("HTTP/1.1 200 OK"); //заголовочная информация
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println("Refresh: 30"); //автоматическое обновление каждые 30 сек
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("<title>Podst</title>");
if (analogRead(A0)>200){
client.print("<font color=\"red\"><H4>Line1 ON </H4>");client.println("<a href=\"/$1\"><button><font color=\"green\"><H4>OFF<H4></button></a>");}
else { client.print("<font color=\"green\"><H4>Line1 OFF </H4>"); client.print("<a href=\"/$1\"><button><font color=\"red\"><H4>ON<H4></button></a>");}
if (analogRead(A0)>200){ client.print("<font color=\"red\"><H2>__________</H2>"); }
else { client.print("<font color=\"green\"><H2>__________</H2>"); }
if (analogRead(A1)>200){
client.print("<font color=\"red\"><H4>Line2 ON </H4>");client.print("<a href=\"/$2\"><button><font color=\"green\"><H4>OFF<H4></button></a>"); }
else { client.print("<font color=\"green\"><H4>Line2 OFF </H4>");client.print("<a href=\"/$2\"><button><font color=\"red\"><H4>ON<H4></button></a>"); }
if (analogRead(A1)>200){ client.print("<font color=\"red\"><H2>__________</H2>"); }
else { client.print("<font color=\"green\"><H2>__________</H2>"); }
if (analogRead(A2)>200){
client.print("<font color=\"red\"><H4>Line3 ON </H4>");client.print("<a href=\"/$3\"><button><font color=\"green\"><H4>OFF<H4></button></a>"); }
else { client.print("<font color=\"green\"><H4>Line3 OFF </H4>");client.print("<a href=\"/$3\"><button><font color=\"red\"><H4>ON<H4></button></a>"); }
if (analogRead(A2)>200){ client.print("<font color=\"red\"><H2>__________</H2>"); }
else { client.print("<font color=\"green\"><H2>__________</H2>"); }
if (analogRead(A3)>200){
client.print("<font color=\"red\"><H4>Line4 ON </H4>");client.print("<a href=\"/$4\"><button><font color=\"green\"><H4>OFF<H4></button></a>"); }
else { client.print("<font color=\"green\"><H4>Line4 OFF </H4>");client.print("<a href=\"/$4\"><button><font color=\"red\"><H4>ON<H4></button></a>"); }
if (analogRead(A3)>200){ client.print("<font color=\"red\"><H2>__________</H2>"); }
else { client.print("<font color=\"green\"><H2>__________</H2>"); }
// client.print("<font color=\"blue \"><H20>___________________________</H20>");
client.println("</html>"); //закрываем тег HTML
break; //выход
}
}
}
delay(1); //время на получение новых данных
client.stop(); //закрываем соеднение
}
}
Видимо ты скетч у того-же человека что и я, я только немного по другому реализовл без возвращения http://192.168.0.203....
Тоесть у меня он не повторяет команду, я так понял ты отправляешь команду "включить pin 2" он включает, а потом через некоторое время выключает его?
Да, мне не нужно его постоянно держать High на включеном, а достаточно подать 1 включить, подать 1 выключить, если отключить автообновление страници проблема снимется автоматом, но оно необходимо...
Пока застрял и не могу сдвинутся с места.... ищу другие решения.
Еще хотел сделать авторизацию, но тоже проблема из за (с). авторизуюсь на сервере нажимаю любую кноку , проходит команда, записывается значение команды в (с) и я не могу больше авторизоваться, скидываю ресет, ну и в таком же духе. авторизацию брал скетч ниже... совмещал со своим...
#include <SPI.h> #include <Ethernet.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, 0, 203); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); //char userPass[200]; //char header[500]; String header; //int bufferSize = 0; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); header += c; if (c == '\n' && currentLineIsBlank) { //parse headers //bWluaDp0ZXN0 = 'minh:test' (user:password) base64 encode Serial.print(header); // Simpler just to find the credential string // send a standard http response header if(header.indexOf("bWluaDp0ZXN0") >= 0) { //successful login client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response //client.println("Refresh: 5"); // refresh the page automatically every 5 sec client.println(); if(header.indexOf("GET / HTTP/1.1") >= 0) { client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("inde xfsd"); client.println("</html>"); } else { client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("hello world!"); client.println("</html>"); } } else { // wrong user/pass //client.println("HTTP/1.0 401 Authorization Required"); client.println("HTTP/1.1 401 Unauthorized"); client.println("WWW-Authenticate: Basic realm=\"Secure\""); client.println("Content-Type: text/html"); client.println(); client.println("<html>Text to send if user hits Cancel button</html>"); // really need this for the popup! } header = ""; 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; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disconnected"); } }Как чар (с) до первоначального состояния.... не знаю, обновлять его при каждом новом цикле, как уже не извращался, не то чтото пишу похоже, newinfo =0; не помогло почему то, чуть больше времени может, может все прсто, а я туплю
Помогите пожалуйста, не могу найти способ как с сервера отправить клиенту пустой запрос..
с помощью кнопки получается, а по другому не могу...
client.print("<a href=\"/пробел\"><button><font color=\"green\"><H4>обновить<H4></button></a>");
Нашел такую команду для решения проблемы.
client.print("<meta HTTP-EQUIV='REFRESH' CONTENT='10; URL=http://192.168.0.200'>"); обновление страници и восстанавливает в строке адрес сервера без выполнения команд.
Тема конечно не про ENC28j60 но при утановке соотвктствующей библиотеки UIPethernet.h работает как с W5100, но дело не в этом, была проблема, долго искал почему происходит зависание этого шилда. Во всех примерах используется подключение к 13, 12, 11, 10 , +5 и gnd, так вот желательно еще и RESET пин подключить, а также CS пин подтянуть к +5 через 10кОм. Мало ли кому поможет..... В основном конечно советы что питания нехватает от плат ардуино, а вот про подтяжку CS пина мало инфы...
После того как это сделал двое суток тестов и нет зависания.
Боюсь, что насчет ENC28J60 и UIPethernet вы заблужаетесь сами и заблуждаете других.
Можно, конечно, CS (который и так подключается к D10) тянуть на VCC и, вероятно, это как-то поможет вам при плохом коннекте между Arduino board и ENC28J60 module, но зачастую проблема вовсе не в этом, если вы используете UIPethernet.
Даже при отличном соединении и питании данный модуль имеет шанс "взвиснуть" рано или поздно из-за маленькой особенности - работы программной части с буфером чипа. Если глубоко не вдаваться в подробности, то необходимо вычитывать буфер и вызывать внутреннюю процедуру UIPethernet::tick() ~каждые 250мс. Напрямую вы ее не сможете дернуть, нужно использовать Ethernet.maintain(), например, или if(EthernetClient). Словом - активней работать с сетью.
В противном случае - буфер ENC переполняется, чип поднимает флаг EIR.RXERIF и всё, приехали - модуль перестает принимать пакеты.
Так что спасение - это короткий loop(), а не окуривание CS ладаном.
Библиотеку UIP обновил до версии 2.0.3, в течении нескольких суток небыло зависания. А на ранних версиях подвисает в течении неопределенного времени.
Это форк какой-то? Оригинал у меня тоже по две недели работал при соблюдении определенных правил написания кода. А потом внезапно, как казалось, переставал пакеты принимать.
Вылечены ли болезни - можно понять, в частности, по флуд-тесту (hping3 -flood) и устройству длинного лупа (более секунды) в сети с обильным трафиком. Если переживет их - отлично. В моей домашней сети без спецмероприятий месяц как-то проработала сборка, а в сети предприятия держалось максимум две недели. Проблему я приблизительно локализовал, сделал workaround код и 1.0.9 уже вот... два с лишним месяца барабанит.
Сейчас ставлю брату для управления электро котлом и твердотопливным https://youtu.be/2dgHHZ8R380
Протестирую по истечении времени отпишу как дальше ведет себя, к примеру через месяц.
Может кто знает, вопрос такой. Возможно ли прописать в коде фильтрацию по MAC адресу клиента, так чтобы не было возможности с любого устройства зайти. А ответ проходил к конкретно прописаным клиентам?
Прямо материал для книги "Из экстремала в экстремиста за 24 часа". Я бы такое дело даже на Wiznet с опаской поднимал, не то что на развивающейся библиотеке для ENC28J60. Надеюсь, что модуль не отвечает за что-то жизненно важное.
Для TCP MAC адрес удаленного узла без вмешательства в исходный код UIPEthernet вы не получите. Можете изобразить авторизацию на уровне HTTP.