本記事はM5Stack Advent Calendar 2020の12月3日分です。
はじめまして! 記事をご覧くださりありがとうございます。
半分NEETのようなフリーランスエンジニアのたつのぶと申します。
今回は、M5stickCで始める筋肉ムキムキ計画💪と題してM5StickC内蔵の加速度センサを
使って腹筋回数を可視化する記事です。ぜひ最後まで読んでくださると幸いです!!
#はじめに
ポテチはおいしいな~(mgmg
箸で食べるという技も極めてるから手も汚れないぜ✨
今日も今日とて間食にスナック菓子を食べる生活をしていた...
最近洋服がきつい。だけど、ポテチうまうま。
訳あって5年ぶりくらいに親戚のおばさんと会った。最初の一言。
「たつのぶくん、太った?」
ぼく「絶対痩せてやる!!!!」
そんなわけでお腹周りをへこませることを目標とした
M5stickCで始める筋肉ムキムキ計画💪の始まり始まり~~~👏👏
#準備するもの
- レンタルサーバー
- PC: WindowsPC
- M5StickC本体/付属USBType-Cケーブル/付属リストバンド
#システム構成図
#M5stickCに書き込む準備
ArduinoIDEのインストール
公式HPよりArduino IDEをインストールする。
https://www.arduino.cc/en/software
M5StickCライブラリのインストール
① 「ツール」>「ライブラリを管理…」を選択。
② 「m5stick」で検索すると、「M5StickC」が現れるので「インストール」をクリッ
ク。
#腹筋回数をカウントしてサーバーにPOSTするファームウェア
⇒SSIDとパスワード、サーバ送信先は自分の環境に合わせてください。
⇒500ミリ秒ごとに加速度センサの値をとって、腹筋行動の閾値になるとサーバにPOSTする
仕組みになってます。
#include <M5StickC.h>
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "yourssid";
const char* password = "yourpassword";
const char* svrinfo = "https://hogehoge.jp/logfit.php";
float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;
float oldaccY = 0.0F;
float oldaccZ = 0.0F;
bool Continuous = false;
void setup()
{
Serial.begin(115200);
M5.begin();
M5.IMU.Init();
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(40, 0);
M5.Lcd.println("IMU");
M5.Lcd.setCursor(0, 10);
M5.Lcd.println(" X Y Z");
delay(4000); //Delay needed before calling the WiFi.begin
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void SvrPost(){
if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status
HTTPClient http;
http.begin(svrinfo); //Specify destination for HTTP request
http.addHeader("Content-Type", "text/plain"); //Specify content-type header
int httpResponseCode = http.POST("fukin"); //Send the actual POST request
if(httpResponseCode>0){
String response = http.getString(); //Get the response to the request
Serial.println(httpResponseCode); //Print return code
Serial.println(response); //Print request answer
}else{
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end(); //Free resources
}else{
Serial.println("Error in WiFi connection");
}
}
void loop()
{
oldaccY = accY;
oldaccZ = accZ;
M5.IMU.getAccelData(&accX, &accY, &accZ);
M5.Lcd.setCursor(0, 30);
M5.Lcd.printf(" %5.2f %5.2f %5.2f ", accX, accY, accZ);
M5.Lcd.setCursor(140, 30);
M5.Lcd.print("G");
if((oldaccY - accY) >= 0.3 && (oldaccZ-accZ) >= -0.3 ){
if(oldaccY == 0.0 && oldaccZ == 0.0 ){
Serial.println(0);
Continuous = false;
}else{
if(Continuous == true){
Serial.println(0);
Continuous = false;
}else{
Serial.println(1);
Continuous = true;
SvrPost();
}
}
}else{
Serial.println(0);
Continuous = false;
}
delay(500);
}
#M5stickCからPOSTされたデータを受け取るサーバーサイドスクリプト
<?php
$data = file_get_contents('php://input');
$time1 = date("Ymd");
$time2 = date("H:i:s");;
$json = file_get_contents('data.json');
$records = (array)json_decode($json, true);
$i = count($records) + 1;
$records[] = [
'id' => $i,
'time1' => $time1,
'time2' => $time2,
];
$out_json = json_encode($records);
file_put_contents('data.json', $out_json);
?>
#腹筋状態を確認するフロントページ
⇒CSS・jsは同一ファイルに書いてます (てへぺろ
⇒サーバにあるjsonを一定周期で参照して腹筋回数を可視化しています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>腹筋ログ</title>
<style>
body {
width: 100%;
}
h2 {
text-align: center;
}
table {
border-collapse: collapse;
margin: 0 auto;
padding: 0;
width: 650px;
table-layout: fixed;
color: #000;
}
table th {
padding: 15px 0;
border-right: 1px solid #bbb;
text-align: center;
}
table tr {
background-color: #fff;
padding: 30px;
border-bottom: 1px solid #bbb;
}
table tr:last-child{
border-bottom: none
}
table td {
padding: 1em 10px 1em 1em;
border-right: 1px solid #bbb;
text-align: center;
}
table th:last-child,
table td:last-child{
border: none;
}
</style>
<script>
var counter;
// 1桁の数字を0埋めで2桁にする
var toDoubleDigits = function(num) {
num += "";
if (num.length === 1) {
num = "0" + num;
}
return num;
};
function getJSON() {
var req = new XMLHttpRequest(); // XMLHttpRequest オブジェクトを生成する
req.onreadystatechange = function() { // XMLHttpRequest オブジェクトの状態が変化した際に呼び出されるイベントハンドラ
if(req.readyState == 4 && req.status == 200){ // サーバーからのレスポンスが完了し、かつ、通信が正常に終了した場合
var data = JSON.parse(req.responseText); // 取得した JSON ファイルの中身を変数へ格納
var len = data.length; // JSON のデータ数を取得
var result = _.chain(data)
.groupBy(function(o){ return o.time1; })
.pick(function(o){ return o.length > 0; })
.mapObject(function(o){return _.pluck(o,'id');})
.value();
var date = new Date();
var yyyy = date.getFullYear();
var mm = toDoubleDigits(date.getMonth() + 1);
var dd = toDoubleDigits(date.getDate());
var yyyymmdd = yyyy + mm + dd;
var resjson = JSON.stringify(result);
resjson = JSON.parse( resjson );
document.querySelector('.titletoday').innerHTML = "本日 [" + String(yyyymmdd) + "] のトレーニング回数";
if(resjson[yyyymmdd]){
document.querySelector('.result').innerHTML = resjson[yyyymmdd].length +"回";
counter = resjson[yyyymmdd].length;
}else{
document.querySelector('.result').innerHTML = "0回";
counter = 0;
}
}
};
req.open("GET", "https://hogehoge.jp/data.json", true); // HTTPメソッドとアクセスするサーバーのURLを指定
req.setRequestHeader('Pragma', 'no-cache');
req.setRequestHeader('Cache-Control', 'no-cache');
req.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
req.send(null); // 実際にサーバーへリクエストを送信
}
function proc1()
{
getJSON();
const input1 = document.getElementById('p1');
if (input1.value < 100 ) {
input1.value = counter;
}
}
setInterval(proc1, 100);
</script>
</head>
<body onload="proc1();">
<div style="border: 2px ridge #000; padding: 10px;">
<p style="font-size: 2.0em;">リアルタイム腹筋回数<br>
</p>
<em style="color: #000000;background-color: #b1f9f6">腹筋ログ</em>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore-min.js"></script>
<h2 class="titletoday"></h2>
<table class="table_box">
<tr>
<th>種目</th>
<th>ステータス</th>
<th>回数</th>
</tr>
<tr>
<td><h2>腹筋</h2><img src="./images/fukkin_man.png" width="309" height="400" alt="hukkin"></td>
<td><progress id="p1" min="0" max="100" value="0"></progress></td>
<td><h2 class="result"></h2></td>
</tr>
</table>
</body>
</html>
M5stickC付属のリストバンドを腹筋ワンダーコアに巻き付ける
#ブラウザで腹筋回数をリアルタイム表示
⇒腹筋ワンダーコアで普通に腹筋をするだけで回数がカウントされます!
#最後に
この記事をご覧になった方。
今回は、約2千円という安価で購入できるM5stickCの新たな使い方を記事にしてみました!
ムキムキボディが手に入るかはさておき、
たのしく腹筋トレーニングができると思います(やったね✌🏼✌🏼
この年末はM5stickCを活用して一年のおなかにたまった脂肪を落としてみてはいかがでしょうか???
それでは✋