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

    [SOLVED] M5StickCPlus and BMM150 (ENV II Hat) do not work

    Arduino
    3
    6
    3.3k
    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.
    • E
      eulic_
      last edited by eulic_

      Hi all,

      I'm working on getting magnetometer data with a M5StickC Plus and ENV II Hat.
      I found that I2C communication between M5StickC Plus and BMM150 is not working as expected, and am wondering if you can provide some guidance to make it work.

      I'm using a sample code at
      https://github.com/m5stack/M5StickC-Plus/tree/master/examples/Hat/ENVII_SHT30_BMP280

      I tried it as is. It did not work (the code stopped running somewhere)
      I added Wire.begin(0, 26) in the setup function since the hat is connected to G0 and G26. This got the same result.

      Then, I dug into where the code stopped.
      It stopped at BMM150::initialize > set_op_mode > suspend_to_sleep_mode > set_power_control_bit > i2c_read
      In i2c_read, when the code called Wire.requestFrom(BMM150_I2C_Address, 1), it did not return.
      How can I fix the issue?

      Here is a minimal code to reproduce the issue.

      #include <M5StickCPlus.h>
      #define BMM150_I2C_Address  0x10  // These are copied from bmm150_defs.h
      #define BMM150_POWER_CONTROL_ADDR 0x4B
      
      void setup() {
        M5.begin();
        Wire.begin(0, 26);
        delay(3000);  // Make sure to avoid any race conditions
        Serial.println("Start setup");
        uint8_t reg_data = i2c_read(BMM150_POWER_CONTROL_ADDR);
      }
      
      void loop() {
        delay(1000);
        Serial.println("loop");
      }
      
      uint8_t i2c_read(short address)
      {
          uint8_t byte;
          int result;
          Wire.beginTransmission(BMM150_I2C_Address);
          result = Wire.endTransmission();
          Serial.printf("%d\n", result); // This sometimes gets 2: NACK, which is a bit strange
      
          Wire.beginTransmission(BMM150_I2C_Address);
          result = Wire.endTransmission();
          Serial.printf("%d\n", result);  // This gets 0: Success
      
          Wire.beginTransmission(BMM150_I2C_Address);
          Wire.write(address);
          result = Wire.endTransmission();
          Serial.printf("%d\n", result); // This gets 0: Success
      
          Wire.beginTransmission(BMM150_I2C_Address);
          Serial.println("call Wire.requestFrom");
          Wire.requestFrom(BMM150_I2C_Address, 1, 0);
          Serial.println("call returned"); // This is never called
          byte = Wire.read();
         
          Wire.endTransmission();
          return byte;
      }
      
      teastainT 1 Reply Last reply Reply Quote 0
      • teastainT
        teastain @eulic_
        last edited by

        @eulic_ Could be related to these includes and begins:

        #include "bmm150.h"
        #include "bmm150_defs.h"
        SHT3X sht3x;
        BMM150 bmm = BMM150();
        bmm150_mag_data value_offset;
        Adafruit_BMP280 bme;
        

        With the StickCPlus include you should not need to add Wire.begin(0, 26);

        Also I don't understand the three

        Wire.beginTransmission(BMM150_I2C_Address);
        

        -Terry

        Cheers, Terry!

        100% M5Stack addict with several drawers full of product!

        E 1 Reply Last reply Reply Quote 0
        • E
          eulic_ @teastain
          last edited by

          @teastain Thank you for your comment Terry!
          I initially had all variables and, unfortunately, it did not work either.
          Wire.begin(0, 26) is necessary because I'm using Hat that connects to GPIO pins not Grove port. Wire.begin start I2C communications using the Grove port by default not G0 and 26 on the Hat connecter side.

          When I checked I2C addresses with I2C_Tester example, With Wire.begin(), it listed only three internal devices. With Wire.begin(0, 26), it listed three additional devices in ENV III Hat including BMM150 at 0x10.

          Btw, sht3x has Wire.begin() in its constructer. So, it's better not to have the sht3x instance if not necessary. It could lead to confusing results.

          G 1 Reply Last reply Reply Quote 1
          • G
            gavin67890 @eulic_
            last edited by

            @eulic_,

            I adapted what is below from the M5Stack examples for StickC (non-Plus) and ENVII hat to work on an Atom. The only real changes I made were to write out to serial instead of LCD and use the LEDs of the Atom, so it might help you fault find. NB Library and pins need changed to suit your StickC Plus. It's a bit rough and ready, but it certainly worked on ENVII with Atom and StickC.

            #include <M5Atom.h> // Swap out for StickC library
            #include "M5_ENV.h"
            #include <Adafruit_BMP280.h>
            #include "Adafruit_Sensor.h"
            
            SHT3X sht30; // SHT3X sht30;
            Adafruit_BMP280 bme; // Adafruit_BMP280 bme;
            
            float tmp      = 0.0;
            float hum      = 0.0;
            float pressure = 0.0;
            
            void setup() {
                M5.begin(true, false, true);             // Init M5Atom
                delay(1500);
                // M5.Lcd.setRotation(3);  // Rotate the screen.
                // M5.dis.fillpix(0xFF0000); //LEDs of atom to black
                Wire.end();
                Wire.begin(19, 22); // Swap out for StickC 0, 26
                sht30.init();
                Serial.println(F("ENVII Unit(SHT30 and BMP280) test...\n"));
            }
            
            void loop() {
            
                while (!bme.begin(0x76)) {  // Init the sensor of bme
                    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
                }
                // M5.dis.fillpix(0x00FF00); // Turns atom leds green
                pressure = bme.readPressure();  // Stores the pressure gained by BMP.
            
                sht30.get();           // Obtain the data of shT30.
                tmp = sht30.cTemp;     // Store the temperature obtained from shT30
                hum = sht30.humidity;  // Store the humidity obtained from the SHT30
                // M5.Lcd.setCursor(0, 20);
                // M5.Lcd.fillRect(0, 20, 100, 60,
                              //  BLACK);  // Fill the screen with black (to clear the screen).
                Serial.printf("Temp: %2.1f  \r\nHumi: %2.0f%%  \r\nPressure:%2.0fPa\r\n",
                              tmp, hum, pressure);
                delay(2000);
            }

            Atom LITE | Atom Matrix | StickC | CORE2 | Paper | ...

            1 Reply Last reply Reply Quote 1
            • E
              eulic_
              last edited by

              Thanks @gavin67890 !
              Yes. We can make the SHT30 and BMP280 in that way, but not BMM150 unfortunately.
              I think the example code for BMM150 is fundamentally broken and M5Stack does not plan to fix it since ENV II Hat is EOL. I will look into an example code from Bosch, which is the manufacture of the BMM150 chip.

              1 Reply Last reply Reply Quote 0
              • E
                eulic_
                last edited by

                I found a solution.
                An example you can find at https://www.waveshare.com/wiki/BMM150_3-Axis_Magnetometer_Sensor (the one linked from Example Demo) with a proper modification worked with BMM150 in Env II Hat. Here is the procedure.

                • Download the zip file from the Example Demo link.
                • Open bmm150_Arduino.ino under Arduino > bmm150_Arduino
                • Search Wire.begin() in the code (you can find one in the line 149)
                • Change it to Wire.begin(0, 26)
                  This is necessary if you are using a Hat version of ENV II HAT, which is connected to the GPIO pin side of the M5Stick variants. If you are using ENV II Hat connected the Grove port, you don't need to change it.

                After this modification, the code should work.

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