WebServer на ардуино 2560 и ethernet контроллере W5100

mozgolomys
Offline
Зарегистрирован: 08.01.2016

Andy пишет:

Еще одна мысль: анимация теряет смысл если страница обновляется сразу по клику.

А как же?

mozgolomys
Offline
Зарегистрирован: 08.01.2016

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

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Вынести в iframe или использовать ajax запросы.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

Сделал так:

"<iframe name='iframe' width='1' height='1' style='display: none;'></iframe>"
"<form method='post' action='#'target='iframe'>"
"<tr>"\
"<td>Режим работы</td>"\
"<td><input type='checkbox' id='manauto' name='manauto'onClick='this.form.submit();'/><input type='hidden' name='manautofrm'><label for='manauto'>AUTO</label></td>"\
"<td>Feedback</td>"\
"</tr>"\
"</form>"

После изменения положения переключателя и перезагрузки страницы незаметно скакание переключателей.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

Вынес исполнительную часть в отдельный файл control.h. Создал функцию ControlFunction.

Все переменные перечисляю в основном файле, но не знаю как в control.h сказать, что переменные находятся в основном файле.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Оформи в виде класса, в control.h описание класса, в control.cpp - реализация. В основном файле #include "control.h" и объявление объекта вроде: Ccontrol control; Все переменные в свойствах класса.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

А вы обошлись без .cpp файла, потому что внутри класса создали функцию?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Можно и в h файл засунуть реализацию, но обычно так делают если реализация класса небольшая.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

В h пытался, но появляется ошибка на условиеif.

exit status 1
expected unqualified-id before 'if'

class ControlFunction 
{

if (filter == 1){
  digitalWrite(relay_filter, HIGH);
}else{
  digitalWrite(relay_filter, LOW);
}
};

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

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Вот так сделай

class ControlFunction 
{
public:
void MyFunction()
{
  if (filter == 1){
  digitalWrite(relay_filter, HIGH);
  }else{
  digitalWrite(relay_filter, LOW);
  }
}
private:
int filter;
};

 

mozgolomys
Offline
Зарегистрирован: 08.01.2016

В основном теле проекта обращение к классу правильное?

ControlFunction control;
Это в loop
control.MyFunction();

Скомпилировалось без ошибок.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Да, верно.

mozgolomys
Offline
Зарегистрирован: 08.01.2016
class ControlFunction 
{
public:
void MyFunction()
{
  if (filter == true){
  digitalWrite(relay_filter, HIGH);
  Serial.println("relay_filter on");
  }else{
  digitalWrite(relay_filter, LOW);
  Serial.println("relay_filter off");
  }
}
private:
int filter;
byte relay_filter;
};

Сейчас всегда сработана ветка else, т.к. я не получаю состояния переключателя из главного файла.

Соответственно если ставлю filter=1, то срабатывает первое условие.

Данной записью
private:
int filter;
byte relay_filter;
мы убрали ошибки при компиляции, но видимо не получем состояние filter.
 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

ООП рекомендует доступ к свойствам класса через set и get функции, вроде:

void set(int f){filter = f;}

int get() {return filter;}

Соответственно вызовы: control.set(x); x=control.get();

Можно сделать переменную публичной и обращаться к ней прямо: x = control.filter;

mozgolomys
Offline
Зарегистрирован: 08.01.2016

mozgolomys пишет:
Сейчас всегда сработана ветка else, т.к. я не получаю состояния переключателя filter из главного файла.

А вы мне предлагаете сделать функцию в файле control.h и обращаться из главного вайла к ней.

Цитата:
ООП рекомендует доступ к свойствам класса через set и get функции, вроде:

void set(int f){filter = f;}

int get() {return filter;}

Соответственно вызовы: control.set(x); x=control.get();

Можно сделать переменную публичной и обращаться к ней прямо: x = control.filter;

Если я правильно понял, то

void set(int f){filter = f;}

int get() {return filter;}

Это мы пишем в главном проекте, а control.set(x); x=control.get(); в control.h или я вас не правильно понял?

 

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016
class ControlFunction 
{
public:
void MyFunction()
{
  if (filter == true){
  digitalWrite(relay_filter, HIGH);
  Serial.println("relay_filter on");
  }else{
  digitalWrite(relay_filter, LOW);
  Serial.println("relay_filter off");
  }
}
void setfilter(int f){filter = f;}
int getfilter() {return filter;}

private:
int filter;
byte relay_filter;
};

А в проекте, в том месте где образуется значение, пишем: control.setfilter(value);

В том месте где значение нужно передать клиенту: value=control.getfilter();

Либо делаем переменную публичной и обращаемся к ней прямо.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

Правильно-ли я сделал так?

в проекте
control.MyFunction(filter,relay_filter, light, relay_svet);

в control.h
class ControlFunction
{
  public:
    void MyFunction(bool filter, byte relay_filter, bool light, byte relay_svet)
    {

      if (filter == true) {
        digitalWrite(relay_filter, HIGH);
        Serial.println("relay_filter on");
      } else {
        digitalWrite(relay_filter, LOW);
        Serial.println("relay_filter off");
      }

            if (light == true) {
        digitalWrite(relay_svet, HIGH);
        Serial.println("relay_svet on");
      } else {
        digitalWrite(relay_svet, LOW);
        Serial.println("relay_svet off");
      }
    }

или лучше переделать, как вы написали?

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

В твоем случае разумнее написать свой set/get для каждой переменной:

class ControlFunction
{
  public:
    void setFilter(bool x)
    {
      if (filter == x) return;//состояние не изменилось
      filter=x; 
      if (x) digitalWrite(FILTERPIN, HIGH);//включить
      else digitalWrite(FILTERPIN, LOW);//выключить
      Serial.print("relay_filter "); Serial.println(x?"on":"off");
    }
    void setLight(bool x)
    {
      if (light == x) return;//состояние не изменилось
      light=x; 
      if (x) digitalWrite(LIGHTPIN, HIGH);//включить
      else digitalWrite(LIGHTPIN, LOW);//выключить
      Serial.print("relay_light "); Serial.println(x?"on":"off");
    }
    bool getFilter(){return filter;}
    bool getLight(){return light;}

 private:
 bool filter, light;
}

 

mozgolomys
Offline
Зарегистрирован: 08.01.2016

'FILTERPIN' was not declared in this scope

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

FILTERPIN и LIGHTPIN это выводы, к которым у тебя подключены relay_filter и relay_svet. Судя по всему они используются только в этом классе, поэтому их здесь и надо объявить через #define

mozgolomys
Offline
Зарегистрирован: 08.01.2016
#define FILTERPIN
#define LIGHTPIN

class ControlFunction
{
  public:
    void setFilter(bool x)
    {
      if (filter == x) return;//состояние не изменилось
      filter=x; 
      if (x) digitalWrite(FILTERPIN, HIGH);//включить
      else digitalWrite(FILTERPIN, LOW);//выключить
      Serial.print("relay_filter "); Serial.println(x?"on":"off");
    }
    void setLight(bool x)
    {
      if (light == x) return;//состояние не изменилось
      light=x; 
      if (x) digitalWrite(LIGHTPIN, HIGH);//включить
      else digitalWrite(LIGHTPIN, LOW);//выключить
      Serial.print("relay_light "); Serial.println(x?"on":"off");
    }
    bool getFilter(){return filter;}
    bool getLight(){return light;}

 private:
 bool filter, light;
};

Получаю ошибку в проекте

pinMode(FILTERPIN, OUTPUT);
expected primary-expression before ',' token

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Номера пинов нужно указать: #define FILTERPIN 10

Настройку этих пинов pinMode нужно перенести из setup() в конструктор этого класса. Добавь:

class ControlFunction
{
 public:
 ControlFunction()//это конструктор
 {
  pinMode(FILTERPIN, OUTPUT);
  pinMode(LIGHTPIN, OUTPUT);
 }
...

 

mozgolomys
Offline
Зарегистрирован: 08.01.2016
#include <SPI.h>
#include <Ethernet.h>
#include "HTML.h"
#include "request.h"
#include <avr/pgmspace.h>
#include <EEPROM.h>
#include "control.h"

ControlFunction control;
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;
//-------- твои переменные -----------
boolean manauto = 1, manautofrm = 0, light = 0, lightfrm = 1, filter = 0, filterfrm = 1, air = 0, airfrm = 1, hiter = 0, hiterfrm = 1;
byte relay_light = 3;
byte relay_filter = 5;
byte relay_air = 7;
byte relay_hiter = 10;


void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  request.init();
  pinMode(relay_light, OUTPUT);
  pinMode(relay_filter, OUTPUT);
  pinMode(relay_air, OUTPUT);
  pinMode(relay_hiter, OUTPUT);
}

//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>");
//}

void send(const char *ptr)
{
  char c;
  while (c = pgm_read_byte(ptr++)) client.print(c);
  //здесь по хорошему символы надо в буфер собирать, а затем отправлять клиенту
}

void sendjs()
{
  /*
    //на стороне клиента должна получиться такая функция
    function setVars()
    {
    document.getElementById('manauto').checked=1;
    document.getElementById('light').checked=0;
    document.getElementById('filter').checked=0;
    document.getElementById('air').checked=0;
    document.getElementById('hiteron').checked=0;
    }
  */
  String s;
  client.println("function setVars(){");
  s = "document.getElementById('manauto').checked=";   if (manauto) s += "1;"; else s += "0;"; client.println(s); Serial.println(s);
  /*s="document.getElementById('manual').checked=" +manual? "1;":"0;";  client.println(s); Serial.println(s);*/
  //s = "document.getElementById('manautofrm').checked=" ;    if (manautofrm) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  s = "document.getElementById('light').checked=";  if (light) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  //s = "document.getElementById('lightfrm').checked="; if (lightfrm) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  s = "document.getElementById('filter').checked="; if (filter) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  //s = "document.getElementById('filterfrm').checked="; if (filterfrm) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  s = "document.getElementById('air').checked=";    if (air) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  // s = "document.getElementById('airfrm').checked=";   if (airfrm) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  s = "document.getElementById('hiter').checked=";  if (hiter) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  // s = "document.getElementById('hiterfrm').checked="; if (hiterfrm) s += "1;"; else s += "0;";  client.println(s); Serial.println(s);
  client.println("}");
}

void setVars()
{
  String s = request.param(); //получаю строку параметров из запроса

  if (s.indexOf("manauto") != -1) //если в запросе присутствует параметр manauto
  { //значит запрос от формы manauto
    if (s.indexOf("manauto=on") != -1) manauto = true; //если есть "manauto=on" значит чекбокс checked
    else manauto = false; //иначе nonchecked
  }
  //
  //  if (s.indexOf("manautofrm") != -1)                      //если в запросе присутствует параметр lightfrm
  //  { //значит запрос от формы Свет
  //    if (s.indexOf("manauto") != -1) manauto = true; //если есть lighton значит чекбокс checked
  //    else manauto = false; //иначе nonchecked
  //  }

  if (s.indexOf("light") != -1)                      //если в запросе присутствует параметр lightfrm
  { //значит запрос от формы Свет
    if (s.indexOf("light=on") != -1) light = true; //если есть lighton значит чекбокс checked
    else light = false; //иначе nonchecked
  }
  if (s.indexOf("filter") != -1)                      //если в запросе присутствует параметр lightfrm
  { //значит запрос от формы Свет
    if (s.indexOf("filter=on") != -1) filter = true; //если есть lighton значит чекбокс checked
    else filter = false; //иначе nonchecked
  }
  if (s.indexOf("air") != -1)                      //если в запросе присутствует параметр lightfrm
  { //значит запрос от формы Свет
    if (s.indexOf("air=on") != -1) air = true; //если есть lighton значит чекбокс checked
    else air = false; //иначе nonchecked
  }
  if (s.indexOf("hiter") != -1)                      //если в запросе присутствует параметр lightfrm
  { //значит запрос от формы Свет
    if (s.indexOf("hiter=on") != -1) hiter = true; //если есть lighton значит чекбокс checked
    else hiter = false; //иначе nonchecked
  }

  Serial.println(s);
}

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 GETJS: send(Ok); sendjs(); break;
          case POST: setVars(); send(Ok); send(html); break;
          default: break;
        }
        break;
      }
    }
    client.stop();
    request.init();
  }
  
//if (filter == true){
//  digitalWrite(relay_filter, HIGH);
//}else{
//  digitalWrite(relay_filter, LOW);
//}
//control.MyFunction(filter,relay_filter, light, relay_svet);
control.setFilter(bool x);
control.setLight(bool x);


}

170 строчка expected primary-expression before 'bool'

#define FILTERPIN 5
#define LIGHTPIN 3

class ControlFunction
{
  public:
   ControlFunction()//это конструктор
 {
  pinMode(FILTERPIN, OUTPUT);
  pinMode(LIGHTPIN, OUTPUT);
 }
    void setFilter(bool x)
    {
      if (filter == x) return;//состояние не изменилось
      filter=x; 
      if (x) digitalWrite(FILTERPIN, HIGH);//включить
      else digitalWrite(FILTERPIN, LOW);//выключить
      Serial.print("relay_filter "); Serial.println(x?"on":"off");
    }
    void setLight(bool x)
    {
      if (light == x) return;//состояние не изменилось
      light=x; 
      if (x) digitalWrite(LIGHTPIN, HIGH);//включить
      else digitalWrite(LIGHTPIN, LOW);//выключить
      Serial.print("relay_light "); Serial.println(x?"on":"off");
    }
    bool getFilter(){return filter;}
    bool getLight(){return light;}

 private:
 bool filter, light;
};

Может быть все это можно как-то проще сделать?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Проведи ревизию в строках 25-29. Переменные и определения пинов ушли в класс ControlFunction.

Строки 169-170 убери. Вместо них в строке 118-119:


if (s.indexOf("light=on") != -1) control.setLight(true); 
    else control.setLight(false);

Аналогично со всеми переменными.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

Andy пишет:
Вместо них в строке 118-119:


if (s.indexOf("light=on") != -1) control.setLight(true); 
    else control.setLight(false);

Аналогично со всеми переменными.

Если я так сделаю, то у меня перестанут работать кнопки

 if (s.indexOf("light=on") != -1) light = true; //если есть lighton значит чекбокс checked
 else light = false; //иначе nonchecked

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

В строке 89: if (control.getLight())

аналогично со всеми переменными.

mozgolomys
Offline
Зарегистрирован: 08.01.2016

Вот наконец-то появилось время продолжить изыскания в данной теме. Гуру, вы со мной?

komsadiman
Offline
Зарегистрирован: 13.05.2016

mozgolomys пишет:

Вот наконец-то появилось время продолжить изыскания в данной теме. Гуру, вы со мной?

А не подскажите, можно включить реле через ссылку а не через web интерфейс если используется метод post мне это нужно для включение сигнализации из сторонний программы которая моежт запускать ссылки.