w5100 web сервер обновление страници и повторное выполнение команды

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Проблему не сразу заметил, при нажатии кнопке отравляется запрос 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();                                     //закрываем соеднение 
}
}

 

artyom.clachin
Offline
Зарегистрирован: 06.02.2017

Видимо ты скетч у того-же человека что и я, я только немного по другому реализовл без возвращения http://192.168.0.203....
Тоесть у меня он не повторяет команду, я так понял ты отправляешь команду "включить pin 2" он включает, а потом через некоторое время выключает его?

 

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Да, мне не нужно его постоянно держать 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");
  }
}

 

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Как чар (с) до первоначального состояния.... не знаю, обновлять его при каждом новом цикле, как уже не извращался, не то чтото пишу похоже, newinfo =0; не помогло почему то, чуть больше времени может, может все прсто, а я туплю

 

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Помогите пожалуйста, не могу найти способ как с сервера отправить клиенту пустой запрос..

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

с помощью кнопки получается, а по другому не могу...

client.print("<a href=\"/пробел\"><button><font color=\"green\"><H4>обновить<H4></button></a>");

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Нашел такую команду для решения проблемы.

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 пина мало инфы...

После того как это сделал двое суток тестов и нет зависания.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Боюсь, что насчет ENC28J60 и UIPethernet вы заблужаетесь сами и заблуждаете других.

Можно, конечно,  CS (который и так подключается к D10) тянуть на VCC и, вероятно, это как-то поможет вам при плохом коннекте между Arduino board и ENC28J60 module, но зачастую проблема вовсе не в этом, если вы используете UIPethernet. 

Даже при отличном соединении и питании данный модуль имеет шанс "взвиснуть" рано или поздно из-за маленькой особенности - работы программной части с буфером чипа.  Если глубоко не вдаваться в подробности, то необходимо вычитывать буфер и вызывать внутреннюю процедуру UIPethernet::tick() ~каждые 250мс. Напрямую вы ее не сможете дернуть, нужно использовать Ethernet.maintain(), например, или if(EthernetClient). Словом - активней работать с сетью.

В противном случае - буфер ENC переполняется, чип поднимает флаг EIR.RXERIF и всё, приехали - модуль перестает принимать пакеты. 

Так что спасение - это короткий loop(), а не окуривание CS ладаном.

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Библиотеку UIP обновил до версии 2.0.3, в течении нескольких суток небыло зависания. А на ранних версиях подвисает в течении неопределенного времени.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Это форк какой-то? Оригинал у меня тоже по две недели работал при соблюдении определенных правил написания кода. А потом внезапно, как казалось, переставал пакеты принимать. 

Вылечены ли болезни - можно понять, в частности, по флуд-тесту (hping3 -flood) и устройству длинного лупа (более секунды) в сети с обильным трафиком. Если переживет их - отлично. В моей домашней сети без спецмероприятий месяц как-то проработала сборка, а в сети предприятия держалось максимум две недели. Проблему я приблизительно локализовал, сделал workaround код и 1.0.9 уже вот...  два с лишним месяца барабанит.

aleksey19ru
Offline
Зарегистрирован: 23.06.2016

Сейчас ставлю брату для управления электро котлом и твердотопливным https://youtu.be/2dgHHZ8R380

Протестирую по истечении времени отпишу как дальше ведет себя, к примеру через месяц.

Может кто знает, вопрос такой. Возможно ли прописать в коде фильтрацию по MAC адресу клиента, так чтобы не было возможности с любого устройства зайти. А ответ проходил к конкретно прописаным клиентам?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Прямо материал для книги "Из экстремала в экстремиста за 24 часа". Я бы такое дело даже на Wiznet с опаской поднимал, не то что на развивающейся библиотеке для ENC28J60. Надеюсь, что модуль не отвечает за что-то жизненно важное.

Для TCP MAC адрес удаленного узла без вмешательства в исходный код UIPEthernet вы не получите. Можете изобразить авторизацию на уровне HTTP.