2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5Atomを使って、遠隔で嫁が筋トレを応援してくれるシステムを作ってみた

Last updated at Posted at 2020-07-13

#はじめに
 この記事は2020年6月18日にIoTLTでプレゼンしたシステムの一部抜粋記事です。
システムの技術要素ごとに3つに分けて書きます。

  1. M5Atomを使って、遠隔で嫁が筋トレを応援してくれるシステムを作ってみた
  2. Node-REDで、MQTTによるデータ送受信(嫁筋トレシステム)
  3. LINE Message

こちらがその時のプレゼンスライドです。(記事書くのに時間かかってしまいました(-_-;))
https://speakerdeck.com/maepu/yuan-ge-dejia-nijin-torewoying-yuan-sitemorau

#概要

 最近、ストレスのせいか暴飲暴食で太ってしまいました。そこで痩せたいと思い、筋トレを始めました。しかし長続きせずということで、嫁に応援してもらおうと思いました。

 しかしながら、嫁は里帰り出産のため沖縄に...。

 ということで、遠隔で嫁が筋トレを応援してくれるシステムを作ってみました!

簡易的なシステム.jpg

こちらがのデモです。
https://www.youtube.com/watch?v=ufq9XtmmxMs

#レシピ
##開発環境

  • M5Atom Lite
  • Arduino IDE ver1.8.12
  • Node-RED ver1.0.4
  • Node.js v10.15.3

##システム構成
 システム構成は次のようになっています。M5Atomのボタンを押したイベントが発生すると、MQTT通信でNode-REDにデータが送られます。MQTT通信をしている間に「Shiftr.io」というものがあります。これはMQTT通信を管理するサーバーです。無料で理想することができます。

 MQTTで送られてきたデータは、Node-REDで作成したフローによりMQTT通信のメッセージからLINE Messageに変換していてます。
 
 LINE botは使用したいグループLINEに招待して使います。筋トレが開始された時と、10回ごと、終了時にメッセージを送ります。

image.png

M5Atom Lite

M5Atom Liteの主な処理は、ボタンのイベントに応じて、データの送信とカウントアップ等を行っています。動作しているプログラムは次の通りです。

Button.ino

#include "M5Atom.h"
#include <WiFi.h>
#include <PubSubClient.h> // MQTTのライブラリ

WiFiClient client;
PubSubClient mqttClient(client);

// Wi-Fi定義
char *ssid = "SSID";            // Wi-FiのSSID
char *password = "PASS";        // Wi-Fiのパスワード

// MQTT ブローカの設定定義
const char *endpoint = "broker.shiftr.io";    shiftr.ioを利用する場合
const int port = 1883;          // MQTT のポート番号 
char *deviceID = "M5Atom";      // デバイスID
char *userName = "認証名";              // MQTTブローカ認証ユーザ名
char *userPass = "認証パスワード";      // MQTTブローカ認証パスワード
char *pubTopic1 = "/start";          // メッセージを知らせるトピック
char *pubTopic2 = "/end";          // メッセージを知らせるトピック
char *pubTopic3 = "/count";          // メッセージを知らせるトピック
char *subTopic = "/sub";          // メッセージを待つトピック

typedef enum {
  AIDLE = 0,
  SUB_AIDLE,
  RUN,
  SUB_RUN,
}STATE;

char pubMessage[128];

uint8_t DisBuff[2 + 5 * 5 * 3];

char main_state = AIDLE;
unsigned int count = 0;

void setBuff(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata)
{
    DisBuff[0] = 0x05;
    DisBuff[1] = 0x05;
    for (int i = 0; i < 25; i++)
    {
        DisBuff[2 + i * 3 + 0] = Rdata;
        DisBuff[2 + i * 3 + 1] = Gdata;
        DisBuff[2 + i * 3 + 2] = Bdata;
    }
}

// MQTTの接続チェック
void mqttLoop() {
    if (!mqttClient.connected()) {
        connectMQTT();
    }
    mqttClient.loop();
}

// MQTT接続時の処理
void connectMQTT() {
  mqttClient.setServer(endpoint, port);
  mqttClient.setCallback(mqttCallback);
  while (!mqttClient.connected()) {
      if (mqttClient.connect(deviceID,userName,userPass)) {
          Serial.println("MQTT Connected.");
          int qos = 0;
          mqttClient.subscribe(subTopic, qos);
          Serial.println("Subscribed.");
      } else {
          Serial.print("Failed. Error state=");
          Serial.print(mqttClient.state());
          // Wait 5 seconds before retrying
          delay(5000);
      }
  }
}

void setup()
{
    main_state = AIDLE;
    count = 0;
    
    M5.begin(true, false, true);
    Serial.begin(115200);
  
    delay(10);
    setBuff(0x00, 0x00, 0x40);
    M5.dis.displaybuff(DisBuff);

    // Wi-Fi設定
    WiFi.begin(ssid, password);  //  Wi-Fi APに接続
    while (WiFi.status() != WL_CONNECTED) {  //  Wi-Fi AP接続待ち
        delay(500);
        Serial.print(".");
    }
    Serial.print("WiFi connected\r\nIP address: ");
    Serial.println(WiFi.localIP());
    
    // connect MQTT
    mqttClient.setServer(endpoint, port);
    mqttClient.setCallback(mqttCallback);
    connectMQTT();
    Serial.println("MQTT connected");
    
    Serial.println("Start my program");
}

void loop()
{
    // ステートマシン
    // ボタンを2秒長押ししたとき
    if(M5.Btn.pressedFor(2000)){
     // Serial.println("Button press");
      switch(main_state){
        case AIDLE :
          main_state = SUB_AIDLE;
          Serial.println("Change to SUB_AIDLE");
          break;
         case RUN :
          main_state = SUB_RUN;
          Serial.println("Change to SUB_AIDLE");
          break; 
      }
    }
    // ボタンを離したとき
    else if(M5.Btn.wasReleased()){
      switch(main_state){
        case SUB_AIDLE :
          main_state = RUN;
          setBuff(0x00, 0x40, 0x00);
          Serial.println("Change to RUN");
          // MQTT 送信
          sprintf(pubMessage, "start");
          mqttClient.publish(pubTopic1, pubMessage);
          break;
        case RUN :
          count++;
          if((count%10 == 0) && (count > 0)){
            sprintf(pubMessage, "%d",count);
            mqttClient.publish(pubTopic3, pubMessage);
          }
          Serial.printf("count = %d\n",count);     
          break;
        case SUB_RUN :
          main_state = AIDLE;
          setBuff(0x00, 0x00, 0x40);
          Serial.println("Change to AIDLE");

          // MQTT 送信
          sprintf(pubMessage, "%d", count);
          mqttClient.publish(pubTopic2, pubMessage);

          count = 0;
          break;
      }
    }

    mqttLoop();
    
    M5.dis.displaybuff(DisBuff);
    delay(50);
    M5.update();
}

// MQTTで何かメッセージを受け取った場合(今回は未使用)
void mqttCallback (char* topic, byte* payload, unsigned int length) {
    String str = "";

    Serial.print("Received. topic=");
    Serial.println(topic);
    for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
        str += (char)payload[i];
    }
    Serial.print("\n");
    Serial.println("recive message");
}

ソースコードから一部抜粋します。

 次の行では、「ボタンを2秒長押しした」のイベント処理です。2秒長押しすると1度この処理に入ります。ここで、筋トレの開始と終了処理をしています。

if(M5.Btn.pressedFor(2000)){

 次の行では、「ボタンを離した」のイベントです。ボタンを離したときに1度この処理を行います。ここでカウント処理をしています。

else if(M5.Btn.wasReleased()){

#次回
 Node-REDの説明をしてきます!
 

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?