Warning: Cannot modify header information - headers already sent by (output started at /home/cra-log/www/index.php:1) in /home/cra-log/www/site-admin-wp/wp-includes/feed-rss2.php on line 8
M5Stack – CRAFT GoGo https://craft-gogo.com Raspberry Pi、3Dプリンタ、プログラミング、DIYなど、ものづくりを中心に趣味レベルで情報を発信! Mon, 01 Apr 2024 03:53:25 +0000 ja hourly 1 https://wordpress.org/?v=6.3.4 https://craft-gogo.com/site-admin-wp/wp-content/uploads/2021/05/cropped-CRAFT-GOGO-LOGO-32x32.png M5Stack – CRAFT GoGo https://craft-gogo.com 32 32 Arduinoで行列計算!ArduinoEigenの使い方 https://craft-gogo.com/arduino_eigen/ Mon, 01 Apr 2024 01:18:31 +0000 https://craft-gogo.com/?p=3675

Pythonでは簡単に行列計算が出来るのに、Arduinoでは行列計算をさせるのに一苦労。そんなときはArduinoEigenライブラリの使用がおすすめです。今回は、ArduinoEigenのインストールから使い方まで解 […]]]>

Pythonでは簡単に行列計算が出来るのに、Arduinoでは行列計算をさせるのに一苦労。そんなときはArduinoEigenライブラリの使用がおすすめです。今回は、ArduinoEigenのインストールから使い方まで解説します。

ArduinoEigenとは

C++には行列計算ライブラリ「Eigen」というものがあります。このEigenをArduinoで直接扱えるようにしたのが「ArduinoEigen」です。ArduinoEigenをインストールすることによって、Arduinoでも行列が簡単に計算できるようになります。

ArduinoEigenのインストール方法

ArduinoEigenのインストール方法はとっても簡単です。ここではArduino IDEとPlatformIOでのインストール方法を紹介します。

Arduino IDE環境

スケッチ > ライブラリをインクルード > ライブラリを管理 をクリックします。

Eigenを検索し、インストールボタンを押せばインストール完了です。

PlatformIO環境

本ブログでは、Arduino開発環境はPlatformIOをお薦めしています。

PlatformIO環境でのArduinoEigenインストール方法も解説していきますね。

Librariesから「Eigen」と検索すると「ArduinoEigen」がヒットします。

Add to Projectボタンを押し、Projectを選択するとインストール完了です。

ArduinoEigenを使った行列計算方法

ArduinoEigenの基本的な使い方について解説していきます。詳細な使い方を知りたい方は、公式ホームページを見て下さいね。

ヘッダファイルのインクルード

まずはヘッダファイルのインクルードが必要です。ArduinoEigen.hをインクルードしましょう。

#include <ArduinoEigen.h>

変数の宣言

変数を宣言するには下のように記述します。

using Eigen::MatrixXd;
MatrixXd m(2, 2);

MatrixXd m(2, 2)は、2×2のdouble型で変数mを宣言したことを意味しています。

正方行列で次数が決まっている場合は、次のように記述します。

using Eigen::Matrix2d;
Matrix2d m;

変数の型をdoubleではなくfloat、intにしたい場合は最後の文字を「d」から「f」、「i」に変更します。

MatrixXd // double型
MatrixXf // float型
MatrixXi // int型

初期値の代入

初期値を代入するには、2×2行列の場合を例にすると1行1列目、1行2列目、2行1列目、2行2列目の順に「,」区切りで記述していきます。

m << 1, 2, 
           3, 4;

加算

加算は「+」演算子を使います。

m = m1 + m2;

減算

減算は「-」演算子を使います。

m = m1 - m2;

乗算

乗算は「*」演算子を使います。

m = m1 * m2;

転置行列

転置行列はinverse()関数を使います。

n = m.inverse();

まとめ

Arduinoで行列を扱うためのArduinoEigenライブラリについて解説しました。今回の解説は行列計算のごく一部です。その他行列計算の使い方は公式ホームページ参照して下さい。

最後までお読みいただきありがとうございました。

楽天ブックス
¥3,278 (2024/04/26 08:44時点 | 楽天市場調べ)
プログラミング言語の人気オンラインコース ]]>
M5StickCを使って倒立振子に挑戦! ~ハードウェア編~ https://craft-gogo.com/invented_pendulum01/ Sat, 16 Mar 2024 17:04:23 +0000 https://craft-gogo.com/?p=3590

制御の醍醐味は不安定な系を安定にさせること。今回は、M5StickCを使って倒立振子に挑戦します! 制御工学を学んでいるけど、数式が多くて難しい、何の役に立つのか分からないといった方の助けになればよいと思います。 倒立振 […]]]>

制御の醍醐味は不安定な系を安定にさせること。今回は、M5StickCを使って倒立振子に挑戦します!

制御工学を学んでいるけど、数式が多くて難しい、何の役に立つのか分からないといった方の助けになればよいと思います。

倒立振子を立たせるのに、かなり試行錯誤しました。どんなところに注意しなければいけないかポイントも紹介していきます。

記事は、ハードウェア設計編、ソフトウエア設計編、実機適合編に分けて連載する予定で、今回はハードウェア設計編です。

完成形

部品選定

準備した部品の一覧表です。

準備物個数
M5StickC Plus1個
FEETECH ギヤードモータ FM902個
タイヤ FS90R対応2個
DRV8835使用ステッピング&DCモータドライバモジュール1個
電池ボックス 単3×2本2個
ボディ(3Dプリンタで自作)1個
ジャンパピン メス必要分
GROVE 4ピンケーブル1本

M5StickC Plus

コントローラはM5StickC Plusを使いました。M5StickCPlusは、小型軽量ながら倒立振子に必要なGセンサ、ジャイロセンサーが備わっているので、部品点数削減に繋がります。あとはモーター、タイヤと電源を準備するだけでOK。

私はM5StickCシリーズの中でもM5StickC Plusを使用しました。M5StickC Plus選定は在庫があったからだけです。より安価に作るのであればM5StickCでも問題ないです。

ネコサン商店
¥8,402 (2024/03/17 01:52時点 | 楽天市場調べ)

FEETECH ギヤードモータ FM90

マブチモーターより小型なFM90を選定しました。FM90はサーボモーターと同一形状のため、サーボモーター用のタイヤを取り付けることができます。

定格電圧は4.8V。モーター特性は秋月電子のホームページを参照してください。

タイヤ FS90R対応

タイヤはFS90R用を使いました。FM90にも取付可能です。タイヤ径は60mm。

ロボショップ 楽天市場店
¥421 (2024/03/10 22:10時点 | 楽天市場調べ)

DRV8835使用ステッピング&DCモータドライバモジュール

モータードライバは、2ch内蔵のモジュールであるDRV8835を使います。15mm×10mmと小型で、搭載性抜群です。

ロボショップ 楽天市場店
¥824 (2024/03/10 22:11時点 | 楽天市場調べ)

電池ボックス 単3×2本

FM90は定格電圧4.8Vのため、充電式単3電池4本使います。重量バランスを考えて、電池2本ずつ前後に搭載することにしたので、2本用を2個用意しました。

配線図

配線図は下図のとおりです。

DRV8835への電源供給のために、単3電池の+端子をDRV8835のVM、VCC端子に繋ぎます。単3電池のー端子は、DRV8835のGNDに繋ぎます。

モーターFM90への接続は、それぞれAOUT1/AOUT2、BOUT1/BOUT2です。モーターは左右で反転して搭載しますので、一方のモーターをプラスマイナス逆転して接続しましょう。

モーターをPWM制御するために、G33端子をAIN1/BIN1、G32端子をAIN2/BIN2に接続しました。

ボディの製作

ボディはFusion360で設計しました。

これを3Dプリンタで製作。一体成型です。3Dプリントの設定はサポート材有り。サポート材を取り除くのにかなり苦労しました。

組み立て

モーターは下方から差し込む構造になっています。

電池ボックスを取り付けるためのネジ穴はボディに空けなかったので、両面テープで貼り付けます。配線は中央の穴を通しました。

タイヤをモーターに取り付け。

モータードライバDRV8835は電池パックに両面テープで貼り付けました。DRV8835のヘッダピンにそれぞれの配線を接続。

DRV8835は剥き出しになってしまったので、もう少し見栄えを良くしたかった。

M5StackC Plusをボディに差し込めば完成!

これにてハードウェア設計編は終わりです。次回はソフトウェア設計編です。

ネコサン商店
¥8,402 (2024/03/17 01:52時点 | 楽天市場調べ)
楽天ブックス
¥3,432 (2024/03/10 14:42時点 | 楽天市場調べ)
]]>
【M5Stack】一定周期で実行されるタイマ割り込みを実装しよう https://craft-gogo.com/m5stack-timer-interrupt/ Wed, 17 Aug 2022 02:07:22 +0000 https://craft-gogo.com/?p=2955

モーター制御などの組み込みシステムでは、一定の制御周期でプログラムを実行するタイマ割り込みが必要不可欠ですよね。 今回の記事では、M5Stackでタイマ割り込みを実装する方法について解説します。 なお、排他制御など難しい […]]]>

モーター制御などの組み込みシステムでは、一定の制御周期でプログラムを実行するタイマ割り込みが必要不可欠ですよね。

今回の記事では、M5Stackでタイマ割り込みを実装する方法について解説します。

なお、排他制御など難しい処理は扱わず、分かりやすいよう最低限の実装に留めました。

それでは始めていきましょう!

この記事はこんな人におすすめ!

  • 一定の制御周期でプログラムを実行したい人
  • タイマ割り込みについて知りたい人
  • M5Stackの知識を深めたい人

概要

タイマ割り込みは、一定の周期でプログラムを実行したいときに用います。

今回のゴールは、図のようにシリアル通信で定期的に情報を送信するプログラムの作成です。

M5StackからPCへ0.1s毎に情報送信

タイマ割り込みの仕組み

マイコンは動作クロック周波数で高速に動作します。

すぐに処理されてしまう簡単なプログラムを1秒間隔で動作させたいとき、どのようにしますか?

メインループ内に1秒待つ処理を加えるのも1つの手です。

でも、タイマ割り込み機能を使えば、待ち時間を作る必要はないです。

タイマ割り込みプログラムをいきなり見ても何をどうしたいのか、さっぱり分からないと思います。プログラムを理解するにはタイマ割り込みの知識が必要不可欠です。

そこでタイマ割り込みについて簡単に説明します。

タイマ割り込みは簡単です。

マイコンが持つタイマ機能が時間をカウントします。

所定の時間になったらメインの処理を一時中断して別の処理をしてねと、タイマ機能からCPUへ割り込み要求を出させます。別の処理実行し終わったら、中断していたメインの処理に戻します。

タイマ割り込みを実現する仕組みが、割り込みサービス・ルーチンと割り込みベクタ・テーブルです。

割り込みサービス・ルーチン

割り込みサービス・ルーチンは割り込み関数のことです。

タイマ機能が割り込みを要求したときに実行する処理を記述します。

割り込みサービスルーチンを実行する際は、メイン処理ループを一時中断。中断したメイン処理ループのアドレスは忘れないようスタックに記憶しておきます。

割り込みサービス・ルーチンが終了したら、スタックから中断したメイン処理ループのアドレスを取り出し、メイン処理ループを再開します。

割り込みベクタ・テーブル

タイマ割り込みが発生したときに実行する割り込みサービス・ルーチンを対応付けた表を割り込みベクタ・テーブルといいます。

割り込みベクタ・テーブルには、割り込みサービス・ルーチンの先頭アドレスが書かれます。

M5Stackのタイマ機能

タイマ割り込みプログラムを書く前に、M5Stackのタイマ機能を調べておきましょう。

タイマ数

M5StackのマイコンはESP32が使用されています。ESP32のタイマ数は「4」です。プログラムでは0~3を指定します。

ペリフェラル周波数

ペリフェラル (peripheral) は、日本語訳で周辺機器です。

M5Stackのペリフェラル周波数は80MHzです。

タイマのカウント周波数は、分周器というペリフェラル周波数を整数分の1に落とす装置で作り出します。タイマカウントしやすいように分周比を80とし、1カウントを80M / 80 = 1MHzにするのが一般的です。

タイマ割り込みプログラム

ここまでタイマ割り込みの仕組み、M5Stackのタイマ機能について説明してきました。これらを理解していれば、タイマ割り込みサンプルプログラムの意味がきっと分かると思います。

▼は、0.1s毎にシリアル通信でプログラム経過時間を送信するサンプルプログラムです。

#include<M5Stack.h>

hw_timer_t * timer = NULL;
volatile uint32_t counter = 0;
volatile uint32_t current_time = 0;

void onTimer(){
  counter++;
  current_time = millis();
  Serial.printf("No. %u, %u ms\n", counter, current_time);
}

void setup() {
  M5.begin();
  Serial.begin(115200);

  // タイマ作成
  timer = timerBegin(0, 80, true);

  // タイマ割り込みサービス・ルーチン onTimer を登録
  timerAttachInterrupt(timer, &onTimer, true);
  
  // 割り込みタイミング(ms)の設定
  timerAlarmWrite(timer, 100000, true);

  // タイマ有効化
  timerAlarmEnable(timer);
}

void loop() {
  
}

プログラムは、まず割り込みサービス・ルーチン onTimerを定義します。そして、タイマ作成→タイマ割り込みサービス・ルーチンの登録→割り込みタイミングの設定→タイマ有効化といった流れです。

このプログラムを実行し、シリアル通信をモニタすると、0.1毎にタイマ割り込みが生じていることが確認できます。

シリアル通信のモニタ方法は▼の記事で解説しています。

https://craft-gogo.com/m5stickc-serial-pclog/

ここからは各処理について解説していきます。

割り込みサービス・ルーチンの定義

タイマ割り込み時に実行する割り込みサービス・ルーチンを定義します。

void onTimer(){
  /* (省略) */
}

タイマ作成

タイマを作成するにはtimerBegin関数を呼び出します。

timer = timerBegin(0, 80, true);

第1引数は使用するタイマ番号です。0~3の値を設定しましょう。今回は0を設定しました。

第2引数は分周比です。M5Stackのペリフェラル周波数は80MHzでしたね。分周比80に設定し、1カウントを1MHzとしました。

タイマ割り込みサービス・ルーチンの登録

割り込みサービス・ルーチン「onTimer」をタイマ割り込みに登録するため、timerAttachInterrupt関数を呼び出します。

timerAttachInterrupt(timer, &onTimer, true);

第1引数には、作成したタイマを指定します。第2引数は登録する割り込みサービス・ルーチンを指定します。第3引数はtrueを指定しましょう。割り込みはレベルトリガーになります。

割り込みタイミングの設定

何秒毎に割り込みが発生するか設定するため、timerAlarmWrite関数を呼び出します。

timerAlarmWrite(timer, 100000, true);

第1引数には、作成したタイマを指定します。第2引数は、割り込み発生のカウント数です。今回は0.1秒毎に割り込み発生したいので、1MHz × 0.1s = 100000回 としています。第3引数は、割り込みは周期的か1回か指定します。 trueだと周期的に割り込みが発生します。

タイマ有効化

ここまででタイマ割り込みの設定が整いました。timerAlarmEnable関数を呼び出し、タイマ割り込みを有効化しましょう。

timerAlarmEnable(timer);

引数は作成したタイマを指定します。

まとめ

今回の記事では、M5Stackでタイマ割り込みを実装する方法について解説しました。

解説したことは

  • タイマ割り込みの仕組み
  • M5Stackのタイマ機能
  • タイマ割り込みプログラム

タイマ割り込みには、割り込み中に別の割り込みを禁止する排他制御がありますが、今回は分かりやすい最低限の実装に留めました。

これから、M5Stackでタイマ割り込みを実装する方のお役に立てれば幸いです。

最後までお読み頂きありがとうございました。

楽天Kobo電子書籍ストア
¥3,089 (2024/04/22 11:49時点 | 楽天市場調べ)
プログラミング言語の人気オンラインコース ]]>
M5StickCの取得データをUSBシリアル通信でPCロギング https://craft-gogo.com/m5stickc-serial-pclog/ Mon, 18 Jul 2022 14:47:37 +0000 https://craft-gogo.com/?p=2916

M5StickCで計測した加速度データをUSBを経由してPCでロギングする実験をしたので記事にしてみました。 PCロギングは、3種類の方法を紹介します。 1つ目はターミナルソフト TeraTermを使ったロギング。2つ目 […]]]>

M5StickCで計測した加速度データをUSBを経由してPCでロギングする実験をしたので記事にしてみました。

PCロギングは、3種類の方法を紹介します。

1つ目はターミナルソフト TeraTermを使ったロギング。2つ目はArduino IDEのシリアルモニタ、シリアルプロッタを使ったロギング。3つ目はPythonでのロギングです。

この記事はこんな人におすすめ!

  • M5Stack/M5Stickのシリアル通信方法を学びたい人
  • M5Stack/M5StickCとPC間をUSB経由でデータ通信したい人
  • M5Stack/M5StickCが取得したデータをPCでロギングする方法を学びたい人

この記事のゴールはこちら▼

Arduino IDE シリアルプロッタを用いた加速度データのロギング

それでは始めていきましょう!

準備するもの

  • M5Stack or M5StickC (今回はM5StickC Plusを使用しています)
  • USBケーブル
  • PC
  • Tera Term
  • Arduino IDE
  • Python開発環境

通信方法

M5StickC側からデータ送信する方法

加速度データを送信するM5StickC側のサンプルプログラムを以下に示します。

#include <M5StickCPlus.h>

float x, y, z; // 加速度データを格納
bool isSend = false; // データ送信フラグ

void setup() {
  M5.begin();
  M5.IMU.Init();

  Serial.begin(57600);
  
  M5.Lcd.setRotation(3);
  M5.Lcd.setCursor(0,0,4);
  M5.Lcd.println("Not Send");
}

void loop() {
  M5.update();
  if(M5.BtnA.wasPressed()){
    isSend = !isSend;
    if(isSend){
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0,0,4);
      M5.Lcd.println("Send");
    }
    else{
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0,0,4);
      M5.Lcd.println("Not Send");
    }
  }

  if(isSend){
    // 加速度データ取得
    M5.IMU.getAccelData(&x, &y, &z);
    
    // 加速度データを送信
    Serial.printf("%5.3f,%5.3f,%5.3f\n", x, y, z);
  }
  delay(200);
}

シリアル通信によるデータ送信方法はとても簡単です。

まず、Serial.begin()関数を呼び出し、シリアル通信のデータ転送速度を設定します。単位は「bps(ビット/秒)」です。

データを送信するには、Serial.printf()の引数に送信したいデータを指定するだけです。

PC側でデータを受信する方法

Tera Termを使ったデータ受信

ターミナルソフト「Tera Term」でデータ受信する方法について解説します。

Tera Termを起動したらTCP/IP、シリアルが選択できますので、シリアルを選択しましょう。

次に「設定」から「シリアルポート」を選択し、スピードをM5StickCで設定した値にします。今回のサンプルプログラムでは、57600[bps」です。

続いて改行コードの設定です。M5StickCは、改行を「\n」で指定しています。そのため、「設定」から「端末」を選択し、改行コードを「LF」に変更します。

「LF」は、Line Feedの略で、「\n」で改行となります。

これでTera Termの設定は完了です。M5StickのAボタン(M5と彫られたボタン)を押しましょう。

0.2秒ごとに加速度センサのデータを受信することが出来ます。

Arduino IDEのシリアルモニタ、シリアルプロッタを使ったデータ受信

Arduino IDEにもシリアル通信する機能があります。シリアルモニタとシリアルプロッタです。

まずシリアルモニタについての解説です。

Arduino IDEを起動し、「ツール」から「シリアルモニタ」を選択して下さい。

M5StickCのAボタンを押すと、Tera Termのときと同様に加速度センサのデータを受信することが出来ます。

次にシリアルプロッタです。シリアルプロッタは受信したデータを時系列で表示することが出来ます。

「ツール」から「シリアルプロッタ」を選択して下さい。

M5StickCのAボタンを押すと、受信したデータが時系列で表示されていきます。

簡易的な機能なので、縦軸などの変更は出来ないようです。

Pythonを使ったデータ受信

Pythonを使ったデータ受信は、プログラムを書く必要がありますが、プログラム次第でどんな表示も出来ます。今回は、TeraTerm、Arduino IDEのシリアルモニタと同様、受信データを順に表示するようにしました。

Pythonには、シリアル通信を簡単に実装することが出来る「pySerial」モジュールがありますので、これを使いました。

import serial
import time

ser = serial.Serial("COM4", 57600, timeout=0.1)

time.sleep(2) 
       
try:
    while True:     
        if ser.in_waiting > 0: # シリアル通信 受信待ち
            bytes = ser.readline()
            result, buf = bytes.decode('utf-8').split('\n')
            data = list(map(float, result.split(',')))
            print("AccX: {0}, AccY: {1}, AccZ: {2}".format(data[0], data[1], data[2]))
            
        time.sleep(0.2)

except KeyboardInterrupt:
    pass

print('program end')
ser.close()

まず、serial.Serialクラスを呼び出します。第1引数にはCOMポート番号、第2引数にはデータ転送速度を設定します。

データを受信したときのみターミナル表示にしたかったので、if文の条件としてser.in_waitingが0より大きいときにしました。ser.in_waitingは受信データのバイト数を戻り値として返します。

無限ループを避けるため、「ctrl + c」でプログラムを終了するようにしました。

M5StickCのAボタンを押すと、ターミナル上に加速度データが表示されていきます。

まとめ

M5StickCで計測した加速度データをUSBを経由してPCでロギングする方法について、TeraTermを使ったロギング、Arduino IDEのシリアルモニタ、シリアルプロッタを使ったロギング、Pythonでのロギングを例に挙げて解説しました。

TeraTerm、Arduino IDEはプログラムを書く必要が無く、手軽にデータロギングすることが出来ます。

一方、Pythonは自分でプログラムを書く必要がありますが、matplotlibなどのグラフ描画ライブラリを使ってグラフ化したり、csvにデータを書き出すなど応用が効くと思います。

以上、今回の記事が皆さんの参考になりましたら幸いです。

]]>
M5Stackで家族に会議中を知らせるディスプレイを制作してみた https://craft-gogo.com/m5stack-meeting-display/ Sat, 18 Jun 2022 15:51:19 +0000 https://craft-gogo.com/?p=2849

テレワーク中に家族が部屋に入ってきて、Webカメラに映りこんでしまった、音声が入りこんでしまったトラブルってありませんか?私はしょっちゅうの出来事です……。 そんな悩みを解決するため、M5Stac […]]]>

テレワーク中に家族が部屋に入ってきて、Webカメラに映りこんでしまった、音声が入りこんでしまったトラブルってありませんか?私はしょっちゅうの出来事です……。

そんな悩みを解決するため、M5Stackを使って今会議中だよ~って知らせるシステムを作ったので、作り方を紹介します。

この記事はこんな人におすすめ!

  • テレワーク中、家族に会議中を知らせたい人
  • M5Stackを使って何か作ってみたい人

それでは始めましょう!

会議中モニタの紹介

今回作ったものはこれ!会議中お知らせディスプレイ。

M5Stackは会議中の部屋の前もしくはリビングに置いておきます。

スマホから会議中ボタンを押すとM5Stackのディスプレイが赤くなるとともに”Meeting in Progress“と表示され、家族に会議中であることを知らせます。

スマホ画面の一部切り抜き

これで家族が不用意に部屋に入ってくることはありません。会議が終わったらFreeボタンを押すとM5Stackのディスプレイが緑色に変わりますので、部屋に入ってもOKと家族に知らせることが出来ます。

システム構成

スマホからM5Stackの操作は、WiFiルータを経由したUDP通信を使用しました。

必要なもの

システムを作るために必要なものは次のとおりです。

  • M5Stack
  • WiFiルータ
  • Androidスマホ
  • Androidアプリ WiFi TCP/UDP Controller
今回の対象はAndroidユーザーのみとなります。

制作方法

M5Stack側プログラミング

プログラムの流れは、M5Stack初期化→WiFi接続→UDP受信待ちとなります。M5Stackの表示モードは2つあり、スマホからの会議中またはFree信号によって切り替わるようにしました。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>

#define MEETING 1
#define FREE 0

void WiFiConnect();

const char* ssid = "*************";
const char* password = "*************";

WiFiUDP wifiUdp;
const char* smpIP = "***.***.***.***";
const int myPort = *****;

int displayMode; // 0: Free, 1: 会議中

void setup() {
  displayMode = FREE; 
  M5.begin();
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(2);
  WiFiConnect();
  wifiUdp.begin(myPort);

}

void loop() {
  switch (displayMode)
  {
  case FREE:
    if(wifiUdp.parsePacket())
    {
      if((char)wifiUdp.read() == 'm'){
        displayMode = MEETING;
        M5.Lcd.setTextSize(5);
        M5.Lcd.setCursor(0,20);
        M5.Lcd.fillScreen(RED);
        M5.Lcd.printf(" Meeting\n\n   in\n\n Progress\n");
      }
    }
    break;
  
  case MEETING:
    if(wifiUdp.parsePacket())
    {
      if((char)wifiUdp.read() == 'f'){
        displayMode = FREE;
        M5.Lcd.fillScreen(GREEN);
      }
    }
    break;

  default:
    break;
  }  
}

void WiFiConnect(){
  WiFi.begin(ssid,password);
  while(WiFi.status() != WL_CONNECTED){
    delay(500);
    M5.Lcd.print('.');
  }

  M5.Lcd.print("\r\nWiFi connected\r\nIP address: ");
  M5.Lcd.println(WiFi.localIP());
  delay(2000);
  M5.Lcd.fillScreen(GREEN);
}

WiFi接続方法、UDP通信方法の解説は、本記事で避けさせて頂きます。

詳細は▼の記事を参照下さい。

https://craft-gogo.com/m5stack-wifi/

https://craft-gogo.com/m5stack-udp/

スマホ側からUDP送信

スマホからM5StackへUDP通信をするためにWiFi TCP/UDP Controllerというアプリを使います。

▼のリンクからアプリをダウンロードしましょう。

Google Play で手に入れよう

ダウンロードしてWiFi TCP/UDP Controllerを起動したら、設定を変更していきます。

まずはNameから。

Nameは、ボタンの表示名です。

分かりやすい表示名にしましょう。今回はbutton1を’会議中‘、button2を’Free‘としました。

次にCommandです。ボタンを押したときに、どんな値を送信するか決めます。button1に’m‘、button2に’f‘を設定し、M5Stack側のプログラムに合わせます。

更にVisilibityの設定です。関係ないボタンは消してしまい、button1とbutton2だけ残しました。

これまでの設定が終わるとコントロール画面は▼になります。

各ボタンをクリックし、M5Stackのディスプレイが切り替われば完成です!

まとめ

以上、M5Stackを使って今会議中だよ~って知らせるシステムの作り方紹介でした。

これでテレワーク中に家族が部屋に入ってきて、Webカメラに映りこんでしまった、音声が入りこんでしまったトラブルも解消出来ます。

M5StackとAndroidスマホがあれば直ぐに作れちゃいますので、興味のある方は是非挑戦してみて下さい。

]]>
UDP通信のメッセージをM5Stackで受信する実験をしてみた https://craft-gogo.com/m5stack-udp/ Sat, 21 May 2022 07:53:19 +0000 https://craft-gogo.com/?p=2786

今回は、スマホからUDPでメッセージを送信して、M5Stackがこのメッセージを受信する実験をしたので記事にしてみました。 今回の記事では、M5StackのUDP送信方法は扱いません。 概要 ▼ 完成形はこちら スマホか […]]]>

今回は、スマホからUDPでメッセージを送信して、M5Stackがこのメッセージを受信する実験をしたので記事にしてみました。

この記事はこんな人におすすめ!

  • M5Stackを使い始めた人
  • M5StackのUDP受信方法が分からない人
  • スマホなど外部デバイスからM5Stackを制御したい人
今回の記事では、M5StackのUDP送信方法は扱いません。

概要

▼ 完成形はこちら

スマホからUDP通信で1から9までを順にM5Stackへ送信した例です。M5Stack画面にスマホから送信したデータが表示されます。

以下では、この方法について解説していきます。

UDP通信とは

UDPとは、TCPと同じトランスポート層のプロトコルです。TCPとは異なり、相手メッセージが届いたか管理を行わないコネクション型通信です。データ落ちが発生した場合の再送など行わないので、高速な分、信頼性は低いです。対象サービスやプロトコルを指定するために、ポート番号設定が必要です。

ポート番号は、著名なサービスやプロトコルが使用しているWell-Knownポート 0~1023を避けた1024~65535を使いましょう。

M5Stack側のプログラム

UDPメッセージを受信するための、サンプルプログラムです。

プログラムは、Wi-Fi接続→UDPメッセージ受信待ちといった流れです。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>
void WiFiConnect();

const char* ssid = "**************";
const char* password = "*************";

WiFiUDP wifiUdp;
const int myPort = *****; // 1024~60253を設定

void setup() {
  M5.begin();
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(2);
  WiFiConnect();
  wifiUdp.begin(myPort);
}

void loop() {
  if(wifiUdp.parsePacket()){
    char s;
    s = (char)wifiUdp.read();
    M5.Lcd.println(s);
  }
}

void WiFiConnect(){
  WiFi.begin(ssid,password);
  while(WiFi.status() != WL_CONNECTED){
    delay(500);
    M5.Lcd.print('.');
  }

  M5.Lcd.print("\r\nWiFi connected\r\nIP address: ");
  M5.Lcd.println(WiFi.localIP());
}

Wi-Fi接続

M5StackをWi-Fi接続するには、WiFiライブラリを使用します。begin関数の引数にWi-Fi機器のSSID、パスワードを設定し、begin関数を呼び出せば簡単にM5StackをWi-Fi接続出来ます。

M5StackのWi-Fi接続方法はこちらの記事で詳しく解説していますので、参照して下さい。

https://craft-gogo.com/m5stack-wifi/

UDPパケットを受信

UDPパケットを受信するには、WiFiUdpライブラリを使用します。

#include <WiFiUdp.h>

WiFiUDP wifiUdp;
const int myPort = *****; // 1024~60253を設定

void setup() {
  wifiUdp.begin(myPort);
}

void loop() {
  if(wifiUdp.parsePacket()){
    char s;
    s = (char)wifiUdp.read();
    M5.Lcd.println(s);
  }
}

まずbegin関数を呼び出すことで、引数で指定したポートを開放し、UDPメッセージを受信する準備をします。

parsePacket関数でパケットを受け取ったことを確認したら、read関数でデータを読み取り、ディスプレイに表示させるようにしました。

スマホからUDPパケットを送信

WiFi TCP/UDP Controllerというアプリを使えば、簡単にUDPパケットを送信することができます。

▼のリンクからアプリをダウンロードしましょう。

Google Play で手に入れよう

アプリを起動して、右上のスパナボタンをクリックし、UDP送信の設定をしましょう。

設定項目はたくさんありますが、以下の項目を設定しておけばOKです。

項目設定
IP or Domain NameM5 StackのIPアドレス
PortM5Stackプログラムで指定したポート番号
TCP/UDPUDP
BUTTON Name自分が使いやすいようボタンのラベル名を設定
BUTTON Commandボタンを押したときに送信するメッセージ

まとめ

以上、スマホからUDPでメッセージを送信して、M5Stackがこのメッセージを受信する方法の解説でした。

みなさんの参考になりましたら幸いです。

]]>
M5StickCを使って加速度計を作ってみた https://craft-gogo.com/m5stick-acc/ Sat, 14 May 2022 05:34:20 +0000 https://craft-gogo.com/?p=2690

クルマやバイクに乗っているとき、加速度が視覚化できたら、運転スキルを磨くのに活用できますよね。 3500円のM5StickC Plusを買って、100行以下の簡単なプログラムを書けば実現できますので、作り方を解説します。 […]]]>

クルマやバイクに乗っているとき、加速度が視覚化できたら、運転スキルを磨くのに活用できますよね。

3500円のM5StickC Plusを買って、100行以下の簡単なプログラムを書けば実現できますので、作り方を解説します。

プログラムのポイントは3つです。

  • 加速度センサからのデータ取得
  • 傾き補正
  • チラつきなくディスプレイに表示

それでは始めましょう!

M5StickC Plus 加速度センサの概要

製作物は下の写真になります。

M5StickC Plusのディスプレイに加速度を表示させました。

加速度が発生していないときは、赤い点はグラフ中心に位置し、加速度に応じて赤い点が上方向、減速度に応じて下方向に動きます。

カーブを曲がったときは、横加速度に応じて赤い点が横方向に移動します。

加速度がどれぐらい発生しているかは、円を基準にすれば分かります。一番外側の円を1G (=9.8m/s2)発生線としました。

M5StickCの取り付けは、裏面に両面テープなどで取り付けます。

垂直に取り付けられない場合に備えて、傾きを補正出来るようにしています。

M5StickCのAボタン(M5と書かれているボタン)を押すと傾きが補正され、赤い点がグラフ中央に位置するようになります。

製作方法

プログラム

全体のプログラムは以下のとおりです。

#include <M5StickCPlus.h>
#include <math.h>

TFT_eSprite sprite = TFT_eSprite(&M5.Lcd);

float OFFSET_X = 0, OFFSET_Y = 0, OFFSET_Z = -0.08;
float accX, accY, accZ, accU, accV, accW;
float x, y, z, theta;
int R1 = 20, R2 = 40, R3 = 60;
int X0 = 120, Y0 = 67;

void setup() {
  M5.begin();
  M5.IMU.Init();
  M5.Lcd.setRotation(3);

  // スプライトの作成
  sprite.setRotation(3);
  sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());
}

void loop() {
  sprite.fillRect(0, 0, M5.Lcd.width(), M5.Lcd.height(), BLACK);
  
  // グラフ描画
  sprite.drawCircle(X0, Y0, R1, WHITE);
  sprite.drawCircle(X0, Y0, R2, WHITE);
  sprite.drawCircle(X0, Y0, R3, WHITE);
  sprite.drawLine(X0 - R3 - 10, Y0, X0 + R3 + 10, Y0, WHITE);
  sprite.drawLine(X0, Y0 - R3 - 5, X0, Y0 + R3 + 5, WHITE);

  // 加速度データ取得
  M5.IMU.getAccelData(&x, &y, &z);
  
  accZ = -(x + OFFSET_X);
  accY = -(y + OFFSET_Y);
  accX = -(z + OFFSET_Z);
  accU = accX * sin(theta*PI/180) + accZ * cos(theta*PI/180);
  accV = accY;
  accW = - accX * cos(theta*PI/180) + accZ * sin(theta*PI/180);
  
  sprite.setCursor(0,5,2);
  sprite.printf("X:%5.2fG\nY:%5.2fG\nZ:%5.2fG", accU, accY, accW);
  sprite.fillCircle(X0 + (int)(accV * R3), Y0 - (int)(accU * R3), 8, RED);

  // 傾き補正
  M5.update();
  if(M5.BtnA.wasPressed()){
    accZ = max(min(accZ, 1.0), -1.0);
    theta = 180 / PI * asin(accZ);
  }

  // スプライトを表示画面に転送する
  sprite.pushSprite(0, 0);
  delay(100);
}

プログラムのポイントは3点です。

  • 加速度センサからのデータ取得
  • 傾き補正
  • チラつきなくディスプレイに表示

加速度センサからのデータ取得方法

M5.IMU.Init();
M5.IMU.getAccelData(&x, &y, &z);

accZ = -(x + OFFSET_X);
accY = -(y + OFFSET_Y);
accX = -(z + OFFSET_Z);

加速度センサを初期化した後、getAccelData関数で加速度データを取得することが出来ます。

M5StickCの座標軸は写真のとおりです。

実際に取り付けたときに発生した加速度が分かりやすいよう、前後方向の加速度をaccX、横方向の加速度をaccY、垂直方向の加速度をaccZとし、取得した加速度データを座標変換しました。

私のM5StickCは、z軸の加速度値がオフセットしていましたので、補正をかけています。

傾き補正

M5StickCを垂直に設置しなくても前後方向の加速度を検出出来るよう、傾きを補正します。

傾斜角の求め方

静止した状態での傾斜角は以下式で求めることが出来ます。

$$accZ=g\sin\theta$$

$$\theta=\sin^{-1}(accZ/g)$$

M5StickのボタンA(M5と書かれているボタン)を押した時に傾斜角を求めるようにしました。

M5.update();
if(M5.BtnA.wasPressed()){
  accZ = max(min(accZ, 1.0), -1.0);
  theta = 180 / PI * asin(accZ);
}

前後方向加速度の求め方

M5StickCが傾いているとき、前後方向の加速度は以下式で求めることが出来ます。

$$accU = accX \sin\theta + accZ \cos\theta$$

accU = accX * sin(theta*PI/180) + accZ * cos(theta*PI/180);

チラつきなくディスプレイに表示

取得した加速度データをリアルタイムでディスプレイに表示させますが、工夫しないとチラつきが発生してしまいます。

チラつき防止方法は、別記事で詳細に解説していますので、こちらを参照下さい。

https://craft-gogo.com/m5stack-sprite/

TFT_eSprite sprite = TFT_eSprite(&M5.Lcd);

sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());
sprite.pushSprite(0, 0);

TFT_eSpriteクラスでSpriteを作成した後、Spriteに図形や文字を描画し、pushSprite関数でM5StickCのディスプレイにこのSpriteを表示させることでチラつきを防止します。

スプライトとは、コンピュータ上で動く図形を表現する際に、動かす図形と固定された背景とを別に作成し、ハードウェア上で合成することによって表示を高速化する手法のことである。

IT用語辞典バイナリ

まとめ

以上、M5StickC Plusを使った加速度センサの作り方解説でした。

クルマやバイクにM5StickC Plusを取り付けることで、加速度を視覚化出来ます。

M5StickC Plusは3500円ほどで購入出来るので、気軽に製作トライできますよ。

プログラムのポイントは3つでした。

  • 加速度センサからのデータ取得
  • 傾き補正
  • チラつきなくディスプレイに表示

みなさんの参考になりましたら幸いです。

]]>
【M5Stack】画面ちらつきのないデジタル時計を作ろう! https://craft-gogo.com/m5stack-sprite/ Thu, 24 Mar 2022 14:41:26 +0000 https://craft-gogo.com/?p=2123

M5Stackの画面に文字や図形を描画した際、画面がちらついて困っていませんか? 普通に画面描画するプログラムを組むとちらついてしまうんです。 本記事では、TFT_eSpriteクラスを使ったちらつき防止方法について、デ […]]]>

M5Stackの画面に文字や図形を描画した際、画面がちらついて困っていませんか?

普通に画面描画するプログラムを組むとちらついてしまうんです。

本記事では、TFT_eSpriteクラスを使ったちらつき防止方法について、デジタル時計をプログラミングしながら解説します。

こんな人におすすめ!

  • M5Stack画面描画のちらつきに困っている人
  • TFT_eSpriteクラスの使い方について知りたい人
  • M5Stackを使って電子工作したい初心者

それでは始めていきましょう。

楽天ブックス
¥2,420 (2024/04/23 10:21時点 | 楽天市場調べ)

画面ちらつき防止方法

画面ちらつきを防止するTFT_eSpriteクラス

そもそもSpriteって何?

スプライトとは、コンピュータ上で動く図形を表現する際に、動かす図形と固定された背景とを別に作成し、ハードウェア上で合成することによって表示を高速化する手法のことである。

IT用語辞典バイナリ

このようにSpriteを使うことによって画面ちらつきが防止出来るわけです。

TFT_eSpriteクラスは、TFT_eSPIというライブラリ内に含まれています。TFT_eSPIライブラリを使うにはM5Stackライブラリをインクルードするだけでよいです。

TFT_eSpriteクラスの使い方

TFT_eSpriteクラスのインスタンス化

まず、TFT_eSpriteクラスをインスタンス化する必要があります。

TFT_eSprite sprite = TFT_eSprite(&M5.Lcd);

ビット深度の指定

扱う色数を指定します。

sprite.setColorDepth(8);

引数は下表から選びます。

引数定義
1616ビット = 65536色
88ビット = 256色
11ビット = 2色

Spriteの作成

Spriteを作成します。

sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());

第1引数にSpriteの横幅、第2引数にSpriteの高さを指定します。

図形や文字などをSpriteに描画

Spriteに表示させたい図形や文字を描画していきます。

sprite.printf("文字描画の例");

M5Stackの画面に表示するときはM5.Lcd.printf(“xxx”)でしたが、M5.Lcdをspriteに変更する形となります。

Spriteを画面に表示

spriteに描画した図形や文字をM5Stackの画面に表示させます。

sprite.pushSprite(0, 0);

第1引数は左端、第2引数は上端です。

サンプルプログラム

#include <M5Stack.h>
#include <WiFi.h>

#define JST (3600L * 9)

const char* ssid = "***************";
const char* password = "**************";

TFT_eSprite sprite = TFT_eSprite(&M5.Lcd);

void WiFiConnect();

void setup() {
  M5.begin();
  M5.Lcd.setTextSize(2);
  WiFiConnect();

  M5.Lcd.setTextSize(3);
  // NTPサーバと時刻を同期
  configTime(JST, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp");

  // スプライトの作成
  sprite.setColorDepth(8);
  sprite.setTextSize(3);
  sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());
}

void loop() {
  struct tm tm;
  if(getLocalTime(&tm)){
    sprite.fillScreen(BLACK);
    sprite.setCursor(20,60);
    sprite.setTextSize(6);
    sprite.printf("%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
    sprite.setCursor(40,140);
    sprite.setTextSize(4);
    sprite.printf("%d/%2d/%2d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
    
    // スプライトを画面表示する
    sprite.pushSprite(0, 0);  
  }
  delay(1000);

}

void WiFiConnect(){
  WiFi.begin(ssid,password);
  while(WiFi.status() != WL_CONNECTED){ 
    delay(500);
    M5.Lcd.print('.');
  }

  M5.Lcd.print("\r\nWiFi connected\r\nIP address: ");
  M5.Lcd.println(WiFi.localIP());
  delay(500);
}

画面ちらつき防止ありなしを比較

画面のちらつきが無くなったのが分かりますよね

まとめ

TFT_eSpriteクラスを使ったちらつき防止方法について、デジタル時計をプログラミングしながら解説しました。

最後までお読み頂きありがとうございました。

私はスイッチサイエンスさん(Amazon)でM5Stackを買いましたので、M5Stackを持っていない方はどうぞ。

書籍もKindleストアで「みんなのM5 Stack入門」を購入し、読みながら勉強してまーす。

楽天ブックス
¥2,420 (2024/04/23 10:21時点 | 楽天市場調べ)
プログラミング言語の人気オンラインコース ]]>
ホッチキスで固定できるM5StickC用壁掛けホルダーを3Dプリント https://craft-gogo.com/m5stickc-holder/ Sat, 19 Mar 2022 17:36:28 +0000 https://craft-gogo.com/?p=2098

「ホッチキスだけで取り付ける棚のように、M5StickCも壁を傷つけずに壁に固定できたらなぁ・・・」 自分で作ればいいじゃないかと思い、3Dプリンタで作ってみました。 今回の記事では、ホッチキスで固定できるM5Stick […]]]>

「ホッチキスだけで取り付ける棚のように、M5StickCも壁を傷つけずに壁に固定できたらなぁ・・・」

自分で作ればいいじゃないかと思い、3Dプリンタで作ってみました。

今回の記事では、ホッチキスで固定できるM5StickC用壁掛けホルダーを3Dプリンタで製作した過程を紹介します。

製作の流れは、

  • M5StickC用ホルダーをFreeCADで設計
  • 3Dプリンタ Creality Ender-3でプリント

といった流れです。

尚、3DデータはThingiverseというファイル共有サイトにアップロードしておきましたので、どなたでもダウンロード可能ですよ!

https://www.thingiverse.com/thing:5323021

この記事はこんな人におすすめ!
 ・M5StickCの壁固定方法に困っている人
 ・M5StickCのホルダー作り方が知りたい人
 ・3Dプリントの使い方が知りたい人

それでは始めましょう。

FreeCADで3Dモデルを作成

FreeCADで3Dモデルを作成していきました。製作過程を紹介していきます。

3Dモデル出来上がり!

Creality Ender-3で3Dプリント

STLファイルをUltimaker Curaで読み込み、3Dプリントの設定をしていきます。

Standard Quality(0.25mm)、インフィル密度は30%に設定しました。

サポートは無しでも問題ないですよ。

私が持っている3Dプリンタ Creality Ender-3でプリント。プリント時間は17分。

https://craft-gogo.com/post-240/

こんな感じで出来上がりました!

出来上がったホルダーを壁に固定してみた

ホッチキスで壁に固定です。

その上からM5StickCを4つの爪に引っかけると・・・

いい感じ!

まとめ

ホッチキスで固定できるM5StickC用壁掛けホルダーを3Dプリンタで製作した過程を紹介しました。

この3DモデルはThingiverseにアップロードしていますので、製作に興味を持った方はダウンロードしてみて下さい。

https://www.thingiverse.com/thing:5323021

最後までお読み頂きありがとうございました。

]]>
【M5Stick】ENV HAT Ⅲを使って3時間おきの気象データをLINEへ送信 https://craft-gogo.com/m5stick-env3/ Wed, 16 Mar 2022 21:38:29 +0000 https://craft-gogo.com/?p=2045

家庭菜園や夏休みの宿題などで毎日の気象データを自動で管理出来たら便利ですよね。 今回、M5Stickと気温、湿度、気圧センサが一体となったENVⅢを使って実現出来たので記事にします。自動管理は、LINE Notifyとい […]]]>

家庭菜園や夏休みの宿題などで毎日の気象データを自動で管理出来たら便利ですよね。

今回、M5Stickと気温、湿度、気圧センサが一体となったENVⅢを使って実現出来たので記事にします。自動管理は、LINE Notifyというサービスを使ってスマホへデータ送信する方法を取りました。

こんな人におすすめ!

  • 家庭菜園や夏休みの宿題などで気象データを管理したい人
  • M5Stack/Stickを活用したい人
  • M5Stickを使ったプログラミングを学習している人

準備したもの

  • M5StickC Plus
  • ENV HAT Ⅲ (気温、湿度、気圧センサー)
  • Wifiルータ
  • LINEがインストールされたスマホ

システム構成

製作方法

製作方法は次の順で解説していきます。まず製作に必要な事前知識です。ENV Ⅲのデータ計測方法、LINE Notifyを使ったデータ送信方法、そしてディープスリープモードによる省電力を説明します。次に全体プログラムの解説になります。

ENV Ⅲの気温・湿度・気圧データ計測方法

ENV Ⅲ概要

今回用いる温度・湿度・気圧センサはENV HAT Ⅲというすべてセンサが1パッケージになっているものを使用します。

2022年3月時点の価格は1430円でした。

温度・湿度センサにはSHT30、気圧センサにはQMP6988というチップが使われています。通信方式はI2Cです。

スペックを載せておきますね。

項目パラメータ
温度測定範囲-40 ~ 120℃
最大測定精度0 ~ 60℃ / ±0.2℃
湿度測定範囲 /誤差10 ~ 90%RH / ±2%
気圧測定範囲 /分解能 /誤差300 ~ 1100 hPa / 0.06 Pa / ±3.9 Pa
通信プロトコルI2C:SHT30(0x44)、QMP6988(0x56)
動作温度範囲0 ~ 40℃

UNIT_ENVライブラリのインストール

M5Stackからライブラリがリリースされているので、今回このライブラリを使用します。

私はArduino IDEではなく、Platform IO IDEを使用していますので、Librariesから「UNIT_ENV」を検索すればライブラリが見つかりますよ。

PlatformIO IDEの使い方については、こちらの記事で紹介していますので参考にして下さい。

https://craft-gogo.com/m5stack-build/

温度・湿度・気圧データ計測するためのプログラム

まずはUNIT_ENVライブラリを呼び出します。

#include "UNIT_ENV.h"

次にWireライブラリを初期化し、I2Cバスに接続します。

Wire.begin(0,26);

温度・湿度はSHT30、気圧はQMP6988を使用していますので、まずはSHT30の解説から。

SHT3Xクラスをインスタンス化し、

SHT3X sht30;

get()関数を呼び出すと温度、湿度が計測されます。

sht30.get()

温度はcTemp、湿度はhumidityに格納されています。

float temp = sht30.cTemp;
float hum = sht30.humidity;

続いてQMP6988の解説。同じようにQMP6988クラスをインスタンス化、初期化し、

QMP6988 qmp6988;
qmp6988.init();

calcPressure()関数を呼び出せば戻り値として気圧が返ってきます。

float pressure = qmp6988.calcPressure();

ライブラリを使えば簡単ですね!

LINE Notifyを使ったデータ送信方法

LINE社が提供しているLINE Notifyを使うとWebサービスからの通知をLINEで受信出来るようになります。

3時間おきにLINE Notifyで温度・湿度・気圧データをLINEへ送信します。

LINE Notifyの使い方はこちらの記事で紹介していますので、今回割愛させていただきます。

https://craft-gogo.com/m5stack-line/

M5Stickの省電力化

データ計測は屋外を想定していますので、なるべくM5Stickを省電力化し、バッテリーを長持ちさせたいです。ここでは3つの方法で省電力化していきます。ディープスリープモードクロック周波数変更液晶バックライト変更です。

ディープスリープモード

データ計測は頻繁に行わないため、待機中の電力消費はもったいないです。

M5Stickに搭載されているマイコンESP32はディープスリープモードという省電力モードがありますので、これを使用しました。

esp_deep_sleep(10800000000ULL); // 3 * 60 * 60 * 1000000 μs = 3h

引数で指定した時間スリープした後、マイコンがリセットされます。引数はμsec単位で指定します。

ディープスリープモードはM5Stick自体の温度を下げる目的もあります。連続でデータ計測していると計測温度はどんどん上がっていくので、正確な温度測定にはディープスリープモードにして温度を下げる必要があります。

クロック周波数変更

CPUのクロック周波数を下げることも省電力化には有効です。

setCpuFrequencyMhz(80);

引数の単位はMHzです。デフォルトは240MHzで動作しています。今回、80MHzまで下げました。下げすぎると無線通信が安定しなくなるようです。

液晶バックライト変更

液晶を暗くすることも省電力化に繋がりますよね。

M5.Axp.ScreenBreath(0);

引数は明るさで0-12の範囲で指定します。液晶は見ない前提なのでゼロまで下げました。

全体プログラム

プログラム全体を載せます。

#include <M5StickCPlus.h>
#include "UNIT_ENV.h"
#include <WiFiClientSecure.h>

void Line_notify(String msg);

SHT3X sht30;
QMP6988 qmp6988;
WiFiClientSecure client;  

const char* ssid = "*************";
const char* password = "*****************";

const char* host = "notify-api.line.me";
const char* token = "************************";

float tmp = 0.0;
float hum = 0.0;
float pressure = 0.0;
double vbat = 0.0;

void setup() {
  M5.begin();
  setCpuFrequencyMhz(80);
  M5.Axp.ScreenBreath(0);
  M5.Lcd.setRotation(3);
  M5.Lcd.setCursor(0,0,4);
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED){
    M5.Lcd.print('.');
    delay(500);
  }
  M5.Lcd.print("\r\nWiFi connected\r\nIP address: ");
  M5.Lcd.println(WiFi.localIP());

  Wire.begin(0,26);
  qmp6988.init();

  pressure = qmp6988.calcPressure();
  if(sht30.get()==0){ 
    tmp = sht30.cTemp;  
    hum = sht30.humidity; 
  }else{
    tmp=0,hum=0;
  }
  vbat = M5.Axp.GetVbatData() * 1.1 / 1000;
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0,0,4);
  M5.Lcd.printf("Temp: %2.1f  \r\nHumi: %2.0f  \r\nPressure: %2.0fPa\r\nVolt: %.2fV  \r\n", tmp, hum, pressure, vbat);

  char msg[100];
  sprintf(msg, "Temp: %2.1f  \r\nHumi: %2.0f  \r\nPressure: %2.0fPa\r\nVolt: %.2fV  \r\n", tmp, hum, pressure, vbat);

  Line_notify(msg); // LINE Notifyへリクエスト送信
  
  esp_deep_sleep(10800000000ULL); // 3 * 60 * 60 * 1000000 μs = 3h
}

void loop() {
  
}

void Line_notify(String msg) {
  client.setInsecure();
  if (!client.connect(host, 443)) {
    delay(2000);
    M5.Lcd.print("Not Connected");
    return;
  }
  String query = String("message=") + msg;
  String request = String("") +
               "POST /api/notify HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Authorization: Bearer " + token + "\r\n" +
               "Content-Length: " + String(query.length()) +  "\r\n" + 
               "Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
                query + "\r\n";
  client.print(request);
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      break;
    }
  }
  
  delay(2000);
}

気象データを計測してみよう

プログラムを書き込むとさっそくLINEで温度・湿度・気圧データが送られてきます。

ほったらかしにして待っていると、数分の誤差はあるものの3時間毎に温度・湿度・気温データがLINEで送られてきました。

電源電圧の下がり方は3時間で0.1Vほどです。電源電圧4.17Vから始めたのですが12時間はバッテリーが持ちました。

まとめ

M5StickとENVⅢを使って3時間ごとに温度・湿度・気圧データをLINEでスマホへ送信するシステム構築の解説をしました。

家庭菜園や夏休みの宿題などで毎日の気象データを自動で管理出来ますね。

今回はM5StickC PLUSのバッテリー駆動のみで12時間しか持ちませんでした。屋外で使用するとなった場合、電源確保必要ですので、今後の課題にしたいと思います。

興味を持たれた方は是非実践してみて下さい。

最後までお読み頂きありがとうございました。

私はM5StickC PLUSとENV ⅢをAmazon(スイッチサイエンス)で購入しました。みんなのM5Stack入門を読んで勉強してます。

]]>