Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    Nicla Sense ME I2C Disconnecting Bug

    Nicla Sense ME I2C Disconnecting Bug

    lsi8
    Member

    I am trying to get this basic tutorial working for the Nicla and Portenta H7 connected over ESLOV (I2C connection). The bug in the example code is that it only works for a little over half an hour before crashing.

    I modified his code for debugging purposes:


    arduino-libraries/Arduino_BHY2Host/examples/Accelerometer/Accelerometer_copy.ino:

     

    #include "Arduino.h"
    #include "Arduino_BHY2Host.h"
    #include <LandoRGBLedPortenta.h>
    
    SensorXYZ accel(SENSOR_ID_ACC);
    LandoRGBLedPortenta portentaLeds;
    
    const int MAX_DUPLICATE_READINGS = 10;
    String colorToToggle = "white";
    int duplicateReadings = 0;
    
    static unsigned long printTime = 0;
    static unsigned long startTime = 0;
    static String timeToCrash = "";
    static String lastAccelReading = "";
    
    void setup()
    {
      Serial.begin(115200);
      while(!Serial);
      Serial.println("Serial started!");
      portentaLeds.setColor("red");
      BHY2Host.begin(false, NICLA_VIA_ESLOV);
      Serial.println("BHY2HostSuccess!");
      portentaLeds.setColor("green");
      accel.begin();
      Serial.println("Leaving setup!");
      portentaLeds.setColor("blue");
      
      printTime = millis();
      startTime = printTime;
    }
    
    void loop()
    {
      BHY2Host.update();
    
      if (millis() - printTime >= 1000) {
        printTime = millis();
        String accelReading = accel.toString();
        if(accelReading == lastAccelReading) {
          duplicateReadings++;
          if(duplicateReadings == MAX_DUPLICATE_READINGS) {
            timeToCrash = " " + String(printTime - startTime) + " ms";
            colorToToggle = "red";
          }
        }
        else {
          duplicateReadings = 0;
        }
        Serial.println(String("Acceleration values: ") + String(accelReading) + String(timeToCrash));
        portentaLeds.toggleColor(colorToToggle);
        lastAccelReading = accelReading;
      }
    }

     

    arduino-libraries/Arduino_BHY2/examples/App/App_copy.ino:

     

    #include "Nicla_System.h"
    #include "Arduino.h"
    #include "Arduino_BHY2.h"
    
    void colorCycle(int loops) {
      for(int i = 0; i < loops; i++) {
        nicla::leds.setColor(red);
        delay(1000);
        nicla::leds.setColor(green);
        delay(1000);
        nicla::leds.setColor(blue);
        delay(1000);
      }
      nicla::leds.setColor(off);
    }
    
    void setup(){
      BHY2.begin(NICLA_I2C, NICLA_VIA_ESLOV);
      nicla::leds.begin();
      colorCycle(5);
    }
    
    void loop(){
      // Update and then sleep
      nicla::leds.setColor(blue);
      BHY2.update(500);
      nicla::leds.setColor(off);
    }

     

    After 1,881,243–2,398,485 ms, the Nicla stops updating…

    • The blue led on Nicla stops flashing, indicating that the BHY2.update(500); line in the loop probably caused an exception.

    144988031-ba9a2f3f-48d6-44dd-ad13-ccb4fe1a9513

    If I reset just the Portenta and relaunch the serial printer, the Portenta halts at the accel.begin(); line in the setup...

    144988310-20de4f21-7a90-4233-be45-72e22cd89e69

    5 REPLIES 5

    zgg
    Long-established Member

    Hi

    Thanks for sharing your detailed info.

    I don't have a portenta device yet, but here are some info (based on experience) that hopefully could give you some hints to pin-point where the problem is.

    1. not sure how long the ESLOV (black cable) is, if it's too long (some of the eariler shipped Nicla boards), then it's more prone to I2C errors, then the ESLOV routible might be stuck somewhere (and hence the BHY2.update() will also be stuck), to confirm it's because of the I2C errors, you could monitor the SDA & SCL lines (also exposed through the headers on Nicla) to see if the lines are pulled to low and do not recover

    2. if it's confirmed that the stuck is with the I2C bus (ESLOV), and if the cable is really long, you could try to shorten the cable length (e.g.: to within 4 inches, 4 here is just an emprical number) to see the issue persists

    3. if you don't want to fiddle with the rework of the long ESLOV cable or if the cable is not crazily long (e.g.: less than 4 inches), you could add more debugging probes (like LED or printf) in to the Arduino_BHY2 library code to locate the stucking point

    4. an easier way (rather than using LED  or printf) to pinpoint the stuck code is to use a debugger, the Nicla board has on-board CMSIS-DAP debugger adapter, and all you need  is a set of compatible software tools such as (pyocd + arm-none-eabi-gdb), if you are not comfortable using the Command Line interfaces from (pyocd + gdb), you could try the Arduino Pro IDE or platform.io IDE which offers GUI debugging.

    5. if 1-3 does not work for you, another backup option is to use Nicla as a shield.

    I could find some time testing using your code to see if I can reproduce the same issue using Nicla Sense and another board (such as MKR), before I have some results, you could check the above info is useful at all. Curious to learn your update.

     

    1. 20" long. I did the same test with the SDA & SCL lines being measured on scope. When it timed out the two channels went low and stay that way forever.

    2. Only have one cable so I won't be trying that.

    3. Will consider doing this.

    4. This will probably be my next step.

    5. I begrudgingly did this (didn't want to have to solder pinheaders on the Nicla or Portenta) today and the same thing happens as reported in step 1 above.

     

    That would be helpful.

    zgg
    Long-established Member

    Hello @lsi8

    I have some updates for you (probably good news).

    I tried your code on my Nicla Sense device + MKR 1010 Wifi board and the problem could be easily reproduced on this particular set up.

    and I think the root cause is found.

    If you change the code (for Nicla) to the following, it should solve the issue.

    #include "Nicla_System.h"
    #include "Arduino.h"
    #include "Arduino_BHY2.h"

    void colorCycle(int loops) {
    for(int i = 0; i < loops; i++) {
    nicla::leds.setColor(red);
    delay(1000);
    nicla::leds.setColor(green);
    delay(1000);
    nicla::leds.setColor(blue);
    delay(1000);
    }
    nicla::leds.setColor(off);
    }

    void setup(){
    BHY2.begin(NICLA_I2C, NICLA_VIA_ESLOV);
    nicla::leds.begin();
    colorCycle(1);
    }

    void mydelay(uint32_t ms)
    {
    delay(ms);
    }

    void loop(){
    // Update and then sleep
    mydelay(50);
    nicla::leds.setColor(blue);
    mydelay(200);


    BHY2.update(500); //because BLE is not used, there is no internal delay inside update(), thus we add delay in between led operations

    mydelay(50);
    nicla::leds.setColor(off);
    mydelay(200); //manual delay, otherwise the LED is abused
    }

     

    Here is my reasoning about the issue:

    there is almost 0 delay between the LED operations and the led.setColor is actually using I2C to set the LED color and because there is 0 delay, it is causing a I2C traffic storm and this overtime might stress the device to a point where it locks up the I2C bus and this will cause a system hang.

    Let me know if this solves the problem for you, at least it does for me (streaming well over muitiple hours no problem).

     

    @zgg

    Thank you so much for trying to help me through this problem; I will definitely check if your code fixes my issue, in case it helps future readers.

    I tried for a couple more days to fix this (as well as another issue which was really slowing down development), and searched for help elsewhere, before deciding to develop my plan-B which was to replace the Nicla with dedicated I2C IMU & PHT sensors. The respective sensors I used (& their output data rates) are...

    My only project goal (& what I was trying to use the Nicla for) was to sample and transmit over I2C—as fast as the sensors' hardware allows—the temperature, humidity, acceleration in xyz, & gyroscope in xyz to the Portenta H7.

    My minimum acceptable transmission rates were...

    • 100 Hz for the accelerometer & gyro (already acheived with the MPU9250).
    • 30 Hz for the temperature & humidity (should be able to get there with the Si7006).

    So my main concern is—and perhaps you could test (or have already tested) this on your working setup—can the Nicla ahieve (or exceed) these speeds?

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist