こんにちはn0bisukeです。
アドベントカレンダーの借金を返した感じがするので心が晴れています。
Nefryアドベントカレンダー15日目です!
今日はLINE Thingsを簡単に試せるLINE Things StarterをNefry BTで動かしてみたいと思います。
作るもの
こんな感じで、LIFFアプリ側でボタンを押すとNefry BTのLEDが反応して、Nefry BTのボタンを押すとLIFFアプリに反映されるものを作ります。
1. LINE Things Starterと友達になったり下準備
さっそくLINE Thingsを触ってみた(ESP32でリモートLチカ) #linedevdayの記事のSTEP3の部分を進めましょう。
↑のQRコードでLINE Things Starterアカウントと友達になりつつ、有効化します。
2. Nefry BTにLINE Things Starter向けのファームを書き込む
Nefry BT向けのArduino IDEの環境構築を参考に、Arduino IDEでNefry BTの開発ができるようにします。
この時のライブラリのバージョンは1.4.1以上にしましょう。(執筆時点の最新)
> 1.4.0以前だとLINE Things向けのファームがうまくコンパイル出来ません。
以下のコードで動きます。
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include<Nefry.h> //Nefryライブラリの読み込み
// Device Name: Maximum 30 bytes
#define DEVICE_NAME "LINE Things Trial ESP32"
// User service UUID: Change this to your generated service UUID
#define USER_SERVICE_UUID "91E4E176-D0B9-464D-9FE4-52EE3E9F1552"
// User service characteristics
#define WRITE_CHARACTERISTIC_UUID "E9062E71-9E62-4BC6-B0D3-35CDCD9B027B"
#define NOTIFY_CHARACTERISTIC_UUID "62FBD229-6EDD-4D1A-B554-5C4E1BB29169"
// PSDI Service UUID: Fixed value for Developer Trial
#define PSDI_SERVICE_UUID "E625601E-9E55-4597-A598-76018A0D293D"
#define PSDI_CHARACTERISTIC_UUID "26E2B12B-85F0-4F3F-9FDD-91D114270E6E"
BLEServer* thingsServer;
BLESecurity *thingsSecurity;
BLEService* userService;
BLEService* psdiService;
BLECharacteristic* psdiCharacteristic;
BLECharacteristic* writeCharacteristic;
BLECharacteristic* notifyCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
volatile int btnAction = 0;
class serverCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class writeCallback: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *bleWriteCharacteristic) {
std::string value = bleWriteCharacteristic->getValue();
if ((char)value[0]) {
Serial.println("LED ON!");
Nefry.setLed(0,100,0); //NefryBTのフルカラーLEDを緑に
}else{
Nefry.setLed(0,0,0); //NefryBTのフルカラーLEDをOFFに
}
}
};
void setup() {
Nefry.enableSW(); //NefryBTのスイッチの有効化
BLEDevice::init("");
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_NO_MITM);
// Security Settings
BLESecurity *thingsSecurity = new BLESecurity();
thingsSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
thingsSecurity->setCapability(ESP_IO_CAP_NONE);
thingsSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
setupServices();
startAdvertising();
Serial.println("Ready to Connect");
}
void loop() {
uint8_t btnValue;
while (Nefry.readSW() && deviceConnected) {
Serial.println("SW!");
btnAction = 0;
btnValue = Nefry.readSW();
notifyCharacteristic->setValue(&btnValue, 1);
notifyCharacteristic->notify();
}
notifyCharacteristic->setValue(&btnValue, 1);
notifyCharacteristic->notify();
// Disconnection
if (!deviceConnected && oldDeviceConnected) {
delay(500); // Wait for BLE Stack to be ready
thingsServer->startAdvertising(); // Restart advertising
oldDeviceConnected = deviceConnected;
}
// Connection
if (deviceConnected && !oldDeviceConnected) {
oldDeviceConnected = deviceConnected;
}
}
void setupServices(void) {
// Create BLE Server
thingsServer = BLEDevice::createServer();
thingsServer->setCallbacks(new serverCallbacks());
// Setup User Service
userService = thingsServer->createService(USER_SERVICE_UUID);
// Create Characteristics for User Service
writeCharacteristic = userService->createCharacteristic(WRITE_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_WRITE);
writeCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
writeCharacteristic->setCallbacks(new writeCallback());
notifyCharacteristic = userService->createCharacteristic(NOTIFY_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_NOTIFY);
notifyCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
BLE2902* ble9202 = new BLE2902();
ble9202->setNotifications(true);
ble9202->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
notifyCharacteristic->addDescriptor(ble9202);
// Setup PSDI Service
psdiService = thingsServer->createService(PSDI_SERVICE_UUID);
psdiCharacteristic = psdiService->createCharacteristic(PSDI_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ);
psdiCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
// Set PSDI (Product Specific Device ID) value
uint64_t macAddress = ESP.getEfuseMac();
psdiCharacteristic->setValue((uint8_t*) &macAddress, sizeof(macAddress));
// Start BLE Services
userService->start();
psdiService->start();
}
void startAdvertising(void) {
// Start Advertising
BLEAdvertisementData scanResponseData = BLEAdvertisementData();
scanResponseData.setFlags(0x06); // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
scanResponseData.setName(DEVICE_NAME);
thingsServer->getAdvertising()->addServiceUUID(userService->getUUID());
thingsServer->getAdvertising()->setScanResponseData(scanResponseData);
thingsServer->getAdvertising()->start();
}
void buttonAction() {
btnAction++;
}
3. 試す
LINE ThingsのLIFFアプリ(とデバイス)を自前で作るの記事の”試す”部分を試します。
ファームがうまく書き込まれてNefry BTが起動すると、BLEアドバタイズをしてくれて、LINEアプリ側でデバイスを見つけることができます。
(今回は"LINE Things Starter"って表示になってると思いますが)、選択するとLIFFアプリが起動して試すことができます。
最初のGIFと一緒です。
https://www.instagram.com/p/BqrcdGnDg-Y/
まとめ
Nefry BTでもLINE Thingsが動きます。
公式対応のESP32 DevkitCでやれたのでわみさんに連絡したら、すぐに対応してくれたのがさすがです。
Nefry BTもESP32なので色々と活用考えられそうですね!
Nefry BT持ってる人は是非試してみて下さい〜 :)