M5Stackに繋いだセンサーの値を、Electronに送ってみる１ー M5Stack編 ー

# はじめに
ElectronとVueを使ってデスクトップアプリを作っていますが、画面の操作を、タッチパネル以外に、物理的なボタンやセンサーを使って操作したい事がたまにあります。
今回はそんなセンサーの値をElectronに送って、画面を動かす方法をM5Stackを使って作っていきたいと思います。
また、M5StackはBluetoothやWifiなど、無線での操作もできると思いますが、今回はUSBを使って、有線でシリアルポートの値を受け取ってみたいと思います。

この記事はボリュームが大きくなってしまったので、２回に分かれています。
[ー M5Stack編 ー（この記事です）](#)
[ー Electron編 ー](https://qiita.com/kaluna/items/6b4b4bc67ef131dc1088)
# 環境
- vue : 3.0.0
- electron : 13.0.0
- serialport:10.4.0
- Arduino IDE
- WebStorm
- Windows10 Home
# 今回使ったセンサー類
- [M5Stack M5Go](https://www.switch-science.com/catalog/7363/)
- [M5Stack用 ToF測距センサユニット](https://www.switch-science.com/catalog/5219/)
- [M5Stack用 回転角ユニット](https://www.switch-science.com/catalog/6551/)
- LEGO Technicsパーツ色々
![M5Stack01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/a594a9c4-b5e0-c4de-ef62-2b1d180ea961.png)
M5Goの背面はLEGOが付けれるようになっていますので、LEGOが家にあれば、色々くっつけて、簡易な台とか作れて楽しいですよ。
# M5Stack の設定
M5StackをArduino IDEで使えるようにするまでの準備は、「[M5StackをArduino IDEで使えるようにする](https://qiita.com/kaluna/items/087d3458cd0b349bcc7c)」を参照してください。
今回はこの準備が出来ていると仮定して進めて行きたいと思います。
## M5Stack とセンサーを繋げる
今回使うセンサーは**ToFセンサー**と、**ANGLEセンサー**を使っていきたいと思います。
![写真 2022-04-26 8 59 06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/8c40eedf-5ce5-c640-4651-31db2ed523bb.jpeg)
**ToFセンサー**は、`PORT-A` を使い、**ANGLEセンサー**は、`PORT-B` を使いますので、それぞれのPORTにつなげていきます。
![写真 2022-04-26 9 01 53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/b1e45964-07d1-d4b7-5392-38cc16e0e3db.jpeg)
このまま使うと、各センサーが軽いので、ケーブルのひねりに負けて、変な方向に向いたりしちゃうので、今回はせっかくLEGOが付けれるので、スッキリまとめてみました。

## サンプルスケッチを使う
### ToF のサンプルスケッチ
![arduino07_tof.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/e5f2f237-90ac-4c20-3388-99cf12203c2a.png)
メニューから、
`ファイル` > `スケッチ例` > `M5Stack` > `Unit` > `Tof_VL53L0X` を選択します。
マイコンボードに書き込むと、M5Stackの画面にセンサーの値が表示されていると思います。
![tof.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/8607f803-2604-3d8b-f91b-4006a2796a53.png)
`distance` の値が距離の数値なので、この値が変化しているか、紙コップを置いたり離したりして数値を見ると、大体**50～450**くらいの範囲で変化しているのが確認できます。何も置いていなかったり、範囲外まで離れると、極端に数値が変化して、2000とか8000とかになったり、20になったりしますので、このあたりは実際に使う時に、値の範囲を絞って処理を変えると良いと思います。
### ANGLE のサンプルスケッチ
![arduino07_angle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/decb1e5c-2b01-b97c-32ba-f0dcc87fb566.png)
メニューから、
`ファイル` > `スケッチ例` > `M5Stack` > `Unit` > `ANGLE` を選択します。
マイコンボードに書き込むと、M5Stackの画面にセンサーの値が表示されていると思います。
![写真 2022-04-27 11 04 17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/b0bbeb21-162e-7a64-439d-2388b58d5790.jpeg)
つまみを回していくと、**0～4095**の範囲で値が変わっていくのが確認できます。
この２つのサンプルを合体させて、２つの値を表示していきたいと思います。
## スケッチの作成
ToFのサンプルスケッチをベースに、ANGLEのサンプルスケッチの必要な情報を移植していきたいと思います。
ToFのサンプルスケッチを別名（例：Tof_and_Angle）で保存します。

```java:ANGLE
#include <M5Stack.h>
int sensorPin = 36; // 移植

int last_sensorValue = 100; // 移植
int cur_sensorValue = 0;  // 移植

void setup() {
  M5.begin(); //Init M5Stack.  
  M5.Power.begin(); //Init power  
  pinMode(sensorPin, INPUT);  //移植
  dacWrite(25, 0); // 移植
  M5.Lcd.setTextSize(2);  //Set the font size to 2.  
  M5.Lcd.print("the value of ANGLE: ");
}

void loop() {
  cur_sensorValue = analogRead(sensorPin);  // 移植  
  M5.Lcd.setCursor(0, 25);  //Place the cursor at (0,25).  
  if(abs(cur_sensorValue - last_sensorValue) > 10){ //移植
    M5.Lcd.fillRect(0, 25, 100, 25, BLACK);
    M5.Lcd.print(cur_sensorValue); // 移植
    last_sensorValue = cur_sensorValue; // 移植
  }
  delay(50);
}
```
ANGLE スケッチで必要なコードを抜き出します。

```java:Tof_and_Angle
#include <M5Stack.h>
//...省略...//

// ANGLEから移植 --->
int sensorPin = 36;
int last_sensorValue = 100;
int cur_sensorValue = 0;
//<--- ANGLEから移植

void setup() {
  // put your setup code here, to run once:
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(115200);  // start serial for output
  Serial.println("VLX53LOX test started.");

  //---osmar
  M5.begin();
  M5.Power.begin();
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(50, 0, 4);
  M5.Lcd.println(("VLX53LOX Example"));
  //---osmar

  // ANGLEから移植--->
  pinMode(sensorPin, INPUT);
  dacWrite(25, 0);
  //<--- ANGLEから移植
}
void loop() {
  write_byte_data_at(VL53L0X_REG_SYSRANGE_START, 0x01);

  byte val = 0;
  int cnt = 0;
  while (cnt < 100) { // 1 second waiting time max
    delay(10);
    val = read_byte_data_at(VL53L0X_REG_RESULT_RANGE_STATUS);
    if (val & 0x01) break;
    cnt++;
  }
  if (val & 0x01) Serial.println("ready"); else Serial.println("not ready");

  read_block_data_at(0x14, 12);
  uint16_t acnt = makeuint16(gbuf[7], gbuf[6]);
  uint16_t scnt = makeuint16(gbuf[9], gbuf[8]);
  uint16_t dist = makeuint16(gbuf[11], gbuf[10]);
  byte DeviceRangeStatusInternal = ((gbuf[0] & 0x78) >> 3);
  M5.Lcd.fillRect(0, 35, 319, 239, BLACK);
  M5.Lcd.setCursor(0, 35, 4);
  M5.Lcd.print("ambient count: "); M5.Lcd.println(acnt);
  M5.Lcd.print("signal count: ");  M5.Lcd.println(scnt);
  M5.Lcd.print("distance: ");       M5.Lcd.println(dist);
  M5.Lcd.print("status: ");        M5.Lcd.println(DeviceRangeStatusInternal);
  
  // ANGLEから移植 --->
  cur_sensorValue = analogRead(sensorPin);
  if(abs(cur_sensorValue - last_sensorValue) > 10){
    M5.Lcd.print(cur_sensorValue);
    last_sensorValue = cur_sensorValue;
  }
  //<--- ANGLEから移植

  delay(1000);
}
```
これでマイコンボードにに書き込みすると、一応、つまみを回すと表示されますが、一定時間で消えちゃったり、更新のタイミングが遅いので、この辺りを調整します。
```java:Tof_and_Angle
#include <M5Stack.h>
//...省略...//

void loop() {
//...省略...//

  // ANGLEから移植 --->
  cur_sensorValue = analogRead(sensorPin);
  if(abs(cur_sensorValue - last_sensorValue) > 10){
    //M5.Lcd.print(cur_sensorValue); //削除
    last_sensorValue = cur_sensorValue;
  }
  M5.Lcd.print("angle: ");  M5.Lcd.println(last_sensorValue); // 画面表示
  //<--- ANGLEから移植
  
  Serial.println(String(dist)+"_"+String(last_sensorValue)); // シリアルモニタに出力
  
  delay(200); // 更新時間を変更
}
```
画面で値が見やすいように、**angle** という文字を追加しています。
また、Electronに値を送れるように、シリアルポートに値を出力する、
`Serial.println`を追加しています。文字列に変換する必要があります。
![arduino09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/aaa9fa39-e979-6659-39c3-5ea96a385bf1.png)
マイコンボードに書き込みした後に、右上の `シリアルモニタ` を押して、
シリアルモニタを表示します。
文字化けしていると思いますので、シリアルモニタも右下の通信速度を、**115200bps** に変更します。
`ready`という文字と数字が交互に出力されているので、プログラムから削除します。
```java
  if (val & 0x01) Serial.println("ready"); else Serial.println("not ready"); // 削除
```
![写真 2022-04-28 16 15 23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49845/7515caf6-d4f4-d58a-7ca3-455f93b47e53.jpeg)
これで再度書き込めば、シリアルモニタには、回転の値と、距離の値のみが出力されている状態になりますので、M5Stackの設定はひとまずこれで終了です。

[ー Electron編 ー](https://qiita.com/kaluna/items/6b4b4bc67ef131dc1088)に続く。

# 参考URL
- [M5Stack事始め（Hello World!!）](https://note.com/rasen/n/n83680dd38573)
- [Arduino IDEの設定 (M5Stackシリーズ)](https://qiita.com/penguinprogrammer/items/774d4b719464e41cdcf3)
- [Arduino IDE Development](https://docs.m5stack.com/en/arduino/arduino_development)