Arduino nano 33 BLE Senseを使って家の鍵の開閉状態を見える化してみた

# 目次
* 最初に
* Arduino nano 33 BLEとはなんぞや？
* この記事をおすすめする人
* 実装 ~Arduino nano 33 BLE Sense編~
* 実装 ~Raspberry Pi編~
* 実際に使ってみた
* 最後に



# 1. 最初に
外出時や就寝時、鍵が閉められているか気になりませんか...?
家から鍵の状態を確かめられたら便利ですよね^^


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936739/21953bc3-f791-1d28-bf2e-0d8fa6f96f0a.png" width=60%>

今回は手軽なマイコンを使って鍵状態を監視できるIoTシステムのプロトタイプを作ってみようと思います！

システム構成は以下の通りになっております。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936739/983010ab-e8fe-0c23-bfd9-151770785cc4.png)






# 2. Arduino nano 33 BLEとはなんぞや？
#### arduino nano 33 BLE senseって知ってますか...?



<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936739/1b12fa5c-3957-0d97-ff2b-fa95e5e98427.png" width=50%>

こいつこんな小さいのにすごいんです...

#### センサー
- 9軸センサ（IMU）
- 温湿度センサ
- 気圧センサ
- マイク
- ジェスチャー
- 色センサ

#### BLE接続
- BLE通信によるデータの送受信が可能

#### マイクロコントローラー
- 32ビットARM Cortex-M4Fプロセッサー
- 1MBフラッシュメモリ
- 256KB SRAM

#### その他機能
- 9軸センサフュージョン
- USB接続によるプログラムのアップロード
- TinyMLやTesorFlowなどの組み込み向けAIイメージ

これ一つでなんでもできますね！IoTの期待の星です！
購入先は[スイッチサイエンス](https://www.switch-science.com/products/7670)です。




# 3. この記事をおすすめする人
- Arduino nano 33 BLE Senseとはなんぞや？って人
- 小型マイコンを使ってIoTを作ってみたい人
- Arduino nano 33 BLE SenseでBLE通信したい人

# 4.  セットアップ・実装  ~Arduino nano 33 BLE Sense編~

```c

#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h>

BLEService dataService("19b10000-e8f2-537e-4f6c-d104768a1214"); //データのUUID
BLEFloatCharacteristic accChar("19b10001-e8f2-537e-4f6c-d104768a1214", BLERead | BLENotify); //加速度値のUUID
BLEFloatCharacteristic gyroChar("19b10002-e8f2-537e-4f6c-d104768a1214", BLERead | BLENotify); //ジャイロ値のUUID
BLEFloatCharacteristic magChar("19b10003-e8f2-537e-4f6c-d104768a1214", BLERead | BLENotify); //磁気センサーの値のUUID

void setup() {
  Serial.begin(9600);
  while (!Serial);

  if (!BLE.begin()) {
    Serial.println("BLE failed to initialize!");
    while (1);
  }

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  BLE.setLocalName("Nano33BLESense"); //BLEのデバイス名を設定
  BLE.setAdvertisedService(dataService); //advertised serviceを設定
  dataService.addCharacteristic(accChar); //characteristicをserviceに追加
  dataService.addCharacteristic(gyroChar); //characteristicをserviceに追加
  dataService.addCharacteristic(magChar); //characteristicをserviceに追加
  BLE.addService(dataService); //serviceを追加

  accChar.writeValue(0); 
  gyroChar.writeValue(0); 
  magChar.writeValue(0); 

  BLE.advertise(); //advertiseを開始
}

void loop() {
  float acc[3];
  float gyro[3];
  float mag[3];

  IMU.readAcceleration(acc[0], acc[1], acc[2]);
  IMU.readGyroscope(gyro[0], gyro[1], gyro[2]);
  IMU.readMagneticField(mag[0], mag[1], mag[2]);
 
  BLEDevice central = BLE.central();
  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());

    while (central.connected()) {
      float acc[3];
      float gyro[3];
      float mag[3];

      IMU.readAcceleration(acc[0], acc[1], acc[2]);
      IMU.readGyroscope(gyro[0], gyro[1], gyro[2]);
      IMU.readMagneticField(mag[0], mag[1], mag[2]);

      accChar.writeValue(acc[0]); //加速度値を送信
      gyroChar.writeValue(gyro[0]); //ジャイロ値を送信
      magChar.writeValue(mag[0]); //磁気センサーの値を送信

      delay(50); //データ送信の間隔を設定
    }
  }
}

```



# 5.  セットアップ・実装  ~raspberry pi編~

bluepyライブラリをインストールする必要があります。以下のコマンドでインストールできます。

```
$ sudo pip3 install bluepy
```


また、コード内のXX:XX:XX:XX:XX:XXを、実際のArduino Nano 33 BLE SenseのMACアドレスに置き換える必要があります。BLEデバイスのアドレスを取得するには、以下の手順を実行してください。

① Raspberry Pi上でBLEデバイスを検出するためのツールであるhcitoolをインストールします。以下のコマンドを実行してください。
```
$ sudo apt-get install bluez
```

② hcitoolを使って、周辺にあるBLEデバイスをスキャンします。以下のコマンドを実行してください。



```
$ sudo hcitool lescan
```
このコマンドを実行すると、BLEデバイスが検出されるまでスキャンが続きます。検出されたBLEデバイスのアドレスが表示されます。例えば、以下のような出力が表示されます。


```
C0:EE:40:13:AC:BA My_BLE_Device
```
この場合、BLEデバイスのアドレスはC0:EE:40:13:AC:BAです。
プログラム内にアドレスを入力してください。

### Arduino nanoからデータ受信し、開閉状態を内部ファイルに書き込みするプログラム
Z方向に重力加速度がかかっていれば、鍵があいている状態
Y方向に重力加速度がかかっていれば、鍵が閉まっている状態と判断し、内部ファイルに書き込んでいます。


```python
import csv
import time
from bluepy.btle import UUID, Peripheral

SERVICE_UUID = UUID('19b10000-e8f2-537e-4f6c-d104768a1214')
ACC_UUID = UUID('19b10001-e8f2-537e-4f6c-d104768a1214')

device_address = "XX:XX:XX:XX:XX:XX" # BLEデバイスのアドレスを指定
peripheral = Peripheral(device_address)

# 重力加速度
GRAVITY_THRESHOLD = 0.9

try:
    service = peripheral.getServiceByUUID(SERVICE_UUID)
    acc_char = service.getCharacteristics(ACC_UUID)[0]

    with open('key_status.csv', 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(["Time", "Key Status"]) # 列名の書き込み

        while True:
            acc_val = acc_char.read() # 返される値は[x,y,z]のリストを想定
            # 鍵の開閉状態の判断
            key_status = ""
            if abs(acc_val[2]) > GRAVITY_THRESHOLD: # Z方向に重力加速度がかかっていると判断
                key_status = "open"
            elif abs(acc_val[1]) > GRAVITY_THRESHOLD: # Y方向に重力加速度がかかっていると判断
                key_status = "close"
            else:
                key_status = "unknown"
            writer.writerow([time.time(), key_status]) # 時刻と鍵の状態を書き込み
            print("Acceleration: {}, Key status: {}".format(acc_val, key_status))
            time.sleep(0.1)

finally:
    peripheral.disconnect()

```



### crontabによって自動起動する開閉状態を送信してくれるプログラム

```python
import requests
import csv

# LINE NotifyのAPI URL
url = "https://notify-api.line.me/api/notify"
# LINE Notifyトークン
token = 'YOUR_LINE_NOTIFY_TOKEN'
headers = {"Authorization" : "Bearer "+ token}

# CSVファイル名
csv_file = 'key_status.csv'

# CSVファイルから最新の鍵の状態を取得
with open(csv_file, 'r') as f:
    reader = csv.reader(f)
    last_row = list(reader)[-1]
    key_status = last_row[1]

# 鍵の状態に基づいてメッセージを作成
if key_status == 'open':
    message = '現在家の鍵は開いています。'
elif key_status == 'close':
    message = '現在家の鍵は閉まっています。'

# LINE Notifyでメッセージを送信
payload = {"message" :  message}
r = requests.post(url ,headers = headers ,params=payload)
```



# 6. 実際に使ってみた
ベットから確認してみました。鍵は閉まっているみたいです！
安心してぐっすり寝れるぜ^^

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1936739/5c4e86f5-268f-db81-2759-3ee9a1a228f8.jpeg" width=50%>

# 7. 最後に

今回はArduino nano 33 BLE Senseを使って家の鍵の開閉状態を通知するシステムを作ってみました！
面白いと思っていただけましたらいいねお願いいたします！