[SOLVED] GNSS on Core2: BMM150 issue when using M5 events
-
Hello,
I'm developing a program that uses the GPS and the Magnetometer (BMM150) of the GNSS Module.
It works fine, but as soon as functions such as M5.BtnA.wasPressed(), screen touch or M5.Axp.GetBatVoltage(), the BMM150 communication seems broken.I tried with address 0x68 and 0x69 -> same problem.
I tried running the task on core 1 or core 0 -> same problem.DO YOU HAVE AN IDEA OF WHAT I'M DOING WRONG HERE?
Examples of error displayed on the monitor.
After M5.Axp.GetBatVoltage() called:
11:59:50.763 -> E (22261) IMU: P:0 R 68 7C E:263After M5.BtnA.wasPressed() called:
12:00:33.754 -> E (16003) IMU: P:0 R 68 7C E:-1
12:00:34.119 -> E (16025) IMU: P:0 R 68 03 E:263
12:00:34.149 -> E (16038) IMU: P:0 R 68 03 E:263Source code to reproduce the issue.
M5Module_GNSS.h is available here: https://github.com/m5stack/M5Module-GNSS/tree/main/src
#include <M5Core2.h>
#include <Arduino.h>
#include <TinyGPS++.h>
#include <Wire.h>
#include "M5Module_GNSS.h"#define BIM270_SENSOR_ADDR 0x68
BMI270::BMI270 bmi270;#define WATCHDOG_TIMER 2000UL // ms
#define BATT_CHECK 20000UL // ms - interval to check battery status// variables
uint32_t last_battery_check = 0;
uint32_t last_json = 0;bool isGPS = false;
// GPS & Magnetometer
float biasX, biasY, rangeX, rangeY;
int16_t magX, magY, magZ;
int16_t minMagX, minMagY, maxMagX, maxMagY;
// The TinyGPS++ object
TinyGPSPlus gps;// functions
void gps_task(void *pvParameters);
void magneto_task(void *pvParameters);void updateBatteryLevel (void) {
float batVoltage = M5.Axp.GetBatVoltage();
float batPercentage = ( batVoltage < 3.2 ) ? 0 : ( batVoltage - 3.2 ) * 100;
Serial.printf("Battery %d\n", batPercentage);
}// ------------------------------------------------ SETUP -----------------------------------------------
void setup() {
magX = 0;
magY = 0;M5.begin(true, true, true, false, kMBusModeOutput);
M5.Axp.SetLed(0);
M5.Lcd.begin();xTaskCreatePinnedToCore(gps_task,
"gps_task",
10000,
NULL,
25,
NULL,
0); // running on core 0xTaskCreatePinnedToCore(magneto_task,
"magneto_task",
10000,
NULL,
25,
NULL,
1); // running on core 0return;
}void magneto_task(void *pvParameters) {
static int data, cpmt = 100;
Serial.print("MAGNETO TASK STARTS\n");
Wire.begin(21, 22, 100000);
bmi270.init(I2C_NUM_0, BIM270_SENSOR_ADDR);while (1) {
// DEBUG
cpmt++;
if ( cpmt > 100 ) {
Serial.print("•");
cpmt = 0;
};
// Get Magnetometer data
if (bmi270.magneticFieldAvailable()) {
bmi270.readMagneticField(magX, magY, magZ);
}
if (cpmt ==0) Serial.printf("x %d y %d\n", magX, magY);
delay(10);
}
}void gps_task(void *pvParameters) {
static int data, cpmt = 100;
Serial.print("GPS TASK STARTS\n");
Serial2.begin(38400, SERIAL_8N1, 13, 14);while (1) {
// DEBUG
cpmt++;
if ( cpmt > 100 ) {
Serial.print("+");
cpmt = 0;
};
// Get GPS data
while (Serial2.available() > 0) {
data = Serial2.read();
//Serial.printf("%c", data);
gps.encode(data);
}
isGPS = gps.location.isValid();
delay(10);
}
}// ------------------------------------------------ LOOP -----------------------------------------------
void loop() {
static char text[256];
static uint32_t msecs;M5.update();
msecs = millis();// WATCHDOG
if ((msecs - last_json) > WATCHDOG_TIMER) {
if (isGPS) sprintf(text, "GPS %d - ", gps.satellites.value());
else sprintf(text, "Sat %d - ", gps.satellites.value());
Serial.println(text);
last_json = msecs;
}// battery timer
if ((msecs - last_battery_check) > BATT_CHECK) {
updateBatteryLevel();
last_battery_check = msecs;
}if (M5.BtnA.wasPressed()) {
Serial.println("BtnA pressed");
}if (M5.BtnB.wasPressed()) {
Serial.println("BtnB pressed");
}if (M5.BtnC.wasPressed()) {
Serial.println("BtnB pressed");
}return;
} -
Hello @UnumDesignum
the issue is probably that the internal I2C of M5Core2 library uses Wire1 (and not Wire). See here.
In your
magneto_task
you initialize Wire with the same GPIOs (21, 22) so you end up with two I2C instances (Wire and Wire1) fighting for the same GPIOs.Try the following and see if that helps:
//Wire.begin(21, 22, 100000); //bmi270.init(I2C_NUM_0, BIM270_SENSOR_ADDR); bmi270.init(I2C_NUM_1, BIM270_SENSOR_ADDR);
Thanks
Felix -