Skip to content

Instantly share code, notes, and snippets.

@katsuyoshi
Last active December 23, 2022 04:57
Show Gist options
  • Select an option

  • Save katsuyoshi/1395d09e156158841df22ea1be50e978 to your computer and use it in GitHub Desktop.

Select an option

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
// MIT License
//
// Copyright (c) 2022 Katsuyoshi Ito
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#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 int num_of_steps = 0;
static void imu_task(void*)
{
int b_ptr = 0;
float val[3];
float vel = 0;
float sum = 0;
bool dir_up = false;
int dir_count = 0;
float dir_threshold = 8;
int tap_size = 63;
float z_buf[tap_size] = {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];
velocity[1] = velocity[0];
diff[1] = diff[0];
/*
// for monitoring
Serial.printf("%.4f", velocity[0]);
Serial.print(",");
Serial.printf("%.4f", diff[0]);
Serial.println("");
*/
if (dir_up) {
if (diff[0] < 0) {
dir_count++;
if (dir_count >= dir_threshold) {
dir_up = false;
dir_count = 0;
}
} else {
dir_count = 0;
}
} else {
if (diff[0] >= 0) {
dir_count++;
if (dir_count >= dir_threshold) {
dir_up = true;
num_of_steps++;
dir_count = 0;
}
} else {
dir_count = 0;
}
}
delay(10);
}
}
static void transfer_task(void*)
{
Ambient ambient;
unsigned long sent_at = millis();
WiFiMulti wifiMulti;
WiFiClient client;
int power_off_count = 0;
int power_off_mins = 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_mins) {
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);
bar_value = constrain(bar_value, 0, w);
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);
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", 4096/*2048*/, NULL, 25, NULL, APP_CPU_NUM);
xTaskCreatePinnedToCore(transfer_task, "transfer_task", 4096, NULL, 25, NULL, APP_CPU_NUM);
M5.Lcd.setBrightness(0);
//M5.Display.sleep();
//M5.Display.waitDisplay();
}
void loop() {
static bool visible = false;
display();
M5.update();
if (M5.BtnB.wasClicked()) {
if (visible) {
M5.Lcd.setBrightness(0);
//M5.Display.sleep();
//M5.Display.waitDisplay();
visible = false;
} else {
M5.Lcd.setBrightness(128);
//M5.Display.wakeup();
//M5.Display.waitDisplay();
visible = true;
}
}
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