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

      return (line1[i+2] — '0');

    }

  }

  return 0;

}

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

192.168.1.10/?0=1&1=0&2=0&3=0&4=0

Список параметров начинается после символа ?. Параметры имеют вид X=Y и отделяются друг от друга символом &. Слева от знака = находится имя параметра (в данном случае цифры от 0 до 4), а справа — значения (в данном примере 1 означает «включено», а 0 — «выключено»). Для простоты параметры в этом примере могут иметь только односимвольные значения. Функция setPinStates устанавливает состояние цифровых выходов в соответствии со значениями элементов массива pinStates.

А теперь вернемся к функции 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",