obniz に ToFセンサ( VL53L1X レーザー距離測定 ) と カメラ ( ArduCAMMini )を繋ぐ

obniz に ToFセンサ とカメラを繋ぐ方法のまとめ。

# ToFセンサ(レーザー距離測定) 
4m まで測定する事ができる VL53L1X ToFレーザー測距センサモジュール を 利用します。


<img width="505" alt="スクリーンショット 2019-03-28 23.03.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/100147/423c9c1c-d2d8-03da-f2c0-5840113d9a1a.png">

[GY-53-L1X](https://ja.aliexpress.com/item/GY-53-L1X-VL53L1X-TOF-arduino/32960031135.html) [aliexpress]
STM32が実装されていてUARTから距離データを取得できるモジュール
このモジュールがかなり便利なので aliexpress から購入すると実装がかなり楽になります。

[GY-53-L0X 仕様書](http://img.banggood.com/file/products/20180830020532SKU645408.pdf)
UART等の通信仕様が同じなので参考にする。

参考
[Amazonよりだいぶ安い！AliExpressでガジェットの購入に挑戦してみた](https://hagane-ya.net/archives/8679)

# ArduCAMMini カメラ
obniz.jsに標準で含まれている ArduCAMMini OV2640の2Mピクセル カメラを利用します。

![3780_001_9WoIsEn.jpg](https://qiita-image-store.s3.amazonaws.com/0/100147/23d3a170-6e50-7ea7-ef90-e31bc414cb3c.jpeg)

[ArduCAMMini OV2640の2Mピクセル](https://www.switch-science.com/catalog/3780/)

obniz.jsに標準で含まれている ので利用がかなり簡単です。

# 電源回路
obnizの端子からの電源では　電流がたりなくて 不安定になる可能性があるので
別で電源回路を用意します。

[ブレッドボード用電源ボード5V/3.3V切り替え式](https://www.switch-science.com/catalog/2243/)
[ACアダプター 9V/1.3A](https://www.switch-science.com/catalog/1795/)

# GY-53-L1X, ArduCAMMini 接続方法
VCC,GND 以外を obniz に接続する。 VCC,GND は別電源回路から5Vを供給。

```
ArduCAMMini
cs:0, mosi:1, miso:2, sclk:3, sda:4, scl:5

GY-53-L1X
tx:6, rx:7
```

# プログラム
距離が近くなったら 撮影して ブラウザに撮影した画像を表示するコードを書いてみます。

## ArduCAMMini を動かしてみる
obniz.jsに標準のライブラリを使ったサンプルが動作するか確認。

```
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@latest/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<img id="image">

<script>
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  var cam = obniz.wired("ArduCAMMini", { cs:0, mosi:1, miso:2, sclk:3, sda:4, scl:5 });
  await cam.startupWait();
  const data = await cam.takeWait('1024x768');
  console.log("image size = " + data.length + " bytes");

  const base64 = cam.arrayToBase64(data);
  document.getElementById("image").src = "data:image/jpeg;base64, " + base64;
}
</script>
</body>
</html>
```

## VL53L1X レーザー距離測定 を動かしてみる
距離を測定して 画面に表示してみるサンプル
[GY-53-L0X 仕様書](http://img.banggood.com/file/products/20180830020532SKU645408.pdf) UARTの通信仕様などが同じなので参考にデータを取得してみる。

```
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@latest/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<div id="distance">---</div>

<script>
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  var uart = obniz.getFreeUart();  
  uart.onreceive = function(data, text) {
    if(data[0] == 0x5A){
      if(data[1] == 0x5A){
        if(data[2] == 0x15){
          if(data[3] == 0x03){
            var distance = data[4] << 8 | data[5];
            //obniz.display.clear();
            //obniz.display.print("distance "+distance);
            console.log({"distance":distance});
            $("#distance").text(distance+" mm");
          }
        }
      }
    }
  }
  uart.start({rx: 6, tx: 7, baud:9600, bits:8, stop:1});
}
</script>
</body>
</html>
```

## 距離が近くなったら 撮影して ブラウザに撮影した画像を表示する
2つのサンプルを組み合わせて 1m 以内になったら撮影するサンプル。

```
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@latest/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<div id="distance">---</div>
<img id="image">

<script>
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
  var cam = obniz.wired("ArduCAMMini", { cs:0, mosi:1, miso:2, sclk:3, sda:4, scl:5 });

  var uart = obniz.getFreeUart();  
  uart.onreceive = function(data, text) {
    if(data[0] == 0x5A){
      if(data[1] == 0x5A){
        if(data[2] == 0x15){
          if(data[3] == 0x03){
            var distance = data[4] << 8 | data[5];
            //obniz.display.clear();
            //obniz.display.print("distance "+distance);
            console.log({"distance":distance});
            $("#distance").text(distance+" mm");
            // 1000 mm 以下の場合 撮影して表示する
            if(distance < 1000){
                await cam.startupWait();
                const data = await cam.takeWait('1024x768');
                console.log("image size = " + data.length + " bytes");

                const base64 = cam.arrayToBase64(data);
                document.getElementById("image").src = "data:image/jpeg;base64, " + base64;
            }
          }
        }
      }
    }
  }
  uart.start({rx: 6, tx: 7, baud:9600, bits:8, stop:1});
}
</script>
</body>
</html>
```