M5stickC で腕時計 ~ G-showC ~
M5stickCで腕時計を作製いたしました。
RTCと加速度センサを組み合わせたM5stickCならではの時計ですのでご報告させてください。
目次
概要
加速度センサを利用して、x軸の角度がhour、y軸の角度がminuteに一致したときのみ表示します。
まさに重力(Gravity )が時(Clock)を示す G-showC (ジーショック)なのです。
ちなみに私のM5StickCの慣性センサはSH200Qです。
動作
以下のように腕をうまいこと傾けることによって、時刻を知ることができます。
x軸の角度がhour、y軸の角度がminuteに一致したときのみ表示します。
Gravity shows clock.
まさに G-showC(ジーショック)!!!#M5StickCWatchContesthttps://t.co/DCm5WPu4M2 pic.twitter.com/blnE5R55F8
— HomeMadeGarbage (@H0meMadeGarbage) August 30, 2019
オプション
- 省エネのため20秒間 時間または分が表示されない場合、ディスプレイはオフになり、ディープスリープモードに入ります。
ボタンAを押して、スリープをキャンセルします。
- 角度の校正機能として、ボタンBを押すと、加速度センサーのオフセットが再計算されその時点の姿勢が0°となります。
Arduinoコード
Arduino用のM5StickCライブラリは初期バージョンの0.1.0を使用しておりますのでご了承ください。
慣性センサはSH200Qです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
#include <M5StickC.h> RTC_TimeTypeDef RTC_TimeStruct; unsigned long Time; int state = 0; int timeCnt = 0; int16_t accX = 0; int16_t accY = 0; int16_t accZ = 0; int offsetX, offsetY; int x, y; int accXoffset = 0; int accYoffset = 0; int accZoffset = 0; //加速度センサのオフセット校正 void offset_cal(){ digitalWrite(10, LOW); delay(1000); accXoffset = 0; accYoffset = 0; accZoffset = 0; for(int i=0; i<10; i++) { M5.IMU.getAccelAdc(&accX,&accY,&accZ); delay(10); accXoffset += accX; accYoffset += accY; accZoffset += accZ; } accXoffset /= 10; accYoffset /= 10; accZoffset = accZoffset / 10 + 8192; offsetX = int(-180.0/PI*atan(((float)accXoffset)/((float)accZoffset))); offsetY = int(180.0/PI*atan(((float)accYoffset)/((float)accZoffset))); digitalWrite(10, HIGH); } void setup() { pinMode(10, OUTPUT); Serial.begin(115200); M5.begin(); M5.Axp.ScreenBreath(8); M5.IMU.Init(); M5.Lcd.setRotation(3); M5.Lcd.fillScreen(BLACK); offset_cal(); //ディープスリープ設定 (ボタンAを押すと起床) esp_sleep_enable_ext0_wakeup(GPIO_NUM_37, 0); M5.Lcd.setTextSize(5); /* RTC_TimeTypeDef TimeStruct; TimeStruct.Hours = 9; TimeStruct.Minutes = 43; TimeStruct.Seconds = 0; M5.Rtc.SetTime(&TimeStruct); */ Time = millis(); } void loop() { M5.Rtc.GetTime(&RTC_TimeStruct); M5.IMU.getAccelAdc(&accX,&accY,&accZ); if(state == 0 && millis() - Time > 500){ state = 1; Time = millis(); timeCnt++; } if(state == 1 && millis() - Time > 500){ state = 0; Time = millis(); } //M5StickC 角度算出 x = int(-180.0/PI*atan(((float)accX)/((float)accZ))) - offsetX; y = int(180.0/PI*atan(((float)accY)/((float)accZ))) - offsetY; Serial.print(x); Serial.print("\t"); Serial.println(y); //"時"の表示 M5.Lcd.setCursor(5, 22); if(x == RTC_TimeStruct.Hours){ M5.Lcd.printf("%02d",RTC_TimeStruct.Hours); timeCnt = 0; }else{ M5.Lcd.printf(" "); } M5.Lcd.setCursor(65, 22); if(state == 0){ M5.Lcd.printf(":"); }else{ M5.Lcd.printf(" "); } //"分"の表示 M5.Lcd.setCursor(95, 22); if(y == RTC_TimeStruct.Minutes){ M5.Lcd.printf("%02d",RTC_TimeStruct.Minutes); timeCnt = 0; }else{ M5.Lcd.printf(" "); } //ボタンBを押すと加速度センサのオフセット再計算 if(digitalRead(39) == LOW){ offset_cal(); } //20秒間 時間または分が表示されない場合ディープスリープON if(timeCnt > 20){ timeCnt = 0; M5.Axp.SetSleep(); //Display OFF ESP.deepSleep(3600000000); //Deep Sleep ON } } |
おわりに
加速度センサのみを使用してM5StickCの角度を導出していますので、振っても時刻が表示されます。
Deep Sleep導入のおかげで電池が長時間持つようになりました。
普段使いに堪えれるほどに電池が持ちます。私のG-showC(ジーショック) pic.twitter.com/tDpHq2BQmb
— HomeMadeGarbage (@H0meMadeGarbage) September 16, 2019
ESP32のスリープ機能によって、電池は半日ほど持ちましたので日常で十分使える時計となりました。
バッテリが低下してM5StickCの電源が落ちても充電後の起動で時刻のずれはございませんでした。
2019/11/25 に急にM5StickCの内部回路が公開されましてRTCの電源が電源コントローラAXP192で供給されていることが判明しました。
恐らくシャットダウン電圧にマージンもたせてRTCに電源供給してるのだと考えられます。
「M5stickC で腕時計 ~ G-showC ~」への1件のフィードバック