Skip to content

Instantly share code, notes, and snippets.

@katsuyoshi
Last active December 23, 2022 04:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save katsuyoshi/1395d09e156158841df22ea1be50e978 to your computer and use it in GitHub Desktop.
Save katsuyoshi/1395d09e156158841df22ea1be50e978 to your computer and use it in GitHub Desktop.
雪寄せ時間を記録するためのM5StickCのプログラム
#ifndef __ENV_H__
#define __ENV_H__
#define WIFI_SSID "your wifi ssid"
#define WIFI_PASSWORD "your password for WIFI_SSID"
//#define WIFI_SSID_2 "your second wifi ssid if you have"
//#define WIFI_PASSWORD_2 "your password for WIFI_SSID2"
//#define WIFI_SSID_3 "your third wifi ssid if you have"
//#define WIFI_PASSWORD_3 "your password for WIFI_SSID3"
#define AMBIENT_CHANNEL_ID 1234 // your ambient channel id
#define AMBIENT_WRITE_KEY "your write key of ambient"
#endif
#include <Arduino.h>
#include <M5Unified.h>
#include <WiFiMulti.h>
#include <Ambient.h>
#include "env.h"
static float velocity[2] = {0};
static float diff[2] = {0};
static float diff2[2] = {0};
static int num_of_steps = 0;
static void imu_task(void*)
{
float threshold = 0.004; // 0.008; // 0.010; //0.005;
int b_ptr = 0;
float val[3];
float vel = 0;
float sum = 0;
bool over = false;
int tap_size = 63;
float z_buf[tap_size] = {0};
int ignore_count = 0;
while(true) {
M5.Imu.getAccel(&val[0], &val[1], &val[2]);
vel = sqrt(val[0] * val[0] + val[1] * val[1] + val[2] * val[2]);
sum -= z_buf[b_ptr];
z_buf[b_ptr] = vel;
sum += z_buf[b_ptr];
b_ptr = (b_ptr + 1) % tap_size;
velocity[0] = sum / tap_size;
diff[0] = velocity[0] - velocity[1];
diff2[0] = diff[0] - diff[1];
velocity[1] = velocity[0];
diff[1] = diff[0];
diff2[1] = diff2[0];
// 250ms以内は無視
if (ignore_count >= 25) {
if (diff2[0] <= - threshold || diff2[0] >= threshold) {
if (over == false) {
over = true;
ignore_count = 0;
num_of_steps++;
}
} else {
over = false;
}
}
delay(10);
ignore_count++;
}
}
static void transfer_task(void*)
{
Ambient ambient;
unsigned long sent_at = millis();
WiFiMulti wifiMulti;
WiFiClient client;
int power_off_count = 0;
int power_off_min = 10;
WiFi.disconnect();
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_STA);
wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
#ifdef WIFI_SSID2
wifiMulti.addAP(WIFI_SSID2, WIFI_PASSWORD2);
#endif
#ifdef WIFI_SSID3
wifiMulti.addAP(WIFI_SSID3, WIFI_PASSWORD3);
#endif
ambient.begin(AMBIENT_CHANNEL_ID, AMBIENT_WRITE_KEY, &client);
while(true) {
if (wifiMulti.run() == WL_CONNECTED) {
unsigned long now = millis();
if (now - sent_at >= 60000) {
if (num_of_steps < 15) {
if (++power_off_count >= power_off_min) {
M5.Power.powerOff();
}
} else {
power_off_count = 0;
}
ambient.set(1, num_of_steps);
ambient.send();
num_of_steps = 0;
sent_at = now;
}
}
}
}
static void display_bar(int no, float fvalue, float gain, int min, int max) {
int value = fvalue * gain;
int space = 2;
int bar_height = 20;
int h = M5.Lcd.height();
int w = M5.Lcd.width();
int y = h - (space + bar_height) * (no + 1) + space;
int bar_value = map(value, min, max, 0, w);
Serial.println(bar_value);
bar_value = constrain(bar_value, 0, w);
Serial.println(bar_value);
M5.Lcd.fillRect(0, y, w, bar_height, TFT_BLACK);
if (min >= 0) {
// 正方向のみ
M5.Lcd.fillRect(0, y, bar_value, bar_height, TFT_GREEN);
M5.Lcd.fillRect(0, y, 3, bar_height, TFT_WHITE);
} else {
// 正負センター振り分け
int half_w = w / 2;
if (bar_value < half_w) {
// 負
M5.Lcd.fillRect(bar_value, y, half_w - bar_value, bar_height, TFT_RED);
} else {
// 正
M5.Lcd.fillRect(half_w, y, bar_value - half_w, bar_height, TFT_GREEN);
}
M5.Lcd.fillRect(half_w - 1, y, 2, bar_height, TFT_WHITE);
}
M5.Lcd.setCursor(1, y + 3);
M5.Lcd.printf("%8.4f", fvalue);
}
static void display() {
display_bar(0, velocity[0], 10000, 0, 20000);
display_bar(1, diff[0], 10000, -200, 200);
display_bar(2, diff2[0], 10000, -200, 200);
int x = M5.Lcd.width() * 3 / 4;
M5.Lcd.setCursor(x, 1);
M5.Lcd.printf("%6d", num_of_steps);
}
void setup() {
auto cfg = M5.config();
cfg.clear_display = true; // default=true. clear the screen when begin.
cfg.output_power = false; // default=true. use external port 5V output.
cfg.internal_imu = true; // default=true. use internal IMU.
cfg.internal_rtc = false; // default=true. use internal RTC.
cfg.internal_spk = false; // default=true. use internal speaker.
cfg.internal_mic = false; // default=true. use internal microphone.
cfg.external_imu = false; // default=false. use Unit Accel & Gyro.
cfg.external_rtc = false; // default=false. use Unit RTC.
cfg.external_spk = false; // default=false. use SPK_HAT / ATOMIC_SPK
cfg.led_brightness = 50; // default= 0. system LED brightness (0=off / 255=max) (※ not NeoPixel)
M5.begin(cfg);
// Rotate LCD origin
M5.Lcd.setRotation(1);
M5.Lcd.setTextSize(1);
// LED OFF
pinMode(GPIO_NUM_10, OUTPUT);
digitalWrite(GPIO_NUM_10, HIGH);
// IMU task
xTaskCreatePinnedToCore(imu_task, "imu_task", 2048, NULL, 25, NULL, APP_CPU_NUM);
xTaskCreatePinnedToCore(transfer_task, "transfer_task", 4096, NULL, 25, NULL, APP_CPU_NUM);
}
void loop() {
Serial.print(".");
display();
delay(100);
}
[env:m5stick-c]
platform = espressif32
board = m5stick-c
framework = arduino
lib_deps =
m5stack/M5Unified@^0.0.7
ambientdatainc/Ambient ESP32 ESP8266 lib@^1.0.3
monitor_speed = 115200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment