Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/Web Net Setup

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Браузерный интерфейс для настройки сети[1]

Этот пример показывает, как при помощи библиотеки Webduino создать браузерный интерфейс, позволяющий менять сетевые настройки Ethernet-модуля.

Код

  1. /* Браузерный интерфейс для настройки сети (Webduino)
  2. Автор:     Маттиас Мадерер (Matthias Maderer)
  3. Дата:      07.03.2013
  4. Версия:    1.0.1
  5. Сайт:      www.edvler-blog.de/arduino_networksetup_webinterface_with_eeprom
  6.  
  7. Это скетч-пример для Webduino!
  8. Более подробно о Webduino можно почитать тут: https://github.com/sirleech/Webduino
  9.  
  10. Более подробно о EEPROMAnything.h смотрите на: http://playground.arduino.cc/Code/EEPROMWriteAnything
  11. */
  12.  
  13. /*
  14. * Этот пример позволяет менять сетевые настройки на модуле Arduino
  15. * Ethernet Shield при помощи браузерного интерфейса. То есть, он
  16. * представляет собой что-то вроде настроек роутера.
  17. *  
  18. * Можно менять следующие настройки:
  19. * - MAC-адрес (MAC address)
  20. * - IP-адрес (IP address)
  21. * - Маску подсети (Subnet)
  22. * - Сетевой шлюз (GW address)
  23. * - DNS-сервер (DNS Server)
  24. * - Порт веб-сервера (Webserver port)
  25. * - Использование DHCP - ДА/НЕТ (Use DHCP). Чтобы узнать адрес,
  26. *   присвоенный через DHCP, при включении питания подключитесь ко всем
  27. *   последовательным портам на скорости 9600 бод.
  28. * - интервал обновления DHCP (Renew interval for DHCP in minutes)
  29. *
  30. * Другие функции:
  31. * - Показ статуса обновления DHCP (DHCP renew return code)
  32. * - Показ времени последнего обновления DHCP (DHCP last renew timestamp)
  33. * - Показ времени работы Arduino (Uptime)
  34. * - Показ объема используемой RAM-памяти (RAM)
  35. *
  36. * Вы также можете задать настройки по умолчанию. Они будут
  37. * использоваться, если не задано вообще никаких настроек.
  38. * См. функцию set_EEPROM_Default().
  39. *
  40. * Также есть возможность подключиться к кнопке RESET. Если нажать
  41. * на нее, это восстановит настройки по умолчанию.
  42. * Смотрите строчку с #define RESET_PIN.
  43. *
  44. * Все настройки хранятся в EEPROM. Это значит, что они постоянные.
  45. * Краткое описание смотрите на http://arduino.cc/en/Reference/EEPROM
  46. *
  47. * По умолчанию IP-адрес указан как http://192.168.0.111/.
  48. * Не забудьте поменять IP-адрес Ethernet-модуля на более подходящий
  49. * (например, на IP-адрес 192.168.0.1, маска подсети 255.255.255.0)!
  50. *
  51. * Чтобы открыть настройки, введите в браузер следующий URL:
  52. * http://192.168.0.111/setupNet.html
  53. *
  54. * Имейте в виду, что никаких проверок на ошибки в скетче нет!
  55. * Поэтому если вводимые вами данные содержат ошибки, то никаких
  56. * уведомлений и предупреждений показано не будет.
  57. *
  58. * Ресурсы:
  59. * Объем HTML-сайта, содержащегося в этом скетче, в скомпилированном
  60. * виде составляет около 27 байт. При этом используется около 2000 байт
  61. * SRAM-памяти. На маленьких Arduino могут возникнуть проблемы.
  62. * Я тестировал его на MEGA 2560.
  63. *
  64. * БАГИ:
  65. * - После загрузки скетча Arduino станет недоступна, поэтому
  66. *   перезагрузите ее.
  67. */
  68.  
  69.  
  70. #define WEBDUINO_FAVICON_DATA "" // иконки нет
  71. //#define DEBUG  // раскомментируйте эту строчку, если хотите видеть отладочные данные
  72. #define USE_SYSTEM_LIBRARY // закомментируйте, если хотите сэкономить
  73.                            // немного места (около 1 байта);
  74.                            // в результате не будут отображаться время
  75.                            // работы Arduino и объем используемой RAM
  76. #define SERIAL_BAUD 9600
  77.  
  78. #include "SPI.h"
  79. #include "avr/pgmspace.h"
  80. #include "Ethernet.h"
  81. #include "WebServer.h"
  82.  
  83.  
  84. /* #############################################################################################################################################################
  85. * Код для всего, что связано с EEPROM
  86. *
  87. */
  88. #include <EEPROM.h>
  89. #include "EEPROMAnything.h"
  90.  
  91. #define RESET_PIN 40    // Подключите кнопку сброса к этому контакту. Нажатие на эту кнопку восстановит настройки по умолчанию.
  92.  
  93. /* Структура, которая будет храниться в EEPROM.
  94. *  Функции для записи и чтения struct смотрите в "EEPROMAnything.h".
  95. */
  96. struct config_t
  97. {
  98.     byte config_set;
  99.     byte use_dhcp;
  100.     byte dhcp_refresh_minutes;
  101.     byte mac[6];
  102.     byte ip[4];
  103.     byte gateway[4];
  104.     byte subnet[4];
  105.     byte dns_server[4];
  106.     unsigned int webserverPort;
  107. } eeprom_config;
  108.  
  109. /**
  110. * Функция set_EEPROM_Default().
  111. *
  112. * Настройки по умолчанию.
  113. * Они используются, если не задано никаких настроек или если нажата кнопка сброса.
  114. */
  115. void set_EEPROM_Default() {
  116.     eeprom_config.config_set=1;  // тут ничего не меняем! эта строчка используется, чтобы проверить, заданы ли какие-нибудь настройки
  117.  
  118.     eeprom_config.use_dhcp=0;  // по умолчанию используем DHCP
  119.     eeprom_config.dhcp_refresh_minutes=60; // обновляем DHCP каждые 60 минут
  120.  
  121.     // Задаем MAC-адрес по умолчанию. В данном случае это DE:AD:BE:EF:FE:ED
  122.     eeprom_config.mac[0]=0xDE;  
  123.     eeprom_config.mac[1]=0xAD;
  124.     eeprom_config.mac[2]=0xBE;
  125.     eeprom_config.mac[3]=0xEF;
  126.     eeprom_config.mac[4]=0xFE;
  127.     eeprom_config.mac[5]=0xED;
  128.    
  129.     // задаем для Arduino IP-адрес по умолчанию. В данном случае это 192.168.0.111
  130.     eeprom_config.ip[0]=192;
  131.     eeprom_config.ip[1]=168;
  132.     eeprom_config.ip[2]=0;
  133.     eeprom_config.ip[3]=111;
  134.  
  135.     // Задаем сетевой шлюз по умолчанию. В данном случае это 192.168.0.254
  136.     eeprom_config.gateway[0]=192;
  137.     eeprom_config.gateway[1]=168;
  138.     eeprom_config.gateway[2]=0;
  139.     eeprom_config.gateway[3]=254;
  140.    
  141.     // Задаем маску подсети по умолчанию. В данном случае это 255.255.255.0
  142.     eeprom_config.subnet[0]=255;
  143.     eeprom_config.subnet[1]=255;
  144.     eeprom_config.subnet[2]=255;
  145.     eeprom_config.subnet[3]=0;
  146.  
  147.     // задаем DNS-сервер по умолчанию. В данном случае это 192.168.0.254
  148.     eeprom_config.dns_server[0]=192;
  149.     eeprom_config.dns_server[1]=168;
  150.     eeprom_config.dns_server[2]=0;
  151.     eeprom_config.dns_server[3]=254;
  152.  
  153.     // задаем порт веб-сервера по умолчанию. В данном случае это 80 порт
  154.     eeprom_config.webserverPort=80;
  155.    
  156.     #ifdef DEBUG
  157.       Serial.println("Config reset");  //  "Сброс настроек"
  158.     #endif
  159. }
  160.  
  161. /**
  162. * Функция read_EEPROM_Settings.
  163. * Эта функция используется, чтобы прочесть настройки EEPROM при запуске Arduino.
  164. *
  165. * Краткое описание:
  166. * - Выставляет контакт, к которому подключена кнопка Reset,
  167. *   в положение INPUT, а затем активирует подтягивающие резисторы.
  168. * - Загружает и сохраняет данные из EEPROM в структуру (struct) eeprom_config.
  169. * - Проверяет, загружены ли настройки и нажата ли кнопка Reset.
  170. *   Если какое-то из этих условий соблюдено, она выставляет
  171. *   настройки по умолчанию.
  172. */
  173. void read_EEPROM_Settings() {
  174.   pinMode(RESET_PIN, INPUT);
  175.   digitalWrite(RESET_PIN, HIGH);
  176.  
  177.   // считываем текущие настройки:
  178.   EEPROM_readAnything(0, eeprom_config);
  179.  
  180.   // проверяем, загружены ли настройки и нажата ли кнопка Reset:
  181.   if (eeprom_config.config_set != 1 || digitalRead(RESET_PIN) == LOW) {
  182.     // выставляем настройки по умолчанию:
  183.     set_EEPROM_Default();
  184.    
  185.     // записываем настройки на EEPROM:
  186.     EEPROM_writeAnything(0, eeprom_config);
  187.   }
  188. }
  189.  
  190. /**
  191. * Функция print_EEPROM_Settings().
  192. *
  193. * Эта функция используется для отладки настроек. Она через
  194. * последовательную коммуникацию выводит данные о текущих настройках
  195. * на монитор порта.
  196. */
  197. #ifdef DEBUG
  198. void print_EEPROM_Settings() {
  199.     Serial.print("IP: ");  // "IP-адрес: "
  200.     for(int i = 0; i<4; i++) {
  201.       Serial.print(eeprom_config.ip[i]);
  202.       if (i<3) {
  203.         Serial.print('.');
  204.       }
  205.     }
  206.     Serial.println();
  207.  
  208.     Serial.print("Subnet: ");  // "Маска подсети: "
  209.     for(int i = 0; i<4; i++) {
  210.       Serial.print(eeprom_config.subnet[i]);
  211.       if (i<3) {
  212.         Serial.print('.');
  213.       }
  214.     }
  215.     Serial.println();
  216.    
  217.     Serial.print("Gateway: ");  // "Сетевой шлюз: "
  218.     for(int i = 0; i<4; i++) {
  219.       Serial.print(eeprom_config.gateway[i]);
  220.       if (i<3) {
  221.         Serial.print('.');
  222.       }
  223.     }
  224.     Serial.println();
  225.  
  226.     Serial.print("DNS Server: ");  // "DNS-сервер: "
  227.     for(int i = 0; i<4; i++) {
  228.       Serial.print(eeprom_config.dns_server[i]);
  229.       if (i<3) {
  230.         Serial.print('.');
  231.       }
  232.     }
  233.     Serial.println();
  234.    
  235.     Serial.print("MAC: ");  // "Mac-адрес: "
  236.     for (int a=0;a<6;a++) {
  237.       Serial.print(eeprom_config.mac[a],HEX);
  238.       if(a<5) {
  239.         Serial.print(":");
  240.       }
  241.     }
  242.     Serial.println();
  243.    
  244.     Serial.print("Webserver Port: ");  // "Порт веб-сервера: "
  245.     Serial.println(eeprom_config.webserverPort);
  246.    
  247.     Serial.print("USE DHCP: ");  // "Использование DHCP: "
  248.     Serial.println(eeprom_config.use_dhcp);
  249.    
  250.     Serial.print(" DHCP renew every ");  // " Обновление DHCP каждые: "
  251.     Serial.print(eeprom_config.dhcp_refresh_minutes);
  252.     Serial.println(" minutes");  // " минут"
  253.    
  254.     Serial.print("Config Set: ");  // "Настройки: "
  255.     Serial.println(eeprom_config.config_set);
  256.  
  257. }
  258. #endif
  259.  
  260. // #############################################################################################################################################################
  261.  
  262.  
  263. /* ЗАПУСК СОЕДИНЕНИЯ #######################################################################################################################################
  264. * Код для настройки сетевого соединения
  265. */
  266. unsigned long last_dhcp_renew;
  267. byte dhcp_state;
  268.  
  269. /**
  270. * Функция renewDHCP().
  271. * Обновляем аренду DHCP через заданный промежуток времени.
  272. *
  273. * Краткое описание:
  274. * - Если interval содержит значение «0», выставляет его на «1».
  275. * - Проверяет, не закончилось ли время в интервале, и если закончилось, обновляет аренду DHCP.
  276. */
  277. void renewDHCP(int interval) {
  278.   unsigned long interval_millis = interval * 60000;
  279.  
  280.   if (interval == 0 ) {
  281.      interval = 1;
  282.   }
  283.   if (eeprom_config.use_dhcp==1) {
  284.     if((millis() - last_dhcp_renew) >  interval_millis) {
  285.       last_dhcp_renew=millis();
  286.       dhcp_state = Ethernet.maintain();
  287.     }
  288.   }
  289. }
  290.  
  291.  
  292. /**
  293. * Функция setupNetwork()
  294. * Эта функция используется, чтобы настроить сеть в соответствии
  295. * с настройками, хранящимися в EEPROM.
  296. *
  297. *   Краткое описание:
  298. * - Сначала считывает настройки, находящиеся в EEPROM.
  299. * - Показывает текущие Ethernet-настройки.
  300. * - Проверяет, используется ли DHCP. Если нет, создает экземпляры
  301. *   IPAddress для IP-адреса (ip), сетевого шлюза (gateway), маски
  302. *   подсети (subnet) и DNS-сервера (dns_server). Затем вызывает
  303. *   функцию Ethernet.begin() со всеми этими параметрами:
  304. *   Ethernet.begin(mac, ip, dns_server, gateway, subnet);.
  305. * - Если DHCP используется, тоже вызываем Ethernet.begin(), но
  306. *   используем только MAC-адрес (mac), а затем показываем IP через
  307. *   монитор порта.
  308. */
  309. void setupNetwork() {
  310.   read_EEPROM_Settings();
  311.  
  312.   #ifdef DEBUG
  313.    print_EEPROM_Settings();
  314.   #endif
  315.  
  316.  // byte mac[] = { eeprom_config.mac[0], eeprom_config.mac[1], eeprom_config.mac[2], eeprom_config.mac[3], eeprom_config.mac[4], eeprom_config.mac[5] };  
  317.  
  318.   if (eeprom_config.use_dhcp != 1) {
  319.     IPAddress ip(eeprom_config.ip[0], eeprom_config.ip[1], eeprom_config.ip[2], eeprom_config.ip[3]);                                              
  320.     IPAddress gateway (eeprom_config.gateway[0],eeprom_config.gateway[1],eeprom_config.gateway[2],eeprom_config.gateway[3]);                      
  321.     IPAddress subnet  (eeprom_config.subnet[0], eeprom_config.subnet[1], eeprom_config.subnet[2], eeprom_config.subnet[3]);  
  322.     IPAddress dns_server  (eeprom_config.dns_server[0], eeprom_config.dns_server[1], eeprom_config.dns_server[2], eeprom_config.dns_server[3]);
  323.     Ethernet.begin(eeprom_config.mac, ip, dns_server, gateway, subnet);
  324.   } else {
  325.     if (Ethernet.begin(eeprom_config.mac) == 0) {
  326.       Serial.print("Failed to configure Ethernet using DHCP");  //  "Не удалось настроить Ethernet при помощи DHCP"
  327.     }
  328.     Serial.println(Ethernet.localIP());
  329.   }
  330. }
  331. // ЗАВЕРШЕНИЕ СОЕДИНЕНИЯ #########################################################################################################################################
  332.  
  333. /* Секция для веб-сервера #######################################################################################################################################
  334. * Код для веб-сервера
  335. */
  336.  
  337. #ifdef USE_SYSTEM_LIBRARY
  338. #include "system.h"
  339. System sys;
  340. #endif
  341.  
  342. /* Сохраняем все строки во FLASH-памяти, чтобы освободить
  343.  * ресурсы SRAM-памяти. Функция P() – из библиотеки Arduino.
  344.  */
  345. P(Page_start) = "<html><head><title>Web_EEPROM_Setup</title></head><body>\n";
  346. P(Page_end) = "</body></html>";
  347.  
  348. P(Http400) = "HTTP 400 - BAD REQUEST";
  349. P(Index) = "<h1>index.html</h1><br>This is your main site!<br>The code is found in the indexHTML() function.<br>You can add more sites if you need. Please see the well documented source code.<br><br>Use the following link to setup the network.<br><a href=\"setupNet.html\">NETWORK SETUP</a>";
  350. //  "Это главная страница. Ее код находится в функции indexHTML(). По желанию можно добавить больше страниц (см. исходный код). Для настройки сети используйте следующую ссылку: setupNet.html\"
  351.  
  352. P(Form_eth_start) = "<FORM action=\"setupNet.html\" method=\"get\">";
  353. P(Form_end) = "<FORM>";
  354. P(Form_input_send) = "<INPUT type=\"submit\" value=\"Set config\">";
  355.  
  356. P(Form_input_text_start) = "<input type=\"text\" name=\"";
  357. P(Form_input_value)  = "\" value=\"";
  358. P(Form_input_size2) = "\" maxlength=\"2\" size=\"2";
  359. P(Form_input_size3) = "\" maxlength=\"3\" size=\"3";
  360. P(Form_input_end) = "\">\n";
  361.  
  362. P(MAC) = "MAC address: ";  //  "MAC-адрес: "
  363. P(IP) = "IP address: ";  //  "IP-адрес: "
  364. P(SUBNET) = "Subnet: ";  //  "Маска подсети: "
  365. P(GW) = "GW address: ";  //  "Адрес сетевого шлюза: "
  366. P(DNS_SERVER) = "DNS server: ";  //  "DNS-сервер: "
  367. P(WEB_PORT) = "Webserver port (1-65535): ";  //  "Порт веб-сервера (1-65535): "
  368. P(DHCP_ACTIVE) = "Use DHCP: ";  //  "Использование DHCP: "
  369. P(DHCP_REFRESH) = "Renew interval for DHCP in minutes (1 - 255): ";  //  "Интервал обновления для DHCP в минутах (1-255): "
  370.  
  371. P(Form_cb) = "<input type=\"radio\" name=\"23\" value=\"";
  372. P(Form_cb_checked) = " checked ";
  373. P(Form_cb_on) = ">On";
  374. P(Form_cb_off) = ">Off";
  375.  
  376. P(br) = "<br>\n";
  377.  
  378. P(table_start) = "<table>";
  379. P(table_tr_start) = "<tr>";
  380. P(table_tr_end) = "</tr>";
  381. P(table_td_start) = "<td>";
  382. P(table_td_end) = "</td>";
  383. P(table_end) = "</table>";
  384.  
  385. P(Config_set) = "<font size=\"6\" color=\"red\">New configuration stored! <br>Please turn off and on your Arduino or use the reset button!</font><br>";  //  "Новые настройки сохранены. Пожалуйста, включите и выключите Arduino или нажмите на кнопку Reset."
  386.  
  387. P(DHCP_STATE_TIME) = "DHCP last renew timestamp (sec)";  //  "Время последнего обновления DHCP (сек)"
  388. P(DHCP_STATE) = "DHCP renew return code (sec)";  //  "Статус обновления DHCP (сек)"
  389.  
  390. P(UPTIME) = "Uptime: ";  //  "Время работы Arduino"
  391.  
  392. #ifdef USE_SYSTEM_LIBRARY
  393. P(RAM_1) = "RAM (byte): ";
  394. P(RAM_2) = " free of ";
  395. #endif
  396.  
  397. /* Создаем указатель к экземпляру веб-сервера. */
  398. WebServer * webserver;
  399.  
  400.  
  401. /**
  402. * Функция indexHTML()
  403. * Эта функция используется для отправки клиенту index.html.
  404. */
  405. void indexHTML(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
  406. {
  407.   /* эта строчка отправляет браузеру стандартное сообщение, что запрос был успешным.*/
  408.   server.httpSuccess();
  409.  
  410.   /* Если получили GET или POST, то показываем данные.
  411.      Если получили HEAD request, останавливаемся после
  412.      показа заголовков */
  413.    if (type == WebServer::HEAD)
  414.     return;
  415.    
  416.   server.printP(Page_start);
  417.  
  418.   server.printP(Index);
  419.  
  420.   server.printP(Page_end);
  421.    
  422. }
  423.  
  424. /**
  425. * Функция setupNetHTML()
  426. * Эта функция отправляет клиенту setupNet.html
  427. *
  428. * Краткое описание:
  429. * - Отправляет ответ «200 OK».
  430. * - Если параметры GET присутствуют, присваивает их соответствующим переменным в структуре (struct) eeprom_config.
  431. * - Показывает настройки.
  432. *
  433. * Параметры – это простые числа. Название параметра конвертируется
  434. * в данные типа int при помощи функции atoi(). Это позволяет
  435. * оптимизировать код в настройке адресов IP и MAC.
  436. */
  437. #define NAMELEN 5
  438. #define VALUELEN 7
  439. void setupNetHTML(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
  440. {
  441.   URLPARAM_RESULT rc;  
  442.   char name[NAMELEN];  
  443.   char value[VALUELEN];
  444.   boolean params_present = false;
  445.   byte param_number = 0;
  446.  
  447.   /* эта строчка отправляет браузеру стандартное сообщение, что запрос был успешным.*/
  448.   server.httpSuccess();
  449.  
  450.   /* Если получили GET или POST, то показываем данные.
  451.      Если получили запрос HEAD, останавливаемся после
  452.      показа заголовков */
  453.   if (type == WebServer::HEAD)
  454.     return;
  455.  
  456.   server.printP(Page_start);
  457.  
  458.   // проверяем параметры:
  459.   if (strlen(url_tail)) {
  460.     while (strlen(url_tail)) {
  461.       rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
  462.       if (rc != URLPARAM_EOS) {
  463.         params_present=true;
  464.         // отладочная информация для параметров:
  465.         #ifdef DEBUG
  466.         Serial.print(name);
  467.         server.print(name);
  468.         Serial.print(" - ");
  469.         server.print(" - ");
  470.         Serial.println(value);
  471.         server.print(value);
  472.         server.print("<br>");
  473.         #endif
  474.        
  475.        
  476.         param_number = atoi(name);
  477.  
  478.         // считываем MAC-адрес:
  479.         if (param_number >=0 && param_number <=5) {
  480.           eeprom_config.mac[param_number]=strtol(value,NULL,16);
  481.         }
  482.    
  483.         // считываем IP-адрес:
  484.         if (param_number >=6 && param_number <=9) {
  485.           eeprom_config.ip[param_number-6]=atoi(value);
  486.         }
  487.    
  488.         // считываем маску подсети:
  489.         if (param_number >=10 && param_number <=13) {
  490.           eeprom_config.subnet[param_number-10]=atoi(value);
  491.         }
  492.    
  493.         // считываем сетевой шлюз:
  494.         if (param_number >=14 && param_number <=17) {
  495.           eeprom_config.gateway[param_number-14]=atoi(value);
  496.         }
  497.    
  498.         // считываем DNS-сервер:
  499.         if (param_number >=18 && param_number <=21) {
  500.           eeprom_config.dns_server[param_number-18]=atoi(value);
  501.         }
  502.        
  503.         // считываем порт веб-сервера:
  504.         if (param_number == 22) {
  505.           eeprom_config.webserverPort=atoi(value);
  506.         }
  507.        
  508.         // считываем, используется DHCP или нет:
  509.         if (param_number == 23) {
  510.           eeprom_config.use_dhcp=atoi(value);
  511.         }
  512.    
  513.         // считываем интервал обновления DHCP:
  514.         if (param_number == 24) {
  515.           eeprom_config.dhcp_refresh_minutes=atoi(value);
  516.         }
  517.       }
  518.     }
  519.     EEPROM_writeAnything(0, eeprom_config);
  520.   }
  521.  
  522.   // показываем форму:
  523.   server.printP(Form_eth_start);
  524.  
  525.   if(params_present==true) {
  526.      server.printP(Config_set);
  527.   }
  528.    
  529.   server.printP(table_start);
  530.  
  531.   // показываем текущий MAC-адрес:
  532.   server.printP(table_tr_start);
  533.   server.printP(table_td_start);
  534.   server.printP(MAC);
  535.   server.printP(table_td_end);
  536.   server.printP(table_td_start);
  537.   for (int a=0;a<6;a++) {
  538.     server.printP(Form_input_text_start);
  539.     server.print(a);
  540.     server.printP(Form_input_value);
  541.     server.print(eeprom_config.mac[a],HEX);
  542.     server.printP(Form_input_size2);    
  543.     server.printP(Form_input_end);
  544.   }
  545.   server.printP(table_td_end);
  546.   server.printP(table_tr_end);
  547.  
  548.   // показываем текущий IP-адрес:
  549.   server.printP(table_tr_start);
  550.   server.printP(table_td_start);
  551.   server.printP(IP);
  552.   server.printP(table_td_end);
  553.   server.printP(table_td_start);    
  554.   for (int a=0;a<4;a++) {
  555.     server.printP(Form_input_text_start);
  556.     server.print(a+6);
  557.     server.printP(Form_input_value);
  558.     server.print(eeprom_config.ip[a]);
  559.     server.printP(Form_input_size3);
  560.     server.printP(Form_input_end);
  561.   }
  562.   server.printP(table_td_end);
  563.   server.printP(table_tr_end);
  564.  
  565.  
  566.   // показываем текущую маску подсети:
  567.   server.printP(table_tr_start);
  568.   server.printP(table_td_start);
  569.   server.printP(SUBNET);
  570.   server.printP(table_td_end);
  571.   server.printP(table_td_start);
  572.   for (int a=0;a<4;a++) {
  573.     server.printP(Form_input_text_start);
  574.     server.print(a+10);
  575.     server.printP(Form_input_value);
  576.     server.print(eeprom_config.subnet[a]);
  577.     server.printP(Form_input_size3);
  578.     server.printP(Form_input_end);
  579.   }
  580.   server.printP(table_td_end);
  581.   server.printP(table_tr_end);
  582.  
  583.   // показываем текущий сетевой шлюз:
  584.   server.printP(table_tr_start);
  585.   server.printP(table_td_start);
  586.   server.printP(GW);
  587.   server.printP(table_td_end);
  588.   server.printP(table_td_start);
  589.   for (int a=0;a<4;a++) {
  590.     server.printP(Form_input_text_start);
  591.     server.print(a+14);
  592.     server.printP(Form_input_value);
  593.     server.print(eeprom_config.gateway[a]);
  594.     server.printP(Form_input_size3);
  595.     server.printP(Form_input_end);
  596.   }
  597.   server.printP(table_td_end);
  598.   server.printP(table_tr_end);
  599.  
  600.   // показываем текущий DNS-сервер:
  601.   server.printP(table_tr_start);
  602.   server.printP(table_td_start);
  603.   server.printP(DNS_SERVER);
  604.   server.printP(table_td_end);
  605.   server.printP(table_td_start);
  606.   for (int a=0;a<4;a++) {
  607.     server.printP(Form_input_text_start);
  608.     server.print(a+18);
  609.     server.printP(Form_input_value);
  610.     server.print(eeprom_config.dns_server[a]);
  611.     server.printP(Form_input_size3);
  612.     server.printP(Form_input_end);
  613.   }
  614.   server.printP(table_td_end);
  615.   server.printP(table_tr_end);
  616.  
  617.  
  618.   // показываем текущий порт веб-сервера:
  619.   server.printP(table_tr_start);
  620.   server.printP(table_td_start);
  621.   server.printP(WEB_PORT);
  622.   server.printP(table_td_end);
  623.   server.printP(table_td_start);
  624.   server.printP(Form_input_text_start);
  625.   server.print(22);
  626.   server.printP(Form_input_value);
  627.   server.print(eeprom_config.webserverPort);
  628.   server.printP(Form_input_end);
  629.   server.printP(table_td_end);
  630.   server.printP(table_tr_end);
  631.  
  632.   // показываем текущие настройки DHCP:
  633.   server.printP(table_tr_start);
  634.   server.printP(table_td_start);
  635.   server.printP(DHCP_ACTIVE);
  636.   server.printP(table_td_end);
  637.   server.printP(table_td_start);
  638.   server.printP(Form_cb);
  639.   server.print("0\"");
  640.    if(eeprom_config.use_dhcp != 1) {
  641.     server.printP(Form_cb_checked);
  642.   }
  643.   server.printP(Form_cb_off);  
  644.  
  645.   server.printP(Form_cb);
  646.   server.print("1\"");
  647.   if(eeprom_config.use_dhcp == 1) {
  648.     server.printP(Form_cb_checked);
  649.   }
  650.   server.printP(Form_cb_on);  
  651.   server.printP(table_td_end);
  652.   server.printP(table_tr_end);
  653.  
  654.   // показываем последнее время обновления DHCP:
  655.   server.printP(table_tr_start);
  656.   server.printP(table_td_start);
  657.   server.printP(DHCP_REFRESH);
  658.   server.printP(table_td_end);
  659.   server.printP(table_td_start);
  660.   server.printP(Form_input_text_start);
  661.   server.print(24);
  662.   server.printP(Form_input_value);
  663.   server.print(eeprom_config.dhcp_refresh_minutes);
  664.   server.printP(Form_input_size3);
  665.   server.printP(Form_input_end);
  666.   server.printP(table_td_end);
  667.   server.printP(table_tr_end);
  668.  
  669.   // показываем статус DHCP:
  670.   if(eeprom_config.use_dhcp == 1) {
  671.     server.printP(table_tr_start);
  672.     server.printP(table_td_start);     
  673.     server.printP(DHCP_STATE);
  674.     server.printP(table_td_end);
  675.     server.printP(table_td_start);
  676.     server.print(dhcp_state);
  677.     server.printP(table_td_end);
  678.     server.printP(table_tr_end);
  679.          
  680.     server.printP(table_tr_start);
  681.     server.printP(table_td_start);     
  682.     server.printP(DHCP_STATE_TIME);
  683.     server.printP(table_td_end);
  684.     server.printP(table_td_start);
  685.     server.print(last_dhcp_renew/1000);
  686.     server.printP(table_td_end);
  687.     server.printP(table_tr_end);
  688.   }
  689.  
  690.   #ifdef USE_SYSTEM_LIBRARY
  691.   // показываем время работы Arduino:
  692.   server.printP(table_tr_start);
  693.   server.printP(table_td_start);       
  694.   server.printP(UPTIME);
  695.   server.printP(table_td_end);
  696.   server.printP(table_td_start);
  697.   server.print(sys.uptime());
  698.   server.printP(table_td_end);
  699.   server.printP(table_tr_end);
  700.  
  701.   server.printP(table_tr_start);
  702.   server.printP(table_td_start);
  703.   server.printP(RAM_1);
  704.   server.print(sys.ramFree());
  705.   server.printP(RAM_2);
  706.   server.print(sys.ramSize());
  707.   server.printP(table_td_end);
  708.   server.printP(table_tr_end);
  709.   #endif
  710.  
  711.   server.printP(table_end);
  712.  
  713.   // показываем кнопку отправки:
  714.   server.printP(Form_input_send);    
  715.   server.printP(Form_end);
  716.    
  717.   server.printP(Page_end);
  718.  
  719. }
  720.  
  721. /**
  722. * Функция errorHTML()
  723. * Эта функция вызывается всякий раз, когда запрашивается
  724. * несуществующая страница. Она отправляет HTTP-заголовок
  725. * «400 Bad Request» и то же самое текстом.
  726. */
  727. void errorHTML(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
  728. {
  729.   /* Эта строчка отправляет браузеру стандартный HTTP-заголовок «HTTP 400 Bad Request» */
  730.   server.httpFail();
  731.  
  732.   /* Если получили GET или POST, то показываем данные.
  733.      Если получили запрос HEAD, останавливаемся после
  734.      показа заголовков */
  735.   if (type == WebServer::HEAD)
  736.     return;
  737.    
  738.   server.printP(Http400);
  739.  
  740.   server.printP(Page_end);
  741. }
  742.  
  743. // ЗАВЕРШАЮЩИЙ КОД ######################################################################################################################################################
  744.  
  745. /*
  746. * Функция setup()
  747. * Эта функция вызывается всякий раз, когда включается Arduino.
  748. */
  749. void setup()
  750. {
  751.   Serial.begin(SERIAL_BAUD);
  752.  
  753.   /* Инициализируем Ethernet-модуль с настройками из EEPROM */
  754.   delay(200); // небольшая задержка, чтобы система успела сделать все свои дела
  755.   setupNetwork();
  756.   delay(200); // аналогично
  757.  
  758.   #define PREFIX ""
  759.   webserver = new WebServer(PREFIX, eeprom_config.webserverPort);
  760.  
  761.   /* задаем команду, которая будет вызываться по умолчанию,
  762.   /* когда пользователь будет запрашивать доступ к корню сервера
  763.   */
  764.   webserver->setDefaultCommand(&indexHTML);
  765.  
  766.   /* задаем команду, которая будет вызываться по умолчанию,
  767.   /* когда пользователь запросит доступ к несуществующей странице
  768.   */
  769.   webserver->setFailureCommand(&errorHTML);
  770.  
  771.   /* запускаем команду indexHTML, если пользователь пытается загрузить страницу /index.html */
  772.   webserver->addCommand("index.html", &indexHTML);
  773.  
  774.   /* Показываем форму сетевых настроек. Сами настройки хранятся в EEPROM */
  775.   webserver->addCommand("setupNet.html", &setupNetHTML);
  776.  
  777.   /* Запускаем веб-сервер */
  778.   webserver->begin();
  779. }
  780.  
  781. /**
  782. * Функция loop()
  783. * Будет работать вечно...
  784. *
  785. * Краткое описание:
  786. * - Обновляет аренду DHCP
  787. * - Обслуживает веб-клиентов
  788. *
  789. */
  790. void loop()
  791. {
  792.   // обновляем аренду DHCP:
  793.   renewDHCP(eeprom_config.dhcp_refresh_minutes);
  794.  
  795.   char buff[200];
  796.   int len = 200;
  797.  
  798.   /* Вечно обрабатываем входящие соединения (одновременно может обрабатываться только одно соединение) */
  799.   webserver->processConnection(buff, &len);
  800. }

См.также

Внешние ссылки

  1. github.com - Web_Net_Setup.pde