Arduino, HM-10 и App Inventor 2
Обновление: BLE-расширение, включённое в примеры, устарело. Скачайте последнюю версию с сайта App Inventor BLE и замените существующее расширение.
Данное руководство даёт хорошее введение в использование HM-10 с App Inventor 2 и выходит за рамки обычных начальных руководств. Хотя я использую Arduino, принципы будут одинаковы для любого другого микроконтроллера или для использования HM-10 самостоятельно.
Внимание: это очень длинная статья.
Для использования этого руководства вы должны быть знакомы с App Inventor, иметь Android-устройство с поддержкой BLE, а также Arduino и HM-10.
Содержание:
BLE
Краткое введение в BLE.
BLE — это не обновление Bluetooth Classic, это другая система с другими целями использования. BLE разработан для приложений с низким энергопотреблением и достигает этого за счёт использования редких и малых пакетов данных. Он не предназначен для постоянных подключений и больших объёмов данных. Для этого лучше подходит Bluetooth Classic.
Существует 2 способа общения BLE-устройств:
Broadcaster + Observer — нет стандартного соединения, Broadcaster (обычно датчик) периодически отправляет сигналы (пакеты объявления), которые Observer прослушивает.
Central + Peripheral — сценарий похож (но не идентичен) классическому подключению. Central (мастер) находит Peripheral (ведомое устройство) и инициирует соединение.
BLE основан на сервисах и характеристиках. Сервис — это коллекция связанных характеристик, а характеристика — это место, где хранятся данные. Каждый сервис и характеристика имеет уникальный идентификатор UUID.
HM-10
HM-10 — это недорогой серийный BLE-модуль от Jinan Huamao. Он имеет серийный/UART уровень, который упрощает использование с Arduino. Для простых подключений или использования в качестве базового iBeacon HM-10 идеален.
Для общего использования HM-10 имеет 2 пользовательские характеристики в одном пользовательском сервисе:
0000FFE0-0000-1000-8000-00805F9B34FB0000FFE1-0000-1000-8000-00805F9B34FB — READ/WRITE/NOTIFY0000FFE2-0000-1000-8000-00805F9B34FB — WRITE onlyХарактеристика FFE1 активна по умолчанию. FFE2 неактивна и должна быть включена перед использованием. В следующих примерах я буду использовать UUID FFE1 для чтения и записи данных.
App Inventor 2
App Inventor 2 — довольно простой способ начать создавать Android-приложения. Он использует систему Blockly вместо текста. BLE-расширение можно скачать с http://iot.appinventor.mit.edu.
App Inventor IOT официально поддерживает Arduino 101 и BBC micro:bit, но можно использовать любой BLE-модуль, такой как HM-10.
Я буду использовать файл BaseConnect aia в качестве отправной точки. Это минимальное приложение-шаблон для сканирования и подключения к BLE-устройствам.
Часть 1: Включение и выключение LED — базовый пример
Начнём с очень простого приложения для управления одним светодиодом: включить и выключить.
Схема Arduino и HM-10
Простая схема: Arduino, HM-10, светодиод и резистор.
Пин RX HM-10 работает на 3.3 В. Пин TX Arduino — 5 В. Делитель напряжения (резисторы 1 кОм и 2 кОм) понижает 5 В до 3.3 В.
Скетч Arduino
Скетч проверяет входящие данные. Если получен «0» — светодиод выключается, если «1» — включается.
// Arduino, HM-10, App Inventor 2
//
// Example Project Part 1: Turn an LED on and off basic
// By Martyn Currey. www.martyncurrey.com
//
// Пины
// BT VCC к Arduino 5V
// BT GND к GND
// Arduino D8 (ASS RX) - BT TX (делитель не нужен)
// Arduino D9 (ASS TX) - BT RX через делитель напряжения
// Arduino D2 - Резистор + LED
#include <AltSoftSerial.h>
AltSoftSerial ASSserial;
byte LEDPin = 2;
char c=' ';
void setup()
{
Serial.begin(9600);
Serial.print("Sketch: "); Serial.println(__FILE__);
Serial.print("Uploaded: "); Serial.println(__DATE__);
Serial.println(" ");
ASSserial.begin(9600);
Serial.println("ASSserial started at 9600");
Serial.println(" ");
pinMode(LEDPin, OUTPUT);
}
void loop()
{
// Чтение из Bluetooth-модуля и управление LED
if (ASSserial.available())
{
c = ASSserial.read();
Serial.println(c);
// ASCII код 0 — десятичный 48
// ASCII код 1 — десятичный 49
if ( c== 48) { digitalWrite(LEDPin, LOW); }
if ( c== 49) { digitalWrite(LEDPin, HIGH); }
}
}
Проверить работу скетча можно в мониторе порта:
Android-приложение
Начнём с простого приложения, отправляющего 2 кода: «0» (выключить LED) и «1» (включить LED). Начальное приложение «глупое» — оно не знает фактическое состояние LED, просто отправляет коды при нажатии кнопок.
Используем шаблон BaseConnect от команды AI2. Скачать можно с http://iot.appinventor.mit.edu.
Откройте App Inventor, загрузите файл BaseConnect aia и сохраните как «ARD_HM10_AI2_Single_LED_01». Нажмите Scan и посмотрите, какие устройства найдены.
Приложение нашло различные BLE-устройства, включая HM-10. К сожалению, текст слишком мелкий. В дизайнере выберите ListBLE и измените TextSize на 48.
Приложение BaseConnect содержит только 7 блоков.
Добавление кнопок управления LED
Добавим кнопки для включения и выключения LED. Используем два блока Button внутри Horizontal Arrangement с текстовыми метками-разделителями.
Переименование элементов:
С BLE нужно записывать данные в определённую характеристику, что означает необходимость знать UUID характеристики и сервиса. В данном примере используется характеристика HM-10 по умолчанию 0000FFE1-0000-1000-8000-00805F9B34FB под сервисом 0000FFE0-0000-1000-8000-00805F9B34FB.
Блоки BLE Write обычно ожидают данные в виде списка. Если использовать простые данные, AI2 сконвертирует их автоматически. Нужны UUID сервиса и UUID характеристики.
Добавьте глобальные переменные для UUID и блоки событий нажатия кнопок:
При нажатии ON отправляется «1», при OFF — «0».
Нужно добавить проверку включённости Bluetooth перед сканированием. Добавляем BluetoothClient и Notifier:
Изменяем ButtonScan.Click для проверки Bluetooth:
Предупреждение при выключенном Bluetooth:
Проверка подключения перед отправкой:
Результат — 3 экрана приложения:
Блоки:
Экран дизайнера:
Результат на телефоне:
Финальный дизайнер и блоки:
Часть 2: Двустороннее управление LED
В этой части добавляем кнопку на стороне Arduino и двустороннее управление. Когда LED включается/выключается кнопкой на Arduino, приложение обновляется. И наоборот.
Схема с кнопкой
К предыдущей схеме добавляем кнопку на пине D3 с подтягивающим резистором 10 кОм.
Скетч Arduino — Часть 2
// Arduino, HM-10, App Inventor 2
//
// Example Project Part 2: Turn an LED on and off 2 way control 01
// By Martyn Currey. www.martyncurrey.com
//
// Пины
// BT VCC к Arduino 5V
// BT GND к GND
// Arduino D8 (ASS RX) - BT TX (делитель не нужен)
// Arduino D9 (ASS TX) - BT RX через делитель напряжения
// Arduino D2 - Резистор + LED
// Arduino D3 - Резистор 10K + кнопка
#include <AltSoftSerial.h>
AltSoftSerial ASSserial;
// Константы для аппаратного обеспечения
const byte LEDPin = 2;
const byte SwitchPin = 3;
// Общие переменные
boolean LED_State = false;
boolean switch_State = false;
boolean oldswitch_State = false;
char c=' ';
void setup()
{
Serial.begin(9600);
Serial.print("Sketch: "); Serial.println(__FILE__);
Serial.print("Uploaded: "); Serial.println(__DATE__);
Serial.println(" ");
ASSserial.begin(9600);
Serial.println("AltSoftSerial started at 9600");
Serial.println(" ");
pinMode(LEDPin, OUTPUT);
digitalWrite(LEDPin,LOW);
pinMode(SwitchPin, INPUT);
} // void setup()
void loop()
{
checkSwitch();
checkRecievedData();
}
void checkSwitch()
{
// Простая функция переключения с дребезгоподавлением
boolean state1 = digitalRead(SwitchPin); delay(1);
boolean state2 = digitalRead(SwitchPin); delay(1);
boolean state3 = digitalRead(SwitchPin);
if ((state1 == state2) && (state1==state3))
{
switch_State = state1;
if ( (switch_State == HIGH) && (oldswitch_State == LOW) )
{
// переключаем LED_State
LED_State = ! LED_State;
// Если LED_State HIGH — включаем LED
if ( LED_State == HIGH)
{
digitalWrite(LEDPin,HIGH); // включить LED
ASSserial.print("1" ); // сообщить приложению
Serial.println("Sent - 1");
}
else
{
digitalWrite(LEDPin,LOW); // выключить LED
ASSserial.print("0"); // сообщить приложению
Serial.println("Sent - 0");
}
}
oldswitch_State = switch_State;
}
}
void checkRecievedData()
{
// Чтение из Bluetooth-модуля и управление LED
if (ASSserial.available())
{
c = ASSserial.read();
Serial.println(c);
// ASCII 0 = 48, ASCII 1 = 49
if ( c== 48) { digitalWrite(LEDPin, LOW); LED_State = LOW; }
if ( c== 49) { digitalWrite(LEDPin, HIGH); LED_State = HIGH; }
}
}
Обновление приложения — приём данных
Для приёма данных от HM-10 необходимо подписаться на характеристику для получения уведомлений. Используется блок RegisterForStrings.
При получении данных обновляем состояние кнопки:
Финальные блоки:
Скачать
Все файлы aia и скетчи Arduino доступны на странице оригинальной статьи.