M5Stick with both Hat and Grove



  • Hello,

    I am trying to use an M5StickC plus with a hat sensor (TOF), a grove sensor (TOF), and the internal IMU. Using the code below I’m able to get data from both the Hat and Grove sensors running using Wire1. However, the IMU no longer functions with the Wire1.begin call as written.

    I’m new to Arduino. Is there a better way to get both Hat and Grove working simultaneously that avoids the need for Wire1? Any ideas on how to get this trio of sensors up and running?

    FWIW I had originally prototyped this in micropython and had all three sensors working; latency was killer however and arduino is much much faster (like > 10x).

    Thx, PD

    #include <VL53L0X.h>
    #include <Wire.h>
    #include <M5StickCPlus.h>

    VL53L0X sensor;
    VL53L0X sensor2;

    void setup() {
    Wire.begin(0, 26, 100000UL); // for I2C of HAT connection
    Wire1.begin(32, 33, 100000UL); // for I2C of grove connection

    M5.begin(); // starts serial 115200

    sensor.setTimeout(500);
    while (!sensor.init()) {
    Serial.println("Failed to detect and initialize sensor!");
    delay(250);
    }
    sensor.startContinuous();

    sensor2.setBus(&Wire1);
    sensor2.setTimeout(500);
    while (!sensor2.init()) {
    Serial.println("Failed to detect and initialize sensor2!");
    delay(250);
    }
    sensor2.startContinuous();

    delay(100);
    int IMUinit = M5.IMU.Init();
    Serial.print("IMU init return val: ");
    Serial.print(IMUinit); // <- -1 means it's not working..
    Serial.println();
    }

    void loop() {
    uint16_t distance1 = sensor.readRangeContinuousMillimeters();
    uint16_t distance2 = sensor2.readRangeContinuousMillimeters();
    Serial.print(distance1);
    Serial.print(" ");
    Serial.print(distance2);

    if (sensor2.timeoutOccurred()) {
    Serial.print(" TIMEOUT");
    }
    Serial.println();
    }



  • The ESP32 has only two I2C channels. Assigning Wire1to pins 0 and 26 you take away the standard I2C channel used for the gyro (pins 22 and 23). The easiest way would be: instead of using the HAT hook up both VL30X TOF Sensors to the grove connector. But you must change one of the sensors I2C address beforehand. Here is the the link to the arduino code assigning a new i2c address (standard 0x29) :
    https://robojax.com/learn/arduino/?vid=robojax_VL53L0X_I2C_address.
    Another possibilty would be using the M5Stack PaHub Unit as an I2C expander.



  • Thanks for the reply @crami25

    Unfortunately I have already purchased the Hats and Grove sensors and have a physical hardware setup that utilizes the Hat positioning relative to how I am mounting the M5Stick.

    The easiest way would be:

    Might there be a harder way that allows me to use the M5stack hardware I have on hand? ;)

    What is strange about all of this to me is that using UIFlow and this exact hardware it works with:
    ToF1 = hat.get(hat.TOF)
    ToF2 = unit.get(unit.TOF, unit.PORTA)
    IMU = IMU()



  • Try putting the Wire1.begin(...) in your program loop instead of the setup {}. assigning other pins to the I2C channel;
    Wire1.begin(32, 33, 100000UL); // for I2C TOF connection ..
    before reading the TOF,
    Wire1.begin(21, 22, 100000UL); // for I2C gyro connection ..
    before reading the gyro.