Arduino выходит в Интернет (ARDUINO+MQTT+IBM Bluemix) ч.1

Поработав с Blynk захотелось, чего-то более универсального. Blynk отличная штука, но когда начинаешь думать не что я могу сделать, а как это сделать на Blynk - приходит понимание, что нужно изучать что-то более гибкое и возможно - перспективнее. Основные задачи на данный момент - получать информацию с arduino (сенсоров), собирать, анализировать и управлять периферийными устройствами как локально, так и с мобильного устройства (приложения) или web-интерфейса.
http://www.sast.in.ua/2016/05/arduino-arduinomqttibm-bluemix-1.html
На одной из последних посещенных конференций по IoT в очередной раз упомянули об MQTT - протоколе обмена данными ориентированном в первую очередь на IoT. (MQTT (Message Queue Telemetry Transport) — упрощённый сетевой протокол, работающий поверх TCP/IP. Используется для обмена сообщения между устройствами по принципу издатель-подписчик). Для обработки полученных данных и управления хотелось использовать что-то от "больших" разработчиков.
Решения в данной области предлагают:
Amazon с AWS IoT - ещё не добрался до изучения но выглядит интересно Google с Google Cloud Platform - обещает бесплатный триал для изучения, но сразу просит реквизиты банковской карточки, чем и отбил охоту изучать.
Microsoft с Azure Iot Suite - что-то вообще не пошло, но нужно будет разобраться...
IBM с Bluemix - с него пожалуй и начну, так как попалась очень хорошая статья. И как я понял IBM является основателем MQTT.
А если ещё немного поискть, можно найти много интересных примеров для понимания работы MQTT в сфере IoT, особый интерес вызвала ещё эта статья.

Процесс изучения начну c "Создание датчика температуры для облачной среды с помощью Arduino Uno и IBM IoT Foundation" Акаунт уже создан
Для отладки на локальном уровне, необходимо установить локальный брокер, ставим Mosquitto хотя странно, так как статья от инженера IBM и у них есть свой брокер, но так как пока учусь - делаю все согласно статье.
В Ubuntu дистрибутив присутствует в центре программного обеспечения, поэтому с установкой вопросов не возникло
Немножко мануала по Mosquitto
И запускаем с колючем -v, но что-то пошло не так и стандартный порт 1883 оказался занят
По команде lsof -c mosquitto обнаружил, что mosquitto уже запущен, но так как мне нужно запустить его в режиме логирования, убиваем процесс и запускаем снова с ключом -v
Теперь брокер Mosquitto ждет поступления команд
Для правильной настройки и использования всего потенциала, очень рекомендую читать мануалы http://mosquitto.org/documentation/ особенно это касается файла конфигурации. Также на GitHub есть отличный MQTT Wiki.
С брокером закончили и он будет постоянно запущен на домашнем Raspberry Pi3. А теперь самое интересное - заставить arduino отправлять ему информацию. Для этого необходимо скачать и установить библиотеку MQTT для Arduino (на момент написания v2.6).
После установки и запуска Arduino IDE можно обнаружить примеры и для разбора возьму mqtt_basic:
************************************************************************* 

/*
 Basic MQTT example

 This sketch demonstrates the basic capabilities of the library.
 It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic"
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary

 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.
 */

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

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 77);
IPAddress server(192, 168, 0, 3);

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

EthernetClient ethClient;
PubSubClient client(ethClient);

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic","hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(57600);

  client.setServer(server, 1883);
  client.setCallback(callback);

  Ethernet.begin(mac, ip);
  // Allow the hardware to sort itself out
  delay(1500);
}

void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

**************************************************************
Но почему-то при попытке скомпилировать получил ошибку:
mqtt_basic.ino:18:26: fatal error: PubSubClient.h: No such file or directory
compilation terminated.


Перепробовав много разных вариантов (на которые и не стоило тратить время), причину ошибки обнаружил и заключалась она в банально неправильном размещении файла библиотеки в архиве разработчика, с папки src файлы PubSubClient.h и PubSubClient.cpp необходимо пеместить в корневую папку библиотеки.

Заливаем скетч на Ардуину и видим, что брокер Mosquitto получил новое соединение, а в мониторинге порта получаем сообщения отправленные с приложения на мобильном телефоне (MQTT Dashboard).

Следующий шаг - вешаем на ардуину датчик DHT11 и будем с него отправлять температуру и влажность на соответствующие topic. За пример возьму скетч предложенный в статье, с которой все и начиналось, но немного подкорректирую для локального использования:
***********************************************************
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <dht11.h>

byte mac[]    = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
char macstr[] = "deedbafefeed";
byte localserver[] = {192, 168, 0, 3 };
byte ip[] = {192, 168, 0, 77 };

String clientName = String("arduino:") + macstr;
String topicName = String("temp");

dht11 DHT11;
float tempF = 0.0;
float tempC = 0.0;
float humidity = 0.0;
EthernetClient ethClient;
PubSubClient client(localserver, 1883, 0, ethClient);

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  DHT11.attach(3);
}

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(60000);
}

String buildJson() {
  String data = "";
  data+=(int)tempC;
  return data;
}

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;
  }
}
**********************************************************
В результате в мобильно приложение MQTT Dashboard получил график динамики температуры.
Для получения актуальной информации, а также управления данный метод уже более чем удобен, но для журналирования полученной информации и её дальнейшего анализа с управлением по результатам брокера и клиента будет мало. Для этого нужно выходить в "облако".
Чем я и займусь в следующей записи.
А пока понаблюдаю как работает брокер и что выводит в логи

Немає коментарів:

Дописати коментар