Flutter + arduino nano 33 BLE sense = очень простой BLE sensor

    В этой статье я хочу рассказать как сделать очень простую bluetooth метеостанцию (куда уж без нее :) ) и написать мобильное приложение на Flutter для нее.



    В начале рассмотрим сам сенсор


    Для повторения понадобится плата Arduino nano 33 BLE sense.

    Плата построена на nrf52840. Устанавливаем ее через менеджер плат в ардуино.



    Сразу же установим необходимые библиотеки:


    Эти библиотеки необходимы для сенсоров, которые уже распаяны на самой плате.

    Немного теории, а дальше рассмотрим практическую реализацию


    Основная идея была в том, чтобы не делать подключаемое устройство, а реализовать широковещательные посылки с включением в них всей необходимой информации.

    Использовался режим обычной bluetooth метки, но с модификацией ManufacturerData. Этот пакет можно передавать в каждой advertise посылке.

    Общий размер advertise посылки 31 байт. Сюда входит вся необходимая информация: имя устройства, системные данные, пользовательские данные. В чистом виде пользователю в ManufacturerData остается около 20 байт. Этого хватает на передачу данных метеостанции.
    Преимущества такого способа передачи данных в более низком энергопотреблении, отсутствии необходимости держать постоянный коннект с устройством, широковещательная рассылка. Такое сообщение может поймать неограниченное количество приемников в радиусе приема.
    ManufacturerData устанавливается перед стартом адвертайзинга.

    А теперь практическая часть


    В коде ардуино указываем тип работы BLE части и задаем стартовый ManufacturerData
    Также для удобства я указываю имя устройства, так его проще искать в приложении.

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

    Начальные данные заданы как набор байтов, чтобы заполнить массив.

    Теперь в основном коде делаем остановку advertising, останавливаем радио производим замер необходимых данных и заполняем ManufacturerData уже реальными данными, после этого запускаем вещание обратно. Эта операция производится каждые 2 сек.

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

    На этом работа с датчиком закончена. Вещать датчик будет каждые 100мс и каждые 2сек обновлять данные на актуальные. Получился очень простой по коду и реализации метео сенсор.

    Теперь рассмотрим мобильное приложение


    Сразу сделаю оговорку: я не разработчик мобильных приложений.

    Для работы я использовал VSCode с плагином Flutter. Эта среда кажется проще, чем Android Studio, как мне показалось. Для работы с BLE использовалась библиотека Flutter_blue, которая сильно упростила подключение устройства.

    Логика работы приложения тоже достаточно простая. Наш сенсор вещает в режиме обычного Beacon, поэтому нужно выполнить всего пару действий:

    1. Просканировать эфир — найти устройство с заданным именем,
    2. Разобрать его ManufacturerData, чтобы отобразить данные на экране.

    Давайте посмотрим как это сделано.

    После старта приложения регулярно запускается таймер, который сканирует Bluetooth устройства каждые 10 сек в течение 2 сек. Чаще и дольше сканировать смысла нет, расход батареи увеличится, а датчик вещает вообще каждые 100мс.

    DeviceScanner() {
       _subscribeToScanEvents();
       _timer = new Timer.periodic(const Duration(seconds: 10), startScan);
     }
    
    void startScan(Timer timer) {
       FlutterBlue.instance.startScan(timeout: Duration(seconds: 2));
    }
    

    Дальше начинаем разбирать результаты сканирования, проверяем есть ли в списке сканирования устройство с заданным именем, и, если есть, то разбираем его посылку, и выводим результат пользователю.

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

    Небольшой нюанс. Bluetooth библиотека для Flutter может показаться странной, данные она получает в виде массива int, а в ардуино мы формируем посылку из байтов, поэтому в сенсоре я формировал посылку чтобы упростить ее анализ. Температура 25.85 градусов разбивается на два значения 25 и 85, которые отправляются в виде отдельных byte значений, и точно так же собираются обратно.

    В конечном результате получилось вот такое приложение.



    Исходный код проекта можно скачать с Github.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 11

      –4
      Скоро уже простой термометр назовут метеостанцией. А тут аж три параметра. Так этож Гидрометцентр уже. Ну а в целом за Flutter +1. Остальное не интересно
        –4

        Ну, не знаю за 30 долларов можно готовую метеостанцию купить.

          +3
          тут скорее интерес был просто запустить. Мне лично больше понравилась работа с бле со стороны Ардуино. Тем более не обязательно брать плату за 30 долларов можно и дешевле варианты найти.
          0
          По 6 баксов на али валом на nRF52832
            0
            Или ESP32 с BLE и WiFi
            0

            Может килопаскали перевести в мм ртутного столба?
            Или еще использовать как высотомер.

              0
              Можно. Просто цели не было. Была цель просто показать что можно легко сделать БЛЕ сенсор, а уже какую туда выводит ьинформацию и во что конвертировать решать вам.
                0
                Вобщем то это следует из названия статьи. Вы его точно не меняли? А то не пойму какого мне столько минусов напихали? Что я не прав, что это нифига ещё не метеостанция? А сейчас выглядит внатуре как будто я до столба докопался
                  0
                  В конкретной реализации я не задумывался о величинах. Можно и переделать. Метеостанция как пример была выбрана по нескольким причинам:
                  1. Их делают все кому не лень
                  2. На плате стоит весь набор датчиков изначально.
                  Если взять другую плату можно сделать термометр, гигрометр… да что угодно на самом деле
              +2
              Те кто пишут что проще купить, не понимают весь смысл радиолюбительства. Гораздо интересней собрать что то своими руками…
                0

                хорошая статья спасибо. теперь знаю как работать с Bluetooth на любом устройстве

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое