M5.begin()
had different parameters and counts for different device libraries. To unify them, M5Unified uses a structure as a parameter to pass various configuration information.SD.h
is not used by default, and SD.begin()
is not executed internally.BtnA
instead of Btn
.M5
), leading to the following compilation error:error: reference to 'jpeg_div_t' is ambiguous jpeg_div_t scale = JPEG_DIV_NONE);
error: conflicting declaration 'M5Stack M5' extern M5Stack M5;
M5.begin
In earlier driver libraries, M5.begin()
had different parameters for each device, as shown below:
// M5Stack
M5.begin(bool LCDEnable = true, bool SDEnable = true, bool SerialEnable = true, bool I2CEnable = false);
// M5Core2
M5.begin(bool LCDEnable = true, bool SDEnable = true, bool SerialEnable = true, bool I2CEnable = false, mbus_mode_t mode = KMBusModeOutput);
// M5StickC
M5.begin(bool LCDEnable = true, bool PowerEnable = true, bool SerialEnable = true);
// M5StickCPlus
M5.begin(bool LCDEnable = true, bool PowerEnable = true, bool SerialEnable = true);
// M5Atom
M5.begin(bool SerialEnable = true, bool I2CEnable = true, bool DisplayEnable = false);
After switching to M5Unified, some initialization configuration information is implemented in a cfg
structure:
auto cfg = M5.config();
// Set the items you want to configure. Omit the following two lines if you use the default settings.
cfg.serial_baudrate = 115200;
cfg.output_power = true;
M5.begin(cfg);
- M5.begin(true, true, true, true);
+ auto cfg = M5.config();
+ cfg.internal_imu = true;
+
+ M5.begin(cfg);
M5.Btn
The number of available buttons varies by M5Stack product, primarily using the following naming conventions:
BtnA
, BtnB
, BtnC
BtnPWR
BtnEXT
Change example: Display the message "BtnA isPressed" when Button A is pressed, and "BtnA isReleased" when released.
#include <M5Unified.h>
void setup() {
auto cfg = M5.config();
cfg.clear_display = true;
M5.begin(cfg);
M5.Lcd.setTextSize(2);
M5.Lcd.println("Press BtnA");
}
void loop() {
// update the button state.
M5.update();
if (M5.BtnA.isPressed()) {
M5.Display.setCursor(0, 16);
M5.Display.println("BtnA isPressed ");
} else {
M5.Display.setCursor(0, 16);
M5.Display.println("BtnA isReleased");
}
}
To update the button state, execute M5.update()
:
#include <M5Unified.h>
uint32_t loop_count = 0;
void setup() {
auto cfg = M5.config();
cfg.clear_display = true;
M5.begin(cfg);
M5.Lcd.setTextSize(2);
M5.Lcd.println("Press BtnA");
}
void loop() {
M5.update(); // update the button state.
if (M5.BtnA.wasPressed()) {
M5.Display.fillScreen(TFT_BLACK);
M5.Display.setCursor(0, 0);
M5.Display.println("BtnA wasPressed");
M5.Display.println("Press BtnA Stop Count");
while (true) {
M5.update(); // update the button state within the subloop.
M5.Display.setCursor(0, 32);
M5.Display.printf("count: %10d\n", loop_count);
if (M5.BtnA.wasPressed()) {
M5.Display.println("Count Stop");
loop_count = 0;
break;
}
loop_count++;
}
}
}
For more information, refer to the M5Unified Button Class .
M5.Lcd
M5Unified relies on the M5GFX library . When installing M5Unified in the Arduino IDE, a popup will prompt you to install this dependency; please install all of them.
Change example: This example program supports M5Stack controllers with LCD or e-Ink displays, using the same set of drawing APIs regardless of screen type.
#include <M5Unified.h>
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.setTextSize(3);
M5.Display.println("HelloWorld!");
}
void loop() {
}
After switching to M5Unified.h
, SD.h
is no longer included by default. You must manually add #include <SD.h>
:
- #include <M5Stack.h>
+ #include <SD.h>
+ #include <M5Unified.h>
Add SD.begin()
:
+ while (false == SD.begin(GPIO_NUM_4, SPI, 25000000))
+ {
+ delay(500);
+ }
M5Unified initializes the internal I2C by default. For devices like Basic/Gray/Fire, where PORT.A is reused for internal I2C, call M5.In_I2C.release()
if PORT.A is mapped to other functions.
auto cfg = M5.config();
.
.
.
M5.begin(cfg);
M5.In_I2C.release();
If you convert the FactoryTest.ino
example from the M5Stack library to M5Unified, it will look like this:
SD.begin
SPEAKER_PIN
M5.Btn.pressedFor
diff --git a/src/main.cpp b/src/main.cpp
index b735e30..dae9b99 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,10 +1,10 @@
#include <Arduino.h>
-#include <M5Stack.h>
+#include <SD.h>
+#include <M5Unified.h>
#include <stdlib.h>
//#include "FastLED.h"
#include "WiFi.h"
-#include "utility/MPU9250.h"
extern const unsigned char gImage_logoM5[];
extern const unsigned char m5stack_startup_music[];
@@ -13,7 +13,8 @@ extern const unsigned char m5stack_startup_music[];
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
-MPU9250 IMU;
+
+#define SPEAKER_PIN 25
// #define LEDS_PIN 15
// #define LEDS_NUM 10
@@ -127,15 +128,15 @@ void writeFile(fs::FS &fs, const char *path, const char *message) {
}
void buttons_test() {
- if (M5.BtnA.wasReleased() || M5.BtnA.pressedFor(1000, 200)) {
+ if (M5.BtnA.wasReleased() || M5.BtnA.pressedFor(1000)) {
M5.Lcd.printf("A");
Serial.printf("A");
}
- if (M5.BtnB.wasReleased() || M5.BtnB.pressedFor(1000, 200)) {
+ if (M5.BtnB.wasReleased() || M5.BtnB.pressedFor(1000)) {
M5.Lcd.printf("B");
Serial.printf("B");
}
- if (M5.BtnC.wasReleased() || M5.BtnC.pressedFor(1000, 200)) {
+ if (M5.BtnC.wasReleased() || M5.BtnC.pressedFor(1000)) {
M5.Lcd.printf("C");
Serial.printf("C");
}
@@ -475,8 +476,11 @@ void setup() {
// GPIO_test();
// }
+ auto cfg = M5.config();
+ cfg.internal_imu = true;
+
// initialize the M5Stack object
- M5.begin();
+ M5.begin(cfg);
/*
Power chip connected to gpio21, gpio22, I2C device
@@ -484,6 +488,10 @@ void setup() {
If used battery, please call this function in your project
*/
M5.Power.begin();
+ while (false == SD.begin(GPIO_NUM_4, SPI, 25000000))
+ {
+ delay(500);
+ }
// dac test
// if (gpio_test_flg)
@@ -492,7 +500,6 @@ void setup() {
// }
startupLogo();
// ledBar();
- Wire.begin();
// Lcd display
M5.Lcd.setBrightness(100);
@@ -609,54 +616,33 @@ void setup() {
M5.Lcd.setBrightness(i);
delay(2);
}
-
- byte c = IMU.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
- Serial.print("MPU9250 ");
- Serial.print("I AM ");
- Serial.print(c, HEX);
- Serial.print(" I should be ");
- Serial.println(0x71, HEX);
- Serial.println("");
- M5.Lcd.setCursor(20, 0);
- M5.Lcd.print("MPU9250");
- M5.Lcd.setCursor(0, 10);
- M5.Lcd.print("I AM");
- M5.Lcd.setCursor(0, 20);
- M5.Lcd.print(c, HEX);
- M5.Lcd.setCursor(0, 30);
- M5.Lcd.print("I Should Be");
- M5.Lcd.setCursor(0, 40);
- M5.Lcd.println(0x71, HEX);
- M5.Lcd.println();
- delay(100);
-
- IMU.initMPU9250();
- // Initialize device for active mode read of acclerometer, gyroscope, and
- // temperature
- Serial.println("MPU9250 initialized for active data mode....");
-
- // Read the WHO_AM_I register of the magnetometer, this is a good test of
- // communication
- byte d = IMU.readByte(AK8963_ADDRESS, WHO_AM_I_AK8963);
- Serial.print("AK8963 ");
- Serial.print("I AM ");
- Serial.print(d, HEX);
- Serial.print(" I should be ");
- Serial.println(0x48, HEX);
-
- // M5.Lcd.fillScreen(BLACK);
- M5.Lcd.setCursor(20, 100);
- M5.Lcd.print("AK8963");
- M5.Lcd.setCursor(0, 110);
- M5.Lcd.print("I AM");
- M5.Lcd.setCursor(0, 120);
- M5.Lcd.print(d, HEX);
- M5.Lcd.setCursor(0, 130);
- M5.Lcd.print("I Should Be");
- M5.Lcd.setCursor(0, 140);
- M5.Lcd.print(0x48, HEX);
+ const char* name;
+ // run-time branch : imu model check
+ switch (M5.Imu.getType())
+ {
+ case m5::imu_t::imu_mpu6050:
+ name = "MPU6050";
+ break;
+ case m5::imu_t::imu_mpu6886:
+ name = "MPU6886";
+ break;
+ case m5::imu_t::imu_mpu9250:
+ name = "MPU9250";
+ break;
+ case m5::imu_t::imu_sh200q:
+ name = "SH200Q";
+ break;
+ default:
+ name = "none";
+ break;
+ }
+ M5.Display.print("IMU:");
+ M5.Display.println(name);
+ M5.Display.endWrite();
+ ESP_LOGI("setup", "imu:%s", name);
delay(1000);
+
M5.Lcd.setCursor(0, 0);
M5.Lcd.println("wifi test:");
M5.Lcd.fillScreen(BLACK);