一、根本操作
BLE客户端+windows BLE explorer

BLE客户端我们就选用ESP32,在之前一篇文章“开启esp32的蓝牙功能,通过BLE发送温湿度数据,并吸收反向掌握”中先容了,通过ArduinoIDE 烧录BLE代码并实现与window端 BLE Explorer工具的数据基本交互功能。
esp32
window桌面版蓝牙工具
在esp32代码中增加串口调试功能,方便调试过程中监测ble数据发送和吸收。
视频加载中...
BLE客户端+thingsboard gateway
thingsboard gateway 供应BLE的做事端功能。它借助python的bluepy库来实现基于蓝牙设备的操作。bluepy 是一个蓝牙开源项目,其紧张功能是用python实现linux上BLE的接口。
thingsboard gateway须要运行在一个有蓝牙的设备中,这里我们用Tinker board S。
tinker board s
tinker board s 系统安装可以参考该篇文章,链接:https://www.smartfire.cn/thread-999-1-1.html
配置系统的python环境,然后进入bluepy目录调试蓝牙搜索功能。如果涌现蓝牙列表解释tinker board S的python 蓝牙环境配置成功。
bluepy 的github地址:https://github.com/IanHarvey/bluepy.git
bluepy 扫描蓝牙客户端设备列表
thingsboard gateway的BLE配置
{ "checkIntervalSeconds": 10, "devices": [ { "MACAddress": "d8:a0:1d:5e:b8:7a", //要连接的BLE客户真个mac地址 "attributeUpdates": [ { "attributeOnThingsBoard": "sharedName", "characteristicUUID": "00002A00-0000-1000-8000-00805F9B34FB" } ], "attributes": [ { "byteFrom": 0, "byteTo": -1, "characteristicUUID": "00002A00-0000-1000-8000-00805F9B34FB", "key": "name", "method": "read" } ], "name": "Temperature and humidity sensor111", "serverSideRpc": [ { "characteristicUUID": "4AC8A682-9736-4E5D-932B-E9B31405049C", "methodProcessing": "write", "methodRPC": "sharedName", "withResponse": true } ], "telemetry": [ { "byteFrom": 0, "byteTo": 4, "characteristicUUID": "0972EF8C-7613-4075-AD52-756F33D4DA91", //特性ID "key": "temperature", "method": "notify" }, { "byteFrom": 6, "byteTo": -1, "characteristicUUID": "0972EF8C-7613-4075-AD52-756F33D4DA91", "key": "humidity", "method": "notify" } ] } ], "name": "BLE Connector", "passiveScanMode": true, "rescanIntervalSeconds": 100, "scanTimeSeconds": 5}
这个ble配置清单中有一些MAC地址和特性ID是须要事先通过其他办法得到,也便是见告thingsboard gateway主动找这个设备并读取数据。
MAC地址:在前面的bluepy项目中可以通过scanner.py 读取到name为:ESP32-BLE的mac地址
特性ID:可以参考thingsboard 官方文档给出的代码
from bluepy.btle import PeripheralMAC = "d8:a0:1d:5e:b8:7a" // 用上面的mac地址更换此处peripheral = Peripheral(MAC)for service in peripheral.getServices(): for characteristic in service.getCharacteristics(): print("Characteristic - id: %s\tname (if exists): %s\tavailable methods: %s" % (str(characteristic.uuid), str(characteristic), characteristic.propertiesToString()))
运行代码可以得到NOTIFY和WRITE两个的特色ID,这两个ID便是ESP32烧录的代码中提前定义好的两个特色ID。个中:NOTIFY用来发送温度湿度的数值,WRITE用来吸收反向写入。
运行结果截图
ESP32中烧录的代码
#include <BLEDevice.h>#include <BLEServer.h>#include <BLEUtils.h>#include <BLE2902.h>#include <Wire.h>#include <HTU21D.h>BLECharacteristic characteristicTX; //através desse objeto iremos enviar dados para o clientHTU21D myHTU21D(HTU21D_RES_RH12_TEMP14);bool deviceConnected = false; //controle de dispositivo conectadoconst int LED = 2; //LED interno do ESP32 (esse pino pode variar de placa para placa) // Could be different depending on the dev board. I used the DOIT ESP32 dev board.const int BUZZER = 23; //pino d BUZZER// See the following for generating UUIDs:// https://www.uuidgenerator.net/#define SERVICE_UUID "ab0828b1-198e-4351-b779-901fa0e0371e" // UART service UUID#define CHARACTERISTIC_UUID_RX "4ac8a682-9736-4e5d-932b-e9b31405049c"#define CHARACTERISTIC_UUID_TX "0972EF8C-7613-4075-AD52-756F33D4DA91"//callback para receber os eventos de conexão de dispositivosclass ServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer pServer) { deviceConnected = true; }; void onDisconnect(BLEServer pServer) { deviceConnected = false; }};//callback para envendos das característicasclass CharacteristicCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic characteristic) { //retorna ponteiro para o registrador contendo o valor atual da caracteristica std::string rxValue = characteristic->getValue(); //verifica se existe dados (tamanho maior que zero) if (rxValue.length() > 0) { Serial.println(""); Serial.print("Received Value: "); for (int i = 0; i < rxValue.length(); i++) { Serial.print(rxValue[i]); } Serial.println(); // Do stuff based on the command received if (rxValue.find("L1") != -1) { Serial.print("Turning LED ON!"); digitalWrite(LED, HIGH); } else if (rxValue.find("L0") != -1) { Serial.print("Turning LED OFF!"); digitalWrite(LED, LOW); } // Do stuff based on the command received from the app else if (rxValue.find("B1") != -1) { Serial.print("Turning Buzzer ON!"); digitalWrite(BUZZER, HIGH); } else if (rxValue.find("B0") != -1) { Serial.print("Turning Buzzer OFF!"); digitalWrite(BUZZER, LOW); } else if (rxValue.find("motor") != -1) { digitalWrite(27, HIGH); delay(1000); digitalWrite(27, LOW); } Serial.println(); Serial.println(""); } }};void setup() { Wire.begin(); Serial.begin(115200); pinMode(27,OUTPUT); while (myHTU21D.begin() != true) { Serial.println(F("HTU21D, SHT21 sensor is faild or not connected")); //(F()) saves string to flash & keeps dynamic memory free delay(5000); } Serial.println(F("HTU21D, SHT21 sensor is active")); pinMode(LED, OUTPUT); pinMode(BUZZER, OUTPUT); // Create the BLE Device BLEDevice::init("ESP32-BLE"); // nome do dispositivo bluetooth // Create the BLE Server BLEServer server = BLEDevice::createServer(); //cria um BLE server server->setCallbacks(new ServerCallbacks()); //seta o callback do server // Create the BLE Service BLEService service = server->createService(SERVICE_UUID); // Create a BLE Characteristic para envio de dados characteristicTX = service->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY ); characteristicTX->addDescriptor(new BLE2902()); // Create a BLE Characteristic para recebimento de dados BLECharacteristic characteristic = service->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE ); characteristic->setCallbacks(new CharacteristicCallbacks()); // Start the service service->start(); // Start advertising (descoberta do ESP32) server->getAdvertising()->start(); //Inicializa sensor de temperatura infravermelho Serial.println("Waiting a client connection to notify...");}void loop() { float temperatureC = myHTU21D.readTemperature(); float humidityC = myHTU21D.readHumidity(); Serial.println(temperatureC); String r; r = String(temperatureC)+","+String(humidityC); //se existe algum dispositivo conectado if (deviceConnected) { //chamamos o método "read" do sensor para realizar a leitura da temperatura //read retornará 1 caso consiga realizar a leitura, ou 0 caso contrário // Let's convert the value to a char array: char txString[10]; // make sure this is big enuffz //dtostrf(r, 1, 2, txString); // float_val, min_width, digits_after_decimal, char_buffer strncpy(txString, r.c_str(), r.length() + 1); characteristicTX->setValue(txString); //seta o valor que a caracteristica notificará (enviar) characteristicTX->notify(); // Envia o valor para o smartphone Serial.print(" Sent Value: "); Serial.print(txString); Serial.println(" "); / delay(1000); characteristicTX2->setValue("Hello!"); // Sending a test message characteristicTX2->notify(); // Send the value to the app!/ } delay(1000);}
经由前面的折腾后,把得到的MAC地址和特色ID配置到BLE.json,开始运行thingsboard gateway来查看数据。
二、运行thingsboard gateway
还是和其他协议配置逻辑一样,在thingsboard的平台创建网关类型设备再把token和ip、port地址copy到gateway的yaml文件中。准备事情到此终于结束了,开始运行tb_gateway.py。
创建网关类型设备,copy设备token
配置tb_gateway.yaml
运行tb_gateway.py
设备创建成功
遥测数据也上来了
三、配置仪表板
通过卡片部件展示遥测数据;
截图中间的反向掌握部件是根据实际需求基于小部件库做的扩展部件,方便快速修正method和params用于调试。
最右侧的send rpc这个部件也可以调试,便是修正method、params参数不是很方便;
仪表板
发送rpc,esp32的串口调试助手收到params的数据
视频加载中...
参考文档:
bluepy https://www.cnblogs.com/zjutlitao/p/10171913.html
thingsboard gateway for BLE https://thingsboard.io/docs/iot-gateway/guides/how-to-connect-ble-sensor-using-gateway/#how-to-get-characteristic-identifiers-list-from-ble-device








