はじめに
ElectronとVueを使ってデスクトップアプリを作っていますが、画面の操作を、タッチパネル以外に、物理的なボタンやセンサーを使って操作したい事がたまにあります。
今回はそんなセンサーの値をElectronに送って、画面を動かす方法をM5Stackを使って作っていきたいと思います。
また、M5StackはBluetoothやWifiなど、無線での操作もできると思いますが、今回はUSBを使って、有線でシリアルポートの値を受け取ってみたいと思います。
この記事はボリュームが大きくなってしまったので、2回に分かれています。
ー M5Stack編 ー(この記事です)
ー Electron編 ー
環境
- vue : 3.0.0
- electron : 13.0.0
- serialport:10.4.0
- Arduino IDE
- WebStorm
- Windows10 Home
今回使ったセンサー類
- M5Stack M5Go
- M5Stack用 ToF測距センサユニット
- M5Stack用 回転角ユニット
- LEGO Technicsパーツ色々
M5Goの背面はLEGOが付けれるようになっていますので、LEGOが家にあれば、色々くっつけて、簡易な台とか作れて楽しいですよ。
M5Stack の設定
M5StackをArduino IDEで使えるようにするまでの準備は、「M5StackをArduino IDEで使えるようにする」を参照してください。
今回はこの準備が出来ていると仮定して進めて行きたいと思います。
M5Stack とセンサーを繋げる
今回使うセンサーはToFセンサーと、ANGLEセンサーを使っていきたいと思います。
ToFセンサーは、PORT-A
を使い、ANGLEセンサーは、PORT-B
を使いますので、それぞれのPORTにつなげていきます。
このまま使うと、各センサーが軽いので、ケーブルのひねりに負けて、変な方向に向いたりしちゃうので、今回はせっかくLEGOが付けれるので、スッキリまとめてみました。
サンプルスケッチを使う
ToF のサンプルスケッチ
メニューから、
ファイル
> スケッチ例
> M5Stack
> Unit
> Tof_VL53L0X
を選択します。
マイコンボードに書き込むと、M5Stackの画面にセンサーの値が表示されていると思います。
distance
の値が距離の数値なので、この値が変化しているか、紙コップを置いたり離したりして数値を見ると、大体50~450くらいの範囲で変化しているのが確認できます。何も置いていなかったり、範囲外まで離れると、極端に数値が変化して、2000とか8000とかになったり、20になったりしますので、このあたりは実際に使う時に、値の範囲を絞って処理を変えると良いと思います。
ANGLE のサンプルスケッチ
メニューから、
ファイル
> スケッチ例
> M5Stack
> Unit
> ANGLE
を選択します。
マイコンボードに書き込むと、M5Stackの画面にセンサーの値が表示されていると思います。
つまみを回していくと、0~4095の範囲で値が変わっていくのが確認できます。
この2つのサンプルを合体させて、2つの値を表示していきたいと思います。
スケッチの作成
ToFのサンプルスケッチをベースに、ANGLEのサンプルスケッチの必要な情報を移植していきたいと思います。
ToFのサンプルスケッチを別名(例:Tof_and_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 スケッチで必要なコードを抜き出します。
#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);
}
これでマイコンボードにに書き込みすると、一応、つまみを回すと表示されますが、一定時間で消えちゃったり、更新のタイミングが遅いので、この辺りを調整します。
#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
を追加しています。文字列に変換する必要があります。
マイコンボードに書き込みした後に、右上の シリアルモニタ
を押して、
シリアルモニタを表示します。
文字化けしていると思いますので、シリアルモニタも右下の通信速度を、115200bps に変更します。
ready
という文字と数字が交互に出力されているので、プログラムから削除します。
if (val & 0x01) Serial.println("ready"); else Serial.println("not ready"); // 削除
これで再度書き込めば、シリアルモニタには、回転の値と、距離の値のみが出力されている状態になりますので、M5Stackの設定はひとまずこれで終了です。
ー Electron編 ーに続く。