Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BME680 bsec library with Arduino IDE uses delay()?!?!? Not solved.

    BME680 bsec library with Arduino IDE uses delay()?!?!? Not solved.

    mgchristensen
    New Poster

    I clicked the wrong button, so I am making a new post. I also think I should have better described the problem.  My original post:

    Use of delay() in Arduino code is universally considered bad practice. The better approach is to test a duration in millis.

    Looking at the code in the provided libraries in BSEC_Arduino_Library, I note, in bsec.cpp, the function void Bsec::delay_us(uint32_t period, void *intfPtr). This function uses delay(). The use of delay() in bsec.cpp interferes with the timing of code in loop() if a call is made to the run() method.

    Has anyone reimplemented bsec.cpp to avoid use of delay()? I plan on doing so, but do not want to "reinvent the wheel" if I can avoid that.

    @BSTRobinreplied

    In bsec.cpp, the delay_us() function has been adapted to the millisecond delay to microsecond delay of the delay() function.

    /**
    @brief Task that delays for a us period of time
    */
    void Bsec::delay_us(uint32_t period, void *intfPtr)
    {
    (void) intfPtr;
    // Wait for a period amount of ms
    // The system may simply idle, sleep or even perform background tasks
    delay(period/1000);
    }

    Thus, hopefully my second attempt will be clearer.

    @BSTRobinThank you for your reply!

    The code line delay(period/1000); is precisely what is, I beleive, causing the issue.  Per the Arduino documentation at https://www.arduino.cc/reference/en/language/functions/time/delay/

    "...the use of delay() in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt. "

    It appears that any use of delay(), once execution passes to loop, especially outside of loop() will pause excution of loop().  If loop() contains deadlines, those deadlines may expire without the execution of that code segment at the time needed.  In my case specifically, adapting the BSEC example basic.ino code to my sketch completely disrupts the timing of loop().

    Use of a timer interrupt with a 1mS resolution is a possible solution for my loop code, but delay() itself is paused while an interrupt service routine is executing.

    SO! I'm thinking...

    Thanks to all in advance!

    3 REPLIES 3

    BSTRobin
    Community Moderator
    Community Moderator

    Hi mgchristensen,

    The delay() function is implemented on the Arduino platform, not BSEC, which simply calls it. You can modify the delay() function implementation on the Arduino platform to achieve the desired effect you want.

    @BSTRobinThank you for your reply.  I must disagree with your reply.

    Note, I am now using the Bosch-BSEC2-Library, it is an improvement over the older BSEC-Arduino-Library.

    A delay is a delay.  A delay is looking at the clock on the wall after finishing the last dish in the sink, noticing it is eleven o'clock, deciding you must leave your residence at noon, and sitting in front of the clock untilI the clock shows noon. I do not have such leasure, and neither does my code. 😀

    I have worked through the layers of Arduino code; there is no way to write a delay function on the Arduino platform that ultimately does not come down to this:

    // From the file esp32-hal.h, line 78:
    
    #define NOP() asm volatile ("nop")
    
    
    // From file esp32-hal-misc.c:
    
    void delay(uint32_t ms)
    {
        vTaskDelay(ms / portTICK_PERIOD_MS);
    }
    
    void ARDUINO_ISR_ATTR delayMicroseconds(uint32_t us)
    {
        uint64_t m = (uint64_t)esp_timer_get_time();
        if(us){
            uint64_t e = (m + us);
            if(m > e){ //overflow
                while((uint64_t)esp_timer_get_time() > e){
                    NOP();
                }
            }
            while((uint64_t)esp_timer_get_time() < e){
                NOP();
            }
        }
    }

     

    The problem starts at the top, where the begin function is declared in bsec2.h:

    bool begin(uint8_t i2cAddr, TwoWire &i2c, bme68x_delay_us_fptr_t idleTask = bme68xDelayUs);

     

    Lots of nops. Thus, no rewrite of the delay function ( bme68xDelayUs() ) called by code in bsec2.cpp will allow any other code to run while bsec is waiting for results from the sensor.  I will dig deeper; It seems to me that asking the sensor to generate the data and reading the data from the sensor must be coded as two separate functions, and it appears that the current code base does not do this.

    To recap: ANY code that runs in loop(), that results in calls to delay(), delayMicroseconds(), or while(){}, will block any other code in loop() froom running.

    Hmmm... still workin' on it.

    Hi mgchristensen,

    For actual microsecond level delays, even blocking is acceptable.
    If it is an actual millisecond level delay, it can be replaced with a non blocking delay function.

    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