42#define CHIP_NAME "Sensirion SGP41"
43#define MANUFACTURER_NAME "Sensirion"
44#define SUPPLY_VOLTAGE_MIN 1.70f
45#define SUPPLY_VOLTAGE_MAX 3.60f
46#define MAX_CURRENT 4.80f
47#define TEMPERATURE_MIN -10.0f
48#define TEMPERATURE_MAX 50.0f
49#define DRIVER_VERSION 1000
54#define SGP41_ADDRESS (0x59 << 1)
59#define SGP41_COMMAND_EXECUTE_CONDITIONING 0x2612U
60#define SGP41_COMMAND_MEASURE_RAW 0x2619U
61#define SGP41_COMMAND_EXECUTE_SELF_TEST 0x280EU
62#define SGP41_COMMAND_TURN_HEATER_OFF 0x3615U
63#define SGP41_COMMAND_GET_SERIAL_ID 0x3682U
64#define SGP41_COMMAND_SOFT_RESET 0x0006U
69#define SGP41_CRC8_POLYNOMIAL 0x31
70#define SGP41_CRC8_INIT 0xFF
86static uint8_t a_sgp41_iic_read_with_param(
sgp41_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len,
87 uint16_t delay_ms, uint8_t *output, uint16_t output_len)
96 memset(buf, 0,
sizeof(uint8_t) * 16);
97 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
98 buf[1] = (uint8_t)(reg & 0xFF);
99 for (i = 0; i < len; i++)
101 buf[2 + i] = data[i];
131static uint8_t a_sgp41_iic_read(
sgp41_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
135 memset(buf, 0,
sizeof(uint8_t) * 2);
136 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
137 buf[1] = (uint8_t)(reg & 0xFF);
164static uint8_t a_sgp41_iic_write(
sgp41_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
173 memset(buf, 0,
sizeof(uint8_t) * 16);
174 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
175 buf[1] = (uint8_t)(reg & 0xFF);
176 for (i = 0; i < len; i++)
178 buf[2 + i] = data[i];
198static uint8_t a_sgp41_generate_crc(uint8_t* data, uint8_t count)
200 uint8_t current_byte;
204 for (current_byte = 0; current_byte < count; ++current_byte)
206 crc ^= (data[current_byte]);
207 for (crc_bit = 8; crc_bit > 0; --crc_bit)
209 if ((crc & 0x80) != 0)
246 *reg = (uint16_t)(rh / 100.0f * 65535.0f);
274 *reg = (uint16_t)((temp + 45.0f) / 175.0f * 65535.0f);
305 memset(buf, 0,
sizeof(uint8_t) * 3);
316 handle->
debug_print(
"sgp41: read measure raw failed.\n");
320 if (buf[2] != a_sgp41_generate_crc((uint8_t *)buf, 2))
322 handle->
debug_print(
"sgp41: sraw voc crc check error.\n");
326 *sraw_voc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
346 uint16_t *sraw_voc, uint16_t *sraw_nox)
361 memset(buf, 0,
sizeof(uint8_t) * 6);
362 input[0] = (raw_humidity >> 8) & 0xFF;
363 input[1] = (raw_humidity >> 0) & 0xFF;
364 input[2] = a_sgp41_generate_crc(&input[0], 2);
365 input[3] = (raw_temperature >> 8) & 0xFF;
366 input[4] = (raw_temperature >> 0) & 0xFF;
367 input[5] = a_sgp41_generate_crc(&input[3], 2);
371 handle->
debug_print(
"sgp41: read measure raw failed.\n");
375 if (buf[2] != a_sgp41_generate_crc((uint8_t *)buf, 2))
377 handle->
debug_print(
"sgp41: sraw voc crc check error.\n");
381 if (buf[5] != a_sgp41_generate_crc((uint8_t *)&buf[3], 2))
383 handle->
debug_print(
"sgp41: sraw nox crc check error.\n");
387 *sraw_voc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
388 *sraw_nox = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]);
420 memset(buf, 0,
sizeof(uint8_t) * 6);
430 handle->
debug_print(
"sgp41: read measure raw failed.\n");
434 if (buf[2] != a_sgp41_generate_crc((uint8_t *)buf, 2))
436 handle->
debug_print(
"sgp41: sraw voc crc check error.\n");
440 if (buf[5] != a_sgp41_generate_crc((uint8_t *)&buf[3], 2))
442 handle->
debug_print(
"sgp41: sraw nox crc check error.\n");
446 *sraw_voc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
447 *sraw_nox = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]);
477 memset(buf, 0,
sizeof(uint8_t) * 3);
481 handle->
debug_print(
"sgp41: read measure test failed.\n");
485 if (buf[2] != a_sgp41_generate_crc((uint8_t *)buf, 2))
487 handle->
debug_print(
"sgp41: measure test check error.\n");
491 *result = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
524 handle->
debug_print(
"sgp41: write soft reset failed.\n");
559 handle->
debug_print(
"sgp41: write turn heater off failed.\n");
593 memset(buf, 0,
sizeof(uint8_t) * 9);
597 handle->
debug_print(
"sgp41: read serial id failed.\n");
601 if (buf[2] != a_sgp41_generate_crc((uint8_t *)&buf[0], 2))
603 handle->
debug_print(
"sgp41: crc 1 check failed.\n");
607 if (buf[5] != a_sgp41_generate_crc((uint8_t *)&buf[3], 2))
609 handle->
debug_print(
"sgp41: crc 2 check failed.\n");
613 if (buf[8] != a_sgp41_generate_crc((uint8_t *)&buf[6], 2))
615 handle->
debug_print(
"sgp41: crc 3 check failed.\n");
619 id[0] = (uint16_t)((((uint16_t)buf[0]) << 8) | buf[1]);
620 id[1] = (uint16_t)((((uint16_t)buf[3]) << 8) | buf[4]);
621 id[2] = (uint16_t)((((uint16_t)buf[6]) << 8) | buf[7]);
654 handle->
debug_print(
"sgp41: iic_deinit is null.\n");
660 handle->
debug_print(
"sgp41: iic_write_cmd is null.\n");
666 handle->
debug_print(
"sgp41: iic_read_cmd is null.\n");
712 handle->
debug_print(
"sgp41: turn heater off failed.\n");
751 return a_sgp41_iic_write(handle, reg, buf, len);
778 return a_sgp41_iic_read(handle, reg, buf, len, 320);
#define SGP41_COMMAND_TURN_HEATER_OFF
#define SGP41_CRC8_POLYNOMIAL
crc8 definition
#define SGP41_COMMAND_GET_SERIAL_ID
#define SUPPLY_VOLTAGE_MAX
#define SGP41_COMMAND_EXECUTE_SELF_TEST
#define MANUFACTURER_NAME
#define SUPPLY_VOLTAGE_MIN
#define CHIP_NAME
chip information definition
#define SGP41_COMMAND_MEASURE_RAW
#define SGP41_ADDRESS
chip address definition
#define SGP41_COMMAND_EXECUTE_CONDITIONING
chip command definition
uint8_t sgp41_temperature_convert_to_register(sgp41_handle_t *handle, float temp, uint16_t *reg)
convert the temperature to the register data
uint8_t sgp41_get_measure_raw(sgp41_handle_t *handle, uint16_t raw_humidity, uint16_t raw_temperature, uint16_t *sraw_voc, uint16_t *sraw_nox)
get the measure raw result
uint8_t sgp41_get_execute_conditioning(sgp41_handle_t *handle, uint16_t *sraw_voc)
get execute conditioning
uint8_t sgp41_info(sgp41_info_t *info)
get chip information
uint8_t sgp41_deinit(sgp41_handle_t *handle)
close the chip
struct sgp41_info_s sgp41_info_t
sgp41 information structure definition
uint8_t sgp41_get_measure_test(sgp41_handle_t *handle, uint16_t *result)
get the chip measure test
uint8_t sgp41_turn_heater_off(sgp41_handle_t *handle)
turn heater off
uint8_t sgp41_soft_reset(sgp41_handle_t *handle)
soft reset the chip
struct sgp41_handle_s sgp41_handle_t
sgp41 handle structure definition
uint8_t sgp41_get_serial_id(sgp41_handle_t *handle, uint16_t id[3])
get the chip serial id
uint8_t sgp41_init(sgp41_handle_t *handle)
initialize the chip
uint8_t sgp41_get_measure_raw_without_compensation(sgp41_handle_t *handle, uint16_t *sraw_voc, uint16_t *sraw_nox)
get the measure raw result without compensation
uint8_t sgp41_humidity_convert_to_register(sgp41_handle_t *handle, float rh, uint16_t *reg)
convert the humidity to the register data
uint8_t sgp41_get_reg(sgp41_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
get the chip register
uint8_t sgp41_set_reg(sgp41_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set the chip register
void(* delay_ms)(uint32_t ms)
void(* debug_print)(const char *const fmt,...)
uint8_t(* iic_init)(void)
uint8_t(* iic_read_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
uint8_t(* iic_deinit)(void)
uint8_t(* iic_write_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
float supply_voltage_max_v
char manufacturer_name[32]
float supply_voltage_min_v