Neste artigo, quero dizer como criar uma estação meteorológica bluetooth muito simples (onde sem ela :)) e escrever um aplicativo móvel no Flutter para ela.
No começo, considere o próprio sensor
Para repetir, você precisará de uma placa de detecção do Arduino nano 33 BLE .A placa é construída no nrf52840. Nós o instalamos através do gerente do conselho no arduino.
Instale imediatamente as bibliotecas necessárias:Essas bibliotecas são necessárias para sensores que já estão soldados na própria placa.Um pouco de teoria e considere a implementação prática
A idéia principal não era criar um dispositivo plug-in, mas implementar mensagens de difusão com todas as informações necessárias incluídas neles.O modo de tag bluetooth usual foi usado, mas com a modificação ManufacturerData. Este pacote pode ser transmitido em todos os pacotes de publicidade.O tamanho total de um pacote de publicidade é de 31 bytes. Isso inclui todas as informações necessárias: nome do dispositivo, dados do sistema, dados do usuário. Em sua forma pura, o usuário no ManufacturerData tem cerca de 20 bytes. Isso é suficiente para transmitir dados da estação meteorológica.As vantagens deste método de transmissão de dados em menor consumo de energia, sem necessidade de manter uma conexão constante com o dispositivo, transmitem. Essa mensagem pode capturar um número ilimitado de receptores no raio de recepção.ManufacturerData é instalado antes do início da publicidade.E agora a parte prática
No código do arduino, indicamos o tipo de trabalho da peça BLE e definimos os dados de fabricante, além de, por conveniência, especificar o nome do dispositivo, para facilitar a localização no aplicativo.BLE.setLocalName("nrf52840.ru");
BLE.setConnectable(false);
byte data[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
BLE.setManufacturerData(data, 8);
BLE.advertise();
Os dados iniciais são fornecidos como um conjunto de bytes para preencher a matriz.Agora, no código principal, paramos de anunciar, paramos o rádio, medimos os dados necessários e preenchemos os dados do fabricante com dados reais e depois começamos a transmitir de volta. Esta operação é realizada a cada 2 segundos.BLE.stopAdvertise();
---------------------
---------------------
byte data[8] = { 0x00, 0x01, t1, t2, h1, h2, p1, p2};
BLE.setManufacturerData(data, 8);
BLE.advertise();
delay(2000);
Isso completa o trabalho com o sensor. O sensor transmitirá a cada 100ms e a cada 2seg atualizará os dados para os atuais. O resultado foi um código climático muito simples e um sensor de implementação.Agora considere o aplicativo móvel
Farei uma reserva imediatamente: não sou desenvolvedor de aplicativos para dispositivos móveis.Para o trabalho, usei o VSCode com o plugin Flutter. Esse ambiente parece mais simples que o Android Studio, como eu pensava. Para trabalhar com o BLE, foi usada a biblioteca Flutter_blue , que simplificou bastante a conexão do dispositivo.A lógica do aplicativo também é bastante simples. Nosso sensor é transmitido no modo Beacon normal, portanto, você só precisa executar algumas ações:- Transmissão de digitalização - encontre o dispositivo com o nome,
- Analise-o ManufacturerData para exibir dados na tela.
Vamos ver como isso é feito.Depois de iniciar o aplicativo, um timer é iniciado regularmente, que verifica os dispositivos Bluetooth a cada 10 segundos por 2 segundos. Não faz sentido digitalizar com mais frequência e mais tempo, o consumo da bateria aumenta e o sensor geralmente é transmitido a cada 100ms.DeviceScanner() {
_subscribeToScanEvents();
_timer = new Timer.periodic(const Duration(seconds: 10), startScan);
}
void startScan(Timer timer) {
FlutterBlue.instance.startScan(timeout: Duration(seconds: 2));
}
Em seguida, começamos a analisar os resultados da verificação, verificamos se há um dispositivo com um nome determinado na lista de verificação e, se houver, analisamos o pacote e exibimos o resultado para o usuário.
void _subscribeToScanEvents() {
FlutterBlue.instance.scanResults.listen((scanResults) {
for (ScanResult scanResult in scanResults) {
if (scanResult.device.name.toString() == "nrf52840.ru") {
final int rssi = scanResult.rssi;
final String name = scanResult.device.name;
final String mac = scanResult.device.id.toString();
final double temp = scanResult.advertisementData.manufacturerData[256]
[0] +
scanResult.advertisementData.manufacturerData[256][1] * 0.01;
final double humm = scanResult.advertisementData.manufacturerData[256]
[2] +
scanResult.advertisementData.manufacturerData[256][3] * 0.01;
final double press =
scanResult.advertisementData.manufacturerData[256][4] +
scanResult.advertisementData.manufacturerData[256][5] * 0.01;
final SensorData sensorData = new SensorData(
name: name,
rssi: rssi,
mac: mac,
temperature: temp,
humidity: humm,
pressure: press);
_streamController.add(sensorData);
print(
'Manufacturer data ${scanResult.advertisementData.manufacturerData}');
FlutterBlue.instance.stopScan();
}
print(
'${scanResult.device.name} found! mac: ${scanResult.device.id} rssi: ${scanResult.rssi}');
}
});
}
Um pouco de nuance. A biblioteca Bluetooth para Flutter pode parecer estranha, ela recebe os dados na forma de uma matriz int e, no arduino, formamos um pacote a partir de bytes, então formei um pacote no sensor para simplificar sua análise. A temperatura de 25,85 graus é dividida em dois valores 25 e 85, que são enviados como valores de bytes separados e são coletados da mesma maneira.O resultado final é esse aplicativo.
O código-fonte do projeto pode ser baixado no Github .