「M5Stack Basic V2.6」の使い方について、基本仕様から端子配列、サンプルプログラムで「Lチカ」やアナログ入力(ADC)、アナログ出力(DAC)、シリアル通信(UART)、液晶表示、バッテリー残量表示等の基本的な動作まで詳しく紹介します。
「液晶表示器」の使い方については、以下のリンクで詳しく紹介しています。
1.「M5Stack Basic V2.6」とは
2.外観
3.基本仕様
4.端子配列
5.端子機能詳細
6.開発環境の紹介
・Arduino IDE
・PlatformIO
・UiFlow(ビジュアルプログラミング)
7.動作詳細、配線図
8.サンプルプログラム(コピペ)
9.動作確認
10.まとめ
1.「M5Stack Basic V2.6」とは
「M5Stack Basic V2.6」とは「M5Stackテクノロジー社」のマイコンボードです。
大きさは 54mm x 54mm x 18mmで2.0インチ(320*240)液晶表示器を搭載しており、入出力端子、3個のボタン、3軸ジャイロ+3軸加速度センサ、スピーカ搭載でSDカードやバッテリーも内蔵されています。
他にもシリアル通信はもちろんWiFiやBluetoothにも対応、これらの機能をプログラムで自由に組み合わせて使用することができるので電子工作やデータ表示器、IoT機器の製作等いろいろなアイデアを形にすることができます。
プログラムは「C言語」ベースの「Arduino IDE」「PlatformIO」や「ビジュアルプログラミング(UiFlow)」「Python(MicroPython)」で作成できます。
2.外観
梱包状態、本体外観は下画像のようになります。
付属品はUSBケーブル(Type-A ー Tyupe-C)ジャンパーケーブル、取説、ステッカーです。
3.基本仕様
基本仕様については下表のようになります。
Specifications | Parameters |
---|---|
ESP32-D0WDQ6-V3 | 240MHz dual core, 600 DMIPS, 520KB SRAM, Wi-Fi |
フラッシュメモリ | 16MB |
電源有力 | 5V @ 500mA |
通信ポート | USB TypeC x1, I2C x1 |
入出力端子 | G21, G22, G23, G19, G18, G3, G1, G16, G17, G2, G5, (G25), G26, G35, G36 |
ボタン | 本体ボタン x 3(A、B、C) |
液晶表示器 | 2.0″@320*240 ILI9342C IPS panel, maximum brightness 853nit |
スピーカ | 1W-0928 |
USB chip | CH9102F |
アンテナ | 2.4G 3D アンテナ |
バッテリー | 110mAh @ 3.7V |
本体重量 | 47.2g |
梱包重量 | 93g |
本体サイズ | 54mm x 54mm x 18mm |
梱包サイズ | 95 x 65 x 25mm |
本体材質 | プラスチック(ポリカーボネート) |
4.端子配列
端子機能は下画像のようになります。
5.端子機能詳細(入出力/ADC/DAC/シリアル通信)
端子機能詳細は下表のようになります。
6.開発環境の紹介
・Arduino IDE
「Arduino IDE」とはArduino」の開発環境ですが「M5Stackシリーズ」でも使えて無償でダウンロードすることができます。
複雑で専門的な知識を必要とするプログラムが「ライブラリ」としてまとめられており、直感的に理解しやすいコマンドでこの「ライブラリ」を使用することで、初心者でも簡単に複雑な動作を実現することができます。
プログラミング言語は「C言語」をベースに、マイコンボードを制御するための「Arduino」独自のコマンドを使用して、マイコンボードを動かしながらプログラミングを進めることで「C言語」も自然に身につくため「C言語」の学習にも最適です。
「Arduino IDE」のインストール方法、使い方は以下のリンクで詳しく紹介しています。
・PlatformIO
「PlatformIO」は開発環境の準備が大変ですが、無料の高機能エディタ「Visual Studio Code(VSCode)」の中で使用することができ、プログラムの編集機能が豊富で慣れてしまうと他の環境には戻れません。
何より書込み速度が速いので本格的にプログラミングするなら「PlatformIO」が特におすすめです。
「PlatformIO」のインストール方法は以下のリンクで詳しく紹介してます。
「VS Code」と「Python」のインストールも別途必要になりますのでリンクを載せておきます。
インストール順は「① VS Code」「② Python」「③ PlatformIO」です。
初期設定については「M5Stackシリーズ」の「ATOM LITE」の初期設定を参考にしてください。
・UiFlow(ビジュアルプログラミング)
「UiFlow」は「ビジュアルプログラミング」の開発環境です。
「ビジュアルプログラミング」とは「ブロックプログラミング」とも呼ばれ、日本語の説明が表示されたコマンドのブロックを組み合わせることでプログラムを作成することができるプログラミング方法で、初心者でも感覚的にプログラミングを体験することができます。
「UiFlow」の使い方は以下のリンクで詳しく紹介しています。
7.動作詳細、配線図
主な端子機能の動作を確認するために以下のような配線で動作確認を行いました。
本体ボタンと外部入力による「Lチカ」やアナログ入力(ADC)、アナログ出力(DAC)、シリアル通信(UART)データ表示、液晶表示、バッテリー残量表示等の基本的な動作が確認できます。
外部端子の左右と上下の同じ色で表示されている端子は内部で繋がっているのでどちらを使用しても良いです。
実際に配線を行ったものは下画像のようになります。
スイッチはジャンパー線の片側をG(0V)側に差したLEDの端子に触れさせることでON/OFFさせます。
動作については以下のようになります。
本体ボタンA[V_UP]を押すと液晶画面の[DAC]部のアナログ出力電圧が大きくなり、本体ボタンB[V_DOWN]を押すと小さくなります。
G35(AD)のアナログ出力とG26(DA)のアナログ入力を接続することで、[ADC]部のアナログ入力電圧には[DAC]のアナログ出力電圧を読み取って表示させることができます。
本体ボタンC[ON/OFF]または外部スイッチ(写真ではジャンパー線)をONすると、液晶画面の「OUTPUT」表示がONになり外部の抵抗内蔵LEDが点灯します。
シリアル通信は標準のシリアル通信とシリアル通信2を使用しています。
どちらのシリアル通信も同じ動作をさせています。受信したデータは液晶画面右上の[SERIAL MONITOR]部に表示させています。
標準のシリアル通信では「ArduinoIDE」等のシリアルモニタに入力したデータを液晶画面に表示させます。
シリアル通信2の送信端子G17(T2)と受信端子G16(R2)は接続しているため、送信したデータをそのまま受信して液晶画面に表示させます。
LEDは「抵抗内蔵LED」の青色を使用していますが、普通のLEDと抵抗の組み合わせでも大丈夫です。
「抵抗内蔵LED」と「スイッチ」については以下のリンクで詳しく紹介しています。
抵抗内蔵LEDは秋月電子通商の「I-06247」がおすすめです。10個 ¥200-
8.サンプルプログラム(コピペ)
サンプルプログラムは以下になります。「コピペ」して書き込んでください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。
#include <M5Stack.h>
/*
M5Stack Basic V2.6端子仕様
G3/G1 :UART0通信用(RX/TX) ※標準のシリアル通信未使用なら入力/出力使用可、書き込み時は未接続にする
G16/G17:UART2通信用(RX/TX) ※シリアル通信2未使用ならG16は入力/出力、G17は出力のみ使用可
G2/G5 :入力/出力/G2のみアナログ入力可
G25/G26:G25はスピーカー専用、G26は入力/出力/アナログ入力/アナログ出力
G35/G36:アナログ入力(入力としても使用できるがプルアップ不可)
G21/G22:I2C通信用 Groveコネクタと共通(SDA/SCL) ※入出力使用可だが電源ICと繋がっているため非推奨
G23/G19/G18:SPI通信用(MOSI/MISO/SCK) ※G19のみ入出力使用可だがTF(SD)Cardと繋がっているため非推奨
G39/G38/G37:本体ボタン(左からボタンA,B,C、内部で接続)
*/
// 端子割り付け
#define IN0 2 // 入力端子
#define OUT0 5 // 出力端子
#define ADC0 35 // アナログ入力端子
#define DAC0 26 // アナログ出力端子
// 変数宣言
float ad_val; // アナログ入力値格納用
float da_val; // アナログ出力値指定用
float v_in = 0; // アナログ入力電圧換算値
float v_out = 0; // アナログ出力電圧換算用
bool state = false; // ボタン状態確認用
bool output0 = LOW; // 出力状態指示用
int cnt = 0; // 表示回数カウント用
String data = ""; // シリアル通信の受信データ格納用
// 関数 ************************************************************************
// シリアルモニタ出力処理
void serial_mon(String data) {
M5.Lcd.fillRect(205, 52, 115, 18, WHITE);
M5.Lcd.setTextFont(2); // フォント
M5.Lcd.setCursor(210, 53); M5.Lcd.setTextColor(BLACK); // 座標指定(x, y) // 文字色、背景
M5.Lcd.print(data); // 受信データ液晶表示
Serial.println(data); // 受信データ標準シリアル出力
}
// 初期設定 ************************************************************************
void setup(){
M5.begin(); // 本体初期化(LCD, SD, Serial, I2C)
M5.Power.begin(); // 電源初期化
Serial.begin(9600); // 標準のシリアル通信初期化(初期値はG3(RX),G1(TX))
Serial2.begin(9600); // シリアル通信2初期化 (初期値は G16(RX), G17(TX))
// 入出力ピン設定
// 入力設定
pinMode(IN0, INPUT_PULLUP); // 入力設定(プルアップ)
// 出力設定
pinMode(OUT0, OUTPUT); // 出力設定
digitalWrite(OUT0, LOW); // 出力初期値
// アナログ入力設定
pinMode(ADC0, ANALOG); // アナログ入力
// アナログ出力設定
pinMode(DAC0, OUTPUT); // 出力端子に設定
dacWrite(DAC0, 0); // 初期値0設定
//LCD表示
M5.Lcd.fillScreen(BLACK); // 背景色
M5.Lcd.setTextSize(1); // 文字サイズ(整数倍率)
M5.Lcd.setTextFont(4); // フォント 1(8px), 2(16px), 4(26px)
// 6(36px数字-.:apm), 7(7セグ-.:), 8(75px数字-.:)
M5.Lcd.drawFastHLine(0, 0, 320, WHITE); // 指定座標から平行線
M5.Lcd.fillRect(0, 1, 320, 27, (uint16_t)0x098a); // タイトルエリア背景
M5.Lcd.drawFastHLine(0, 29, 320, WHITE); // 指定座標から平行線
M5.Lcd.setTextColor(WHITE); // 文字色
M5.Lcd.drawCentreString("M5Stack Basic V2.6 TEST", 160, 4, 4); // 指定座標を中心に文字表示(x, y, font)
M5.Lcd.drawFastVLine(202, 29, 43, WHITE); // 指定座標から垂直線(x, y, l, 色)
M5.Lcd.drawFastHLine(0, 72, 320, WHITE); // 指定座標から平行線(x, y, l, 色)
M5.Lcd.drawFastHLine(0, 132, 320, WHITE);
M5.Lcd.drawFastHLine(0, 192, 320, WHITE);
M5.Lcd.drawCircle(10, 51, 9, WHITE); // 指定座標で半径を指定して円描画(x, y, r, 色)
M5.Lcd.setTextFont(2); // フォント
M5.Lcd.setCursor(212, 34); M5.Lcd.print("SERIAL MONITOR"); // シリアルモニタ項目表示
M5.Lcd.fillRect(205, 52, 115, 18, WHITE); // 塗りつぶし四角
//本体ボタン項目表示
M5.Lcd.drawRect(37, 216, 66, 23, WHITE); // 本体ボタン表示枠用四角
M5.Lcd.drawRect(127, 216, 66, 23, WHITE);
M5.Lcd.drawRect(217, 216, 66, 23, WHITE);
M5.Lcd.setTextFont(2); // フォント
M5.Lcd.setCursor(55, 221); M5.Lcd.print("V_UP"); // アナログ出力電圧アップボタン
M5.Lcd.setCursor(135, 221); M5.Lcd.print("V_DOWN"); // アナログ出力電圧ダウンボタン
M5.Lcd.setCursor(225, 221); M5.Lcd.print("ON/OFF"); // ON/OFFボタン
}
// メイン処理 ************************************************************************
void loop() {
M5.update(); // ボタン状態更新
// 本体ボタン、外部ボタン入力処理
// ボタンA または 外部スイッチ赤が押されている かつ アナログ出力255より小さいなら
if (M5.BtnA.isPressed() && da_val < 255) {
Serial.println("V_UP!"); // 標準のシリアル出力
Serial2.println("V_UP!"); // シリアル2出力
da_val++; // アナログ出力 +1
}
// ボタンB または 外部スイッチ青が押されてる かつ アナログ出力0より大きいなら
if (M5.BtnB.isPressed() && da_val > 0) {
Serial.println("V_DOWN!"); // 標準のシリアル出力
Serial2.println("V_DOWN!"); // シリアル2出力
da_val--; // アナログ出力 -1
}
// ボタンCを押すか外部入力がONするごとに出力をON/OFF
// ボタンCまたは外部入力がONでstateがfalseなら
if ((M5.BtnC.isPressed() == true || digitalRead(IN0) == LOW) && state == false) {
state = true; // ボタン状態stateをtrue
output0 = !output0; // 出力指示値反転
digitalWrite(OUT0, output0); // 外部出力実行
if (output0 == HIGH) { // 出力指示値がHIGHならON出力
Serial.println("ON!"); // 標準のシリアル出力
Serial2.println("ON!"); // シリアル2出力
} else { // 出力指示値がHIGHでなければOFF出力
Serial.println("OFF!"); // 標準のシリアル出力
Serial2.println("OFF!"); // シリアル2出力
}
}
if (M5.BtnC.isReleased() == true && digitalRead(IN0) == HIGH) { // ボタンCと外部入力がOFFなら
state = false; // ボタン状態stateをfalse
}
// 液晶表示上のシリアルモニタ表示処理
if (Serial.available()) { // 標準のシリアルデータ受信で
data = Serial.readStringUntil('\n'); // 区切り文字「LF」の手前までデータ取得
serial_mon(data); // シリアルモニタ出力処理関数呼び出し
}
if (Serial2.available()) { // シリアル2のデータ受信で
data = Serial2.readStringUntil('\n'); // 区切り文字「LF」の手前までデータ取得
serial_mon(data); // シリアルモニタ出力処理関数呼び出し
}
// アナログ入出力、電圧換算処理
// アナログ入力処理
ad_val = analogRead(ADC0); // アナログ入力値を取得(0〜4095、12bit)
v_in = ad_val * (3.3 / 4095); // 3.3Vへ換算
// アナログ出力処理
dacWrite(DAC0, da_val); // アナログ出力実行(0〜255、8bit)
v_out = da_val * (3.3 / 255); // 3.3Vへ換算
// LCD表示処理
// ON/OFFボタン出力状態表示
M5.Lcd.setTextFont(4); // フォント
M5.Lcd.setCursor(26, 42); // 座標指定(x, y)
if (output0 == LOW) {
M5.Lcd.setTextColor(CYAN, BLACK); // (文字色, 背景)
M5.Lcd.printf("OUTPUT : OFF"); // 出力端子の状態表示
M5.Lcd.fillCircle(10, 51, 8, BLACK); // 指定座標に半径を指定して塗り潰し円描画(x, y, r, 色)
} else {
M5.Lcd.setTextColor(ORANGE, BLACK); // (文字色, 背景)
M5.Lcd.printf("OUTPUT : ON "); // 出力端子の状態表示
M5.Lcd.fillCircle(10, 51, 8, ORANGE); // 指定座標に半径を指定して塗り潰し円描画(x, y, r, 色)
}
// アナログ入出力電圧(アナログ入出力値)表示
M5.Lcd.setTextFont(4); // フォント
M5.Lcd.setCursor(5, 105); M5.Lcd.setTextColor(WHITE, BLACK); // 座標指定(x, y) // 文字色、背景
M5.Lcd.printf("ADC : "); // アナログ入力項目表示
M5.Lcd.setCursor(5, 165); // 座標指定(x, y)
M5.Lcd.printf("DAC : "); // アナログ出力項目表示
M5.Lcd.setTextFont(7); // フォント
M5.Lcd.setCursor(85, 80); M5.Lcd.setTextColor(WHITE, BLACK); // 座標指定(x, y) // 文字色、背景
M5.Lcd.printf("%01.2fv", v_in); // アナログ入力電圧表示
M5.Lcd.setCursor(85, 140); // 座標指定(x, y)
M5.Lcd.printf("%01.2fv", v_out); // アナログ出力電圧表示
M5.Lcd.setTextFont(4); // フォント
M5.Lcd.setCursor(200, 105); M5.Lcd.setTextColor(WHITE, BLACK);// 座標指定(x, y) // 文字色、背景
M5.Lcd.printf("V ( %04.0f )", ad_val); // アナログ入力値表示
M5.Lcd.setCursor(200, 165); // 座標指定(x, y)
M5.Lcd.printf("V ( %04.0f )", da_val); // アナログ出力値表示
// バッテリー残量表示(表示更新10回に1回)
if (cnt == 10) { // サンプリング
M5.Lcd.setTextFont(1); // フォント
M5.Lcd.setCursor(295, 228); M5.Lcd.setTextColor(DARKGREY, BLACK); // 座標指定(x, y) // 文字色、背景
M5.Lcd.printf("%d%%", M5.Power.getBatteryLevel()); // バッテリー残量表示
cnt = 0; // サンプリング回数0リセット
}
cnt++; // 表示回数カウント +1
delay(100); // 遅延時間
}
シリアル通信のプログラムを抜粋すると以下のようになります。
// 変数宣言
String data = ""; // 受信データ格納用
// 初期設定 -----------------------------------------------
void setup() {
M5.begin(); // 本体初期化
// 使用するシリアル通信ごとに通信速度を指定して初期化
Serial.begin(9600); // 標準のシリアル通信初期化(初期値はG3(RX),G1(TX))
Serial2.begin(9600); // シリアル通信2初期化 (初期値は G16(RX), G17(TX))
}
// メイン -------------------------------------------------
void loop() {
// データ受信時処理
if (Serial.available()) { // シリアルデータ受信で
data = SerialBT.readStringUntil('\n'); // 改行の手前までデータ取得
Serial.print(data); // 受信データ送信
}
delay(100); // 0.1秒ごとに実行
}
まずは「通信速度」を指定して以下のように初期化を行います。
Serial2.begin( 通信速度 ) ; //シリアル通信2、初期値G16(RX),G17(TX)
・通信速度:通信速度(ボーレート)を数値で指定します。
通信速度には以下のようなものがあります。(単位 bps)
1200/2400/4800/9600/19200/38400/57600/115200
※省略すると9600bpsとなります。
シリアルデータの送受信には以下のコマンドを使用しています。
SerialBT.readStringUntil( ‘\n’) ; // 受信データを指定した文字の手前まで文字列で取得
今回は受信データの取得には 「SerialBT.readStringUntil(‘\n’)」を使用しました。
これで、受信したデータを区切り文字「‘\n’(改行)」の手前まで取得できるので、変数(文字列)に格納して使用しています。
「入出力端子」や「ボタン」「アナログ入力」の使い方、「C言語」については以下のリンクで詳しく紹介しています。
9.動作確認
サンプルプログラムの動作確認をしてみましょう。
プログラムを書きこむと本体液晶表示は下画像のようになります。
液晶画面の表示内容について
・OUTPUT :出力端子の状態表示「ON/OFF」左の円はONでオレンジの塗り潰し円に変化
・SERIAL MONITOR :シリアル通信受信データ表示
・ADC :アナログ入力電圧換算値0~3.3V(12bit アナログ入力値 0~4095)
・DAC :アナログ出力電圧換算値0~3.3V(8bit アナログ出力値 0~255)
・V_UP :本体ボタンA、ONでアナログ出力値(DAC)上昇
・V_DOWN :本体ボタンB、ONでアナログ出力値(DAC)下降
・ON/OFF :本体ボタンC、ONするごとに出力状態変化
・右下(%) :バッテリー残量表示
上画像のように[V_UP]ボタンを押すと「DAC」の数値が上昇します。
「DAC」の値を読み込んで「ADC」の値も上昇します。
[V_DOWN]ボタンを押すと「DAC」の数値が下降します。
「DAC」の値を読み込んで「ADC」の値も下降します。
「DAC」のアナログ出力電圧ごとに「ADC」のアナログ入力電圧を確認すると以下のようになりました。意外と誤差が大きいですね・・・最終的には3.3Vにはなりました。
次に[ON/OFF]ボタンの動作を確認します。
上画像のように[ON/OFF]ボタンを押すと「OUTPUT:」表示はONになり、左の円はオレンジの塗り潰し円に変化、外部LEDは点灯します。
再度[ON/OFF]ボタンを押すと「OUTPUT:」表示はOFFになり、左の円は黒の円に変化、外部LEDは消灯します。
外部入力のスイッチは上画像のようにジャンパー線で代用しています。
LEDの0V端子に触れるとONします。
再びLEDの0V端子に触れるとOFFします。
最後に液晶表示器右上のシリアルモニタの表示確認です。
[V_UP]ボタンを押すと「V_UP!」表示
[V_DOWN]ボタンを押すと「V_DOWN!」表示
[ON/OFF]ボタンを押すと「ON!」表示
再び[ON/OFF]ボタンを押すと「OFF!」表示
「ArduinoIDE」等のシリアルモニタ([ツール]→[シリアルモニタ])で好きな文字を入力して送信したものも表示できます。
今回はブログ名の「Logikara Blog」を入力しました。
パソコン側から送信されたデータが受信されて表示されます。
入力した「Logikara Blog」が表示されました。
シリアルモニタの使い方については以下のリンクで詳しく紹介しています。
その他の動作確認として外付けボリュームを使ってアナログ入力の動作確認もしてみました。
動作確認には「M5Stack社」製のボリューム「ANGLE UNIT」を下画像のように配線して行いました。
ボリュームを回転させると「ADC」の値が変化することが確認できます。
アナログ入力の使い方やボリューム(可変抵抗器)について以下のリンクで詳しく紹介しています。
10.まとめ
「M5Stack Basic V2.6」は「M5Stack社」のマイコンボードの上位機種で最上位機種には「CORE2」がありますが、入出力端子の扱いは「Basic」の方が扱いやすく、タッチボタン搭載の「CORE2」よりも物理ボタンを搭載している「Basic」の方がボタン動作が安定していて、個人的にはタッチパネルが必須でなければ「Basic」の方が使いやすいと思います。
開発環境は「C言語」ベースの「Arduino IDE」「PlatformIO」や「Python」の「MicroPytho」、ビジュアルプログラミングの「UiFlow」を使ってプログラミングを行うことができます。
価格的には「M5StickC Plus」の方が安いですが、液晶の大きさや扱える端子も多く「CORE2」よりも扱いやすいため「M5Stackシリーズ」の中では一番万能で扱いやすく、なんでもできてアイデアを形にするには「M5Stack Basuc V2.6」が一番良いのではと思います。
コメント