ラズベリーパイ、Arduinoに会ってください.ラズベリーパイ.ブルートゥースを話しましょう


数ヶ月前に私はブログの記事を書いたArduino Nano 33 IoT とどのようにオンボードのBluetoothモジュールの相互作用する.その時私はNordic Semiconductor's nRF Connect App StoreからArduinoと対話するツール.このポストで、私は私がしたものを構築して、Arduinoと対話するためにラズベリーパイを使います.
そこには私の仕事をより簡単にすることができるいくつかの良い立派なヘルパーライブラリがあります.しかし、すべてが等しく作成されるわけではありませんが、いくつかは周辺のBLUEアプリケーションを構築するのに最適かもしれませんが、中央のBLUEアプリケーションに最適ではないかもしれません.私はラズベリーパイをクライアントにするつもりです.Bleak 偉大な使用することです.BLACKはGATTクライアントソフトウェアで、GATTサーバとして機能するブルデバイスに接続することができます.これは、非同期、クロスプラットフォームPython APIを接続し、他のデバイスとの通信などのセンサーを提供するように設計されます.
シナリオは以下のシーケンス図によって記述されます.

上の図は3つの主要な要素から成ります.
  • ラズベリーパイ
  • Arduinoナノ33 iot
  • スイッチ
  • ラズベリーパイ
    ラズベリーパイはオペレーティングシステムを持つ単一のボードコンピュータ(SBC)です、そして、それがオペレーティングシステムによって管理されるので、我々はマルチタスクのようなPCに関して、我々が同じような利益を得て、パイソンとCのようなより高い言語を使っているアプリケーションを開発します.NETアプリケーションとリストが有効になります.一方、オペレーティングシステムによって管理されていることは、低レベルのサービスへのアクセスとハードウェアリソースが単純ではないことを意味します.
    このケースのラズベリーパイは、特にArduino装置を捜して、ブルクライアントとして機能しています.一旦発見されると、それはArduinoに接続して、スイッチの状態が変化するとき、通知されるために登録されます.
    Arduinoナノ33 iot
    Arduinoナノ33 IoBoardはマイクロコントローラで、オペレーティングシステムがなく、C/C +のような下位レベルの言語を使用して書かれた単一のプログラムをホストしています.このボードは非常に簡単に私はラズベリーパイとArduinoボードを参照してくださいなぜではなく、補完的なデバイスとして競合するデバイスとしてデバイスを動作するように簡単になります.は、ローカルネットワークとインターネットの間のゲートウェイとしてラズベリーパイを使用して、ローカルセンサー/アクチュエータに話をするArduinoボードを使用してください.
    この場合のArduinoナノ33 IOTボードは、スイッチの現在の状態を記述する特性からなるブルGATTサーバとして機能する.スイッチの状態が変更されると、Arduinoボードは新しい状態の任意の登録クライアントに通知します.
    スイッチ
    スイッチは、Arduino上のGPIO線を制御する物理デバイスである.押されると、ラインはハイに設定されます.押されると、ラインはローに設定されます.

    raspberry pi上のPython環境の設定


    BLACKはPythonライブラリですので、Raspberry Pi上でPython 3仮想環境を設定し、Blaakをインストールしましょう.

    今すぐ荒れをインストールします.
        (venv) pi@raspberrypi:~/Workspace/ble_client $ pip install bleak
        Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
        Collecting bleak
        Using cached https://www.piwheels.org/simple/bleak/bleak-0.12.1-py2.py3-none-any.whl (123 kB)
        Collecting dbus-next
        Using cached https://www.piwheels.org/simple/dbus-next/dbus_next-0.2.3-py3-none-any.whl (57 kB)
        Installing collected packages: dbus-next, bleak
        Successfully installed bleak-0.12.1 dbus-next-0.2.3
        (venv) pi@raspberrypi:~/Workspace/ble_client $ pip list
        Package    Version
        ---------- -------
        bleak      0.12.1
        dbus-next  0.2.3
        pip        21.2.4
        setuptools 57.4.0
        wheel      0.37.0
        venv) pi@raspberrypi:~/Workspace/ble_client $
    

    Arduinoナノ33 IOTボードを設定する


    次のArduinoスケッチをナノ33のIOTボードにロードします.これは、実際のコードと同じですBeyond The Built-In LED 投稿しました.
        #include <ArduinoBLE.h>
    
        #define SWITCH_PIN 2u
    
        static bool isPressed;
    
        BLEService switchService("8158b2fd-94e4-4ff5-a99d-9a7980e998d7");
        BLEByteCharacteristic switchServiceCharacteristic("8158b2fe-94e4-4ff5-a99d-9a7980e998d7", BLERead | BLENotify);
    
        void setup()
        {
            Serial.begin(19200);
            pinMode(LED_BUILTIN, OUTPUT);
            pinMode(SWITCH_PIN, INPUT);
            isPressed = false;
    
            if (!BLE.begin())
            {
                /* Just keep looping until BLE module is up and running. */
                while (1);
            }
    
            /* BLE module is up and running, now add our service and characteristic to it. */
            BLE.setLocalName("My Arduino");
    
            switchServiceCharacteristic.writeValue(isPressed);
            switchService.addCharacteristic(switchServiceCharacteristic);
            BLE.addService(switchService);
    
            BLE.setAdvertisedService(switchService);
            BLE.advertise();
            Serial.println("My Arduino started");
        }
    
        void loop()
        {
            BLE.poll();
    
            if (digitalRead(SWITCH_PIN) == HIGH)
            {
                if (!isPressed)
                {
                    digitalWrite(LED_BUILTIN, HIGH);
                    isPressed = true;
                    switchServiceCharacteristic.writeValue(isPressed);
                    Serial.println("Switch is pressed");
                }
            }
            else
            {
                if (isPressed)
                {
                    digitalWrite(LED_BUILTIN, LOW);
                    isPressed = false;
                    switchServiceCharacteristic.writeValue(isPressed);
                    Serial.println("Switch is depressed");
                }
            }
        }
    
    さて、ARDUCIOシリアルポートに端末を使って接続したらPutty たとえば、スイッチが押されて押されたときにコンソールのログを見ることができるはずです.

    話しましょう


    上記のスケッチで、私はArduinoボードにブルートゥース装置名を与えましたMy Arduino . 私はその後、1つの特性を持つサービスを追加し、また、この特性はread or be notified を返します.
    ちょうど横のメモとして、ラズベリーパイがブルートゥース接続を始めたので、それは、ブル中心装置(クライアント)と考えられます.一方、Arduinoボードは接続要求を受け入れて、サービスを提供しています、それは、ブル周辺機器(サーバー)と考えられます.
    いくつかのPythonコードをラズベリーパイに追加してください.
        import asyncio
        import sys
    
        from bleak import BleakScanner
        from bleak.backends.bluezdbus.client import BleakClientBlueZDBus
    
        device_name = "My Arduino"
        switch_status_char_uuid = "8158b2fe-94e4-4ff5-a99d-9a7980e998d7"
    
        def notification_handler(sender, data):
            print("Switch is active: {}".format(bool(data[0])))
    
        async def run():
            client = None
            device = await BleakScanner.find_device_by_filter(
                lambda d, ad: d.name and d.name.lower() == device_name.lower()
            )
    
            if device is None:
                print("{} not found".format(device_name))
                sys.exit()
            else:
                print("{} found".format(device))
    
            client = BleakClientBlueZDBus(device)
    
            while True:
                if not client.is_connected:
                    try:
                        if await client.connect():
                            print("Connected to {}".format(device_name))
                            await client.start_notify(switch_status_char_uuid, notification_handler)
                    except:
                        print("Connected to {} failed or lost".format(device_name))
                        await asyncio.sleep(1)
                        client = BleakClientBlueZDBus(device)
                        print("Retrying...")
                else:
                    await asyncio.sleep(1)
    
        loop = asyncio.get_event_loop()
        loop.run_until_complete(run())
    
    基本的には、上記のPythonコードは何の名前で特定のブルデバイスのスキャンですかMy Arduino . 範囲内にあるならば、それはそれにつながります.その後、プログラムはスイッチ状態の特性を監視し始め、アップデートが受信されると、それはNotificationRange handler ()で処理されます.

    行動しましょう


    以下に短いクリップを示します.
  • ポータブルUSB充電器によって動かされるArduinoナノ33 iot
  • Arduinoに接続されたスイッチ
  • SSH経由でラズベリーピアに接続電話Termius )
  • 我々が見ることができるように、スイッチが押されるか、押されるとき、我々は電話がBLUE通知を受けるのを見ることができます.
    それは基本的には、スイッチである必要はありません.我々は(アナログまたはデジタル)好きなセンサーを接続することができますし、必要に応じてArduinoデバイスに必要なブルのサービスを追加します.

    This blog post was originally posted on my blog site An IoT Odyssey