Как сделать сервер для ардуино

Создание веб-сервера ESP8266 — код и схемы

Этот проект представляет собой пошаговое руководство, в котором показано, как создать автономный веб-сервер ESP8266, который управляет двумя выходами (два светодиода). Веб-сервер ESP8266 контролируется мобильными устройствами, и к нему можно получить доступ с любого устройства с браузером в локальной сети.

Если вы хотите узнать больше о модуле ESP8266, сначала прочтите мое Руководство по началу работы с модулем WiFi ESP8266.

В данном руководстве рассматриваются два разных метода построения веб-сервера:

  • Часть 1. Создание веб-сервера с использованием Arduino IDE
  • Часть 2. Создание веб-сервера с помощью NodeMCU

ЧАСТЬ 1: СОЗДАЙТЕ ВЕБ-СЕРВЕР, ИСПОЛЬЗУЯ ARDUINO IDE

В этой части показано, как создать веб-сервер для управления двумя выходами с помощью Arduino IDE. Вы можете использовать этот метод для создания другого веб-сервера для удовлетворения ваших потребностей.

Подготовьте IDE Arduino

1. Загрузите и установите Arduino IDE в вашей операционной системе (некоторые старые версии не будут работать).

2. Затем вам необходимо установить дополнение ESP8266 для Arduino IDE. Для этого перейдите в File> Preferences.

3. Введите http://arduino.esp8266.com/stable/package_esp8266com_index.json в поле «Additional boards manager urls», как показано на рисунке ниже. Затем нажмите кнопку «ОК».

4. Перейдите в Инструменты > Платы > Менеджер плат…

5. Прокрутите вниз, выберите пункт меню платы ESP8266 и установите «плату esp8266», как показано на рисунке ниже.

6. Перейдите в Инструменты > Плата и выберите свою плату ESP8266. Затем снова откройте вашу Arduino IDE.

Скопируйте приведенный ниже код в вашу Arduino IDE, но пока не загружайте его. Вам нужно внести некоторые изменения, чтобы он работал у вас.

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

Загрузка скетча

Загрузка скетча в ESP-12E

Если вы используете ESP-12E NodeMCU Kit, загрузка скетча очень проста, поскольку в нем есть встроенный программатор. Подключите вашу плату к компьютеру. Убедитесь, что вы выбрали правильную плату и COM-порт.

Затем нажмите кнопку «Загрузить» в IDE Arduino и подождите несколько секунд, пока не увидите сообщение «Закончена загрузка» в левом нижнем углу.

Загрузка скетча в ESP-01

Загрузка кода в ESP-01 требует установления последовательного соединения между вашим ESP8266 и программатором FTDI, как показано на схематической диаграмме ниже.

В следующей таблице показаны соединения, которые необходимо установить между ESP8266 и программатором FTDI.

ESP8266 FTDI programmer
RX TX
TX RX
CH_PD 3.3V
GPIO 0 GND
VCC 3.3V
GND GND

Если у вас новый программатор FTDI, и вам нужно установить драйверы FTDI на ПК с Windows, посетите официальный веб-сайт для получения официальных драйверов. Кроме того, вы можете связаться с продавцом, который продал вам программатор FTDI.

Затем вам просто нужно подключить программатор FTDI к вашему компьютеру и загрузить код в ESP8266.

Schematics

Для построения схемы вам понадобятся следующие детали:

  • ESP8266 12-E
  • Платы для разработки Wi-Fi
  • 2 светодиода
  • 2 резистора (220 или 330 Ом подойдут)
  • макетная плата
  • Перемычки

Если вы используете ESP-01, вам также нужен программатор FTDI.

Подключите два светодиода к ESP8266, как показано на следующей принципиальной схеме — один светодиод подключен к GPIO 4 (D2), а другой к GPIO 5 (D1).

Если вы используете ESP-01 .

Если вы используете ESP8266-01, используйте следующую схему в качестве справки, но вам нужно изменить назначение GPIO в коде (на GPIO 2 и GPIO 0).

Тестирование веб-сервера

Теперь вы можете загрузить код, и он сразу заработает. Не забудьте проверить, правильно ли выбрана плата и COM-порт, в противном случае вы получите ошибку при попытке загрузки. Откройте последовательный монитор со скоростью 115200 бод.

Нахождение IP-адреса ESP

Нажмите кнопку сброса ESP8266, и он выведет IP-адрес ESP на последовательный монитор

Скопируйте этот IP-адрес, потому что он нужен вам для доступа к веб-серверу.

Доступ к веб-серверу

Откройте браузер, введите IP-адрес ESP, и вы увидите следующую страницу. Эта страница отправляетсяESP8266, когда вы посылаете запрос на IP-адрес ESP.

Если вы посмотрите на последовательный монитор, вы можете увидеть, что происходит в фоне. ESP получает HTTP-запрос от нового клиента — в данном случае, вашего браузера.

Вы также можете увидеть другую информацию о HTTP-запросе — эти поля называются полями HTTP-заголовка и определяют рабочие параметры HTTP-запроса.

Тестирование веб-сервера

Давайте проверим веб-сервер. Нажмите кнопку, чтобы включить GPIO 5. ESP получает запрос по URL-адресу / 5 / и включает светодиод 5.

Состояние светодиода также обновляется на веб-странице.

Проверьте кнопку GPIO 4 и убедитесь, что она работает аналогичным образом.

Как работает код

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

Первое, что вам нужно сделать, это включить библиотеку ESP8266WiFi.

Как упоминалось ранее, вам нужно вставить свой ssid и пароль в следующие строки внутри двойных кавычек.

Затем вы устанавливаете свой веб-сервер на порт 80.

Следующая строка создает переменную для хранения заголовка HTTP-запроса:

Затем вы создаете вспомогательные переменные для хранения текущего состояния ваших выходных данных. Если вы хотите добавить больше выходных данных и сохранить их состояние, вам нужно создать больше переменных.

Вам также необходимо назначить GPIO каждому из ваших выходов. Здесь мы используем GPIO 4 и GPIO 5. Вы можете использовать любые другие подходящие GPIO.

Настройка

Теперь перейдем к настройке. Функция setup () запускается только один раз при первой загрузке ESP. Сначала мы запускаем последовательную связь со скоростью 115200 бод для целей отладки.

Вы также определяете свои GPIO как ВЫХОДЫ и устанавливаете их в LOW.

Следующие строки начинают соединение Wi-Fi с WiFi.begin (ssid, пароль), ожидают успешного соединения и печатают IP-адрес ESP в Serial Monitor.

В loop() мы программируем то, что происходит, когда новый клиент устанавливает соединение с веб-сервером.

ESP всегда прослушивает входящих клиентов этой строкой:

Когда запрос получен от клиента, мы сохраним входящие данные. Последующий цикл while будет работать до тех пор, пока клиент остается подключенным. Мы не рекомендуем менять следующую часть кода, если вы точно не знаете, что делаете.

Следующий раздел операторов if и else проверяет, какая кнопка была нажата на вашей веб-странице, и соответственно контролирует результаты. Как мы видели ранее, мы делаем запрос на разные URL в зависимости от кнопки, которую нажимаем.

Например, если вы нажали кнопку GPIO 5 ON, URL-адрес изменится на IP-адрес ESP, а затем / 5 / ON, и мы получим эту информацию в заголовке HTTP. Итак, мы можем проверить, содержит ли заголовок выражение GET / 5 / on.

Если он содержится, код печатает сообщение на последовательном мониторе, изменяет значение переменной output5State на on и включает светодиод.

Это работает аналогично для других кнопок. Поэтому, если вы хотите добавить больше выходных данных, вы должны изменить эту часть кода, чтобы включить их.

Отображение веб-страницы HTML

Следующее, что вам нужно сделать, это создать веб-страницу. ESP отправит в ваш браузер ответ с текстом HTML для отображения веб-страницы.

Веб-страница отправляется клиенту с помощью функции client.println (). Вы должны ввести то, что вы хотите отправить клиенту в качестве аргумента.

Первый текст, который вы всегда должны отправлять, — это следующая строка, которая указывает, что мы отправляем HTML.

Затем следующая строка делает веб-страницу отзывчивой в любом веб-браузере.

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

Стилизация веб-страницы

Далее у нас есть немного CSS для стилизации кнопок и внешнего вида веб-страницы. Мы выбираем шрифт Helvetica, определяем содержимое, которое будет отображаться в виде блока и выравниваться по центру.

Настройка заголовка веб-страницы

В следующей строке вы устанавливаете заголовок вашей веб-страницы, вы можете изменить этот текст на любой другой.

Отображение кнопок и соответствующего состояния

Затем вы пишете абзац для отображения текущего состояния GPIO 5. Как вы можете видеть, мы используем переменную output5State, поэтому состояние изменяется мгновенно при изменении этой переменной.

Затем мы отображаем кнопку включения или выключения, в зависимости от текущего состояния GPIO.

Мы используем ту же процедуру для GPIO 4.

Закрытие соединения

Наконец, когда ответ заканчивается, мы очищаем переменную заголовка и прекращаем соединение с клиентом с помощью client.stop ().

Завершение

Теперь, когда вы знаете, как работает код, вы можете изменить код, чтобы добавить дополнительные выходные данные или изменить свою веб-страницу. Чтобы изменить свою веб-страницу, вам может понадобиться знание основ HTML и CSS. Вместо управления двумя светодиодами вы можете управлять реле для управления практически любыми электронными приборами.

ЧАСТЬ 2: СОЗДАНИЕ ВЕБ-СЕРВЕРА С ИСПОЛЬЗОВАНИЕМ NODEMCU

В этой части показано, как создать веб-сервер для управления двумя выходами с использованием прошивки NodeMCU и языка программирования LUA. Вы можете использовать этот метод для создания другого веб-сервера.

Источник

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 70. Протокол HTTP. Создание WEB-сервера на Ардуино. Использование HTML-кода.

Изучим протокол передачи гипертекста HTTP. Научимся разрабатывать WEB серверы в системе Ардуино. Покажу простой способ, как оформлять информацию для браузера с помощью HTML-редактора.

Обычно уроки я строю по принципу – даю формальное описание функций, методов, протоколов…, а затем, используя эту информацию, разрабатываю учебные проекты.

Информация о протоколе HTTP объемная. Что-то нам не пригодится, поэтому в этом уроке я решил все перемешать. Последовательно рассказывать о протоколе и тут же демонстрировать его применение на практике.

Я не претендую на полноту освещения этой объемной темы. Рассмотрю варианты использования HTTP протокола наиболее приемлемые для систем на базе Ардуино.

Общая информация.

HTTP — это протокол уровня приложений (высокого уровня) для передачи гипертекстовых документов.

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

Скорее это устаревшее определение HTTP. Сейчас по этому протоколу передается не только текстовая, а практически любая информация, в том числе картинки и фильмы. Правильнее сказать, что это протокол передачи гипермедиа данных.

В настоящее время HTTP используется сервисом World Wide Web (Всемирная Сеть) для получения информации с WEB-сайтов. На ваш компьютер информация с сайтов интернета попадает через именно этот протокол. И то, что вы читаете сейчас доставлено посредством HTTP.

Надо твердо помнить, что:

  • HTTP работает по технологии клиент-сервер. Клиент посылает запрос и получает в ответ информацию с сервера. В нашем случае:
    • клиентом является WEB-браузер на компьютере;
    • сервером – плата Ардуино с сетевым Ethernet-модулем ENC28j60.
  • Запрос будет формировать браузер, отвечать – удаленный сервер.
  • HTTP – протокол уровня приложений, т.е. приложение на компьютере (веб-браузер) обменивается данными с приложением на удаленном сервере (в нашем случае с резидентной программой Ардуино).
  • Обмен данными происходит через TCP-соединение.
  • Для создания WEB-сервера нет специальных функций библиотеки. Мы будем устанавливать TCP-соединение и через него передавать данные в формате HTTP.
  • Основной объект для HTTP протокола – это ресурс (URI – Uniform Resource Identifier ), который задается в запросе клиента. Обычно ресурсом являются файлы, расположенные на сервере, но может быть что угодно, даже нечто абстрактное. Для идентификации ресурсов используются глобальные идентификаторы URI, т.е. адреса Интернета.
  • Стандартным портом для HTTP считается порт 80.
  • Сама текстовая информация обычно передается на языке гипертекстовой разметки HTML.

Аппаратная часть, для которой мы будем разрабатывать программы в этом уроке, описывается в уроке 63 и была нами использована в уроках 64 и 69. Это плата Arduino UNO R3 и модуль ENC28J60 подключенный к роутеру прямым кабелем.

Структура протокола.

Клиент и сервер обмениваются сообщениями – блоками данных.

В общем виде обмен информацией происходит так:

  • клиент устанавливает с сервером TCP-соединение;
  • посылает на сервер сообщение-запрос;
  • в ответ получает сообщение-ответ;
  • дальше TCP-соединение может быть разорвано или ожидать новых блоков данных.

Каждое сообщение состоит из 3 частей:

  • Стартовая строка – задает тип сообщения.
  • Заголовки – дают серверу дополнительную информацию о запросе, о клиенте, параметры обмена и прочие технические сведения.
  • Тело сообщения – собственно данные, информация. Тело заголовка должно обязательно отделяться от предыдущих частей пустой строкой.

Тело сообщения может отсутствовать, особенно, в запросе клиента. А стартовая строка и заголовки должны присутствовать в любом сообщении.

Структура запроса.

Запрос это сообщение от клиента серверу.

Давайте напишем простую программу, позволяющую увидеть запросы клиента. Немного изменим первую программу из урока 64.

// TCP сервер, выводит полученные данные
#include
#include

EthernetServer server(80); // с оздаем сервер, порт 80
EthernetClient client; // объект клиент
boolean clientAlreadyConnected= false; // признак клиент уже подключен

void setup() <
Ethernet.begin(mac, ip); // инициализация контроллера
server.begin(); // включаем ожидание входящих соединений
Serial.begin(9600);
Serial.print(«Server address:»);
Serial.println(Ethernet.localIP()); // выводим IP-адрес контроллера
>

void loop() <
client = server.available(); // ожидаем объект клиент
if (client) <
// есть данные от клиента
if (clientAlreadyConnected == false) <
// сообщение о подключении
Serial.println(«Client connected»);
Serial.println(«»);
clientAlreadyConnected= true;
>

  • при запуске выводит IP-адрес сервера;
  • при установке TCP-соединения выдает сообщение;
  • выводит в монитор последовательного порта все, что поступает с клиента.

В строке адреса браузера наберем IP-адрес сервера (у меня 192.168.1.10).

Браузер пошлет HTTP-запрос на сервер. Мы увидим его в мониторе последовательного порта.

Стартовая строка.

Стартовая строка запроса имеет следующий формат:

МЕТОД URI HTTP/Версия

  • Метод – тип запроса.
  • URI – идентификатор ресурса. Определяет путь к запрашиваемому файлу.
  • Версия – разделенные точкой цифры.

В нашем случае: GET / HTTP/1.1

  • GET – метод.
  • / — URI. Мы обратились к серверу без указания дополнительных идентификаторов ресурса, т.е. просто по адресу 192.168.1.10.
  • HTTP/1.1 – версия HTTP.

Методы.

Методы это команды серверу. Они сообщают серверу, что он должен делать.

Состоят из любых символов, кроме управляющих и разделителей.

Методы чувствительны к регистру.

Система может использовать любые методы, даже не документированные в протоколе. Если сервер не распознал указанный метод, он должен вернуть код состояния 501. Если метод известен, но не может быть применим к указанному ресурсу, то возвращается код 405.

Любой сервер обязан обрабатывать методы GET и HEAD.

На практике востребованными являются только методы GET и POST. Мы будем использовать только эти запросы.

Метод Описание
GET Применяется для запроса содержимого ресурса. GET-запрос может запустить какой-либо процесс на сервере, информации о ходе выполнения которого обычно передается в ответном сообщении.

Через GET-запросы клиент может передавать параметры. Параметры отделятся от URI символом “?”. Параметры разделяются символом “&”.

GET /path/resourse?parameter1=value1& parameter2=value2 HTTP/1.1

HEAD Действие аналогично методу GET, за исключением того, что в ответе отсутствует тело сообщения.
POST Используется для передачи данных ресурсу. Например, комментарии к записям сайта или заполнение регистрационных форм. Пользователь вводит текст в окне браузера, данные передаются на сервер и сохраняются там. Также, с помощью POST-метода на сервер загружаются файлы.

Передаваемые методом POST данные включаются в тело запроса.

В следующем уроки, при реализации методов GET и POST, я расскажу о них подробнее.

Заголовки.

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

Блок заголовков должен отделяться от тела сообщения хотя бы одной пустой строкой.

В нашем запросе блок заголовков выглядит так.

Host: 192.168.1.10
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7

Почти вся информация понятна без расшифровки.

Заголовки разделяются на 4 группы:

  • Основные – могут включаться в любое сообщение сервера и клиента.
  • Заголовки запроса – применяются только в запросах клиентов.
  • Заголовки ответа – используются только в ответах от серверов.
  • Заголовки сущности – используются для описания тела сообщения. Определяют вид представления информации конечному пользователю.

Если не хватает стандартных, то заголовки можно вводить свои.

Тело сообщения.

В запросе тело сообщения бывает только при использовании метода POST. Об этом в следующем уроке.

Структура ответа.

После получения и обработки запроса, сервер посылает клиенту ответ.

Стартовая строка ответа должна выглядеть так:

HTTP/ВЕРСИЯ КодСостояния Пояснения

  • Версия – разделенные точкой цифры.
  • Код состояния – число из 3 цифр. Говорит клиенту о результате выполнения запроса и определяет его дальнейшие действия. Набор кодов состояния описан в протоколе.
  • Пояснение – короткое текстовое пояснение кода состояния. Необязательное поле, не влияющее на действия клиента.

Стартовая строка ответа может выглядеть так:

Код состояния.

Представляет собой 3-значное число. Первая цифра определяет класс состояния.

Необязательный параметр стартовой строки ПОЯСНЕНИЕ разъясняет код состояния в коротком текстовом сочетании.

200 OK
102 Processing
202 Accepted
304 Not Modified
407 Proxy Authentication Required
500 Internal Server Error

По коду ответа клиент узнает о результатах его запроса и решает, какие действия предпринять.

Существует 5 классов кодов.

Код состояния Класс Назначение
1XX Информационный Информирование о процессе передачи данных.
2XX Успех Информирование об успешной обработке запроса клиента.
3XX Перенаправление Сообщает клиенту о необходимости сделать запрос по другому URI.
4XX Ошибка клиента Информирует об ошибках со стороны клиента.
5XX Ошибка сервера Информирует о неудачных операциях по вине сервера.

Тело сообщения.

Тело сообщение это собственно информация ресурса, которую запросил клиент. Кодировка и формат данных указывается в поле заголовков. Тело сообщений, предназначенных для браузеров, содержит HTML-код.

Конечно, это значительно сокращенная форма представления протокола HTTP. Но для наших целей вполне достаточно.

Создание простого WEB-сервера.

Для начала разработаем самый простой WEB-сервер, который по GET-запросу клиента будет передавать одну и ту же текстовую строку.

  • установить TCP-соединение;
  • принять запрос клиента;
  • выделить в нем пустую строку, те окончание блока заголовков (для простого GET-запроса это окончание запроса);
  • послать ответ клиенту;
  • разорвать соединение;
  • все операции запротоколировать в мониторе последовательного порта.

Вот скетч такого сервера.

// WEB сервер, передает клиенту текстовую строку
#include
#include

EthernetServer server(80); // создаем сервер, порт 80
EthernetClient client; // объект клиент

boolean flagEmptyLine = true; // признак строка пустая
char tempChar;

void setup() <
Ethernet.begin(mac, ip); // инициализация контроллера
server.begin(); // включаем ожидание входящих соединений
Serial.begin(9600);
Serial.print(«Server address:»);
Serial.println(Ethernet.localIP()); // выводим IP-адрес контроллера
Serial.print(«»);
>

void loop() <
client = server.available(); // ожидаем объект клиент
if (client) <
flagEmptyLine = true;
Serial.println(«New request from client:»);

while (client.connected()) <
if (client.available()) <
tempChar = client.read();
Serial.write(tempChar);

if (tempChar == ‘\n’ && flagEmptyLine) <
// пустая строка, ответ клиенту
client.println(«HTTP/1.1 200 OK»); // стартовая строка
client.println(«Content-Type: text/html; charset=utf-8»); // тело передается в коде HTML, кодировка UTF-8
client.println(«Connection: close»); // закрыть сессию после ответа
client.println(); // пустая строка отделяет тело сообщения
client.println(» «); // тело сообщения
client.println(» «);
client.println(«

Первый WEB-сервер

Загрузил скетч в плату.

Запустил браузер GoogleChrome.

Набрал адрес моего сервера 192.168.1.10. В браузере появилось сообщение.

Сообщение состояло из иероглифов, пока я не задал правильную кодировку строкой:

client.println(«Content-Type: text/html; charset=utf-8»); // тело передается в коде HTML, кодировка UTF-8

Ардуино для кириллических символов использует кодировку UTF-8. В большинстве браузеров по умолчанию другая кодировка.

Этот пример показывает, как заголовки влияют на отображение информации.

В мониторе последовательного порта видно, что появилось 2 запроса.

Вторым запросом Google Chrome пытается получить с сервера иконку favicon, чтобы отобразить ее рядом с информацией ресурса.

Я перешел на браузер Internet Explorer.

В нем только один запрос. Дальнейшие проверки я буду производить с веб-обозревателем Internet Explorer.

Более сложный WEB-сервер.

Первый вариант сервера выводит одну и ту же статичную информацию. Мы его создали для демонстрации принципа организации HTTP-обмена. Вряд ли он будет востребован на практике.

Но ничего не мешает в сообщении-ответе сервера передавать клиенту динамические данные. Например, состояние кнопок, измеренное на аналоговых входах напряжение, температуру и т.п.

Чтобы не подключать к плате Ардуино дополнительные элементы, давайте передадим клиенту значение функции millis(), т.е. время с момента включения сервера.

Заодно немного приукрасим текстовую информацию, которая появится в окне браузера.

Информация для браузера в теле сообщения обычно передается HTML-кодом. Это совершенно другая, очень объемная тема. На нее есть прекрасные уроки. Для разработки WEB-серверов необходимо знать основы HTML-языка. Я покажу, как упростить процесс создания HTML-сообщений.

Я предлагаю использовать HTML-редактор. В окне такого редактора вы набираете текст, задаете шрифты, размеры фрагментов, раскрашиваете их, полностью оформляете текстовую информацию. На выходе получаете HTML-код, который можете передавать клиенту.

Существует огромное количество простых и сложных, платных и бесплатных редакторов. Можете выбрать по своему вкусу. Чтобы не заниматься загрузкой и установкой, я использовал онлайн HTML-редактор Vulk. Он мне первым попался под руку.

Я создавал сервер в такой последовательности.

  • Запустил HTML-редактор http://vulk.ru/.
  • В меню выбрал Визуальный редактор.

  • Написал и раскрасил текстовую информацию. Оформить, конечно, можно было и красивее.

Число 34,56 – показатель времени я пока задал статическим.

  • Нажал закладку HTML в левом нижнем углу редактора.

Эти строчки надо передать клиенту.

Т.е. вставить их в тело сообщения.

client.println(» «); // тело сообщения
client.println(» «);
client.println(«

Символ “двойные кавычки” (“) используется в функции prrint() для задания строки. Поэтому кавычки внутри HTML-кода надо экранировать символом ”\”.

Другой вариант – подготовить текстовую строку и передать ее в функцию print() через указатель.

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

Пока проигнорируем и запустим браузер. Запросим сервер.

Мы получили статическое сообщение, оформленное нами в HTML-редакторе.

Беспокоит предупреждение при компиляции “Недостаточно памяти, программа может работать нестабильно.” Причина его понятна. Мы задали много текстовой информации в строках функции print() и почти заполнили всю оперативную память. А сообщения могут быть намного длиннее.

Выход – хранить текстовую информацию не в ОЗУ, а в FLASH памяти. У микроконтроллера ATmega 328 объем FLASH 32 кбайт, а ОЗУ всего 2 кбайт.

Это делается просто. Достаточно использовать макрос F() библиотеки pgmspace.h. Я писал о ней в уроке 27, но макроса F() не касался.

Так вот, если текстовую строку разместить в качестве аргумента макроса F(), то она будет сохранена в FLASH.

Serial.print(“test”); // строка ”test” размещается в ОЗУ
Serial.print(F(“test”)); // строка ”test” размещается в FLASH

Перепишем заголовки и тело сообщения с учетом вышесказанного.

client.println(F(«HTTP/1.1 200 OK»)); // стартовая строка
client.println(F(«Content-Type: text/html; charset=utf-8»)); // тело передается в коде HTML, кодировка UTF-8
client.println(F(«Connection: close»)); // закрыть сессию после ответа
client.println(); // пустая строка отделяет тело сообщения

client.println(F(» «)); // тело сообщения
client.println(F(» «));
client.println(F(«

Вот скетч полностью.

Теперь трансляция проходит без пугающих предупреждений. И оперативной памяти используется намного меньше, 1318 байт . В предыдущем варианте программы было 1696.

Здесь я вынужден сделать небольшое отступление. До последнего варианта программы все работало идеально. Как только я стал использовать в программе макрос F() сервер начал виснуть. На второе, третье обращение. Я убрал макрос и вставил несколько одинаковых строк с функцией println(). Сервер периодически зависал. Я заменил плату Arduino UNO R3, затем модуль ENC28j60. Ничего не помогало. Система заработала стабильно только после того, как я подключил модуль к плате Arduino Nano. Мощности стабилизатора платы 3,3 В для питания ENC28j60 явно не хватает. Поэтому я использовал внешний стабилизатор LD1117.

После этого все заработало идеально. К серверу по последнему варианту программы я сделал более 2000 запросов.

Я не стал разбираться в причине происходящего. Могу предположить, что либо не хватает пиковой мощности стабилизатора 3,3 В платы Arduino UNO, либо библиотека UIPEthernet не работает с этой платой. Если кто-то разберется в этом вопросе – напишите. Я добавлю эту информацию в урок. Можно создать тему на форуме сайта.

Дальнейшие испытания я производил на связке Arduino Nano — модуль ENC28j60.

Последний вариант сервера дает в ответе только статичное сообщение. Давайте часть строки ”34,56” заменим на вывод значения функции millis().

Функция millis() возвращает значение времени в мс, а нам надо в секундах. Сделаем простейшее преобразование.

client.print( (float)millis() /1000. ); // вывод времени в секундах

Разорвем длинную строку HTML кода и вместо 34,56 вставим вывод времени.

В итоге тело сообщения будет выглядеть так.

client.println(F(» «)); // тело сообщения
client.println(F(» «));
client.print(F(«

А весь скетч будет таким.

В браузере увидим время.

Можно добавить в заголовки ответа строку

client.println(F(«Refresh: 2»)); // обновить страницу автоматически

Тогда браузер будет сам обновлять страницу каждые 2 секунды.

В течение часа мой сервер отработал в таком режиме. Никаких сбоев, зависаний.

Работает сервер и при обращении с телефона.

В следующем уроке продолжим тему. Научимся передавать данные от клиента серверу с помощью GET и POST запросов. Разработаем простой WEB-клиент.

Источник

Adblock
detector