WioTerminalには、初めから加速度センサがついているので、これを使って…と、なると、とりあえず、水準器あたりからですかねぇ~?
というわけで、水準器、作ってみました。
特に、説明もいらないと思いますが、一応、5つボタンでスケールを変えられるようにしてあります。
上下で5段階変更できます。 これで、フルスケールが変わります。
スケール1のときは、真ん中が水平、一番外の丸が90度、に、なるはず…。
プログラムもほとんどライブラリのサンプルのままです。 角度にするのにちょっとだけ計算してます。
#include"LIS3DHTR.h" #include "TFT_eSPI.h" #include <math.h> LIS3DHTR<TwoWire> lis; TFT_eSPI tft; void disp_sight() { tft.drawCircle(159,119,90,TFT_WHITE); tft.drawCircle(159,119,60,TFT_WHITE); tft.drawCircle(159,119,30,TFT_WHITE); tft.drawLine(159,29,159,209,TFT_WHITE); tft.drawLine(69,119,249,119,TFT_WHITE); tft.fillCircle(159,119,3,TFT_RED); tft.fillRoundRect(56,215,206,20,10,TFT_DARKGREEN); tft.fillRoundRect(295,16,20,206,10,TFT_DARKGREEN); } void setup() { Serial.begin(115200); // while (!Serial); pinMode(WIO_5S_UP, INPUT_PULLUP); pinMode(WIO_5S_DOWN, INPUT_PULLUP); lis.begin(Wire1); if (!lis) { Serial.println("ERROR"); while(1); } lis.setOutputDataRate(LIS3DHTR_DATARATE_25HZ); //Data output rate lis.setFullScaleRange(LIS3DHTR_RANGE_2G); //Scale range set to 2g // Display set up tft.begin(); tft.setRotation(3); tft.setTextColor(TFT_YELLOW); tft.setTextSize(2); tft.fillScreen(TFT_BLACK); disp_sight(); tft.drawString("Angle", 5, 20); tft.drawString("X: ", 10, 40); tft.drawString("Y: ", 10, 60); tft.drawString("Accel.", 5, 120); tft.drawString("X: ", 10, 140); tft.drawString("Y: ", 10, 160); tft.drawString("Z: ", 10, 180); tft.drawString("Scale", 238, 20); } int p_plot_x = 159, p_plot_y = 119; int scale = 1, p_scale = 5; void loop() { float x_values, y_values, z_values; int plot_x, plot_y; x_values = lis.getAccelerationX(); y_values = lis.getAccelerationY(); z_values = lis.getAccelerationZ(); /* Serial.print("X: "); Serial.print(x_values); Serial.print(" Y: "); Serial.print(y_values); Serial.print(" Z: "); Serial.print(z_values); Serial.println(); */ tft.fillRect(50,40,72,35,TFT_BLACK); tft.fillRect(50,140,72,55,TFT_BLACK); tft.drawString(String(180.0/3.1415*asin(x_values)), 50, 40); tft.drawString(String(180.0/3.1415*asin(y_values)), 50, 60); tft.drawString(String(x_values), 50, 140); tft.drawString(String(y_values), 50, 160); tft.drawString(String(z_values), 50, 180); if (scale != p_scale) { tft.fillRect(260,41,25,20,TFT_BLACK); tft.drawString(String(scale), 260, 41); } tft.fillCircle(p_plot_x,p_plot_y,10,TFT_BLACK); tft.fillRect(p_plot_x+3,215,6,20,TFT_DARKGREEN); tft.fillRect(295,p_plot_y-3,20,6,TFT_DARKGREEN); disp_sight(); plot_x = 159 + scale*(90.0/3.1415 * 2 * asin(y_values)); if (plot_x > 249) plot_x = 249; if (plot_x < 69) plot_x = 69; plot_y = 119 - scale*(90.0/3.1415 * 2 * asin(x_values)); if (plot_y > 209) plot_y = 209; if (plot_y < 29) plot_y = 29; tft.fillCircle(plot_x,plot_y,10,TFT_YELLOW); tft.fillRect(plot_x-3,215,6,20,TFT_WHITE); tft.drawLine(plot_x,215,plot_x,235,TFT_BLACK); tft.fillRect(295,plot_y-3,20,6,TFT_WHITE); tft.drawLine(295,plot_y,315,plot_y,TFT_BLACK); if (digitalRead(WIO_5S_UP) == LOW) { scale++; if (scale > 5) scale = 5; while(digitalRead(WIO_5S_UP) == LOW); } if (digitalRead(WIO_5S_DOWN) == LOW) { scale--; if (scale <1) scale = 1; while(digitalRead(WIO_5S_DOWN) == LOW); } p_plot_x = plot_x; p_plot_y = plot_y; delay(50); }
じっと見てると、結構、画面がちらちらして、目が疲れます。
そんなわけで、らびやん さんのLovyanGFX というライブラリを使ってみました。
画面のちらちらは、解消されたようです。 LovyanGFX おそるべし!!
が、いかんせん、加速度の数字そのものが、ちらちらと変化しているものだから、そこんとこはしかたないですね。
値の表示をやめれば、結構、いい感じかも。
#include"LIS3DHTR.h" #include <LovyanGFX.hpp> #include <math.h> #define DARKGREEN24 0x38761DU #define GREEN24 0x00FF00 #define RED24 0xFF0000U #define YELLOW24 0xFFFF00U #define WHITE24 0xFFFFFFU #define BLACK24 0x000000U LIS3DHTR<TwoWire> lis; static LGFX lcd; //static LGFX_Sprite canvas(&lcd); static LGFX_Sprite sight(&lcd); static LGFX_Sprite bottom(&lcd); static LGFX_Sprite right(&lcd); static LGFX_Sprite bubble(&sight); static LGFX_Sprite idx_X(&lcd); static LGFX_Sprite idx_Y(&lcd); static auto transpalette = 0; void setup() { Serial.begin(115200); // while (!Serial); pinMode(WIO_5S_UP, INPUT_PULLUP); pinMode(WIO_5S_DOWN, INPUT_PULLUP); lis.begin(Wire1); if (!lis) { Serial.println("ERROR"); while(1); } lis.setOutputDataRate(LIS3DHTR_DATARATE_25HZ); //Data output rate lis.setFullScaleRange(LIS3DHTR_RANGE_2G); //Scale range set to 2g // Display set up lcd.init(); lcd.setRotation(1); lcd.setBrightness(128); //keep memory //canvas.createSprite(200, 200); sight.createSprite(200, 200); bottom.createSprite(206, 20); right.createSprite(20, 206); bubble.createSprite(20, 20); idx_X.createSprite(6, 20); idx_Y.createSprite(20, 6); // create parts sight.fillScreen(transpalette); bottom.fillScreen(transpalette); right.fillScreen(transpalette); bubble.fillScreen(transpalette); idx_X.fillScreen(transpalette); idx_Y.fillScreen(transpalette); sight.drawCircle(100,100,90,WHITE24); sight.drawCircle(100,100,60,WHITE24); sight.drawCircle(100,100,30,WHITE24); sight.drawLine(100,10,100,190,WHITE24); sight.drawLine(10,100,190,100,WHITE24); sight.fillCircle(100,100,3,RED24); bottom.fillRoundRect(0,0,206,20,10,DARKGREEN24); right.fillRoundRect(0,0,20,206,10,DARKGREEN24); bubble.fillCircle(10,10,10,YELLOW24); idx_X.fillRect(0,0,6,20,WHITE24); idx_X.drawFastVLine(3,0,20,BLACK24); idx_Y.fillRect(0,0,20,6,WHITE24); idx_Y.drawFastHLine(0,3,20,BLACK24); lcd.setTextColor(YELLOW24, BLACK24); lcd.setTextSize(2); sight.pushSprite(59,19); lcd.drawString("Angle", 5, 20); lcd.drawString("X: ", 10, 40); lcd.drawString("Y: ", 10, 60); lcd.drawString("Accel.", 5, 120); lcd.drawString("X: ", 10, 140); lcd.drawString("Y: ", 10, 160); lcd.drawString("Z: ", 10, 180); bottom.pushSprite(56,215); right.pushSprite(295,16); } int p_plot_x = 159, p_plot_y = 119; float px_values=0.0, py_values=0.0, pz_values=0.0; float px_angle=0, py_angle=0; int scale = 1, p_scale = 5;; void loop() { float x_values, y_values, z_values, x_angle, y_angle; int plot_x, plot_y; x_values = lis.getAccelerationX(); y_values = lis.getAccelerationY(); z_values = lis.getAccelerationZ(); x_angle = 180.0/3.1415*asin(x_values); y_angle = 180.0/3.1415*asin(y_values); plot_x = 100 + scale*(90.0/3.1415 * 2 * asin(y_values)); if (plot_x > 197) plot_x = 197; if (plot_x < 3) plot_x = 3; plot_y = 100 - scale*(90.0/3.1415 * 2 * asin(x_values)); if (plot_y > 197) plot_y = 197; if (plot_y < 3) plot_y = 3; sight.clear(); sight.drawCircle(100,100,90,WHITE24); sight.drawCircle(100,100,60,WHITE24); sight.drawCircle(100,100,30,WHITE24); sight.drawLine(100,10,100,190,WHITE24); sight.drawLine(10,100,190,100,WHITE24); sight.fillCircle(100,100,3,RED24); sight.fillCircle(plot_x,plot_y,10,YELLOW24); sight.pushSprite(59,19); bottom.pushSprite(56,215); right.pushSprite(295,16); idx_X.pushSprite(plot_x-3+60, 215); idx_Y.pushSprite(295, plot_y-3+20); lcd.setTextColor(BLACK24,BLACK24); lcd.drawString(String(px_angle), 50, 40); lcd.drawString(String(py_angle), 50, 60); lcd.drawString(String(px_values), 50, 140); lcd.drawString(String(py_values), 50, 160); lcd.drawString(String(pz_values), 50, 180); lcd.setTextColor(WHITE24,BLACK24); lcd.drawString(String(x_angle), 50, 40); lcd.drawString(String(y_angle), 50, 60); lcd.drawString(String(x_values), 50, 140); lcd.drawString(String(y_values), 50, 160); lcd.drawString(String(z_values), 50, 180); lcd.drawString("Scl", 260, 20); if (scale != p_scale) { lcd.fillRect(270,41,25,20,TFT_BLACK); lcd.drawString(String(scale), 270, 41); } p_plot_x = plot_x; p_plot_y = plot_y; px_values = x_values; py_values = y_values; pz_values = z_values; px_angle = x_angle; py_angle = y_angle; if (digitalRead(WIO_5S_UP) == LOW) { scale++; if (scale > 5) scale = 5; while(digitalRead(WIO_5S_UP) == LOW); } if (digitalRead(WIO_5S_DOWN) == LOW) { scale--; if (scale <1) scale = 1; while(digitalRead(WIO_5S_DOWN) == LOW); } delay(50); }
じっと、見てると時々 1g を超えたりする。
一応、自宅の重力加速度を調べてみると、9.797と出たので、1g を超えることはないはず…?
ん? 重力異常?
なんか、壁から宇宙人が出てきそう…。
ぐるっと一回りさせて表示させてみたら、0.93g から1.04g まで、ばらついている。
やっぱり、ちゃんと使うには、キャリブレーションとか必要なんでしょうね。
参考サイト
Overview - Seeed Wiki