Flutter + arduino nano 33 BLE sense = sensor BLE muito simples

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);
// start advertising
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();
// read all the sensor values
---------------------
       
---------------------
byte data[8] = { 0x00, 0x01, t1, t2, h1, h2, p1, p2}; // t -  (2 ), h -  (2 ), p -  (2 )
BLE.setManufacturerData(data, 8);
BLE.advertise();
// wait 2 second to print again
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:

  1. Transmissão de digitalização - encontre o dispositivo com o nome,
  2. 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 .

All Articles