How to convert the gas resistance of bme680 sensor to IAQ in thingy53

Hi 
I am working on thingy53, Using Hello world application    NCS- 1.9.1

So I have enable the bme680 sensor of thingy53

I received the values for temp, pressure, humidity, gas resistance. ------How to change this gas resistance to IAQ value in thingy53-----  

This is my main.c 

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <drivers/sensor.h>

void main(void)
{
	
	const struct device *bme = DEVICE_DT_GET_ONE(bosch_bme680);
	struct sensor_value temp, press, humidity, gas_res;


	if (!device_is_ready(bme)) {
		printk("sensor: device not ready.\n");
		return;
	}
	printk("Device %p name is %s\n", bme, bme->name);

	while (1) {
		k_sleep(K_MSEC(3000));

		sensor_sample_fetch(bme);
		sensor_channel_get(bme, SENSOR_CHAN_AMBIENT_TEMP, &temp);
		sensor_channel_get(bme, SENSOR_CHAN_PRESS, &press);
		sensor_channel_get(bme, SENSOR_CHAN_HUMIDITY, &humidity);
		sensor_channel_get(bme, SENSOR_CHAN_GAS_RES, &gas_res);

		printk("T: %d.%06d | P: %d.%06d | H: %d.%06d | G: %d.%06d\n",
				temp.val1, temp.val2, press.val1, press.val2,
				humidity.val1, humidity.val2, gas_res.val1,
				gas_res.val2);
	}
}

And this is the output on RTT monitor

I have gone through many tickets but didn't find a solution.

Please help

Parents Reply Children
  • What above Hieu's reply above the suggested answer, are you able to follow those instructions? If not, please let me know how far you got and what step you got stuck on. 

  • I followed every step as rtlab said.

    I am facing  error  " error: '../libs/lib_bsec/src/libalgobsec.a', needed by 'zephyr/zephyr_pre0.elf', missing and no known rule to make it"  when I add these lines in my CMake

     zephyr_library_import(lib_bsec ${CMAKE_CURRENT_SOURCE_DIR}/libs/lib_bsec/src/libalgobsec.a)
     target_include_directories(app PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/lib_bsec/include)
     target_link_libraries(lib_bsec INTERFACE kernel)
     target_link_libraries(app PRIVATE lib_bsec)

    I am on step of adding  bsec_sensor_control(); to my file 

  • The error indicates that the library was not found. Maybe the library path is incorrect. Either way, please try to link in the library like I did in this modified hello world sample:

     hello_world_with_static_lib.zip

    You should not need to use a Makefile as suggested in rtlab's answer. 

  • Hi 
    Thank you for being so helpful

    I have tested according to your suggestion, and now that error is resolved but facing another error

    Please have a look at my CMake list now

    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.20.0)
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(peripheral)
    
    target_sources(app PRIVATE
      src/main.c
      src/bms_serial.c
     )
    
    
    set(LIB_DIR  ${CMAKE_CURRENT_SOURCE_DIR}/BSEC_2.2.0.0_Generic_Release_30052022/algo/normal_version/bin/gcc/Cortex_M33)
    target_include_directories(app PUBLIC ${LIB_DIR})
    
    zephyr_library_link_libraries(${LIB_DIR}/libalgobsec.a)

    I have added CONFIG_NEWLIB_LIBC=y in prj as well

    Here is my bme688.c file 

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <kernel.h>
    #include <drivers/sensor.h>
    #include <sys/printk.h>
    #include "D:/firmware/zephyr/samples/bluetooth/peripheral/BSEC_2.2.0.0_Generic_Release_30052022/algo/normal_version/bin/gcc/Cortex_M33/bsec_interface.h"
    
    // #include <logging/log.h>
    // #define LOG_MODULE_NAME bme680_sensor
    // LOG_MODULE_REGISTER(LOG_MODULE_NAME);
    
    char temperature[10];
    char pressure[10];
    char humidity_sensor[10];
    char aqi[10];
    static struct bt_conn *current_conn;
    
    void env_sensor(char flash_buffer[])
    {
    	const struct device *bme = DEVICE_DT_GET_ONE(bosch_bme680);
    	struct sensor_value temp, press, humidity, gas_res;
    	char ble_tx_string[50];
    	int ret;
    	int64_t unix_timestamp_ns = 0;
    	float iaq = 0.0f;
    	float static_iaq = 0.0f;
        
    
    	if (!device_is_ready(bme)) {
    		printk("BME680: device not ready./n");
    		return;
    	}
    	
    		sensor_sample_fetch(bme);
    		sensor_channel_get(bme, SENSOR_CHAN_AMBIENT_TEMP, &temp);
    		sensor_channel_get(bme, SENSOR_CHAN_PRESS, &press);
    		sensor_channel_get(bme, SENSOR_CHAN_HUMIDITY, &humidity);
    		sensor_channel_get(bme, SENSOR_CHAN_GAS_RES, &gas_res);
    
    		
            snprintk(temperature,10,"%d.%02d",temp.val1, temp.val2);
    		snprintk(pressure,10,"%d.%02d",press.val1, press.val2);
    		snprintk(humidity_sensor,10,"%d.%02d",humidity.val1, humidity.val2);
    		snprintk(aqi,15,"%d.%02d",gas_res.val1,gas_res.val2);
    
    
    		bsec_init();
    			// Allocate variables
    			uint8_t serialized_settings[BSEC_MAX_PROPERTY_BLOB_SIZE];
    			uint32_t n_serialized_settings_max = BSEC_MAX_PROPERTY_BLOB_SIZE;
    			uint8_t work_buffer[BSEC_MAX_WORKBUFFER_SIZE];
    			uint32_t n_work_buffer = BSEC_MAX_WORKBUFFER_SIZE;
    		ret = bsec_set_configuration(serialized_settings, n_serialized_settings_max, work_buffer, n_work_buffer);
    		
    			bsec_sensor_configuration_t requested_virtual_sensors[0];
    			uint8_t n_requested_virtual_sensors = 1;
    			requested_virtual_sensors[0].sensor_id = BSEC_OUTPUT_IAQ;
    			requested_virtual_sensors[0].sample_rate = BSEC_SAMPLE_RATE_LP;
    			// Allocate a struct for the returned physical sensor settings
    			bsec_sensor_configuration_t required_sensor_settings[BSEC_MAX_PHYSICAL_SENSOR];
    			uint8_t n_required_sensor_settings = BSEC_MAX_PHYSICAL_SENSOR;
    		bsec_update_subscription(requested_virtual_sensors, n_requested_virtual_sensors, required_sensor_settings, &n_required_sensor_settings);
    			date_time_now(&unix_timestamp_ns);
    			unix_timestamp_ns = unix_timestamp_ns/1000000;
    			bsec_bme_settings_t run_gas[1];
    		bsec_sensor_control(unix_timestamp_ns,run_gas);
    
    		 // Allocate input and output memory
    		bsec_input_t input[3];
    		uint8_t n_input = 3;
    		bsec_output_t output[2];
    		uint8_t  n_output=2;
    
    		bsec_library_return_t status;
    
    		// Populate the input structs, assuming the we have timestamp (ts), 
    		// gas sensor resistance (R), temperature (T), and humidity (rH) available
    		// as input variables
    		input[0].sensor_id = BSEC_INPUT_GASRESISTOR;
    		input[0].signal = gas_res.val1;
    		input[0].time_stamp= unix_timestamp_ns;   
    		input[1].sensor_id = BSEC_INPUT_TEMPERATURE;   
    		input[1].signal = temp.val1;   
    		input[1].time_stamp= unix_timestamp_ns;   
    		input[2].sensor_id = BSEC_INPUT_HUMIDITY;
    		input[2].signal = humidity.val1;
    		input[2].time_stamp= unix_timestamp_ns;   
    
    			
    		// Invoke main processing BSEC function
    		status = bsec_do_steps( input, n_input, output, &n_output );
    
    		// Iterate through the BSEC output data, if the call succeeded
    		if(status == BSEC_OK)
    		{
    			for(int i = 0; i < n_output; i++)
    			{   
    				switch(output[i].sensor_id)
    				{
    					case BSEC_OUTPUT_IAQ:
    						iaq = output[i].signal;
    						// Retrieve the IAQ results from output[i].signal
    						// and do something with the data
    						break;
    					case BSEC_OUTPUT_STATIC_IAQ:
    						static_iaq = output[i].signal;
    						// Retrieve the static IAQ results from output[i].signal
    						// and do something with the data
    						break;
    					
    				}
    			}
    		}
    
    		
    			memset(ble_tx_string,'/0',50);			
    			if(current_conn != NULL){
    				sprintf(ble_tx_string,"temp %s",temperature);
    				bt_nus_send (NULL,ble_tx_string, strlen(ble_tx_string));}
    			else {
    				snprintk(ble_tx_string,20,"temp %s#",temperature);k_msleep(500);
    				snprintk(flash_buffer+strlen(flash_buffer),strlen(ble_tx_string)+1,ble_tx_string);}
    
    			memset(ble_tx_string,'/0',50);
    			if(current_conn != NULL){
    				sprintf(ble_tx_string,"hum %s",humidity_sensor);
    				bt_nus_send (NULL,ble_tx_string, strlen(ble_tx_string));}
    			else {
    				snprintk(ble_tx_string,sizeof(humidity_sensor)+15,"hum %s#",humidity_sensor);k_msleep(500);
    				snprintk(flash_buffer+strlen(flash_buffer),strlen(ble_tx_string)+1,ble_tx_string);}
    
    			memset(ble_tx_string,'/0',50);			
    			if(current_conn != NULL){
    				sprintf(ble_tx_string,"atmp %s",pressure);
    				bt_nus_send (NULL,ble_tx_string, strlen(ble_tx_string));}
    			else {
    				snprintk(ble_tx_string,sizeof(pressure)+15,"atmp %s#",pressure);k_msleep(500);
    				snprintk(flash_buffer+strlen(flash_buffer),strlen(ble_tx_string)+1,ble_tx_string);}
    
    			memset(ble_tx_string,'/0',50);			
    			if(current_conn != NULL){
    				sprintf(ble_tx_string,"bsec_iaq %s",aqi);
    				bt_nus_send (NULL,ble_tx_string, strlen(ble_tx_string));}
    			else {
    				snprintk(ble_tx_string,sizeof(aqi)+20,"bsec_iaq %s#",aqi);k_msleep(500);
    				snprintk(flash_buffer+strlen(flash_buffer),strlen(ble_tx_string)+1,ble_tx_string);}
    		// printk("T: %d.%d | P: %d.%02d | H: %d.%02d | G: %d.%02d/n",
    		// 		temp.val1, temp.val2, press.val1, press.val2,
    		// 		humidity.val1, humidity.val2, gas_res.val1,
    		// 		gas_res.val2);
    	}
    	
    

    If you look into this I have not used the variable of lines 106 and 111, I will replace the AQI with these variables later. 

    Please help as this is a very important task which has been pending for 2 months

  • Hi,

    The linker errors indicate that your app is built with the FPU enabled. In that case, you must use the FPU enabled variant of the library located in /algo/normal_version/bin/gcc/Cortex_M33and not the one in /algo/normal_version/bin/gcc/Cortex_M33. 

Related