Flutter + arduino nano 33 BLE sense = مستشعر BLE بسيط جدًا

في هذه المقالة ، أريد أن أخبرك عن كيفية إنشاء محطة طقس بلوتوث بسيطة للغاية (حيث بدونها :)) وكتابة تطبيق محمول على Flutter لذلك.



في البداية ، ضع في اعتبارك المستشعر نفسه


للتكرار ، ستحتاج إلى لوحة استشعار Arduino nano 33 BLE .

المجلس مبني على nrf52840. نقوم بتثبيته من خلال مدير المجلس في اردوينو.



قم بتثبيت المكتبات اللازمة على الفور:


هذه المكتبات ضرورية لأجهزة الاستشعار التي تم لحامها بالفعل على اللوحة نفسها.

قليلا من النظرية ، ثم النظر في التنفيذ العملي


لم تكن الفكرة الرئيسية هي إنشاء جهاز إضافي ، ولكن تنفيذ رسائل البث مع جميع المعلومات الضرورية المضمنة فيها.

تم استخدام وضع علامة البلوتوث المعتاد ، ولكن مع تعديل ManufacturerData. يمكن إرسال هذه الحزمة في كل حزمة إعلان.

الحجم الكلي لحزمة الإعلان هو 31 بايت. يتضمن ذلك جميع المعلومات اللازمة: اسم الجهاز وبيانات النظام وبيانات المستخدم. في شكلها الخالص ، يبلغ حجم المستخدم في ManufacturerData حوالي 20 بايت. هذا يكفي لنقل بيانات محطة الطقس.
مزايا هذه الطريقة لنقل البيانات في استهلاك طاقة أقل ، لا حاجة للحفاظ على اتصال مستمر مع الجهاز ، البث. يمكن لمثل هذه الرسالة التقاط عدد غير محدود من أجهزة الاستقبال في دائرة الاستقبال.
يتم تثبيت بيانات المصنع قبل بدء الإعلان.

والآن الجزء العملي


في كود اردوينو ، نشير إلى نوع عمل جزء BLE وقم بتعيين بدء بيانات المصنع
، ولتحقيق الراحة ، حدد اسم الجهاز ، بحيث يسهل العثور عليه في التطبيق.

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

يتم إعطاء البيانات الأولية كمجموعة من البايت لملء الصفيف.

الآن في الكود الرئيسي ، نتوقف عن الإعلان ، ونوقف الراديو ، ونقيس البيانات الضرورية ونملأ بيانات المصنع ببيانات حقيقية ، ثم نبدأ البث مرة أخرى. تتم هذه العملية كل ثانيتين.

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. قم بتحليل بيانات المُصنِّع لعرض البيانات على الشاشة.

دعونا نرى كيف يتم ذلك.

بعد بدء التطبيق ، يتم تشغيل مؤقت بشكل منتظم ، والذي يقوم بمسح أجهزة Bluetooth كل 10 ثوانٍ لمدة ثانيتين. ليس من المنطقي إجراء مسح ضوئي أكثر وأكثر لفترة أطول ، وسيزداد استهلاك البطارية ، ويقوم جهاز الاستشعار ببث كل 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 ، وفي arduino نشكل حزمة من وحدات البايت ، لذلك قمت بتشكيل حزمة في المستشعر لتبسيط تحليلها. تنقسم درجة الحرارة 25.85 درجة إلى قيمتين 25 و 85 ، يتم إرسالهما كقيم بايت منفصلة ، ويتم جمعهما بنفس الطريقة.

والنتيجة النهائية مثل هذا التطبيق.



يمكن تنزيل شفرة مصدر المشروع من Github .

All Articles