これは、自分用メモです。(随時更新)
注意
ケーブル(Type-C)の表裏があることがある。
長いケーブルはうまく認識できないことがある。
ハード
Bus
GPIO | M5Stack Basic | PULL UP |
備考 | M5Port Explain | ESP32 ADC/DAC | M5Fire | |
---|---|---|---|---|---|---|---|
G23 | MOSI | TF_DI ILI9342C_MOSI_MISO |
12K | - | |||
G19 | MISO | TF_DO | 12K | - | |||
G18 | SCK | TF_SCLK ILI9342C_CLK |
12K | - | |||
G3 | IO0 RXD1 |
USB_RXD0 | - | ||||
G16 | IO2 RXD2 |
Port C (Blue) UART |
GROVE-C PS-RAM |
||||
G21 | IO4 SDA |
GROVEA_SDA IP5306 |
Port A (Red) I2C |
MPU6886_SDA BMM150_SDA |
|||
G2 | IO6 | WiFi使用時にADC使えない 起動時のモード選択で利用される |
ADC2 | ||||
G12 | IO8 IIS_SCLK |
- | 起動時に1だと LDOが1.8V, 0だと3.3Vになる* WiFi使用時にADC使えない |
ADC2 | - | ||
G15 | IO10 IIS_OUT |
- | 標準でPULLUP 起動時に設定すると SDIOスレーブタイミングの設定* WiFi使用時にADC使えない |
ADC2 | LED_BAR | ||
G35 | ADC1 | 入力専用?* | ADC1 | ||||
G36 | ADC2 | 入力専用?* | Port B (Black) ADC |
ADC1 | GROVE-B | ||
G25 | DAC0 AUDIO_L Speaker |
Speaker | DAC1 | - | |||
G26 | DAC1 AUDIO_R |
WiFi使用時にADC使えない | Port B (Black) DAC |
DAC2 | GROVE-B | ||
G1 | IO1 TXD1 |
USB_TXD0 | - | ||||
G17 | IO3 TXD2 |
Port C (Blue) UART |
GROVE-C PS-RAM |
||||
G22 | IO5 SCL |
GOVEA_SCL IP5306_SCL |
Port A (Red) I2C |
MPU6886_SCL BMM150_SCL |
|||
G05 | IO7 | - | 標準でPULLUP 起動時に設定すると SDIOスレーブタイミングの設定* | - | |||
G13 | IO9 IIS_WS |
ADC2 | |||||
G0 | IO11 IIS_MCLR BOOT |
AUTO_DOWNLOAD | 12K | 使用不可 起動時のモード選択で利用される |
ADC2 | - | |
G34 | ADC0 IIS_IN |
入力専用?* | ADC1 | MIC | |||
G39 | BTN A | 入力専用?* | ADC1 | - | |||
G38 | BTN B | 入力専用?* | ADC1 | - | |||
G37 | BTN C | 入力専用?* | ADC1 | - | |||
G4 | TF_CS | 12K | WiFi使用時にADC使えない | ADC2 | - | ||
G33 | ILI9342C_RST | ADC1 | - | ||||
G27 | ILI9342C_DC | WiFi使用時にADC使えない | ADC2 | - | |||
G14 | ILI9342C_CS | WiFi使用時にADC使えない | ADC2 | - | |||
G32 | ILI9342C_BL | 100k PullDown |
ADC1 | - |
ドキュメント https://docs.m5stack.com/#/en/core/basic
図面 https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/schematic/Core/M5-Core-Schematic(20171206).pdf
-
http://ghz2000.com/wordpress/?p=1418
入力専用は、チップ内のPullUPができないみたい
**【ESP32】Wifi接続時のanalogReadについて https://rikoubou.hatenablog.com/entry/2017/07/26/193021
GPIO12 Easter Eggに割り当て? https://macsbug.wordpress.com/2017/01/04/easter-egg-of-esp-32/
M5Stack Fire
Grove端子CはPSRAMと兼用不可。
使いたい場合はArduinoIDEのツールのPSRAMをDisableにする。
M5StickC
FTDIのUSB-Serial変換器らしい。(M5Stackとは違う)
USBドライバーがないときは、下記から持ってくる。真ん中あたりの表の右(WHQL Certified. Includes VCP and D2XX.
Available as a setup executable が便利)
https://ftdichip.com/drivers/vcp-drivers/
M5StickC Plus
HATの出力ポート
pinMode(25, OUTPUT);
gpio_pulldown_dis(GPIO_NUM_36);
gpio_pullup_dis(GPIO_NUM_36);
HATの方のWireはWire1を利用する。スピードを指定する必要あり?
Wire1.begin(0, 26);
Wire1.setClock(50000);
base15
M5Stack Basic と Base15 の組み合わせが便利(電池不要・固定)
https://m5stack.com/collections/m5-base/products/base15-proto-industrial-board-module
Groveコネクタは配線してないので自由に結線できます。(代わりに電源も結線が必要)
ACアダプタは9−24Vが使用可能 https://www.switch-science.com/catalog/1795/
DC/DCコンバータ https://www.tij.co.jp/jp/lit/ds/symlink/tps54360.pdf
RS485のボードがなぜかついているが端子がない。(別途購入すれば使える?・Base26と同じパッケージ?)
DINもしくはひっかけネジで固定できそう。
DINの固定はネジ1本?
DIN使用時はM5Stackが横向きになるので注意(コードが下向きの方が良いからそれはそう)
M5.lcd.setRotation(2);
で横向きにする。
付属の六角レンチはなめやすいので、市販品を使った方が良さそう
Pb.HUB
https://docs.m5stack.com/#/en/unit/pbhub
IOが5Vなので、SeeedStudioの5V Digitalの物がつかえそう
https://wiki.seeedstudio.com/Grove-2-Channel_SPDT_Relay/(例えば
スケッチ例のm5Stack unit pbhub のヘッダーファイルとライブラリをコピーして使う
多分ライブラリはNeopixelが接続して簡単に使えるように書いてある。未確認
ドキュメントの図面ではGROVE1個あたりにINとOUTが一個ずつだったが、デジタルは入出力2本ずつで利用可能、アナログ入力は1本だけ
5A,6Aはデジタル入力のみ、出力不可
5B,6Bはデジタル出力のみ、入力不可
Firmware(M5Burner)
注意:勘です。
なんかnode.jsで動いているみたい。(bin\Resources\app.asarを展開するとソースが見れる。)
Proxyでデータ(binファイルが持ってこれないとき)
一覧は環境変数のHTTP_PROXYとHTTPS_PROXYを設定し、M5Burnerを起動すれば持ってきます。
肝心のbinファイルは、下図の”A",”B",”C"がわかれば、http://firmware-cdn.m5stack.com/firmware/A-B(小文字で)-C.bin で取得できるみたい。この場合だとhttp://firmware-cdn.m5stack.com/firmware/UIFlow_StickC-stickc-v1.7.3.bin になります。
取得したファイルをA-C.binにリネーム(この場合はUIFlow_StickC-v1.7.3.bin)して\packeages\fw\Bのフォルダ(この場合は\packeages\fw\stickc)に入れる。
M5Burnerを立ち上げるとBurnできるようになっていると思う。
※Bは、たぶん正式には \packages\fw\local.json をみるとわかる。
ソフト(Arduino)
注意すること。
3秒以内に1回はdelay(1)をいれWDTをリセットすること。https://www.mgo-tec.com/blog-entry-arduino-esp32-multi-task-dual-core-01.html/3
比較
BASIC | Stick | Stick C Plus | 備考 |
---|---|---|---|
M5.Speaker.begin(); M5.Speaker.mute(); |
--- | M5.Beep.begin(); M5.Beep.mute(); |
スピーカから音がするときの対処 |
M5.Lcd.setBrightness(0-255); | M5.Axp.begin(); M5.Axp.ScreenBreath(7-15); |
M5.Axp.begin(); M5.Axp.ScreenBreath(7-15); |
液晶バックLEDの明るさ |
M5.Power.reset(); | esp_restart(); | esp_restart(); | リセット |
API
System:
M5.begin();
M5.update();
Power:
M5.Power.setPowerBoostKeepOn()
M5.Power.setCharge(uint8_t mode);
M5.Power.setPowerBoostKeepOn(bool en);
M5.Power.isChargeFull();
M5.Power.setWakeupButton(uint8_t button);
M5.Power.powerOFF();
bool setPowerBoostOnOff(bool en);
bool setPowerBoostSet(bool en);
bool setPowerVin(bool en);
bool setPowerWLEDSet(bool en);
LCD:
M5.lcd.setBrightness(uint8_t brightness);
M5.Lcd.drawPixel(int16_t x, int16_t y, uint16_t color);
M5.Lcd.drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
M5.Lcd.fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
M5.Lcd.fillScreen(uint16_t color);
M5.Lcd.drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
M5.Lcd.drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,uint16_t color);
M5.Lcd.fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
M5.Lcd.fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,int16_t delta, uint16_t color);
M5.Lcd.drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
M5.Lcd.fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
M5.Lcd.drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
M5.Lcd.fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
M5.Lcd.drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color);
M5.Lcd.drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h),
M5.Lcd.drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size);
M5.Lcd.setCursor(uint16_t x0, uint16_t y0);
M5.Lcd.setTextColor(uint16_t color);
M5.Lcd.setTextColor(uint16_t color, uint16_t backgroundcolor);
M5.Lcd.setTextSize(uint8_t size);
M5.Lcd.setTextWrap(boolean w);
M5.Lcd.printf();
M5.Lcd.print();
M5.Lcd.println();
M5.Lcd.drawCentreString(const char *string, int dX, int poY, int font);
M5.Lcd.drawRightString(const char *string, int dX, int poY, int font);
M5.Lcd.drawJpg(const uint8_t *jpg_data, size_t jpg_len, uint16_t x, uint16_t y);
M5.Lcd.drawJpgFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y);
M5.Lcd.drawBmpFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y);
Button:
M5.BtnA/B/C.read();
M5.BtnA/B/C.isPressed();
M5.BtnA/B/C.isReleased();
M5.BtnA/B/C.wasPressed();
M5.BtnA/B/C.wasReleased();
M5.BtnA/B/C.wasreleasedFor()
M5.BtnA/B/C.pressedFor(uint32_t ms);
M5.BtnA/B/C.releasedFor(uint32_t ms);
M5.BtnA/B/C.lastChange();
Speaker:
M5.Speaker.tone(uint32_t freq);
M5.Speaker.tone(freq, time);
M5.Speaker.beep();
M5.Speaker.setBeep(uint16_t frequency, uint16_t duration);
M5.Speaker.mute();
M5.Lcd.drawxbitmapやdrawString,drawFloatなども使えるが、ここでは書いてないなあ
M5.beginの定義、中身
void M5Stack::begin(bool LCDEnable, bool SDEnable, bool SerialEnable, bool I2CEnable) {
// Correct init once
if (isInited == true) {
return;
} else {
isInited = true;
}
// UART
if (SerialEnable == true) {
Serial.begin(115200);
Serial.flush();
delay(50);
Serial.print("M5Stack initializing...");
}
// LCD INIT
if (LCDEnable == true) {
Lcd.begin();
}
// TF Card
if (SDEnable == true) {
SD.begin(TFCARD_CS_PIN, SPI, 40000000);
}
// TONE
// Speaker.begin();
// Set wakeup button
Power.setWakeupButton(BUTTON_A_PIN);
// I2C init
if (I2CEnable == true) {
Wire.begin(21, 22);
}
if (SerialEnable == true) {
Serial.println("OK");
}
}
M5.updateの中身
void M5Stack::update() {
//Button update
BtnA.read();
BtnB.read();
BtnC.read();
//Speaker update
Speaker.update();
}
新しいボタンの定義(Dual ButtonをGroveのB端子につないだ時)
Button BtnRed = Button(G26, true, 10);
Button BtnBlue = Button(G36, true, 10);
pinMode(_pin, INPUT_PULLUP);になっているので、回路はGNDに接続するだけでOK。ただし入力専用のポートはPullUPできないのでPullUP抵抗が必要
https://github.com/m5stack/M5Stack/blob/master/src/utility/Button.cpp
ただし、この場合が、m5.updateで更新されないので、個別に.readする必要あり。
BtnRed.read();
BtnBlue.read();
FONTの定義(m5stack.h)
# define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
# define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
# define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
# define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
# define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
# define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
# define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
色の定義(In.eSPI.h)
// New color definitions use for all my libraries
# define TFT_BLACK 0x0000 /* 0, 0, 0 */
# define TFT_NAVY 0x000F /* 0, 0, 128 */
# define TFT_DARKGREEN 0x03E0 /* 0, 128, 0 */
# define TFT_DARKCYAN 0x03EF /* 0, 128, 128 */
# define TFT_MAROON 0x7800 /* 128, 0, 0 */
# define TFT_PURPLE 0x780F /* 128, 0, 128 */
# define TFT_OLIVE 0x7BE0 /* 128, 128, 0 */
# define TFT_LIGHTGREY 0xC618 /* 192, 192, 192 */
# define TFT_DARKGREY 0x7BEF /* 128, 128, 128 */
# define TFT_BLUE 0x001F /* 0, 0, 255 */
# define TFT_GREEN 0x07E0 /* 0, 255, 0 */
# define TFT_CYAN 0x07FF /* 0, 255, 255 */
# define TFT_RED 0xF800 /* 255, 0, 0 */
# define TFT_MAGENTA 0xF81F /* 255, 0, 255 */
# define TFT_YELLOW 0xFFE0 /* 255, 255, 0 */
# define TFT_WHITE 0xFFFF /* 255, 255, 255 */
# define TFT_ORANGE 0xFDA0 /* 255, 180, 0 */
# define TFT_GREENYELLOW 0xB7E0 /* 180, 255, 0 */
# define TFT_PINK 0xFC9F
画面設計
なるべく部品ごとに絵をかいてスプライトで表示した方が良さそう。
XBITMAP
XBITMAPを使うと便利。
fontにない日本語とかをイメージで表示
SDカードとか不要
黒が背景になる。
白は書くときに指定した色になる。(スプライト表示時に色が指定できる)
使い方
イラレ(RGB) -PNG-> 変換サイト -XBM->書き換え-->ヘッダーファイル
変換サイト https://www.online-utility.org/image/convert/to/XBM
書き換えは、ファイルをコピーして、ファイルの内容の先頭を以下のように変更し拡張子をXBMからhに変更。ファイルをスケッチと同じフォルダに置いてArduinoIDEでスケッチを読み込むと羅列される。定義名はファイル名と一緒が分かりやすい。
# define 1594346505063_width 50
# define 1594346505063_height 50
static char 1594346505063_bits[] = {
↓
# include <Arduino.h>
# define btn1_width 50
# define btn1_height 50
PROGMEM const unsigned char btn1_bits[] = {
あとは、スケッチでinclude#include"btn1.h"
で読み込み、描画関数M5.lcd.drawXBitmap(0, 0, btn1_bits, btn1_width, btn1_height, TFT_WHITE);
と書くだけです。
変化する文字・数値
7Seg風に書くdrawFloat(omosa, 2, 300, 20, 7);
スプライトを使った方が画面の変化がなめらか。
例
TFT_eSprite spr = TFT_eSprite(&M5.Lcd);
void setup() {
spr.setColorDepth(8);
spr.createSprite(320, 145);
}
void loop(){
spr.fillRect(0, 0, 320, 145, TFT_BLACK);
spr.setTextSize(2);
spr.setTextDatum(TR_DATUM);
spr.setTextColor(TFT_WHITE, TFT_BLACK);
spr.drawFloat(omosa, 2, 300, 20, 7);
spr.pushSprite(0, 20);
}
M5Stack Avator
Timer内の変数はうまく表示できない。下のchar s[10];
の位置に着目
ダメな例
# include <M5Stack.h>
# include <Avatar.h>
# include<Ticker.h>
using namespace m5avatar;
Avatar avatar;
Ticker Timer;
void TimeTick() {
static int i = 100;
char s[10];
sprintf(s, "%d ppm", i);
avatar.setSpeechText(s);
i++;
}
void setup() {
M5.begin();
Timer.attach_ms(2000, TimeTick);
avatar.init();
}
void loop() {
M5.update();
delay(1);
}
良い例
# include <M5Stack.h>
# include <Avatar.h>
# include<Ticker.h>
using namespace m5avatar;
Avatar avatar;
Ticker Timer;
char s[10];
void TimeTick() {
static int i = 100;
sprintf(s, "%d ppm", i);
avatar.setSpeechText(s);
i++;
}
void setup() {
M5.begin();
Timer.attach_ms(2000, TimeTick);
avatar.init();
}
void loop() {
M5.update();
delay(1);
}
Bluetooth Serialでの接続サンプル
ArduinoIDEのシリアルモニタでは見れない時がある。TeraTermなど他のターミナルソフトも試すべき
一旦離れた時の処理を書くこと。でないと再接続できない。リセットが必要
# include "BluetoothSerial.h"
BluetoothSerial SerialBT;
void setup() {
Serial.begin(9600);
// delay(100); //おまじない。あった方が御利益ありそう。
Serial.println("**Start*");
SerialBT.begin("ESP32test");
Serial.println("BTReady");
}
void loop() {
static int i = 1;
static bool isConnected = false;
if (!SerialBT.connected(100)) {
Serial.println("BT disconnect");
if (isConnected) {
SerialBT.disconnect();
isConnected = false;
}
} else {
Serial.println("BT Connected");
isConnected = true;
}
SerialBT.print(i);
SerialBT.println(":hello World!");
i++;
delay(1000);
}