Arduino+ethernet w5100 генерация простого меню без SD-карты

Lukasik
Offline
Зарегистрирован: 19.01.2015

Добрый день уважаемые Arduinщики!!! 

Arduino+ethernet w5100 генерация простого меню без SD-карты

Возможно у кого-то из Вас есть данные наработки.

Идея такова: Ардуина генерирует главную страницу, через которую можно перейти по ссылке на страницу с данными по температуре и страницу для управления релюшками.

Вот как я это себе представляю:

ГЛАВНАЯ СТРАНИЦА:

Если перейти по ссылке с датчиками температуры(допустим это 192.168.1.33/temperatura.html)

то Ардуино сервер сгенерирует вот такую страницу:

Ну и если перейти по ссылке управления реле(192.168.1.33/relay.html)

сгенерируется такая страница:

С Ардуино занимаюсь год, до этого момента еще не дошел :)

Я думаю, что не только мне такая идея нужна, давайте вместе разберемся?

Artemiy
Offline
Зарегистрирован: 20.10.2014

Сразу вопрос: а почему без SD карты?

нарисовали красиво. Через 4 недели придет шильд - попробую в качестве спортивного интереса. А то так оно мне не особо нужно. С этим справляется Vera.

Lukasik
Offline
Зарегистрирован: 19.01.2015

Сейчас кое-что нагуглил....скоро будет готовый код :)

Lukasik
Offline
Зарегистрирован: 19.01.2015

Нашел вот этот код....попробую разобраться в нем и внедрить в него температуру и управление реле....

С маху сразу не получится....щас буду ковырять :)

Не откажусь от помощи ;)



#include <SPI.h>
#include <Ethernet.h>
#include <avr/pgmspace.h>
#include <string.h>

/* MAC address and IP address */
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 
  10, 0, 5, 11 };

/* Memory space for string management and setup WebServer service */

// for send html to client
#define STRING_BUFFER_SIZE 128
char buffer[STRING_BUFFER_SIZE];

// to store data from http request
#define STRING_LOAD_SIZE 128
char load[STRING_LOAD_SIZE];

// POST and GET variables
#define STRING_VARS_SIZE 128
char vars[STRING_VARS_SIZE];

/* Strings stored in flash of the HTML we will be xmitting */

#define NUM_PAGES 5

// HTTP Request message
PROGMEM prog_char content_404[] = "HTTP/1.1 404 Not Found\nServer: arduino\nContent-Type: text/html\n\n<html><head><title>Arduino Web Server - Error 404</title></head><body><h1>Error 404: Sorry, that page cannot be found!</h1></body>";
PGM_P page_404[] PROGMEM = { 
  content_404 }; // table with 404 page

// HTML Header for pages
PROGMEM prog_char content_main_header[] = "HTTP/1.0 200 OK\nServer: arduino\nCache-Control: no-store, no-cache, must-revalidate\nPragma: no-cache\nConnection: close\nContent-Type: text/html\n";
PROGMEM prog_char content_main_top[] = "<html><head><title>Arduino Web Server</title><style type=\"text/css\">table{border-collapse:collapse;}td{padding:0.25em 0.5em;border:0.5em solid #C8C8C8;}</style></head><body><h1>Arduino Web Server. V3</h1>";
PROGMEM prog_char content_main_menu[] = "<table width=\"500\"><tr><td align=\"center\"><a href=\"/\"?phpMyAdmin=BemiZd2nMBb39BXlkvpVVcBydS9>Page 1</a></td><td align=\"center\"><a href=\"page2\"?phpMyAdmin=BemiZd2nMBb39BXlkvpVVcBydS9>Page 2</a></td><td align=\"center\"><a href=\"page3\"?phpMyAdmin=BemiZd2nMBb39BXlkvpVVcBydS9>Page 3</a></td><td align=\"center\"><a href=\"page4\"?phpMyAdmin=BemiZd2nMBb39BXlkvpVVcBydS9>Page 4</a></td></tr></table>";
PROGMEM prog_char content_main_footer[] = "</body></html>";
PGM_P contents_main[] PROGMEM = { 
  content_main_header, content_main_top, content_main_menu, content_main_footer }; // table with 404 page
#define CONT_HEADER 0
#define CONT_TOP 1
#define CONT_MENU 2
#define CONT_FOOTER 3

// Page 1
PROGMEM prog_char http_uri1[] = "/";
PROGMEM prog_char content_title1[] = "<h2>Page 1</h2>";
PROGMEM prog_char content_page1[] = "<hr /><h3>Content of Page 1</h3><p>Nothing... yet.</p><br /><form action=\"/login\" method=\"POST\"><input type=\"hidden\" name=\"phpMyAdmin\" value=\"BemiZd2nMBb39BXlkvpVVcBydS9\" /><input type=\"text\" name=\"prova\"><input type=\"submit\" value=\"post\"></form>";

// Page 2
PROGMEM prog_char http_uri2[] = "/page2";
PROGMEM prog_char content_title2[] = "<h2>Page 2</h2>";
PROGMEM prog_char content_page2[] = "<hr /><h3>Content of Page 2</h3><p>Nothing here.</p>";

// Page 3
PROGMEM prog_char http_uri3[] = "/page3";
PROGMEM prog_char content_title3[] = "<h2>Page 3</h2>";
PROGMEM prog_char content_page3[] = "<hr /><h3>Content of Page 3</h3><p>No no no, white page here.</p>";

// Page 4
PROGMEM prog_char http_uri4[] = "/page4";
PROGMEM prog_char content_title4[] = "<h2>Page 4</h2>";
PROGMEM prog_char content_page4[] = "<hr /><h3>Content of Page 4</h3><p>Ehm... no, nothing.</p>";

// Page 5
PROGMEM prog_char http_uri5[] = "/login";
PROGMEM prog_char content_title5[] = "<h2>POST Page 5</h2>";
PROGMEM prog_char content_page5[] = "<hr /><h3>Content of Page 5</h3><p>received a POST request</p>";

// declare tables for the pages
PGM_P contents_titles[] PROGMEM = { 
  content_title1, content_title2, content_title3, content_title4, content_title5 }; // titles
PGM_P http_uris[] PROGMEM = { 
  http_uri1, http_uri2, http_uri3, http_uri4, http_uri5 }; // URIs
PGM_P contents_pages[] PROGMEM = { 
  content_page1, content_page2, content_page3, content_page4, content_page5 }; // real content

/* define HTTP return structur ID for parsing HTTP header request */
struct HTTP_DEF {
  int pages;
  char vars[20];
} 
;

/* Shared variable */
EthernetServer server(80);

void setup() {
  Ethernet.begin(mac, ip);
  server.begin();

  Serial.begin(9600); // DEBUG
}

/*  Main loop */

void loop() {
  EthernetClient client = server.available();
  if (client) { // now client is connected to arduino

    // read HTTP header request... so select what page client are looking for
    HTTP_DEF http_def = readHTTPRequest(client);

    if (http_def.pages > 0) {
      sendPage(client,http_def);
    } 
    else {
      contentPrinter(client,(char*)pgm_read_word(&(page_404[0])));
    }

    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }

}

/* Method for read HTTP Header Request from web client */
struct HTTP_DEF readHTTPRequest(EthernetClient client) {
  char c;
  int i;

  // use buffer, pay attenction!
  int bufindex = 0; // reset buffer
  int loadindex = 0; // reset load

  int contentLenght = 0; // reset POST content lenght
  char compare[50]; // page comparation (uri selection)

  HTTP_DEF http_def; // use the structure for multiple returns

  http_def.pages = 0; // default page selection... error

  // reading all rows of header
  if (client.connected() && client.available()) { // read a row
    buffer[0] = client.read();
    buffer[1] = client.read();
    bufindex = 2;
    // read the first line to determinate the request page
    while (buffer[bufindex-2] != '\r' && buffer[bufindex-1] != '\n') { // read full row and save it in buffer
      c = client.read();
      if (bufindex<STRING_BUFFER_SIZE) buffer[bufindex] = c;
      bufindex++;
    }

    // select the page from the buffer (GET and POST) [start]
    for(i = 0; i < NUM_PAGES; i++) {
      strcpy_P(load, (char*)pgm_read_word(&(http_uris[i])));
      // GET
      strcpy(compare,"GET ");
      strcat(compare,load);
      strcat(compare," ");
      Serial.print("GET compare: "); // DEBUG
      Serial.println(compare); // DEBUG
      if (strncmp(buffer,compare, strlen(load)+5)==0) {
        http_def.pages = i+1;
        break;
      }

      // POST
      strcpy(compare,"POST ");
      strcat(compare,load);
      strcat(compare," ");
      Serial.print("POST compare: "); // DEBUG
      Serial.println(compare); // DEBUG
      if (strncmp(buffer,compare, strlen(load)+6)==0) {
        http_def.pages = i+1;
        break;
      }

    }
    // select the page from the buffer (GET and POST) [stop]

    // read other stuff (for POST requests) [start]
    if (strncmp(buffer, "POST /", 5)==0) {
processRequest:
      loadindex = 2; // reset load

      memset(load,0,STRING_LOAD_SIZE);
      load[0] = client.read();
      load[1] = client.read();
      while (load[loadindex-2] != '\r' && load[loadindex-1] != '\n') {
        c = client.read();
        if (loadindex<STRING_BUFFER_SIZE) load[loadindex] = c;
        loadindex++;
      }
      if (strncmp(load, "Content-Length: ",16)==0) {
        loadindex = 16;
        for(i = loadindex; i< strlen(load) ; i++) {
          if (load[i] != ' ' && load[i] != '\r' && load[i] != '\n') {
            vars[i-loadindex] = load[i];
          } 
          else {
            break;
          }
        }

        contentLenght = atoi(vars);
        memset(vars,0,STRING_VARS_SIZE);
        client.read(); 
        client.read(); // read null line
        i = 0;
        while (i<contentLenght) {
          c = client.read();
          vars[i] = c;
          ++i;
        }

      } 
      else {
        goto processRequest;
      }
    }
    // read other stuff (for POST requests) [stop]


    // clean buffer for next row
    bufindex = 0;
  }

  //      delay(10); // removing this nothing work... if you understand why mail me a bebbo [at] bebbo [dot] it
  Serial.print("Grepped page: "); // DEBUG
  Serial.println(http_def.pages); // DEBUG

  strncpy(http_def.vars,vars,STRING_VARS_SIZE);

  return http_def;
}

/* Send Pages */
void sendPage(EthernetClient client,struct HTTP_DEF http_def) {

  // send html header
  // contentPrinter(client,(char*)pgm_read_word(&(contents_main[CONT_HEADER])));
  contentPrinter(client,(char*)pgm_read_word(&(contents_main[CONT_TOP])));

  // send menu
  contentPrinter(client,(char*)pgm_read_word(&(contents_main[CONT_MENU])));

  // send title
  contentPrinter(client,(char*)pgm_read_word(&(contents_titles[http_def.pages-1])));

  // send the body for the requested page
  sendContent(client,http_def.pages-1);

  client.print("<br />");
  // send POST variables
  client.print(vars);

  // send footer
  contentPrinter(client,(char*)pgm_read_word(&(contents_main[CONT_FOOTER])));
}

/* Seond content splittere by buffer size */
void contentPrinter(EthernetClient client, char *realword) {
  int total = 0;
  int start = 0;
  char buffer[STRING_BUFFER_SIZE];
  int realLen = strlen_P(realword);

  memset(buffer,0,STRING_BUFFER_SIZE);

  while (total <= realLen) {
    // print content
    strncpy_P(buffer, realword+start, STRING_BUFFER_SIZE-1);
    client.print(buffer);

    // more content to print?
    total = start + STRING_BUFFER_SIZE-1;
    start = start + STRING_BUFFER_SIZE-1;

  }
}

/* Send real page content */
void sendContent(EthernetClient client, int pageId) {
  contentPrinter(client,(char*)pgm_read_word(&(contents_pages[pageId])));
}

 

Lukasik
Offline
Зарегистрирован: 19.01.2015

Вот что в браузере, довольно таки не плохо получается:

Lukasik
Offline
Зарегистрирован: 19.01.2015

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

У меня это работает. Вот полностью рабочий код (датчики температуры и реле еще не подключал )...

Как видите SD карта здесь не нужна.....Надеюсь оцените:) Жду комментов!!!


#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 
  192, 168, 1, 33 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 
  192, 168, 1, 1 };                   // internet access via router
byte subnet[] = { 
  255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString;


void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // Create a client connection
  
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {          
          Serial.println(readString); //print to serial monitor for debuging
          
          delay(1);
          
          
          if (readString.indexOf("?index") >0)//Главная страница
            {
          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='Content-Type' content='text/html; charset=utf-8' /> ");
          client.println("<TITLE>Arduino+Ethernet Shield W5100</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<br>");
          client.println("Arduino+Ethernet Shield W5100");
          client.println("<br>");
          client.println("Arduino+ethernet w5100 генерация простого меню без SD-карты");
          client.println("<br><br><br>");
          client.println("<a href=\"http://192.168.1.33/?temperatura\">Ссылка на страницу с датчиками температуры</a><br>");
          client.println("<a href=\"http://192.168.1.33/?relay\">Ссылка на страницу управления реле</a><br>");
          client.println("</BODY>");
          client.println("</HTML>");
            }
                    
          //********************************************************************
            if (readString.indexOf("?temperatura") >0)//страница с датчиками температуры
            {
              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='Content-Type' content='text/html; charset=utf-8' /> ");
          client.println("<TITLE>Arduino+Ethernet Shield W5100</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<br>");
          client.println("Arduino+Ethernet Shield W5100");
          client.println("<br>");
          client.println("Arduino+ethernet w5100 генерация простого меню без SD-карты");
          client.println("<br><br><br>");
          client.println("Температура в доме = 28&degC");
          client.println("<br><br>");
          client.println("Температура за окном = 3&degC");
          client.println("<br><br><br>");
          client.println("<a href=\"http://192.168.1.33/?index\">НА ГЛАВНУЮ</a>");
          client.println("</BODY>");
          client.println("</HTML>");
            
            }
            if (readString.indexOf("?relay") >0)//страница с релюшками
            {
              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='Content-Type' content='text/html; charset=utf-8' /> ");
          client.println("<TITLE>Arduino+Ethernet Shield W5100</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<br>");
          client.println("Arduino+Ethernet Shield W5100");
          client.println("<br>");
          client.println("Arduino+ethernet w5100 генерация простого меню без SD-карты");
          client.println("<br><br><br>");
          client.println("Реле№1");
          client.println("<a href=\"http://\">ВКЛ</a>");
          client.println("/");
          client.println("<a href=\"http://\">ВЫКЛ</a>");
          client.println("<br><br><br>");
          client.println("Реле№2");
          client.println("<a href=\"http://\">ВКЛ</a>");
          client.println("/");
          client.println("<a href=\"http://\">ВЫКЛ</a>");
          client.println("<br><br><br>");
          client.println("<a href=\"http://192.168.1.33/?index\">НА ГЛАВНУЮ</a>");
          client.println("</BODY>");
          client.println("</HTML>");
                        
            }
          
            readString="";
          
          
          client.stop();
        }
      }
    }
  }
}

Вот скрины из браузера

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а чем закончилось?

Lukasik
Offline
Зарегистрирован: 19.01.2015

Привет. Пост 2 года назад писал.Был реализован проект по мониторингу температуры и управления релейным модулем. Далее проект наращивал, IP камеру подключил,облако google, уведомления о критической температуре на смартфон через смс и через push уведомления. На данный момент устройство разобрано по частям,эх.было бы время свободное можно было ещё что-нибудь спроектировать.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

привет. и все без sd карты?

Lukasik
Offline
Зарегистрирован: 19.01.2015

Весь проект без SD карты,всё меню организовывал в ардуинке меге,а с помощью езернет шильда отправлял и получал данные,он был как клиент,так и сервер.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

хорошо) я тоже пытаюсь на есп сделать