Отслеживание GPS в реальном времени с Helium, Azure IoT Hub и Power BI
Компоненты и материалы
| Helium Atom Prototyping Module | × | 1 |
| Arduino Zero | × | 1 |
| Adafruit Ultimate GPS Breakout | × | 1 |
| Breadboard (generic) | × | 1 |
Приложения и онлайн-сервисы
| Microsoft Azure |
| Arduino IDE |
О проекте
Helium помогает разработчикам создавать низкопотребляющие, безопасные, подключенные устройства. В этом проекте мы рассмотрим использование модуля прототипирования Helium Atom с Arduino Zero и Adafruit Ultimate GPS Breakout для бесперебойной передачи данных в Azure IoT Hub, а затем в отчет Power BI для визуализации данных.
Подробнее о продуктах Helium с низким потреблением энергии, безопасной и дальней передачей данных, а также приобретении необходимого оборудования можно на helium.com/store.
Аппаратная часть
Сначала необходимо закрепить модуль Helium Atom Prototyping на переходнике Helium Atom Arduino Adapter, а затем подключить к Arduino. В этом руководстве используется Arduino Zero, но подойдут также Uno, Due, M0 или любая другая плата Arduino.
После подключения Atom к Arduino конструкция должна выглядеть примерно так:

Далее подключим Adafruit Ultimate GPS Breakout к «сэндвичу» Arduino. Для наглядности используем макетную плату, но можно подключить GPS-модуль напрямую. Схема подключения:
- Arduino 5V → GPS VIN
- Arduino GND → GPS GND
- Arduino D12 → GPS TX
- Arduino D10 → GPS RX
Готовая сборка:

Теперь подключим и включим Helium Element. Если у вас Cellular Element, просто включите его и дождитесь, пока индикатор станет бирюзовым. Для Ethernet Element подключите порт к DHCP-порту (например, к кабельному модему или роутеру). После включения индикатор на передней панели должен стать зеленым.

Переходим к настройке в Helium Dashboard.
Helium Dashboard и каналы
Сначала добавим Atom и Element в аккаунт на дашборде. Если у вас нет аккаунта, но есть оборудование, напишите на support@helium.com. Иначе войдите с учетными данными, полученными при покупке.
Активация Element: нажмите Elements слева, затем Add New справа вверху. Введите последние 4 символа MAC-адреса и HVV с этикетки на задней панели, задайте имя и при необходимости теги. Нажмите Activate Element.

Аналогично активируем Atom: Atoms → Add New, введите MAC и HVV с этикетки Atom, добавьте теги, нажмите Activate Atom.

Теперь создадим Azure IoT Hub как точку приема данных от устройств Helium Atom. Предполагается, что у вас уже есть учетная запись Azure.
На портале Azure: + → Internet of Things → IoT Hub.

Настройте параметры и нажмите Create. Рекомендуется выбрать Pin to Dashboard для быстрого доступа.

После развертывания (может занять несколько минут) откройте хаб с дашборда. Для настройки канала Helium нам понадобится строка подключения. В IoT Hub выберите Shared Access Policies → RegistryReadWrite → скопируйте значок копирования рядом с Connection string—primary key. Не сообщайте эту строку посторонним.

Вернитесь в Helium Dashboard: Channels → Azure IoT Hub под Create New Channel. Вставьте скопированную Connection String.

Задайте имя канала и нажмите Create. Запомните имя — оно понадобится в коде Arduino для отправки данных в этот канал.
Скетч для Arduino
С настроенным Azure IoT Hub и созданным каналом Helium напишем скетч, использующий библиотеки Helium Arduino и Adafruit GPS для отправки GPS-координат в Helium, а затем в Azure-канал.
Установите обе библиотеки через Sketch → Include Library → Manage Libraries, найдите Helium и Adafruit GPS, нажмите Install.

Ниже приведен полный скетч. Он инициализирует Atom, создает канал, соответствующий созданному в Azure, собирает GPS-данные, форматирует их в JSON и отправляет через сеть Helium.
/* * Copyright 2017, Helium Systems, Inc. * All Rights Reserved. See LICENCE.txt for license information */ #include "Arduino.h" #include "avr/dtostrf.h" #include "Helium.h" #include #include #include "wiring_private.h" // pinPeripheral() function #define atom_serial Serial1 //for GPS #define PIN_SERIAL2_RX (34ul) // Pin description number for PIO_SERCOM on D12 #define PIN_SERIAL2_TX (36ul) // Pin description number for PIO_SERCOM on D10 #define PAD_SERIAL2_TX (UART_TX_PAD_2) // SERCOM pad 2 #define PAD_SERIAL2_RX (SERCOM_RX_PAD_3) // SERCOM pad 3 Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); void SERCOM1_Handler() { Serial2.IrqHandler(); } Helium helium(&atom_serial); Channel channel(&helium); //GPS stuff #define gps_serial Serial2 Adafruit_GPS GPS(&gps_serial); void setup() { pinPeripheral(10, PIO_SERCOM); pinPeripheral(12, PIO_SERCOM); Serial.begin(115200); Serial.println("Starting"); // Begin communication with the Helium Atom // The baud rate differs per supported board // and is configured in Board.h helium.begin(helium_baud_b115200); // Connect the Atom to the Helium Network Serial.print("Connecting - "); int status = helium.connect(); while (status != helium_status_OK) { status = helium.connect(); } Serial.println("Succeeded"); // Begin communicating with the channel. This should only need to // be done once. // // NOTE: Please ensure you've created a matching channel in the Helium Dashbaord int8_t result; Serial.print("Creating Channel - "); status = channel.begin("Hackster Guide", &result); if (helium_status_OK == status && result == 0) { Serial.println("Succeeded"); } else { Serial.println("Failed"); } delay(1000); //Init GPS GPS.begin(9600); GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); GPS.sendCommand(PGCMD_NOANTENNA); delay(2000); } uint32_t timer = millis(); void loop() { char c = GPS.read(); if (GPS.newNMEAreceived()) { if (!GPS.parse(GPS.lastNMEA())) return; } if (timer > millis()) timer = millis(); if (millis() - timer > 2000) { timer = millis(); // reset the timer if (GPS.fix) { char lat[10]; char lon[10]; char data[100]; dtostrf(GPS.latitudeDegrees, 4, 4, lat); dtostrf(GPS.longitudeDegrees, 4, 4, lon); //format a JSON object of lat/lon to send to Azure sprintf(data, "{\"lat\": \"%s\", \"lon\": \"%s\"}", lat, lon); // Send the location data to the configured channel int8_t result; //the response from the Helium Router Serial.print("Sending - "); int status = channel.send(data, strlen(data), &result); //status is the response from the Atom serial connection if (helium_status_OK == status && result == 0) { Serial.print("Successfully sent "); Serial.println(data); } else { Serial.println("Failed"); } } else { Serial.println("No GPS fix!"); } } }
Создайте новый скетч (File → New), вставьте код, подключите Arduino/Atom по USB и нажмите Upload (стрелка вправо).
Через несколько секунд индикаторы Atom начнут мигать красным и синим, затем перейдут в режим постоянного красного мигания — значит, Atom подключен к сети Helium. Индикатор FIX GPS также будет медленно мигать красным, пока не будет захвачен спутник. Лучше разместить GPS у окна или на улице.
Проверьте Serial Monitor (Tools → Serial Monitor) — должны появиться сообщения о подключении, создании канале, а затем серия No GPS fix! до захвата спутников.
Проверка передачи данных
Вернитесь в Helium Dashboard: Channels → выберите ваш Azure-канал в разделе Active Channels. Прокрутите вниз к Event Log — там должны отображаться временные метки, размер данных и статус успешной маршрутизации в Azure.

В Azure IoT Hub в разделе Device Explorer должно появиться ваше устройство Helium Atom по MAC-адресу. Нажав на него, вы увидите, что устройство автоматически защищено аппаратным X.509 сертификатом.

Передача данных в Power BI
Предполагается, что у вас есть аккаунт Power BI и создано рабочее пространство. Если нет — зарегистрируйтесь на www.powerbi.com.
Создадим Azure Stream Analytics Job для передачи данных из IoT Hub в Power BI.
- На портале Azure: New → поиск Stream Analytics Job → Create.
- После развертывания: в Streaming Job выберите Inputs → Add. Задайте псевдоним, источник IoT Hub, выберите ваш хаб, остальное по умолчанию.
- Создайте выход: Outputs → Add. Выберите Power BI в Sink, авторизуйтесь, выберите рабочее пространство, задайте имя таблицы.
- Создайте запрос: Query. Запрос должен выбирать все данные из IoT Hub и направлять их в Power BI (имена входа/выхода согласно предыдущим шагам).
- Нажмите Save, вернитесь на Overview и нажмите Start. Через несколько минуты данные начнут поступать в Power BI.



Визуализация в Power BI
В рабочем пространстве Power BI: + Create → Report → выберите датасет из Stream Analytics Job → Create.

Выберите визуализацию «Карта» (значок глобуса). Перетащите lat в Latitude, lon в Longitude. При необходимости добавьте EventProcessedUTCTime в Tooltips. Нажмите Save. Теперь на карте отображается положение вашего Helium Atom с Arduino.

Код
Atom + Arduino + Adafruit GPS (C/C++)
/* * Copyright 2017, Helium Systems, Inc. * All Rights Reserved. See LICENCE.txt for license information */ #include "Arduino.h" #include "avr/dtostrf.h" #include "Helium.h" #include #include #include "wiring_private.h" // pinPeripheral() function #define atom_serial Serial1 //for GPS #define PIN_SERIAL2_RX (34ul) // Pin description number for PIO_SERCOM on D12 #define PIN_SERIAL2_TX (36ul) // Pin description number for PIO_SERCOM on D10 #define PAD_SERIAL2_TX (UART_TX_PAD_2) // SERCOM pad 2 #define PAD_SERIAL2_RX (SERCOM_RX_PAD_3) // SERCOM pad 3 Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); void SERCOM1_Handler() { Serial2.IrqHandler(); } Helium helium(&atom_serial); Channel channel(&helium); //GPS stuff #define gps_serial Serial2 Adafruit_GPS GPS(&gps_serial); void setup() { pinPeripheral(10, PIO_SERCOM); pinPeripheral(12, PIO_SERCOM); Serial.begin(115200); Serial.println("Starting"); // Begin communication with the Helium Atom // The baud rate differs per supported board // and is configured in Board.h helium.begin(helium_baud_b115200); // Connect the Atom to the Helium Network Serial.print("Connecting - "); int status = helium.connect(); while (status != helium_status_OK) { status = helium.connect(); } Serial.println("Succeeded"); // Begin communicating with the channel. This should only need to // be done once. // // NOTE: Please ensure you've created a matching channel in the Helium Dashbaord int8_t result; Serial.print("Creating Channel - "); status = channel.begin("Hackster Guide", &result); if (helium_status_OK == status && result == 0) { Serial.println("Succeeded"); } else { Serial.println("Failed"); } delay(1000); //Init GPS GPS.begin(9600); GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); GPS.sendCommand(PGCMD_NOANTENNA); delay(2000); } uint32_t timer = millis(); void loop() { char c = GPS.read(); if (GPS.newNMEAreceived()) { if (!GPS.parse(GPS.lastNMEA())) return; } if (timer > millis()) timer = millis(); if (millis() - timer > 2000) { timer = millis(); // reset the timer if (GPS.fix) { char lat[10]; char lon[10]; char data[100]; dtostrf(GPS.latitudeDegrees, 4, 4, lat); dtostrf(GPS.longitudeDegrees, 4, 4, lon); //format a JSON object of lat/lon to send to Azure sprintf(data, "{\"lat\": \"%s\", \"lon\": \"%s\"}", lat, lon); // Send the location data to the configured channel int8_t result; //the response from the Helium Router Serial.print("Sending - "); int status = channel.send(data, strlen(data), &result); //status is the response from the Atom serial connection if (helium_status_OK == status && result == 0) { Serial.print("Successfully sent "); Serial.println(data); } else { Serial.println("Failed"); } } else { Serial.println("No GPS fix!"); } } }
Производственный процесс
- Надежная система учета рабочего времени на Arduino с RFID и Python
- GPS-трекер с пространственным анализом на Azure IoT Hub
- Универсальный Android-пульт на Arduino, 1Sheeld и ИК-управлении
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- IoT-монитор пульса в реальном времени на Arduino и MAX30100
- Удаленное IoT-управление самодельной манипулятором
- Умная банка на ESP8266 + Arduino: мониторинг наполненности в реальном времени
- Точное измерение частоты и коэффициента заполнения на Arduino UNO
- Измерение расстояния в реальном времени: Ардуино-сонар с визуализацией в Processing
- Система управления бассейном на Azure IoT: умные датчики и удаленный мониторинг