🤖Have you ever tried Chat.M5Stack.com before asking??😎
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    [SOLVED] GNSS on Core2: BMM150 issue when using M5 events

    Modules
    2
    3
    860
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • U
      UnumDesignum
      last edited by UnumDesignum

      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:263

      After 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:263

      Source 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 0

      xTaskCreatePinnedToCore(magneto_task,
      "magneto_task",
      10000,
      NULL,
      25,
      NULL,
      1); // running on core 0

      return;
      }

      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;
      }

      1 Reply Last reply Reply Quote 0
      • felmueF
        felmue
        last edited by

        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

        GPIO translation table M5Stack / M5Core2
        Information about various M5Stack products.
        Code examples

        U 1 Reply Last reply Reply Quote 0
        • U
          UnumDesignum @felmue
          last edited by

          @felmue A million thanks!

          This was my issue. Your solution works like a charm.

          Thank you!

          1 Reply Last reply Reply Quote 0
          • First post
            Last post