Flutter + arduino nano 33 BLE sense = sensor BLE muy simple

En este artículo quiero decir cómo hacer una estación meteorológica bluetooth muy simple (sin ella :)) y escribir una aplicación móvil en Flutter para ello.



Al principio, considere el sensor en sí


Para repetir, necesitará una placa de detección Arduino nano 33 BLE .

El tablero está construido en nrf52840. Lo instalamos a través del administrador de la placa en arduino.



Instale inmediatamente las bibliotecas necesarias:


Estas bibliotecas son necesarias para sensores que ya están soldados en la placa.

Un poco de teoría, y luego considere la implementación práctica


La idea principal no era hacer un dispositivo enchufable, sino implementar mensajes de difusión con toda la información necesaria incluida en ellos.

Se usó el modo habitual de etiqueta bluetooth, pero con la modificación ManufacturerData. Este paquete se puede transmitir en cada paquete publicitario.

El tamaño total de un paquete publicitario es de 31 bytes. Esto incluye toda la información necesaria: nombre del dispositivo, datos del sistema, datos del usuario. En su forma pura, el usuario en ManufacturerData tiene aproximadamente 20 bytes. Esto es suficiente para transmitir datos de la estación meteorológica.
Las ventajas de este método de transmisión de datos en el menor consumo de energía, no es necesario mantener una conexión constante con el dispositivo, la transmisión. Tal mensaje puede atrapar un número ilimitado de receptores en el radio de recepción.
ManufacturerData se instala antes del inicio de la publicidad.

Y ahora la parte práctica


En el código arduino, indicamos el tipo de trabajo de la parte BLE y establecemos los datos de inicio del fabricante.
Además, por conveniencia, especifico el nombre del dispositivo, por lo que es más fácil de encontrar en la aplicación.

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();

Los datos iniciales se proporcionan como un conjunto de bytes para llenar la matriz.

Ahora, en el código principal, dejamos de anunciar, detenemos la radio, medimos los datos necesarios y completamos ManufacturerData con datos reales, luego comenzamos a transmitir. Esta operación se realiza 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);

Esto completa el trabajo con el sensor. El sensor emitirá cada 100 ms y cada 2 segundos actualizará los datos a los actuales. El resultado fue un código meteorológico muy simple y un sensor de implementación.

Ahora considere la aplicación móvil


Haré una reserva de inmediato: no soy un desarrollador de aplicaciones móviles.

Para el trabajo, utilicé VSCode con el complemento Flutter. Este entorno parece más simple que Android Studio, como pensé. Para trabajar con BLE, se utilizó la biblioteca Flutter_blue , lo que simplificó enormemente la conexión del dispositivo.

La lógica de la aplicación también es bastante simple. Nuestro sensor transmite en modo Beacon normal, por lo que solo necesita realizar un par de acciones:

  1. Escanear difusión: busque el dispositivo con el nombre,
  2. Analizarlo Datos del fabricante para mostrar los datos en la pantalla.

Veamos cómo se hace esto.

Después de iniciar la aplicación, se inicia regularmente un temporizador, que escanea los dispositivos Bluetooth cada 10 segundos durante 2 segundos. No tiene sentido escanear con mayor frecuencia y durante más tiempo, el consumo de batería aumentará y el sensor transmite generalmente cada 100 ms.

DeviceScanner() {
   _subscribeToScanEvents();
   _timer = new Timer.periodic(const Duration(seconds: 10), startScan);
 }

void startScan(Timer timer) {
   FlutterBlue.instance.startScan(timeout: Duration(seconds: 2));
}

A continuación, comenzamos a analizar los resultados del análisis, verificamos si hay un dispositivo con un nombre en la lista de análisis y, de ser así, analizamos su paquete y mostramos el resultado al usuario.


  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}');
      }
    });
  }

Un pequeño matiz. La biblioteca Bluetooth para Flutter puede parecer extraña, recibe los datos en forma de una matriz int, y en arduino formamos un paquete a partir de bytes, por lo que formé un paquete en el sensor para simplificar su análisis. La temperatura de 25.85 grados se divide en dos valores 25 y 85, que se envían como valores de byte separados y se recopilan de la misma manera.

El resultado final es una aplicación de este tipo.



El código fuente del proyecto se puede descargar desde Github .

All Articles