BME690 Parallel Mode displays no new data during second step.

static int32_t run_step(uint8_t mode, bme690_sample_t *out)
{
	char str[35];
	int err;
    memset(out, 0, 10 * sizeof(*out));
    out->sensor_id  = s_sensor_id;
//    out->step_index = step;
    s_heatr.enable = BME69X_ENABLE;
    s_heatr.profile_len = s_profile.num_steps;
    s_heatr.heatr_temp = s_profile.temperature[0];
    s_heatr.heatr_dur  = s_profile.duration_ms[0];
    s_heatr.heatr_temp_prof = s_profile.temperature;
    s_heatr.heatr_dur_prof = s_profile.duration_ms;
    struct bme69x_conf conf;


    if ((err = bme69x_get_conf(&conf, &s_dev)) != BME69X_OK){
    	snprintf(str, sizeof(str) - 1, "BME conf Err: %d", err);
    	ui_terminal_write(str, ST7789_COLOR_RED);
    	return -1;
    }
    s_heatr.shared_heatr_dur = (uint16_t)(140 - (bme69x_get_meas_dur(mode, &conf, &s_dev) / 1000));

    if ((err = bme69x_set_heatr_conf(mode, &s_heatr, &s_dev)) != BME69X_OK) {
    	snprintf(str, sizeof(str) - 1, "Htr conf Err: %d", err);
    	ui_terminal_write(str, ST7789_COLOR_RED);
        out->err = 1; return -1;
    }

    uint8_t regs[11];
    int len = 0;

    for (uint8_t i = 0; i < 10; i++) {
        regs[i] = 0;
        if(bme69x_get_regs(0x64 + i, &regs[i], 1, &s_dev) != BME69X_OK){
        	snprintf(str, sizeof(str), "%02X error", regs[i]);
        	ui_terminal_write(str, ST7789_COLOR_RED);
        }
    }

    regs[10] = 0;
    bme69x_get_regs(0x71, &regs[10], 1, &s_dev);

    for (uint8_t i = 0; i < 10; i++) {
        snprintf(str, sizeof(str),
                        "%02X: %02u", 0x64 + i, (unsigned int) regs[i]);

        ui_terminal_write(str, ST7789_COLOR_LIGHTGREEN);
    }

    snprintf(str, sizeof(str) - len,
             "71: %02X", regs[10]);
    ui_terminal_write(str, ST7789_COLOR_LIGHTGREEN);

    struct bme69x_data d[10];
    uint8_t n_fields = 0;

    if(mode == BME69X_FORCED_MODE){
	    if ((err = bme69x_set_op_mode(mode, &s_dev)) != BME69X_OK) {
	    	snprintf(str, sizeof(str) - 1, "Op Mode Err: %d", err);
	    	ui_terminal_write(str, ST7789_COLOR_RED);
	        out->err = 2; return -2;
	    }

    	err = bme69x_get_data(mode, d, &n_fields, &s_dev);
    	if (err != BME69X_OK) {
    		snprintf(str, sizeof(str) - 1, "Get Data Error: %d", err);
    		ui_terminal_write(str, ST7789_COLOR_RED);
    		out->err = 3;
    		return -3;
    	}
    	if (n_fields == 0)     {
    		ui_terminal_write("Error: n fields is zero", ST7789_COLOR_RED);
    		out->err = 4;
    		return -4;
    	}

    	out->tick_ms        = app_get_millis();
    	out->temperature    = d[0].temperature;
    	out->pressure       = d[0].pressure;
    	out->humidity       = d[0].humidity;
    	out->gas_resistance = d[0].gas_resistance;

        /* heat_stab_r: check the dedicated status register if you want this bit.
         * bme69x_data.status is the driver's own validity flag, not a raw
         * register value — do not mask it with register-bit constants. */
        out->heat_stab = 0;

        out->err = 0;

    }
    else if(mode == BME69X_PARALLEL_MODE){
	    if ((err = bme69x_set_op_mode(mode, &s_dev)) != BME69X_OK) {
	    	snprintf(str, sizeof(str) - 1, "Op Mode Err: %d", err);
	    	ui_terminal_write(str, ST7789_COLOR_RED);
	        out->err = 2; return -2;
	    }

	    uint32_t start_ms = app_get_millis();

	    uint8_t op_mode = 0;

	    err = bme69x_get_op_mode(&op_mode, &s_dev);

	    bool step_collected[10] = { false };
    	uint8_t collected = 0;
    	uint8_t succ_fields = 0;
    	while (collected < s_profile.num_steps){
    		uint32_t dur_us = 3 * (bme69x_get_meas_dur(BME69X_PARALLEL_MODE, &conf, &s_dev) + ((uint32_t)s_heatr.shared_heatr_dur * 1000));
    		uint8_t count = 0;
    		do{
    			s_dev.delay_us(dur_us, NULL);

    			err = bme69x_get_data(mode, d, &n_fields, &s_dev);

    			count++;

    		} while (err == BME69X_W_NO_NEW_DATA && count < 3);

    	    snprintf(str, sizeof(str),
    	             "t:%lu err:%d n:%u c:%u",
    	             (unsigned long)(app_get_millis() - start_ms),
    	             err, n_fields, collected);

    	    ui_terminal_write(str,
    	        err == BME69X_OK ? ST7789_COLOR_LIGHTGREEN
    	                         : ST7789_COLOR_RED);

    		if (err != BME69X_OK) {
        		snprintf(str, sizeof(str) - 1, "Get Data Error: %d", err);
        		ui_terminal_write(str, ST7789_COLOR_RED);
        		snprintf(str, sizeof(str) - 1, "Successful reads: %d", succ_fields);
        		ui_terminal_write(str, ST7789_COLOR_YELLOW);

    		    out->err = 3;
    		    return -5;
    		}
    		succ_fields += n_fields;

        	for (uint8_t j = 0; j < n_fields; j++) {
        		if((d[j].status & BME69X_NEW_DATA_MSK) && (d[j].status & BME69X_GASM_VALID_MSK)){
        			uint8_t idx = d[j].gas_index;
        			if (idx >= s_profile.num_steps) continue;

        			out[idx].tick_ms        = app_get_millis();
        			out[idx].rtc 			= app_get_unix_time();
        			out[idx].sensor_id      = s_sensor_id;
        			out[idx].temperature    = d[j].temperature;
        			out[idx].pressure       = d[j].pressure;
        			out[idx].humidity       = d[j].humidity;
        			out[idx].gas_resistance = d[j].gas_resistance;
        			if (!step_collected[idx])
        			{
        			    step_collected[idx] = true;
        			    collected++;
        			}
        		}
    		}

    		if (n_fields == 0) {
        		ui_terminal_write("Error: n fields is zero", ST7789_COLOR_RED);
    		    out->err = 4;
    		    return -6;
    		}
    	}
    }
    return 0;
}

The above code is a function that is supposed to manage the data collection mode from a given heater profile. The run step waits for approximately the time for the 3 field registers to fill, and then retrieves the data, and filters for the ones with valid gas measurements. The issue is that the BME690 stops recording new data during the second step, as shown from the LCD terminal:

64: 02
65: 41
66: 02
67: 14
68: 14
69: 14
6A: 02
6B: 14
6C: 14
6D: 14
71: 2A
t:430 err:0 n:3 c:0
t:860 err:0 n:3 c:1
t:1290 err:0 n:3 c:1
t:1719 err:0 n:3 c:1
t:3004 err:0 n:3 c:1
Get Data Error: 2
Successful reads: 12

The heater profile used to test used is based on HP-301 from the AI studio as such:

    p1 = build_profile(1, now,
                       steps=[(100, 280/140), (100, (6020-280)/140), (200, (6300-6020)/140),
                                (200, (8260-6300)/140), (200, (10220-8260)/140),
                                (200, (12180-10220)/140), (320, (12460-12180)/140),
                                (320, (14420-12460)/140), (320, (16380-14420)/140),
                                (320, (18340-16380)/140)],
                       shared_heater=140, duty_scan=1, duty_sleep=4)

But that is likely irrelevant, as the register values reflect that the proper times are included.

Sensor
BME690
Application
Others
Use case
BME690 Gas data collection
Development Platform
STM32
Project Phase
PVT
Label
Sensor API
5 replies
BME690