Выбрать главу

А теперь вернемся к функции sendBody. Вслед за таблицей со значениями аналоговых входов нужно послать разметку HTML с коллекцией раскрывающихся списков, соответствующих цифровым выходам. В каждом списке нужно выбрать пункт On (Включено) или Off (Выключено) в зависимости от текущего состояния цифрового выхода. Для этого нужно добавить текст «selected» в значение, соответствующее состоянию данного выхода в массиве pinStates.

Код разметки HTML для цифровых выходов заключается в форму, чтобы посетитель мог изменить значения в форме и, щелкнув на кнопке Update (Обновить), сгенерировать новый запрос к этой странице с соответствующими параметрами для установки цифровых выходов. А теперь посмотрим, как выглядит разметка HTML-страницы:

<html><body>

<hq>Analog Inputs</h1>

<table border='1'>

<tr><td>A0</td><td>0.58 V</td></tr>

<tr><td>A1</td><td>0.63 V</td></tr>

<tr><td>A2</td><td>0.60 V</td></tr>

<tr><td>A3</td><td>0.65 V</td></tr>

<tr><td>A4</td><td>0.60 V</td></tr>

</table>

<h1>Output Pins</h1>

<form method='GET'>

<p>Pin 3<select name='0'>

<option value='0'>Off</option>

<option value='1' selected>On</option>

</select></p>

<p>Pin 4<select name='1'>

<option value='0' selected >Off</option>

<option value='1'>On</option>

</select></p>

<p>Pin 5<select name='2'>

<option value='0' selected >Off</option>

<option value='1'>On</option>

</select></p>

<p>Pin 6<select name='3'>

<option value='0' selected >Off</option>

<option value='1'>On</option>

</select></p>

<p>Pin 7<select name='4'>

<option value='0' selected >Off</option>

<option value='1'>On</option>

</select></p>

<input type='submit'> value='Update'/>

</form>

</body></html>

Увидеть этот код можно, воспользовавшись функцией View Source (Исходный код страницы) в браузере.

Использование веб-службы JSON

Для иллюстрации возможности отправки веб-запросов из платы Arduino внешним веб-сайтам я воспользуюсь веб-службой, возвращающей данные о погоде в определенном географическом пункте. Плата будет выводить краткое описание погоды в монитор последовательного порта (рис. 12.6). Описываемый скетч посылает запрос один раз в момент запуска, но его нетрудно изменить, чтобы он запрашивал погоду каждый час и выводил результаты на двухстрочный жидкокристаллический дисплей.

Рис. 12.6. Получение информации о погоде от веб-службы

Скетч для этого примера получился очень коротким, всего 45 строк кода (sketch_12_03_web_request). Наибольший интерес для нас представляет функция hitWebPage:

void hitWebPage()

{

  if (client.connect("api.openweathermap.org", 80))

  {

    client.println("GET /data/2.5/weather?q=Manchester,uk HTTP/1.0");

    client.println();

    while (client.connected())

    {

      if (client.available())

      {

        client.findUntil("description\":\"", "\0");

        String description = client.readStringUntil('\"');

        Serial.println(description);

      }

    }

    client.stop();

  }

}

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

client.println("GET /data/2.5/weather?q=Manchester,uk HTTP/1.0");

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

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

{"coord":{"lon":-2.23743,"lat":53.480949},

"sys":{"country":"GB","sunrise":1371094771,

"sunset":1371155927},"weather":[{"id":520, "main":"Rain",

"description":"light intensity shower rain", "icon": "09d"}]

"humidity":87,"temp_min":283.15,"temp_max":285.93},

"wind":{"speed:5.1,"deg":270},"rain":{"1h":0.83},

"clouds":{"all":40},"dt":1371135000,"id":3643123,

"name":"Manchester","cod":200}

Функция hitWebPage с помощью функций findUntil и readStringUntil извлекает фрагмент текста, следующий за словом «description», с двоеточием и двойной кавычкой до следующей двойной кавычки.

Функция findUntil просто игнорирует все, пока не встретит указанную строку. Затем функция readStringUntil читает текст из потока, пока не встретит двойную кавычку.

Библиотека WiFi

Библиотека WiFi, как можно было ожидать, очень похожа на библиотеку Ethernet. Если в скетче заменить Ethernet на WiFi, EthernetServer на WiFiServer и EthernetClient на WiFiClient, остальной код останется почти неизменным.

Создание соединения

Главное отличие библиотеки WiFi от Ethernet заключается в подключении к сети. Прежде всего нужно импортировать библиотеку WiFi: