Содержание


Создание датчика температуры для облачной среды с помощью Arduino Uno и IBM IoT Foundation

Часть 2. Напишите эскиз и подключитесь к IBM IoT Foundation Quickstart

Comments

Серия контента:

Этот контент является частью # из серии # статей: Создание датчика температуры для облачной среды с помощью Arduino Uno и IBM IoT Foundation

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Создание датчика температуры для облачной среды с помощью Arduino Uno и IBM IoT Foundation

Следите за выходом новых статей этой серии.

В первой части данной серии, состоящей из четырех учебников, я рассказал о схеме проекта для отслеживания температуры в монтажном шкафу, созданном с использованием платформы Arduino Uno и температурного датчика Virtuabotix DHT11. Я описал схему монтажа проекта, процедуру установки Arduino IDE и принципы тестирования отдельных компонентов проекта с помощью примеров эскизов для Arduino. Теперь можно приступить к обсуждению проекта эскиза, связывающего проект IoT с облачной средой, и действия, которые необходимо выполнить для удаленного включения контроля за температурой и влажностью в режиме реального времени. Однако в первую очередь необходимо познакомиться с протоколом, который используется для связи с IBM IoT Foundation, а именно протоколом MQTT.

Что такое MQTT?

MQTT (ранее известный как Message Queueing Telemetry Transport) - это простой, быстродействующий протокол связи, разработанный для "Интернета вещей". Он зародился в недрах IBM (где его первоначальной разработкой занимался Энди Стэнфорд-Кларк), а затем был передан для стандартизации в организацию OASIS (Organization for the Advancement of Structured Information Standards). В настоящее время используется стандарт протокола версии 3.1. Согласно спецификации MQTT V3.1 Protocol Specification, протокол призван быть "простым протоколом обмена сообщениями через брокера по схеме публикации/подписки, при разработке которого преследуется цель обеспечить открытость, простоту, минимальные требования к ресурсам и удобство внедрения." С момента его появления цель "удобства внедрения" была достигнута, так как были разработаны различные библиотеки для внедрения клиентов MQTT. Ссылки почти на все библиотеки приведены на странице проекта Eclipse Paho.

MQTT превосходно подходит для использования во встроенных устройствах, так как:

  • Он асинхронный и поддерживает несколько уровней качества обслуживания, что важно при наличии ненадежного подключения к Интернету.
  • Он отправляет короткие, сжатые сообщения, что удобно в случае невысокой пропускной способности соединения.
  • Для внедрения клиента не требуется устанавливать большое количество ПО, благодаря чему он прекрасно подходит для устройств с ограниченным объемом памяти, таких как Arduino.

Решение IBM IoT Foundation QuickStart разработано для получения данных по протоколу MQTT.

Загрузка и установка библиотек MQTT для Arduino

В этом учебнике предполагается использовать встроенные функции решения IBM Internet of Things Foundation Quickstart для вывода показателей датчика Arduino на графике в режиме реального времени.

Установка библиотек клиента MQTT для Arduino выполняется так же легко и просто, как установка библиотек для определенных физических устройств, поиском которых вам уже приходилось заниматься в первой части учебника. Библиотека, которая потребуется в этом проекте, доступна на веб-сайте Arduino Client for MQTT, содержащем описание библиотеки, ссылки на документацию и дополнительную ссылку на GitHub, откуда библиотеку можно загрузить.

В моем случае я использовал клиент V1.9.1 из GitHub. Загрузите файл ZIP или TAR и извлеките каталог PubSubClient из архива в подкаталог Libraries каталога Arduino IDE. Затем перезапустите Arduino IDE. В меню должны появиться пункты PubSubClient>mqtt_auth, PubSubClient>mqtt_basic и PubSubClient>mqtt_publish_in_callback (см. рисунок 1).

Рисунок 1. Меню PubSubClient
Меню PubSubClient
Меню PubSubClient

Тестирование MQTT в локальной системе

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

Протокол MQTT использует брокер: клиенты подключаются к брокеру, который выступает посредником в обмене данными между ними. На самом деле весь процесс достаточно прост. Ряд клиентов сообщают брокеру о том, что их интересует определенная тема. Когда другой клиент публикует сообщение в этой теме, брокер пересылает сообщение всем подписавшимся клиентам.

Для тестирования в локальной системе будет использоваться брокер Mosquitto, который представляет собой еще одно решение с открытым исходным кодом. Установите его на локальном компьютере, который используется для программирования микроконтроллера Arduino, а затем проверьте, работает ли связь между Arduino и брокером.

Mosquitto

Загрузите Mosquitto с веб-сайта Mosquitto. Доступны варианты для платформ Windows®, Mac и большинства версий Linux.® Его установка не представляет труда: в Linux достаточно установить новый пакет, а в Windows его можно установить как службу Windows или независимую исполняемую программу. В Windows необходимо отменить выбор переключателя, предназначенного для установки в качестве службы. Этот инструмент проще запускать из командной строки, так как в этом случае удобнее отслеживать отладочную информацию по мере ее появления.

После установки Mosquitto запустите его из командной строки (вне зависимости от платформы), используя следующую команду:

mosquitto -v

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

Загрузка примера эскиза

Следующий шаг заключается в загрузке примера эскиза, объединяющего все элементы в единое целое (см. Загрузка). Сообщение будет публиковаться через MQTT в брокере MQTT (вначале в локальном брокере, а затем - в брокере, входящем в состав IoT Foundation QuickStart). Для того чтобы решение IoT Foundation QuickStart смогло проанализировать и отобразить данные датчика, их необходимо опубликовать в теме iot-2/evt/status/fmt/json. Кроме того, данные должны иметь определенный формат. Если открыть документацию по IoT Foundation QuickStart и найти инструкцию "Подключение моего устройства к QuickStart ", там будет указано, что данные должны иметь следующий формат JSON:

{
    "d": {
         "name1": "stringvalue",
         "name2": intvalue,
         ...
    }
}

Пример эскиза - это простая программа. Изучив другие примеры для Arduino, о которых я говорил вам в первой части , вы могли обнаружить, что все программы для Arduino имеют одинаковую структуру. Они содержат стандартный набор функций с именами setup() и loop() , а также объявления дополнительных переменных и служебных функций, применяемых внутри функций setup() и loop(). Вначале необходимо внести ряд изменений в объявления переменных, расположенные в начале кода, чтобы программу можно было протестировать на локальном компьютере.

Изменение примера эскиза

Как и в остальных эскизах Arduino, в начале программы находятся ссылки на библиотеки, которые используются в эскизе:

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

Как вы можете убедиться, в эскизе используются библиотеки Ethernet для поддержки работы модуля Ethernet и библиотеки DHT11 для доступа к показателям, считанным с датчика DHT11 — как и в примерах, которые рассматривались в первой части. Однако в дополнение к ним используются библиотеки PubSubClient, которые ранее не упоминались. Для их применения необходимо внести некоторые изменения в код, чтобы протестировать их работу с локальным сервером:

// Update this to either the MAC address found on the sticker on your Ethernet shield (newer shields)
// or a different random hexadecimal value (change at least the last four bytes)
byte mac[]    = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
char macstr[] = "deedbafefeed";
// Note this next value is only used if you intend to test against a local MQTT server
byte localserver[] = {192, 168, 1, 98 };
// Update this value to an appropriate open IP on your local network
byte ip[]     = {192, 168, 1, 20 };

Как видно из первого комментария, в первую очередь необходимо изменить значения переменных mac и macstr на MAC-адрес модуля Ethernet. В новых моделях модулей Ethernet это значение указано на наклейке, расположенной на карте. При использовании старой модели карты измените последние четыре шестнадцатеричных символа на случайные шестнадцатеричные значения - это должно сработать. Затем измените значение переменной ip на открытый IP-адрес в локальной сети. Библиотеки Ethernet поддерживают использование DHCP, и, если вам интересно, вы можете узнать, как его использовать, однако проще использовать фиксированный IP-адрес. Затем измените значение переменной localserver на IP-адрес компьютера, на котором установлен сервер Mosquitto. Наконец, измените эскиз так, чтобы он подключался к локальному серверу MQTT, а не к серверу IBM IoT Foundation QuickStart.

Найдите следующий фрагмент кода:

// Uncomment this next line and comment out the line after it to test against a local MQTT server
//PubSubClient client(localserver, 1883, 0, ethClient);
PubSubClient client(servername, 1883, callback, ethClient);

Удалите символы комментария из строки, содержащей конструктор для запуска client(localserver и заключите в комментарий указанную ниже строку, в которой запускается client(servername. Затем сохраните эскиз.

После внесения необходимых изменений быстро просмотрите остальной код этой несложной программы. Между двумя рассмотренными ранее фрагментами кода расположены объявления переменных:

char servername[]="messaging.quickstart.internetofthings.ibmcloud.com";
String clientName = String("d:quickstart:arduino:") + macstr;
String topicName = String("iot-2/evt/status/fmt/json");
dht11 DHT11;
float tempF = 0.0;
float tempC = 0.0;
float humidity = 0.0;
EthernetClient ethClient;

Как вы могли заметить, это переменные для хранения температуры в градусах Фаренгейта и Цельсия, а также влажности. Кроме того, существует переменная для хранения экземпляра клиента Ethernet, который будет применяться клиентом PubSub.

Далее следует определение функции setup() :

void setup()

{
  // Start the Ethernet client, open up serial port for debugging, and attach the DHT11 sensor
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  DHT11.attach(3);
}

Это довольно простая функция: она запускает клиент Ethernet, используя указанный MAC-адрес и статический IP-адрес, на котором будет работать клиент. Затем она запускает последовательный порт (для подключения к компоненту Serial Monitor с целью отладки) и устанавливает связь с датчиком DHT11 через контакт 3.

Далее находится определение функции loop() , которая вызывается непрерывно, пока работает Arduino:

void loop()
{
  char clientStr[34];
  clientName.toCharArray(clientStr,34);
  char topicStr[26];
  topicName.toCharArray(topicStr,26);
  getData();
  if (!client.connected()) {
    Serial.print("Trying to connect to: ");
    Serial.println(clientStr);
    client.connect(clientStr);
  }
  if (client.connected() ) {
    String json = buildJson();
    char jsonStr[200];
    json.toCharArray(jsonStr,200);
    boolean pubresult = client.publish(topicStr,jsonStr);
    Serial.print("attempt to send ");
    Serial.println(jsonStr);
    Serial.print("to ");
    Serial.println(topicStr);
    if (pubresult)
      Serial.println("successfully sent");
    else
      Serial.println("unsuccessfully sent");
  }
  delay(5000);
}

Как вы могли заметить, большая часть этой функции предназначена для создания отладочного вывода. Однако следует обратить внимание на ряд центральных элементов. Ближе к началу функции находится вызов функции getData() (которую мы рассмотрим позже) для получения показаний датчика от DHT11. Затем функция loop() проверяет, установлено ли соединение с клиентом PubSubClient. Если соединение не установлено, то функция loop() пытается подключиться к брокеру MQTT. Если соединение установлено, то функция loop() форматирует данные как строку JSON с помощью функции buildJson() и публикует ее в брокере MQTT с помощью метода publish() класса PubSubClient. Наконец, функция loop() переходит в режим ожидания на 5 000 мс, перед тем как среда выполнения Arduino возвращается в цикле назад и снова вызывает функцию.

Теперь рассмотрим функцию getData() :

void getData() {
  int chk = DHT11.read();
  switch (chk)
  {
  case 0:
    Serial.println("Read OK");
    humidity = (float)DHT11.humidity;
    tempF = DHT11.fahrenheit();
    tempC = DHT11.temperature;
    break;
  case -1:
    Serial.println("Checksum error");
    break;
  case -2:
    Serial.println("Time out error");
    break;
  default:
    Serial.println("Unknown error");
    break;
  }
}

Эта функция проверяет состояние данных в библиотеке DHT11, а затем считывает значения показателей датчика, если они готовы. В противном случае она выводит информационное сообщение на консоль.

Наконец, рассмотрим функцию форматирования вывода JSON:

String buildJson() {
  String data = "{";
  data+="\n";
  data+= "\"d\": {";
  data+="\n";
  data+="\"myName\": \"Arduino DHT11\",";
  data+="\n";
  data+="\"temperature (F)\": ";
  data+=(int)tempF;
  data+= ",";
  data+="\n";
  data+="\"temperature (C)\": ";
  data+=(int)tempC;
  data+= ",";
  data+="\n";
  data+="\"humidity\": ";
  data+=(int)humidity;
  data+="\n";
  data+="}";
  data+="\n";
  data+="}";
  return data;
}

Одно из слабых мест реализации языка Processing в Arduino состоит в отсутствии хороших средств для работы со строками. Вы могли обратить внимание на странные преобразования, которые приходится делать между экземплярами класса String и значениями строкового типа для вызова функций, которые ожидают получить ввод в том или ином формате. Даже создание строки JSON такого простого формата, как этот, представляет определенные трудности из-за отсутствия хорошей библиотеки функций форматирования строк — при том что аналогичные функции для форматирования вывода на консоль существуют.

Тестирование с помощью локального брокера Mosquitto

Итак, первая часть почти подошла к концу. Теперь необходимо передать измененный эскиз в устройство Arduino, следуя инструкциям, приведенным в первой части. После появления статуса "Done uploading." в строке состояния Arduino IDE откройте компонент Serial Monitor, нажав клавиши Ctrl-Shift-M.

Проверка вывода

Если до этого момента никаких проблем не возникло, в окне терминала, в котором был запущен Mosquitto, должен быть показан следующий вывод:

1405807697: mosquitto version 1.2.3 (build date 22/12/2013 13:36:32.54) starting
1405807697: Using default config.
1405807697: Opening ipv6 listen socket on port 1883.
1405807697: Opening ipv4 listen socket on port 1883.
1405807718: New connection from 192.168.1.20 on port 1883.
1405807718: New client connected from 192.168.1.20 as d:quickstart:arduino:deedb
afefeed (c2, k15).
1405807718: Sending CONNACK to d:quickstart:arduino:deedbafefeed (0)
1405807718: Received PUBLISH from d:quickstart:arduino:deedbafefeed (d0, q0, r0,
 m0, 'iot-2/evt/status/fmt/json', ... (100 bytes))
1405807723: Socket error on client d:quickstart:arduino:deedbafefeed, disconnect
ing.
1405807723: New connection from 192.168.1.20 on port 1883.
1405807723: New client connected from 192.168.1.20 as d:quickstart:arduino:deedb
afefeed (c2, k15).
1405807723: Sending CONNACK to d:quickstart:arduino:deedbafefeed (0)
1405807723: Received PUBLISH from d:quickstart:arduino:deedbafefeed (d0, q0, r0,
 m0, 'iot-2/evt/status/fmt/json', ... (100 bytes))
1405807729: Received PUBLISH from d:quickstart:arduino:deedbafefeed (d0, q0, r0,
 m0, 'iot-2/evt/status/fmt/json', ... (100 bytes))
1405807734: Received PUBLISH from d:quickstart:arduino:deedbafefeed (d0, q0, r0,
 m0, 'iot-2/evt/status/fmt/json', ... (100 bytes))

Признаком того, что все работает правильно, является наличие последних строк вида Received PUBLISH from.... Они означают, что эскиз Arduino успешно подключился к брокеру Mosquitto. Теперь посмотрите на окно Serial Monitor: оно должно содержать сообщения следующего вида:

Read OK
Trying to connect to d:quickstart:arduino:deedbafefeed
attempt to send {
"d": {
"myName": "Arduino DHT11",
"temperature (F)": 71,
"temperature (C)": 22,
"humidity": 43
}
}
to iot-2/evt/status/fmt/json
successfully sent

Подключение Arduino к IoT Foundation Quickstart

Убедившись в том, что локально все работает правильно, можно попробовать подключиться к IoT Foundation QuickStart. Перейдите в браузере на веб-сайт IBM Internet of Things Foundation как показано на рис. 2.

Рисунок 2. Домашняя страница IBM IoT Foundation
Домашняя страница IBM IoT Foundation
Домашняя страница IBM IoT Foundation

Нажмите кнопку Try it out with our Quickstart. Будет показана страница, приведенная на рисунке 3.

Рисунок 3. Страница приветствия IBM IoT Foundation Quickstart
Страница приветствия IBM IoT Foundation Quickstart
Страница приветствия IBM IoT Foundation Quickstart

В этом учебнике планируется использовать встроенные функции IoT Foundation Quickstart для вывода данных с датчика Arduino на графике в режиме реального времени. В третьей части и четвертой части будет написано приложение для дополнительной обработки полученных данных.

В IoT Foundation предусмотрено несколько готовых сценариев для ряда других устройств. Если у вас есть более сложное устройство, такое как Intel Galileo или Raspberry Pi, то вы можете опробовать эти сценарии. В нашем случае достаточно ввести MAC-адрес устройства Arduino. Но перед нажатием кнопки Go необходимо немного изменить эскиз.

Изменение эскиза

Помните ли вы о том, что несколько шагов назад вы заменили адрес сервера MQTT в IoT Foundation на адрес локального сервера MQTT? Теперь его можно изменить обратно. Добавьте и удалите символы комментария, чтобы вернуться к исходной версии кода:

// Uncomment this next line and comment out the line after it to test against a local MQTT server
//PubSubClient client(localserver, 1883, 0, ethClient);
PubSubClient client(servername, 1883, callback, ethClient);

Сохраните измененный эскиз и передайте его в устройство Arduino. При желании вы можете перезапустить Serial Monitor, однако настоящим доказательством правильности работы систему будет вывод, полученный в IoT Foundation. Вернитесь к окну браузера, нажмите кнопку Go на странице ввода MAC-адреса и подождите несколько минут.

Построение графика на основе данных

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

Рисунок 4. Данные на графике
Данные на графике
Данные на графике

Все готово! Вы создали устройство и сделали его частью глобальной сети IoT. В моем несложном случае этого было достаточно: на протяжении нескольких часов я мог наблюдать за графиком температуры в монтажном шкафу. Плохо было то, что даже в полдень жаркого дня температура никогда не поднималась выше 73°F (23°C), поэтому мне пришлось снова засесть за чертежи для выяснения причины неполадок. Однако вам еще предстоит проделать долгий путь, чтобы узнать обо всех возможностях IoT.

Что дальше?

В следующих двух учебниках этой серии (третьей части и четвертой части ) вы напишете собственное приложение — работающее в IBM® Bluemix™— которое может сохранять данные, полученные от устройства Arduino, отображать их и сравнивать полученные ранее данные с текущими данными.


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Облачные вычисления, Open source
ArticleID=994530
ArticleTitle=Создание датчика температуры для облачной среды с помощью Arduino Uno и IBM IoT Foundation: Часть 2. Напишите эскиз и подключитесь к IBM IoT Foundation Quickstart
publish-date=02092015