M5StickC Plus に Grove Water Level Sensor をつなげるメモです。
先日行われた 【オンラインコラボ企画】ゆるメカトロ・Noodl・ビジュアルプログラミングで合同もくもく会 で進めたものをまとめました。
Grove Water Level Sensor
スイッチサイエンスで Grove – 水位センサ(10cm) を購入しました。
このセンサーは 0 ~ 100 mm で 5mm 刻みで I2C でデータが取れます。実際の動かし方は Seeed 社本家の Wiki の Arduinoソースを参考にしました。
Grove – Water Level Sensor – Seeed Wiki
M5Stick C Plus の Hello World でハマる
M5StickC のソースのまま M5StickC Plus 動かそうとしたら全然動かなくて、「え、M5StickC Plus、M5StickCと違うの?」ってなったとき、以下の記事もとても助かりました。ありがとうございます~。
M5StickCとM5StickC Plusの違い – Lang-ship
M5StickC Plus の独立してる Arduino ライブラリとして入れて動かします。
このようなソースです。
// #include <M5StickC.h> #include <M5StickCPlus.h> void setup(){ // Initialize M5.begin(); // LCD display M5.Lcd.setRotation(3); M5.Lcd.setTextSize(2); M5.Lcd.println("[M5StickCPlus]"); M5.Lcd.println(""); M5.Lcd.setTextSize(3); M5.Lcd.println("Hello World,"); M5.Lcd.setTextSize(2); M5.Lcd.println("finally(>_<;)"); } void loop() { }
M5Stick C Plus に Grove Water Level Sensor をつなげる
あとは こちらのプログラム を M5Stick C Plus に合体させればOKです。
このセンサーはタッチセンサーのような仕組みで水をとらえているようで、実は指で抑えてもテストすることができます。
#Seeed Grove の Water Level Sensor 、タッチセンサーが5mmごとに並んでいる仕様ぽい。指で触れても少し反応する。#ゆるメカトロ #Noodlもくもく会 #ビジュアルプログラミング交流会 pic.twitter.com/w7idgWfEBQ
— Tanaka Seigo (@1ft_seabass) August 29, 2020
ちゃんと 0 cm のところから連続して触れると水位レベルとしてとらえられます。仮に、指が一部密着 0 cm のところから密着しているところまでが水位となりますのでテスト時は注意ください。
実際にはこのようなソースを書きました。
// #include <M5StickC.h> #include <M5StickCPlus.h> #include <Wire.h> #ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE #define SERIAL SerialUSB #else #define SERIAL Serial #endif unsigned char low_data[8] = {0}; unsigned char high_data[12] = {0}; #define NO_TOUCH 0xFE #define THRESHOLD 100 #define ATTINY1_HIGH_ADDR 0x78 #define ATTINY2_LOW_ADDR 0x77 void getHigh12SectionValue(void) { memset(high_data, 0, sizeof(high_data)); Wire.requestFrom(ATTINY1_HIGH_ADDR, 12); while (12 != Wire.available()); for (int i = 0; i < 12; i++) { high_data[i] = Wire.read(); } delay(10); } void getLow8SectionValue(void) { memset(low_data, 0, sizeof(low_data)); Wire.requestFrom(ATTINY2_LOW_ADDR, 8); while (8 != Wire.available()); for (int i = 0; i < 8 ; i++) { low_data[i] = Wire.read(); // receive a byte as character } delay(10); } void check() { int sensorvalue_min = 250; int sensorvalue_max = 255; int low_count = 0; int high_count = 0; while (1) { uint32_t touch_val = 0; uint8_t trig_section = 0; low_count = 0; high_count = 0; getLow8SectionValue(); getHigh12SectionValue(); Serial.println("low 8 sections value = "); for (int i = 0; i < 8; i++) { Serial.print(low_data[i]); Serial.print("."); if (low_data[i] >= sensorvalue_min && low_data[i] <= sensorvalue_max) { low_count++; } if (low_count == 8) { Serial.print(" "); Serial.print("PASS"); } } Serial.println(" "); Serial.println(" "); Serial.println("high 12 sections value = "); for (int i = 0; i < 12; i++) { Serial.print(high_data[i]); Serial.print("."); if (high_data[i] >= sensorvalue_min && high_data[i] <= sensorvalue_max) { high_count++; } if (high_count == 12) { Serial.print(" "); Serial.print("PASS"); } } Serial.println(" "); Serial.println(" "); for (int i = 0 ; i < 8; i++) { if (low_data[i] > THRESHOLD) { touch_val |= 1 << i; } } for (int i = 0 ; i < 12; i++) { if (high_data[i] > THRESHOLD) { touch_val |= (uint32_t)1 << (8 + i); } } while (touch_val & 0x01) { trig_section++; touch_val >>= 1; } SERIAL.print("water level = "); SERIAL.print(trig_section * 5); SERIAL.println("% "); M5.Lcd.setCursor(0, 50); // M5.Lcd.fillScreen(TFT_BLACK); // M5.Lcd.print("water level = "); M5.Lcd.setTextSize(5); M5.Lcd.print(trig_section * 5); // M5.Lcd.setTextSize(4); M5.Lcd.println("% "); SERIAL.println(" "); SERIAL.println("*********************************************************"); delay(1000); } } // the setup routine runs once when M5StickC starts up void setup(){ // Initialize the M5StickC object M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.setTextSize(2); // LCD display M5.Lcd.print("Hello World"); M5.Lcd.setCursor(0, 0); M5.Lcd.setTextSize(3); M5.Lcd.fillScreen(TFT_BLACK); M5.Lcd.print("[water Lv]"); SERIAL.begin(115200); Wire.begin(); } // the loop routine runs over and over again forever void loop() { check(); }
実際にはこのように動きます。
#LEGO 化、試行錯誤のおかげで固定度が増して構造がシンプルになり、電子工作以外は多少濡れても良いのでこれは水のテストしやすい!#ゆるメカトロ #Noodlもくもく会 #ビジュアルプログラミング交流会 pic.twitter.com/ftjLHrbklY
— Tanaka Seigo (@1ft_seabass) August 29, 2020