From 674806b5356862fe9bde107d027f5ed5eab0b8b5 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sun, 24 Jul 2022 13:11:52 +0100 Subject: [PATCH 01/28] feature: add module for BME280 sensor. --- Lib/Inc/BME280.h | 17 +++++++++++++++++ Lib/Src/BME280.c | 12 ++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 Lib/Inc/BME280.h create mode 100644 Lib/Src/BME280.c diff --git a/Lib/Inc/BME280.h b/Lib/Inc/BME280.h new file mode 100644 index 00000000..1bde7816 --- /dev/null +++ b/Lib/Inc/BME280.h @@ -0,0 +1,17 @@ +/** + *@file BME280.h + *@brief This file contains the API functions for accessing BME280 sensor. + * + */ + +/* + * BME280.h + * + * Created on: 24 Jul 2022 + * Author: salavat.magazov + */ + +#ifndef INC_BME280_H_ +#define INC_BME280_H_ + +#endif /* INC_BME280_H_ */ diff --git a/Lib/Src/BME280.c b/Lib/Src/BME280.c new file mode 100644 index 00000000..c95eb52a --- /dev/null +++ b/Lib/Src/BME280.c @@ -0,0 +1,12 @@ +/** + *@file BME280.c + *@brief This file contains the BME280 sensor driver code. + * + */ + +/* + * BME280.c + * + * Created on: 24 Jul 2022 + * Author: salavat.magazov + */ From 1e3a824369aa880299b1e4ee3f0784205625f13e Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sun, 24 Jul 2022 13:30:08 +0100 Subject: [PATCH 02/28] feature: transfer Sam's code unmodified to a new module. --- Lib/Inc/BME280.h | 12 +++ Lib/Src/BME280.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) diff --git a/Lib/Inc/BME280.h b/Lib/Inc/BME280.h index 1bde7816..6fe8f3b0 100644 --- a/Lib/Inc/BME280.h +++ b/Lib/Inc/BME280.h @@ -14,4 +14,16 @@ #ifndef INC_BME280_H_ #define INC_BME280_H_ +#ifdef __cplusplus +extern "C" +{ +#endif + + // Function prototypes and all definitions that should be visible from + // outside the module go here. + +#ifdef __cplusplus +} +#endif + #endif /* INC_BME280_H_ */ diff --git a/Lib/Src/BME280.c b/Lib/Src/BME280.c index c95eb52a..8c9f526b 100644 --- a/Lib/Src/BME280.c +++ b/Lib/Src/BME280.c @@ -10,3 +10,224 @@ * Created on: 24 Jul 2022 * Author: salavat.magazov */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "gpio.h" +#include "spi.h" + + const uint8_t ctrl_meas = 0b01110100; + const uint8_t ctrl_hum = 0b01110010; + const uint8_t config = 0b01110101; + const uint8_t status = 0b11110011; + const uint8_t hum_msb = 0b11111101; + const uint8_t temp_msb = 0b11111010; + const uint8_t dig_H1_addr = 0b10100001; + const uint8_t dig_H2_addr = 0b11100001; + const uint8_t dig_H3_addr = 0b11100011; + const uint8_t dig_H4_addr = 0b11100100; + const uint8_t dig_H5_addr = 0b11100101; + const uint8_t dig_H6_addr = 0b11100111; + const uint8_t dig_T1_addr = 0b10001000; + const uint8_t dig_T2_addr = 0b10001010; + const uint8_t dig_T3_addr = 0b10001100; + + HAL_StatusTypeDef ret; + uint8_t hum_val[3]; // humidity raw value + uint8_t temp_val[3]; // temperature raw value + typedef int32_t BME280_S32_t; + typedef uint32_t BME280_U32_t; + + BME280_S32_t t_fine, adc_T, adc_H; + uint8_t spi_buff[5]; // SPI buffer not for measurements + uint8_t hum_osrs = 0b00000001; // enable humidity with x1 oversampling + uint8_t meas_val = 0b00100001; // set forced mode and turn off press + uint8_t filter_off = 0b00000000; // turn off filter + BME280_U32_t humidity; // final humidity value + uint8_t digT1[2]; + int8_t digT2[2], digT3[2], digH2[2]; + + unsigned short dig_T1; + short dig_T2, dig_T3, dig_H2, dig_H4, dig_H5, dig_H4_ls[2], dig_H5_ls[2]; + unsigned char dig_H1, dig_H3, digH6; + char dig_H6; + memset(spi_buff, 0, sizeof(spi_buff)); + // select mode 0 + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); + + // write settings + HAL_SPI_Transmit(&hspi2, (uint8_t *)&ctrl_hum, 1, 100); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&hum_osrs, 1, 100); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&ctrl_meas, 1, 100); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&meas_val, 1, 100); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&config, 1, 100); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&filter_off, 1, 100); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); + + spi_buff[0] = 1; + + // check status + while (spi_buff[0] & 0b00001000) + { // bit masking need bit 3 + + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&status, 1, 100); + HAL_SPI_Receive(&hspi2, (uint8_t *)spi_buff, 1, 100); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); + } + + // read hum data + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&hum_msb, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)hum_val, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)hum_val, 2, 100); + } + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); + adc_H = (hum_val[1] >> 8) | (hum_val[0]); + + // read temp data + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&temp_msb, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)temp_val, 1, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)temp_val, 1, 100); + } + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); + + // correct temp data + adc_T = (temp_val[2] >> 24) | (temp_val[1] >> 21) | temp_val[0]; + + // read data + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_T1_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT1, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT1, 2, 100); + } + + dig_T1 = (digT1[1] << 8) | digT1[0]; + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_T2_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT2, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT2, 2, 100); + } + + dig_T2 = (int)(digT2[1] << 8) | (int)digT2[0]; + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_T3_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT3, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT3, 2, 100); + } + + dig_T3 = (int)((digT3[1] << 8) | digT3[0]); + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H1_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H1, 1, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H1, 1, 100); + } + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H2_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digH2, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digH2, 2, 100); + } + + dig_H2 = (int)((digH2[1] << 8) | digH2[0]); + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H3_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H3, 1, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H3, 1, 100); + } + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H4_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H4_ls, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H4_ls, 2, 100); + } + + dig_H4_ls[1] = dig_H4_ls[1] & 0b0000000000001111; + dig_H4 = (int)(dig_H4_ls[0] | dig_H4_ls[1]); + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H5_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H5_ls, 2, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H5_ls, 2, 100); + } + + dig_H5_ls[0] = (dig_H5_ls[0] & 0b1111000000000000) >> 12; + dig_H5_ls[1] = dig_H5_ls[1] << 8; + dig_H5 = (int)(dig_H5_ls[1] | dig_H5_ls[0]); + + HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H6_addr, 1, 100); + ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&digH6, 1, 100); + while (ret != HAL_OK) + { + ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&digH6, 1, 100); + } + + dig_H6 = (char)digH6; + + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); + + // perform calculations + BME280_S32_t var1, var2; + var1 = ((((adc_T >> 3) - ((BME280_S32_t)dig_T1 << 1))) * + ((BME280_S32_t)dig_T2)) >> + 11; + + var2 = (((((adc_T >> 4) - ((BME280_S32_t)dig_T1)) * + ((adc_T >> 4) - ((BME280_S32_t)dig_T1))) >> + 12) * + ((BME280_S32_t)dig_T3)) >> + 14; + t_fine = var1 + var2; + + BME280_S32_t v_x1_u32r; + v_x1_u32r = (t_fine - ((BME280_S32_t)76800)); + v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - + (((BME280_S32_t)dig_H5) * v_x1_u32r)) + + ((BME280_S32_t)16384)) >> + 15) * + (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * + (((v_x1_u32r * ((BME280_S32_t)dig_H3)) >> 11) + + ((BME280_S32_t)32768))) >> + 10) + + ((BME280_S32_t)2097152)) * + ((BME280_S32_t)dig_H2) + + 8192) >> + 14)); + v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * + ((BME280_S32_t)dig_H1)) >> + 4)); + v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); + v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); + + humidity = (BME280_U32_t)(v_x1_u32r >> 12); + +#ifdef __cplusplus +} +#endif From 852b544cf8f14073be3bd022e41db6f81dc6bedd Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Mon, 25 Jul 2022 08:50:44 +0100 Subject: [PATCH 03/28] feature: add sensor initialisation method --- Lib/Inc/BME280.h | 29 ------ Lib/Inc/CBME280.h | 84 ++++++++++++++++ Lib/Src/BME280.c | 233 -------------------------------------------- Lib/Src/CBME280.cpp | 148 ++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+), 262 deletions(-) delete mode 100644 Lib/Inc/BME280.h create mode 100644 Lib/Inc/CBME280.h delete mode 100644 Lib/Src/BME280.c create mode 100644 Lib/Src/CBME280.cpp diff --git a/Lib/Inc/BME280.h b/Lib/Inc/BME280.h deleted file mode 100644 index 6fe8f3b0..00000000 --- a/Lib/Inc/BME280.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - *@file BME280.h - *@brief This file contains the API functions for accessing BME280 sensor. - * - */ - -/* - * BME280.h - * - * Created on: 24 Jul 2022 - * Author: salavat.magazov - */ - -#ifndef INC_BME280_H_ -#define INC_BME280_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - - // Function prototypes and all definitions that should be visible from - // outside the module go here. - -#ifdef __cplusplus -} -#endif - -#endif /* INC_BME280_H_ */ diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h new file mode 100644 index 00000000..438905ee --- /dev/null +++ b/Lib/Inc/CBME280.h @@ -0,0 +1,84 @@ +/** + *@file CBME280.h + * + */ + +/* + * CBME280.h + * + * Created on: 24 Jul 2022 + * Author: salavat.magazov + */ + +#ifndef CBME280_H_ +#define CBME280_H_ + +#include "CGpioWrapper.h" +#include "gpio.h" +#include "spi.h" + +#define T_CALIBRATION_SIZE 3 +#define P_CALIBRATION_SIZE 9 +#define H_CALIBRATION_SIZE 6 + +class CBME280 +{ + enum REGISTER_MAP + { + /* Calibration registers. */ + DIG_T1 = 0x88, + DIG_T2 = 0x8A, + DIG_T3 = 0x8C, + DIG_P1 = 0x8E, + DIG_P2 = 0x90, + DIG_P3 = 0x92, + DIG_P4 = 0x94, + DIG_P5 = 0x96, + DIG_P6 = 0x98, + DIG_P7 = 0x9A, + DIG_P8 = 0x9C, + DIG_P9 = 0x9E, + DIG_H1 = 0xA1, + DIG_H2 = 0xE1, + DIG_H3 = 0xE3, + DIG_H4 = 0xE4, + DIG_H5 = 0xE5, + /* Sensor data registers. */ + ID = 0xD0, + RESET = 0xE0, + CTRL_HUM = 0xF2, + STATUS = 0xF3, + CTRL_MEAS = 0xF4, + CONFIG = 0xF5, + PRESS_MSB = 0xF7, + PRESS_LSB = 0xF8, + PRESS_XLSB = 0xF9, + TEMP_MSB = 0xFA, + TEMP_LSB = 0xFB, + TEMP_XLSB = 0xFC, + HUM_MSB = 0xFD, + HUM_LSB = 0xFE + }; + +public: + CBME280(SPI_HandleTypeDef *p_spi, + GPIO_TypeDef *p_slave_select_port, + uint16_t slave_select_pin); + virtual ~CBME280(); + + bool init(); + +private: + void calibrateSensor(uint8_t const *const p_calibration_data); + + SPI_HandleTypeDef *mp_spi; + CGpioWrapper m_slave_select; + + bool mb_initialised; + + uint16_t m_temperature_calibration[T_CALIBRATION_SIZE]; + uint16_t m_pressure_calibration[P_CALIBRATION_SIZE]; + uint16_t m_humidity_calibration[H_CALIBRATION_SIZE]; +}; + +#endif /* CBME280_H_ */ diff --git a/Lib/Src/BME280.c b/Lib/Src/BME280.c deleted file mode 100644 index 8c9f526b..00000000 --- a/Lib/Src/BME280.c +++ /dev/null @@ -1,233 +0,0 @@ -/** - *@file BME280.c - *@brief This file contains the BME280 sensor driver code. - * - */ - -/* - * BME280.c - * - * Created on: 24 Jul 2022 - * Author: salavat.magazov - */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include "gpio.h" -#include "spi.h" - - const uint8_t ctrl_meas = 0b01110100; - const uint8_t ctrl_hum = 0b01110010; - const uint8_t config = 0b01110101; - const uint8_t status = 0b11110011; - const uint8_t hum_msb = 0b11111101; - const uint8_t temp_msb = 0b11111010; - const uint8_t dig_H1_addr = 0b10100001; - const uint8_t dig_H2_addr = 0b11100001; - const uint8_t dig_H3_addr = 0b11100011; - const uint8_t dig_H4_addr = 0b11100100; - const uint8_t dig_H5_addr = 0b11100101; - const uint8_t dig_H6_addr = 0b11100111; - const uint8_t dig_T1_addr = 0b10001000; - const uint8_t dig_T2_addr = 0b10001010; - const uint8_t dig_T3_addr = 0b10001100; - - HAL_StatusTypeDef ret; - uint8_t hum_val[3]; // humidity raw value - uint8_t temp_val[3]; // temperature raw value - typedef int32_t BME280_S32_t; - typedef uint32_t BME280_U32_t; - - BME280_S32_t t_fine, adc_T, adc_H; - uint8_t spi_buff[5]; // SPI buffer not for measurements - uint8_t hum_osrs = 0b00000001; // enable humidity with x1 oversampling - uint8_t meas_val = 0b00100001; // set forced mode and turn off press - uint8_t filter_off = 0b00000000; // turn off filter - BME280_U32_t humidity; // final humidity value - uint8_t digT1[2]; - int8_t digT2[2], digT3[2], digH2[2]; - - unsigned short dig_T1; - short dig_T2, dig_T3, dig_H2, dig_H4, dig_H5, dig_H4_ls[2], dig_H5_ls[2]; - unsigned char dig_H1, dig_H3, digH6; - char dig_H6; - memset(spi_buff, 0, sizeof(spi_buff)); - // select mode 0 - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); - - // write settings - HAL_SPI_Transmit(&hspi2, (uint8_t *)&ctrl_hum, 1, 100); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&hum_osrs, 1, 100); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&ctrl_meas, 1, 100); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&meas_val, 1, 100); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&config, 1, 100); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&filter_off, 1, 100); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); - - spi_buff[0] = 1; - - // check status - while (spi_buff[0] & 0b00001000) - { // bit masking need bit 3 - - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&status, 1, 100); - HAL_SPI_Receive(&hspi2, (uint8_t *)spi_buff, 1, 100); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); - } - - // read hum data - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&hum_msb, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)hum_val, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)hum_val, 2, 100); - } - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); - adc_H = (hum_val[1] >> 8) | (hum_val[0]); - - // read temp data - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&temp_msb, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)temp_val, 1, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)temp_val, 1, 100); - } - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); - - // correct temp data - adc_T = (temp_val[2] >> 24) | (temp_val[1] >> 21) | temp_val[0]; - - // read data - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_T1_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT1, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT1, 2, 100); - } - - dig_T1 = (digT1[1] << 8) | digT1[0]; - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_T2_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT2, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT2, 2, 100); - } - - dig_T2 = (int)(digT2[1] << 8) | (int)digT2[0]; - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_T3_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT3, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digT3, 2, 100); - } - - dig_T3 = (int)((digT3[1] << 8) | digT3[0]); - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H1_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H1, 1, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H1, 1, 100); - } - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H2_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digH2, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)digH2, 2, 100); - } - - dig_H2 = (int)((digH2[1] << 8) | digH2[0]); - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H3_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H3, 1, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&dig_H3, 1, 100); - } - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H4_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H4_ls, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H4_ls, 2, 100); - } - - dig_H4_ls[1] = dig_H4_ls[1] & 0b0000000000001111; - dig_H4 = (int)(dig_H4_ls[0] | dig_H4_ls[1]); - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H5_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H5_ls, 2, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (uint8_t *)dig_H5_ls, 2, 100); - } - - dig_H5_ls[0] = (dig_H5_ls[0] & 0b1111000000000000) >> 12; - dig_H5_ls[1] = dig_H5_ls[1] << 8; - dig_H5 = (int)(dig_H5_ls[1] | dig_H5_ls[0]); - - HAL_SPI_Transmit(&hspi2, (uint8_t *)&dig_H6_addr, 1, 100); - ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&digH6, 1, 100); - while (ret != HAL_OK) - { - ret = HAL_SPI_Receive(&hspi2, (unsigned char *)&digH6, 1, 100); - } - - dig_H6 = (char)digH6; - - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); - - // perform calculations - BME280_S32_t var1, var2; - var1 = ((((adc_T >> 3) - ((BME280_S32_t)dig_T1 << 1))) * - ((BME280_S32_t)dig_T2)) >> - 11; - - var2 = (((((adc_T >> 4) - ((BME280_S32_t)dig_T1)) * - ((adc_T >> 4) - ((BME280_S32_t)dig_T1))) >> - 12) * - ((BME280_S32_t)dig_T3)) >> - 14; - t_fine = var1 + var2; - - BME280_S32_t v_x1_u32r; - v_x1_u32r = (t_fine - ((BME280_S32_t)76800)); - v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - - (((BME280_S32_t)dig_H5) * v_x1_u32r)) + - ((BME280_S32_t)16384)) >> - 15) * - (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * - (((v_x1_u32r * ((BME280_S32_t)dig_H3)) >> 11) + - ((BME280_S32_t)32768))) >> - 10) + - ((BME280_S32_t)2097152)) * - ((BME280_S32_t)dig_H2) + - 8192) >> - 14)); - v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * - ((BME280_S32_t)dig_H1)) >> - 4)); - v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); - v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); - - humidity = (BME280_U32_t)(v_x1_u32r >> 12); - -#ifdef __cplusplus -} -#endif diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp new file mode 100644 index 00000000..bf7e6a9f --- /dev/null +++ b/Lib/Src/CBME280.cpp @@ -0,0 +1,148 @@ +/** + *@file CBME280.cpp + * + */ + +/* + * BME280.cpp + * + * Created on: 24 Jul 2022 + * Author: salavat.magazov + */ + +#include + +#define BME280_ID 0x60 +#define BMP280_ID 0x58 +#define SOFT_RESET 0xB6 +#define SPI_WRITE_MASK 0x80 +#define ID_PACKET_SIZE 2 +#define CALIB1_PACKET_SIZE 24 +#define CALIB2_PACKET_SIZE 1 +#define CALIB3_PACKET_SIZE 8 +#define SPI_TIMEOUT_MS 100 +#define SENSOR_RESET_DELAY_MS 9 + +#define CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb) + +#define HIGH true +#define LOW false + +CBME280::CBME280(SPI_HandleTypeDef *p_spi, + GPIO_TypeDef *p_slave_select_port, + uint16_t slave_select_pin) + : mp_spi(p_spi), + m_slave_select(p_slave_select_port, slave_select_pin), + mb_initialised(false) +{ + if (mp_spi == nullptr) + { + Error_Handler(); + } + m_slave_select.set(true); +} + +CBME280::~CBME280() +{ + // TODO Auto-generated destructor stub +} + +bool CBME280::init() +{ + /* TODO: + * 1. Check SPI works. + * 2. Read chip ID to verify comms to sensor works. + * 3. Read calibration values and store in appropriate places. + */ + /* This communication via SPI is going to be done without interrupts.*/ + // TODO: how do we ensure SPI is available? Perhaps need a wrapper around + // SPI with a mutex. + if (HAL_SPI_GetState(mp_spi) != HAL_SPI_STATE_READY) + { + Error_Handler(); + } + uint8_t register_address; + /* Soft reset. */ + register_address = RESET; + m_slave_select.set(false); + HAL_SPI_Transmit(mp_spi, ®ister_address, 1, SPI_TIMEOUT_MS); + m_slave_select.set(true); + HAL_Delay(SENSOR_RESET_DELAY_MS); + /* Read sensor ID to see if it is responding to comms. */ + register_address = ID; + uint8_t id_register[ID_PACKET_SIZE]; + m_slave_select.set(LOW); + HAL_SPI_TransmitReceive(mp_spi, + ®ister_address, + id_register, + ID_PACKET_SIZE, + SPI_TIMEOUT_MS); + m_slave_select.set(HIGH); + if ((id_register[1] != BME280_ID) && (id_register[1] != BMP280_ID)) + { + return false; + } + /* Read sensor calibration data. */ + register_address = DIG_T1; + uint8_t calibration_register[CALIB1_PACKET_SIZE + + CALIB2_PACKET_SIZE * CALIB3_PACKET_SIZE]; + m_slave_select.set(LOW); + HAL_SPI_TransmitReceive(mp_spi, + ®ister_address, + calibration_register, + CALIB1_PACKET_SIZE, + SPI_TIMEOUT_MS); + m_slave_select.set(HIGH); + register_address = DIG_H1; + m_slave_select.set(LOW); + HAL_SPI_TransmitReceive(mp_spi, + ®ister_address, + &(calibration_register[CALIB1_PACKET_SIZE - 1]), + CALIB2_PACKET_SIZE, + SPI_TIMEOUT_MS); + m_slave_select.set(HIGH); + register_address = DIG_H2; + m_slave_select.set(LOW); + HAL_SPI_TransmitReceive(mp_spi, + ®ister_address, + &(calibration_register[CALIB1_PACKET_SIZE]), + CALIB2_PACKET_SIZE, + SPI_TIMEOUT_MS); + m_slave_select.set(HIGH); + calibrateSensor(calibration_register); + mb_initialised = true; + return true; +} + +void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) +{ + uint8_t const *p_runner = p_calibration_data; + for (int i = 0; i < T_CALIBRATION_SIZE; i++) + { + m_temperature_calibration[i] = *p_runner; + m_temperature_calibration[i] |= *(++p_runner) << 8; + ++p_runner; + } + for (int i = 0; i < P_CALIBRATION_SIZE; i++) + { + m_pressure_calibration[i] = *p_runner; + m_pressure_calibration[i] |= *(++p_runner) << 8; + ++p_runner; + } + /* Humidity calibration data is spread around and is stored in a weird + * convoluted way. See the manual. This recovery was copied with + * modifications from the Bosch github repository. + * https://github.com/BoschSensortec/BME280_driver */ + /* I am certain the engineer at Bosch who came up with this had management + * breathing down their neck. One day they stopped caring and made this + * monstrocity.*/ + m_humidity_calibration[0] = p_calibration_data[25]; + m_humidity_calibration[1] = + (p_calibration_data[27] << 8) + p_calibration_data[26]; + m_humidity_calibration[2] = p_calibration_data[28]; + m_humidity_calibration[3] = + (p_calibration_data[29] << 4) + (p_calibration_data[30] & 0x0F); + m_humidity_calibration[4] = + (p_calibration_data[31] << 4) + (p_calibration_data[30] >> 4); + m_humidity_calibration[5] = p_calibration_data[32]; +} From 7c55e7f50d4e293237d3fb72da60a2d17b5b2a68 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Mon, 25 Jul 2022 09:16:09 +0100 Subject: [PATCH 04/28] docs: add doxygen headers to methods. feature: add sensor data access methods. --- Lib/Inc/CBME280.h | 39 +++++++++++++++++++++++++++++++++++++++ Lib/Src/CBME280.cpp | 19 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index 438905ee..c4e5fa1e 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -68,8 +68,39 @@ class CBME280 bool init(); + /** + * @brief Access processed temperature data. + * + * @return Temperature in degrees Celsius. + */ + float getTemperature() const + { + return m_temperature; + }; + + /** + * @brief Access processed pressure data. + * + * @return Pressure in Pascals. + */ + float getPressure() const + { + return m_pressure; + }; + + /** + * @brief Access processed humidity data. + * + * @return Humidity in %RH. + */ + float getHumidity() const + { + return m_humidity; + }; + private: void calibrateSensor(uint8_t const *const p_calibration_data); + void convertRawData(uint8_t const *const p_raw_adc_data); SPI_HandleTypeDef *mp_spi; CGpioWrapper m_slave_select; @@ -79,6 +110,14 @@ class CBME280 uint16_t m_temperature_calibration[T_CALIBRATION_SIZE]; uint16_t m_pressure_calibration[P_CALIBRATION_SIZE]; uint16_t m_humidity_calibration[H_CALIBRATION_SIZE]; + + uint32_t m_raw_temperature_data; + uint32_t m_raw_pressure_data; + uint32_t m_raw_humidity_data; + + float m_temperature; + float m_pressure; + float m_humidity; }; #endif /* CBME280_H_ */ diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index bf7e6a9f..bcecb682 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -28,6 +28,13 @@ #define HIGH true #define LOW false +/** + * @brief Construct a sensor driver class instance. + * + * @param p_spi Pointer to HAL handler for SPI channel. + * @param p_slave_select_port Pointer to GPIO port for SS pin. + * @param slave_select_pin Mask of the SS pin. + */ CBME280::CBME280(SPI_HandleTypeDef *p_spi, GPIO_TypeDef *p_slave_select_port, uint16_t slave_select_pin) @@ -47,6 +54,12 @@ CBME280::~CBME280() // TODO Auto-generated destructor stub } +/** + * @brief Initialise the sensor. This must be successfully completed before + * sensor can be accessed for data. + * + * @return True if initialisation is successful, false otherwise. + */ bool CBME280::init() { /* TODO: @@ -114,6 +127,12 @@ bool CBME280::init() return true; } +/** + * @brief Convert raw data from the sensor registers into usable calibration + * values. + * + * @param p_calibration_data Pointer to raw data stream of 33 8-bit values. + */ void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) { uint8_t const *p_runner = p_calibration_data; From 478051074e039dae98e5fb2d6612a0172f2ecaf1 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Mon, 25 Jul 2022 10:22:59 +0100 Subject: [PATCH 05/28] feature: add conversion of raw data stream into raw structured data. --- Lib/Src/CBME280.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index bcecb682..735327d5 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -165,3 +165,28 @@ void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) (p_calibration_data[31] << 4) + (p_calibration_data[30] >> 4); m_humidity_calibration[5] = p_calibration_data[32]; } + +/** + * @brief Convert raw data from sensor registers into corresponding unprocessed + * sensor values. + * + * @param p_raw_adc_data Pointer to raw data stream of 8 8-bit values. + */ +void CBME280::convertRawData(uint8_t const *const p_raw_adc_data) +{ + m_raw_pressure_data = p_raw_adc_data[0]; + m_raw_pressure_data = m_raw_pressure_data << 8; + m_raw_pressure_data += p_raw_adc_data[1]; + m_raw_pressure_data = m_raw_pressure_data << 4; + m_raw_pressure_data += p_raw_adc_data[2] >> 4; + + m_raw_temperature_data = p_raw_adc_data[0]; + m_raw_temperature_data = m_raw_temperature_data << 8; + m_raw_temperature_data += p_raw_adc_data[1]; + m_raw_temperature_data = m_raw_temperature_data << 4; + m_raw_temperature_data += p_raw_adc_data[2] >> 4; + + m_raw_humidity_data = p_raw_adc_data[6]; + m_raw_humidity_data = m_raw_humidity_data << 8; + m_raw_humidity_data += p_raw_adc_data[7]; +} From 59dfe1f2e8449c2b89c046ee64f4f069d3631627 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Mon, 25 Jul 2022 11:18:00 +0100 Subject: [PATCH 06/28] feature: add basic state machine to run sensor. --- Lib/Inc/CBME280.h | 15 +++++++-- Lib/Src/CBME280.cpp | 80 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index c4e5fa1e..4ce43578 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -20,6 +20,7 @@ #define T_CALIBRATION_SIZE 3 #define P_CALIBRATION_SIZE 9 #define H_CALIBRATION_SIZE 6 +#define RAW_ADC_DATA_SIZE 8 class CBME280 { @@ -67,6 +68,7 @@ class CBME280 virtual ~CBME280(); bool init(); + bool run(); /** * @brief Access processed temperature data. @@ -100,17 +102,26 @@ class CBME280 private: void calibrateSensor(uint8_t const *const p_calibration_data); - void convertRawData(uint8_t const *const p_raw_adc_data); + void convertRawData(); + bool startMeasument(); + void applyCalibration(); SPI_HandleTypeDef *mp_spi; CGpioWrapper m_slave_select; - bool mb_initialised; + enum STATES + { + INIT_PENDING = 0, + READY, + MEASURING, + NEW_DATA + } m_state; uint16_t m_temperature_calibration[T_CALIBRATION_SIZE]; uint16_t m_pressure_calibration[P_CALIBRATION_SIZE]; uint16_t m_humidity_calibration[H_CALIBRATION_SIZE]; + uint8_t m_raw_adc_data[RAW_ADC_DATA_SIZE]; uint32_t m_raw_temperature_data; uint32_t m_raw_pressure_data; uint32_t m_raw_humidity_data; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index 735327d5..a4dadb0b 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -40,7 +40,7 @@ CBME280::CBME280(SPI_HandleTypeDef *p_spi, uint16_t slave_select_pin) : mp_spi(p_spi), m_slave_select(p_slave_select_port, slave_select_pin), - mb_initialised(false) + m_state(INIT_PENDING) { if (mp_spi == nullptr) { @@ -63,7 +63,7 @@ CBME280::~CBME280() bool CBME280::init() { /* TODO: - * 1. Check SPI works. + * 1. Check SPI available. * 2. Read chip ID to verify comms to sensor works. * 3. Read calibration values and store in appropriate places. */ @@ -72,7 +72,7 @@ bool CBME280::init() // SPI with a mutex. if (HAL_SPI_GetState(mp_spi) != HAL_SPI_STATE_READY) { - Error_Handler(); + return false; } uint8_t register_address; /* Soft reset. */ @@ -123,10 +123,43 @@ bool CBME280::init() SPI_TIMEOUT_MS); m_slave_select.set(HIGH); calibrateSensor(calibration_register); - mb_initialised = true; return true; } +bool CBME280::run() +{ + bool b_new_data = false; + switch (m_state) + { + case INIT_PENDING: + if (init()) + { + m_state = READY; + } + break; + case READY: + // TODO: perhaps need to have some sort of timeout here to only run + // this at regular intervals. + if (startMeasument()) + { + m_state = MEASURING; + } + break; + case MEASURING: + // N.B. This state is a wait-state to allow class to know when it is + // busy waiting for SPI interrupt to fire. + break; + case NEW_DATA: + convertRawData(); + applyCalibration(); + b_new_data = true; + break; + default: + Error_Handler(); + } + return b_new_data; +} + /** * @brief Convert raw data from the sensor registers into usable calibration * values. @@ -172,21 +205,42 @@ void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) * * @param p_raw_adc_data Pointer to raw data stream of 8 8-bit values. */ -void CBME280::convertRawData(uint8_t const *const p_raw_adc_data) +void CBME280::convertRawData() { - m_raw_pressure_data = p_raw_adc_data[0]; + m_raw_pressure_data = m_raw_adc_data[0]; m_raw_pressure_data = m_raw_pressure_data << 8; - m_raw_pressure_data += p_raw_adc_data[1]; + m_raw_pressure_data += m_raw_adc_data[1]; m_raw_pressure_data = m_raw_pressure_data << 4; - m_raw_pressure_data += p_raw_adc_data[2] >> 4; + m_raw_pressure_data += m_raw_adc_data[2] >> 4; - m_raw_temperature_data = p_raw_adc_data[0]; + m_raw_temperature_data = m_raw_adc_data[0]; m_raw_temperature_data = m_raw_temperature_data << 8; - m_raw_temperature_data += p_raw_adc_data[1]; + m_raw_temperature_data += m_raw_adc_data[1]; m_raw_temperature_data = m_raw_temperature_data << 4; - m_raw_temperature_data += p_raw_adc_data[2] >> 4; + m_raw_temperature_data += m_raw_adc_data[2] >> 4; - m_raw_humidity_data = p_raw_adc_data[6]; + m_raw_humidity_data = m_raw_adc_data[6]; m_raw_humidity_data = m_raw_humidity_data << 8; - m_raw_humidity_data += p_raw_adc_data[7]; + m_raw_humidity_data += m_raw_adc_data[7]; } + +/** + * @brief Initiate measurement process. + * + * @return True if measurement started successfully. + */ +bool CBME280::startMeasument() +{ + if (HAL_SPI_GetState(mp_spi) != HAL_SPI_STATE_READY) + { + return false; + } + + return true; +} + +/** + * @brief Apply calibration to raw data. + * + */ +void CBME280::applyCalibration() {} From 65d9806c8793c7cc2e3185ee7a214e9798c88e96 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Mon, 25 Jul 2022 12:07:23 +0100 Subject: [PATCH 07/28] wip --- Lib/Inc/CBME280.h | 10 +++++++++- Lib/Src/CBME280.cpp | 22 ++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index 4ce43578..954c6505 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -21,6 +21,7 @@ #define P_CALIBRATION_SIZE 9 #define H_CALIBRATION_SIZE 6 #define RAW_ADC_DATA_SIZE 8 +#define MAX_SENSORS 2 class CBME280 { @@ -100,10 +101,15 @@ class CBME280 return m_humidity; }; + bool isMeasuring() const + { + return m_state == MEASURING; + } + private: void calibrateSensor(uint8_t const *const p_calibration_data); void convertRawData(); - bool startMeasument(); + bool startMeasurement(); void applyCalibration(); SPI_HandleTypeDef *mp_spi; @@ -117,6 +123,8 @@ class CBME280 NEW_DATA } m_state; + static CBME280* sp_sensors[] + uint16_t m_temperature_calibration[T_CALIBRATION_SIZE]; uint16_t m_pressure_calibration[P_CALIBRATION_SIZE]; uint16_t m_humidity_calibration[H_CALIBRATION_SIZE]; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index a4dadb0b..2ac42259 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -140,7 +140,7 @@ bool CBME280::run() case READY: // TODO: perhaps need to have some sort of timeout here to only run // this at regular intervals. - if (startMeasument()) + if (startMeasurement()) { m_state = MEASURING; } @@ -229,12 +229,24 @@ void CBME280::convertRawData() * * @return True if measurement started successfully. */ -bool CBME280::startMeasument() +bool CBME280::startMeasurement() { if (HAL_SPI_GetState(mp_spi) != HAL_SPI_STATE_READY) { return false; } + /* Configure SPI comms as required by the sensor. */ + // TODO: this type of channel sharing with different configurations should + // be handled by a wrapper class. It can also queue up traffic and call + // callback functions. + mp_spi->Init.CLKPolarity = SPI_POLARITY_HIGH; + mp_spi->Init.CLKPhase = SPI_PHASE_2EDGE; + mp_spi->Init.NSS = SPI_NSS_SOFT; + mp_spi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; + if (HAL_SPI_Init(&hspi2) != HAL_OK) + { + return false; + } return true; } @@ -244,3 +256,9 @@ bool CBME280::startMeasument() * */ void CBME280::applyCalibration() {} + +#ifdef __cplusplus +extern "C" +{ + void HAL_SPI_RxCpltCallback(hspi) {} +} From 0f2470169661ef68a76d77ae9d6a612da0a16ece Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Thu, 28 Jul 2022 13:38:45 +0100 Subject: [PATCH 08/28] wip. --- Lib/Inc/CBME280.h | 6 ++++-- Lib/Src/CBME280.cpp | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index 954c6505..e76a4bfa 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -21,7 +21,7 @@ #define P_CALIBRATION_SIZE 9 #define H_CALIBRATION_SIZE 6 #define RAW_ADC_DATA_SIZE 8 -#define MAX_SENSORS 2 +#define MAX_SENSORS 2 class CBME280 { @@ -111,6 +111,7 @@ class CBME280 void convertRawData(); bool startMeasurement(); void applyCalibration(); + void receiveNewData(); SPI_HandleTypeDef *mp_spi; CGpioWrapper m_slave_select; @@ -123,7 +124,8 @@ class CBME280 NEW_DATA } m_state; - static CBME280* sp_sensors[] + static CBME280 *sp_sensors[MAX_SENSORS]; + static uint8_t s_sensor_count; uint16_t m_temperature_calibration[T_CALIBRATION_SIZE]; uint16_t m_pressure_calibration[P_CALIBRATION_SIZE]; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index 2ac42259..e516c7f8 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -28,6 +28,10 @@ #define HIGH true #define LOW false +/* Static instance control variables. */ +CBME280 *CBME280::sp_sensors[] = {nullptr}; +uint8_t CBME280::s_sensor_count = 0; + /** * @brief Construct a sensor driver class instance. * @@ -47,6 +51,15 @@ CBME280::CBME280(SPI_HandleTypeDef *p_spi, Error_Handler(); } m_slave_select.set(true); + if (s_sensor_count < MAX_SENSORS) + { + sp_sensors[s_sensor_count] = this; + s_sensor_count++; + } + else + { + Error_handler(); + } } CBME280::~CBME280() @@ -260,5 +273,7 @@ void CBME280::applyCalibration() {} #ifdef __cplusplus extern "C" { - void HAL_SPI_RxCpltCallback(hspi) {} + void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {} } + +#endif From 65218ba78f5eb92fb71d9541c339594d98ba9086 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sat, 30 Jul 2022 10:32:43 +0100 Subject: [PATCH 09/28] feature: add ADC data receive functionality. --- Lib/Inc/CBME280.h | 3 ++- Lib/Src/CBME280.cpp | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index e76a4bfa..65f1d871 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -106,12 +106,13 @@ class CBME280 return m_state == MEASURING; } + static void processIrq(); + private: void calibrateSensor(uint8_t const *const p_calibration_data); void convertRawData(); bool startMeasurement(); void applyCalibration(); - void receiveNewData(); SPI_HandleTypeDef *mp_spi; CGpioWrapper m_slave_select; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index e516c7f8..8dc0d3fe 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -58,7 +58,7 @@ CBME280::CBME280(SPI_HandleTypeDef *p_spi, } else { - Error_handler(); + Error_Handler(); } } @@ -260,7 +260,15 @@ bool CBME280::startMeasurement() { return false; } - + m_raw_adc_data[0] = PRESS_MSB; + for (int i = 1; i < RAW_ADC_DATA_SIZE; i++) + { + m_raw_adc_data[i] = 0; + } + HAL_SPI_TransmitReceive_IT(mp_spi, + m_raw_adc_data, + m_raw_adc_data, + RAW_ADC_DATA_SIZE); return true; } @@ -270,10 +278,33 @@ bool CBME280::startMeasurement() */ void CBME280::applyCalibration() {} +/** + * @brief Process IRQ call for all registered and active sensors + * + */ +void CBME280::processIrq() +{ + uint8_t sensor = 0; + while ((sp_sensors[sensor] != nullptr) && sensor < s_sensor_count) + { + if (sp_sensors[sensor]->isMeasuring()) + { + sp_sensors[sensor]->m_state = NEW_DATA; + break; + } + sensor++; + } +} + +CBME280::processIrq(); + #ifdef __cplusplus extern "C" { - void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {} + void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) + { + CBME280::processIRQ(); + } } #endif From 661c56737289a66bb0250c5309496a730f4c833c Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sat, 30 Jul 2022 10:55:24 +0100 Subject: [PATCH 10/28] feature: enable IRQ for SPI2 engine. --- Core/Inc/stm32f4xx_it.h | 1 + Core/Src/spi.c | 5 +++++ Core/Src/stm32f4xx_it.c | 15 +++++++++++++++ Multichannel temperature sensor.ioc | 3 ++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Core/Inc/stm32f4xx_it.h b/Core/Inc/stm32f4xx_it.h index deb0aa40..902a5f97 100644 --- a/Core/Inc/stm32f4xx_it.h +++ b/Core/Inc/stm32f4xx_it.h @@ -55,6 +55,7 @@ void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); +void SPI2_IRQHandler(void); void USART1_IRQHandler(void); void USART2_IRQHandler(void); void DMA2_Stream0_IRQHandler(void); diff --git a/Core/Src/spi.c b/Core/Src/spi.c index 51b2da7a..2982ec6c 100644 --- a/Core/Src/spi.c +++ b/Core/Src/spi.c @@ -85,6 +85,9 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + /* SPI2 interrupt Init */ + HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(SPI2_IRQn); /* USER CODE BEGIN SPI2_MspInit 1 */ /* USER CODE END SPI2_MspInit 1 */ @@ -110,6 +113,8 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15); + /* SPI2 interrupt Deinit */ + HAL_NVIC_DisableIRQ(SPI2_IRQn); /* USER CODE BEGIN SPI2_MspDeInit 1 */ /* USER CODE END SPI2_MspDeInit 1 */ diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index 4aae7358..f093fd62 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -56,6 +56,7 @@ /* External variables --------------------------------------------------------*/ extern DMA_HandleTypeDef hdma_adc1; +extern SPI_HandleTypeDef hspi2; extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart2; /* USER CODE BEGIN EV */ @@ -200,6 +201,20 @@ void SysTick_Handler(void) /* please refer to the startup file (startup_stm32f4xx.s). */ /******************************************************************************/ +/** + * @brief This function handles SPI2 global interrupt. + */ +void SPI2_IRQHandler(void) +{ + /* USER CODE BEGIN SPI2_IRQn 0 */ + + /* USER CODE END SPI2_IRQn 0 */ + HAL_SPI_IRQHandler(&hspi2); + /* USER CODE BEGIN SPI2_IRQn 1 */ + + /* USER CODE END SPI2_IRQn 1 */ +} + /** * @brief This function handles USART1 global interrupt. */ diff --git a/Multichannel temperature sensor.ioc b/Multichannel temperature sensor.ioc index 0ac350fe..de1522cb 100644 --- a/Multichannel temperature sensor.ioc +++ b/Multichannel temperature sensor.ioc @@ -147,6 +147,7 @@ NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SPI2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true @@ -354,7 +355,7 @@ ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true -ProjectManager.LastFirmware=true +ProjectManager.LastFirmware=false ProjectManager.LibraryCopy=1 ProjectManager.MainLocation=Core/Src ProjectManager.MultiThreaded=true From e2600934970be1bdfded375f32f8a30e8c3e6fdb Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sat, 30 Jul 2022 10:56:20 +0100 Subject: [PATCH 11/28] feature: add IRQ callback via static method. --- Lib/Src/CBME280.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index 8dc0d3fe..b62a9de2 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -279,7 +279,7 @@ bool CBME280::startMeasurement() void CBME280::applyCalibration() {} /** - * @brief Process IRQ call for all registered and active sensors + * @brief Process IRQ call for all registered and active sensors. * */ void CBME280::processIrq() @@ -296,15 +296,7 @@ void CBME280::processIrq() } } -CBME280::processIrq(); - -#ifdef __cplusplus -extern "C" +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { - void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) - { - CBME280::processIRQ(); - } + CBME280::processIrq(); } - -#endif From b1a5ac6319845144805701dbfcad3e31d857f623 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sat, 30 Jul 2022 11:00:16 +0100 Subject: [PATCH 12/28] wip. --- Lib/Src/CBME280.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index b62a9de2..b836b941 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -136,6 +136,9 @@ bool CBME280::init() SPI_TIMEOUT_MS); m_slave_select.set(HIGH); calibrateSensor(calibration_register); + // TODO: sensor requires setting up. + // set operational mode. + // set oversampling modes for all three measurements. return true; } From 4254bc617bf2be226d4510b09c70276f0da31c76 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sun, 7 Aug 2022 11:21:34 +0100 Subject: [PATCH 13/28] feature: modify calibration from integer to float. --- Lib/Inc/CBME280.h | 6 +++--- Lib/Src/CBME280.cpp | 50 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index 65f1d871..3985928a 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -128,9 +128,9 @@ class CBME280 static CBME280 *sp_sensors[MAX_SENSORS]; static uint8_t s_sensor_count; - uint16_t m_temperature_calibration[T_CALIBRATION_SIZE]; - uint16_t m_pressure_calibration[P_CALIBRATION_SIZE]; - uint16_t m_humidity_calibration[H_CALIBRATION_SIZE]; + float m_temperature_calibration[T_CALIBRATION_SIZE]; + float m_pressure_calibration[P_CALIBRATION_SIZE]; + float m_humidity_calibration[H_CALIBRATION_SIZE]; uint8_t m_raw_adc_data[RAW_ADC_DATA_SIZE]; uint32_t m_raw_temperature_data; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index b836b941..89189bae 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -11,6 +11,7 @@ */ #include +#include #define BME280_ID 0x60 #define BMP280_ID 0x58 @@ -28,6 +29,25 @@ #define HIGH true #define LOW false +/* These values were extracted from BME280 calibration source code. The original + * calibration source code was intended for use with integers to allow its use + * on resource constrained MCUs. This code will run on MCU with floating point + * unit, so converting into float calibration increases dynamic range and make + * code much more readable and maintainable. + */ +constexpr float T_CALIB_CORRECTION[] = {1, 1 / 1024, 1 / sqrt(8092)}; +constexpr float P_CALIB_CORRECTION[] = {1 / 6250, + 1 / 524288 / 32768, + 1 / 524288 / 524288 / 32768, + 65536 / 4096, + 1 / 2 / 4096, + 1 / 32768 / 4 / 4096, + 1 / 16, + 1 / 32768 / 16, + 1 / 2147483648 / 16}; +constexpr float H_CALIB_CORRECTION[] = + {-1 / 524288, 1 / 65536, 1 / 67108864, -1 / 64, 1 / 16384, 1 / 67108864}; + /* Static instance control variables. */ CBME280 *CBME280::sp_sensors[] = {nullptr}; uint8_t CBME280::s_sensor_count = 0; @@ -185,16 +205,19 @@ bool CBME280::run() void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) { uint8_t const *p_runner = p_calibration_data; + uint32_t raw_calibration; for (int i = 0; i < T_CALIBRATION_SIZE; i++) { - m_temperature_calibration[i] = *p_runner; - m_temperature_calibration[i] |= *(++p_runner) << 8; + raw_calibration = m_temperature_calibration[i] = *p_runner; + raw_calibration |= *(++p_runner) << 8; + m_temperature_calibration[i] = raw_calibration * T_CALIB_CORRECTION[i]; ++p_runner; } for (int i = 0; i < P_CALIBRATION_SIZE; i++) { - m_pressure_calibration[i] = *p_runner; - m_pressure_calibration[i] |= *(++p_runner) << 8; + raw_calibration = *p_runner; + raw_calibration |= *(++p_runner) << 8; + m_pressure_calibration[i] = raw_calibration * P_CALIB_CORRECTION[i]; ++p_runner; } /* Humidity calibration data is spread around and is stored in a weird @@ -204,15 +227,20 @@ void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) /* I am certain the engineer at Bosch who came up with this had management * breathing down their neck. One day they stopped caring and made this * monstrocity.*/ - m_humidity_calibration[0] = p_calibration_data[25]; - m_humidity_calibration[1] = - (p_calibration_data[27] << 8) + p_calibration_data[26]; - m_humidity_calibration[2] = p_calibration_data[28]; - m_humidity_calibration[3] = + raw_calibration = p_calibration_data[25]; + m_humidity_calibration[0] = raw_calibration * H_CALIB_CORRECTION[0]; + raw_calibration = (p_calibration_data[27] << 8) + p_calibration_data[26]; + m_humidity_calibration[1] = raw_calibration * H_CALIB_CORRECTION[1]; + raw_calibration = p_calibration_data[28]; + m_humidity_calibration[2] = raw_calibration * H_CALIB_CORRECTION[2]; + raw_calibration = (p_calibration_data[29] << 4) + (p_calibration_data[30] & 0x0F); - m_humidity_calibration[4] = + m_humidity_calibration[3] = raw_calibration * H_CALIB_CORRECTION[3]; + raw_calibration = (p_calibration_data[31] << 4) + (p_calibration_data[30] >> 4); - m_humidity_calibration[5] = p_calibration_data[32]; + m_humidity_calibration[4] = raw_calibration * H_CALIB_CORRECTION[4]; + raw_calibration = p_calibration_data[32]; + m_humidity_calibration[5] = raw_calibration * H_CALIB_CORRECTION[5]; } /** From d37fde7d74be5a2a563f70c0f3ccb41a42aec4d2 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sun, 7 Aug 2022 12:16:00 +0100 Subject: [PATCH 14/28] feature: implement raw data calibration for T, P, and H measurements. --- Lib/Inc/CBME280.h | 5 ++- Lib/Src/CBME280.cpp | 87 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index 3985928a..76186f15 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -112,7 +112,9 @@ class CBME280 void calibrateSensor(uint8_t const *const p_calibration_data); void convertRawData(); bool startMeasurement(); - void applyCalibration(); + void calculateT(); + void calculateP(); + void calculateH(); SPI_HandleTypeDef *mp_spi; CGpioWrapper m_slave_select; @@ -137,6 +139,7 @@ class CBME280 uint32_t m_raw_pressure_data; uint32_t m_raw_humidity_data; + float m_t_fine; float m_temperature; float m_pressure; float m_humidity; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index 89189bae..7d26ce80 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -48,6 +48,11 @@ constexpr float P_CALIB_CORRECTION[] = {1 / 6250, constexpr float H_CALIB_CORRECTION[] = {-1 / 524288, 1 / 65536, 1 / 67108864, -1 / 64, 1 / 16384, 1 / 67108864}; +constexpr float T_SCALE_FACTOR = 1 / 5120; +constexpr float P_OFFSET_1 = 64000; +constexpr float P_OFFSET_2 = 1048576; +constexpr float H_OFFSET = 76800; + /* Static instance control variables. */ CBME280 *CBME280::sp_sensors[] = {nullptr}; uint8_t CBME280::s_sensor_count = 0; @@ -186,8 +191,12 @@ bool CBME280::run() // busy waiting for SPI interrupt to fire. break; case NEW_DATA: - convertRawData(); - applyCalibration(); + /* The sequence of these method calls must be preserved since + * temperature is used in pressure and humidity calculations. + * convertRawData();*/ + calculateT(); + calculateP(); + calculateH(); b_new_data = true; break; default: @@ -220,13 +229,13 @@ void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) m_pressure_calibration[i] = raw_calibration * P_CALIB_CORRECTION[i]; ++p_runner; } - /* Humidity calibration data is spread around and is stored in a weird - * convoluted way. See the manual. This recovery was copied with - * modifications from the Bosch github repository. + /* Humidity calibration data is spread around and is stored in a + * weird convoluted way. See the manual. This recovery was + * copied with modifications from the Bosch github repository. * https://github.com/BoschSensortec/BME280_driver */ - /* I am certain the engineer at Bosch who came up with this had management - * breathing down their neck. One day they stopped caring and made this - * monstrocity.*/ + /* I am certain the engineer at Bosch who came up with this had + * management breathing down their neck. One day they stopped + * caring and made this monstrocity.*/ raw_calibration = p_calibration_data[25]; m_humidity_calibration[0] = raw_calibration * H_CALIB_CORRECTION[0]; raw_calibration = (p_calibration_data[27] << 8) + p_calibration_data[26]; @@ -244,10 +253,11 @@ void CBME280::calibrateSensor(uint8_t const *const p_calibration_data) } /** - * @brief Convert raw data from sensor registers into corresponding unprocessed - * sensor values. + * @brief Convert raw data from sensor registers into corresponding + * unprocessed sensor values. * - * @param p_raw_adc_data Pointer to raw data stream of 8 8-bit values. + * @param p_raw_adc_data Pointer to raw data stream of 8 8-bit + * values. */ void CBME280::convertRawData() { @@ -280,9 +290,9 @@ bool CBME280::startMeasurement() return false; } /* Configure SPI comms as required by the sensor. */ - // TODO: this type of channel sharing with different configurations should - // be handled by a wrapper class. It can also queue up traffic and call - // callback functions. + // TODO: this type of channel sharing with different + // configurations should be handled by a wrapper class. It can + // also queue up traffic and call callback functions. mp_spi->Init.CLKPolarity = SPI_POLARITY_HIGH; mp_spi->Init.CLKPhase = SPI_PHASE_2EDGE; mp_spi->Init.NSS = SPI_NSS_SOFT; @@ -304,10 +314,55 @@ bool CBME280::startMeasurement() } /** - * @brief Apply calibration to raw data. + * @brief Apply temperature calibration to raw data. + * + */ +void CBME280::calculateT() +{ + float t; + t = (m_raw_temperature_data / 16 - m_temperature_calibration[0]); + m_t_fine = + t * m_temperature_calibration[1] + t * t * m_temperature_calibration[2]; + m_temperature = m_t_fine / T_SCALE_FACTOR; +} + +/** + * @brief Apply pressure calibration to raw data. * */ -void CBME280::applyCalibration() {} +void CBME280::calculateP() +{ + float t_p = m_t_fine / 2 - P_OFFSET_1; + float var_1 = m_pressure_calibration[3]; + var_1 += t_p * m_pressure_calibration[4]; + var_1 += t_p * t_p * m_pressure_calibration[5]; + float var_2 = 1; + var_2 += t_p * m_pressure_calibration[1]; + var_2 += t_p * t_p * m_pressure_calibration[2]; + var_2 *= m_pressure_calibration[0]; + float var_3 = P_OFFSET_2 - m_raw_pressure_data - var_1; + var_3 /= var_2; + m_pressure = m_pressure_calibration[6]; + m_pressure += var_3 * m_pressure_calibration[7]; + m_pressure += var_3 * var_3 * m_pressure_calibration[8]; +} + +/** + * @brief Apply humidity calibration to raw data. + * + */ +void CBME280::calculateH() +{ + float t_h = m_t_fine - H_OFFSET; + float var_1 = 1 + t_h * m_humidity_calibration[2]; + var_1 *= t_h * m_humidity_calibration[5]; + var_1 += 1; + var_1 *= m_humidity_calibration[1]; + var_1 *= m_raw_humidity_data + m_humidity_calibration[3] + + t_h * m_humidity_calibration[4]; + m_humidity = var_1; + m_humidity += var_1 * var_1 * m_humidity_calibration[0]; +} /** * @brief Process IRQ call for all registered and active sensors. From 53006bd81fa148b8e1b29f188a13aafac524cce4 Mon Sep 17 00:00:00 2001 From: samkno1 Date: Wed, 24 Aug 2022 01:18:21 -0300 Subject: [PATCH 15/28] central sensor version --- Controllers/CHumidityController.cpp | 264 ++++++++++++++++++++++++++++ Controllers/CHumidityController.h | 43 +++++ 2 files changed, 307 insertions(+) create mode 100644 Controllers/CHumidityController.cpp create mode 100644 Controllers/CHumidityController.h diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp new file mode 100644 index 00000000..3c018785 --- /dev/null +++ b/Controllers/CHumidityController.cpp @@ -0,0 +1,264 @@ +/* + * CHumidityController.cpp + * + * Created on: Aug. 11, 2022 + * Author: samk + */ + +#include "CHumidityController.h" +#include +#include "ICommand.h" +#include "IHardwareMap.h" +#include "CBME280.h" + +#define MIN_TEMPERATURE 10 +#define MAX_TEMPERATURE 50 +#define MIN_POWER 0 +#define MAX_POWER 100 +#define DISABLE_OVERRIDE -1 +#define DISABLE_TARGET 0 +#define MIN_HUMIDITY 85 +#define MAX_HUMIDITY 95 +//#define X_HEATERS_ON 4 +//#define X_HEATERS_OFF 4 + +/* + * Read relative humidity value + * If ideal, do nothing + * If below ideal, turn on heater + * If above ideal, turn off heater + */ + +CHumidityController::CHumidityController( + IHardwareMap *p_hardware, + etl::string name, + uint32_t run_period_ms) + : CController(name, run_period_ms), + mp_hw(p_hardware) +{ + // TODO Auto-generated constructor stub + reset(); +} + +/** + * @brief Run all repeated humidity control activities. + * + */ +void CHumidityController::run() +{ + float actual_humidity; + for (int i = 0; i < CHANNEL_NUMBER; i++) + { + float power = 0; + actual_humidity = hum_sensor->getHumidity(); + float actual_temperature = hum_sensor->getTemperature(); + if (m_power_override[i] == DISABLE_OVERRIDE && + target_humidity != DISABLE_TARGET) + { + if (actual_humidity != target_humidity) + { + if(actual_humidity < target_humidity) + { + power = m_control_loop[i].run(actual_temperature, + MIN_TEMPERATURE); + } + else + { + power = m_control_loop[i].run(actual_temperature, + MAX_TEMPERATURE); + } + } + else + { + break; + } + } + else + { + power = m_power_override[i]; + } + mp_hw->setHardPwmOutput(power, i); + } + while(actual_humidity != target_humidity){ + run(); + } +} + +bool CHumidityController::newCommand(ICommand *p_command, + IComChannel *p_comchannel) +{ + bool b_command_recognised = false; + ICommand::command_error_code_t result = ICommand::COMMAND_OK; + /** + * Query about current state of all active channels. + * + */ + if (p_command->getName()->compare("?humidity") == 0) + { + sendStatus(p_comchannel); + b_command_recognised = true; + } + + if (p_command->getName()->compare("humidity") == 0) + { + result = setHumidity(p_command); + b_command_recognised = true; + } + + if (p_command->getName()->compare("heater") == 0) + { + result = overrideHeater(p_command); + b_command_recognised = true; + } + if (b_command_recognised) + { + switch (result) + { + case ICommand::COMMAND_OK: + // p_comchannel->send("OK.\n"); + break; + case ICommand::ERROR_ARG_COUNT: + p_comchannel->send("Wrong number of arguments.\n"); + break; + case ICommand::ERROR_OUT_OF_BOUNDS: + p_comchannel->send("Argument out of bounds.\n"); + break; + case ICommand::ERROR_TYPE_MISMATCH: + p_comchannel->send("Argument type mismatch.\n"); + break; + default: + p_comchannel->send("Non-specific error with the command."); + } + } + return b_command_recognised; +} + +void CHumidityController::reset() +{ + for (int i = 0; i < CHANNEL_NUMBER; i++) + { + target_humidity = DISABLE_TARGET; + m_power_override[i] = DISABLE_OVERRIDE; + m_control_loop[i].reset(); + } +} + +void CHumidityController::sendStatus(IComChannel *p_comchannel){ + etl::string message; + char value[10]; + //send target humidity + message.assign("Target: "); + sprintf(value, "%2.1f", target_humidity); + message.append(value); + p_comchannel->send(message); + // Send actual humidity + message.assign("Humidity: "); + sprintf(value, "%2.1f, ", hum_sensor->getHumidity()); + message.append(value); + p_comchannel->send(message); + // Send heater power + message.assign("Power: "); + float power; + for (int i = 0; i < CHANNEL_NUMBER - 1; i++) + { + if (m_power_override[i] == DISABLE_OVERRIDE) + { + power = mp_hw->getHardPwmOutput(i); + } + else + { + power = m_power_override[i]; + } + sprintf(value, "%4.1f, ", power); + message.append(value); + } + if (m_power_override[CHANNEL_NUMBER - 1] == DISABLE_OVERRIDE) + { + power = mp_hw->getHardPwmOutput(CHANNEL_NUMBER - 1); + } + else + { + power = m_power_override[CHANNEL_NUMBER - 1]; + } + sprintf(value, "%4.1f\n", power); + message.append(value); + p_comchannel->send(message); +} + +/** + * @brief Set humidity value + */ +ICommand::command_error_code_t CHumidityController::setHumidity( + ICommand *p_command) +{ + // Sanitise command arguments + if ((p_command->getArgumentCount() < 1) || + (p_command->getArgumentCount() > 2)) + { + return ICommand::ERROR_ARG_COUNT; + } + target_humidity = (*p_command)[0]; + + if (target_humidity > MAX_HUMIDITY) + { + target_humidity = MAX_HUMIDITY; + } + if ((target_humidity < MIN_HUMIDITY) && (target_humidity != DISABLE_TARGET)) + { + target_humidity = MIN_HUMIDITY; + } + + return ICommand::COMMAND_OK; +} + +ICommand::command_error_code_t CHumidityController::overrideHeater( + ICommand *p_command) +{ + // Sanitise command arguments + if ((p_command->getArgumentCount() < 1) || + (p_command->getArgumentCount() > 2)) + { + return ICommand::ERROR_ARG_COUNT; + } + float power = (*p_command)[0]; + uint8_t channel = (uint8_t)(*p_command)[1]; + if (channel > CHANNEL_NUMBER) + { + return ICommand::ERROR_OUT_OF_BOUNDS; + } + if (p_command->getArgumentCount() == 1) + { + channel = 0; + } + else + { + // compare typecast value to original to find out if there is + // fraction. + if (channel != (*p_command)[1]) + { + return ICommand::ERROR_TYPE_MISMATCH; + } + } + // Execute command + if (power > MAX_POWER) + { + power = MAX_POWER; + } + if ((power < MIN_POWER) && (power != DISABLE_OVERRIDE)) + { + power = MIN_POWER; + } + if (channel == 0) + { + for (int i = 0; i < CHANNEL_NUMBER; i++) + { + m_power_override[i] = power; + } + } + else + { + m_power_override[channel - 1] = power; + } + return ICommand::COMMAND_OK; +} + diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h new file mode 100644 index 00000000..c9a64bf2 --- /dev/null +++ b/Controllers/CHumidityController.h @@ -0,0 +1,43 @@ +/* + * CHumidityController.h + * + * Created on: Aug. 11, 2022 + * Author: samk + */ + +#ifndef CHUMIDITYCONTROLLER_H_ +#define CHUMIDITYCONTROLLER_H_ + +#include "CController.h" +#include "CPIDLoop.h" +#include "IHardwareMap.h" +#include "CBME280.h" +#include "main.h" + +#define CHANNEL_NUMBER 8 + +class CHumidityController : public CController +{ +public: + CHumidityController(IHardwareMap *p_hardwaremap, + etl::string name, + uint32_t run_period_ms); + virtual void run(); + virtual bool newCommand(ICommand *p_command, IComChannel *p_comchannel); + virtual void reset(); + +private: + void sendStatus(IComChannel *p_comchannel); + ICommand::command_error_code_t setHumidity(ICommand *p_command); + ICommand::command_error_code_t overrideHeater(ICommand *p_command); + + IHardwareMap *mp_hw; + CBME280 *hum_sensor; + + float target_humidity; + float m_power_override[CHANNEL_NUMBER]; + CPIDLoop m_control_loop[CHANNEL_NUMBER]; +}; + + +#endif /* CHUMIDITYCONTROLLER_H_ */ From 7da5c58a519c00a977019fc55e55abc8d6a2f3e8 Mon Sep 17 00:00:00 2001 From: samkno1 Date: Wed, 24 Aug 2022 01:53:41 -0300 Subject: [PATCH 16/28] feature: humidity controller setup --- Controllers/CHumidityController.cpp | 9 --------- Controllers/CHumidityController.h | 2 ++ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index 3c018785..bb8a5897 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -19,15 +19,6 @@ #define DISABLE_TARGET 0 #define MIN_HUMIDITY 85 #define MAX_HUMIDITY 95 -//#define X_HEATERS_ON 4 -//#define X_HEATERS_OFF 4 - -/* - * Read relative humidity value - * If ideal, do nothing - * If below ideal, turn on heater - * If above ideal, turn off heater - */ CHumidityController::CHumidityController( IHardwareMap *p_hardware, diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h index c9a64bf2..dc6043fb 100644 --- a/Controllers/CHumidityController.h +++ b/Controllers/CHumidityController.h @@ -32,6 +32,8 @@ class CHumidityController : public CController ICommand::command_error_code_t overrideHeater(ICommand *p_command); IHardwareMap *mp_hw; + + // TODO Instantiate BME280 class? CBME280 *hum_sensor; float target_humidity; From c28330bfce60357ef2d7e3b20622ca84b2ed1128 Mon Sep 17 00:00:00 2001 From: samkno1 Date: Sun, 28 Aug 2022 17:50:31 -0300 Subject: [PATCH 17/28] feature: humidity controller --- Controllers/CHumidityController.cpp | 154 +++++++++++++++------------- Controllers/CHumidityController.h | 30 +++--- 2 files changed, 95 insertions(+), 89 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index bb8a5897..a4f7349a 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -7,9 +7,9 @@ #include "CHumidityController.h" #include +#include "CBME280.h" #include "ICommand.h" #include "IHardwareMap.h" -#include "CBME280.h" #define MIN_TEMPERATURE 10 #define MAX_TEMPERATURE 50 @@ -17,18 +17,23 @@ #define MAX_POWER 100 #define DISABLE_OVERRIDE -1 #define DISABLE_TARGET 0 -#define MIN_HUMIDITY 85 -#define MAX_HUMIDITY 95 +#define MIN_HUMIDITY 85 +#define MAX_HUMIDITY 95 -CHumidityController::CHumidityController( - IHardwareMap *p_hardware, - etl::string name, - uint32_t run_period_ms) - : CController(name, run_period_ms), - mp_hw(p_hardware) +CHumidityController::CHumidityController(IHardwareMap *p_hardware, + etl::string name, + uint32_t run_period_ms, + SPI_HandleTypeDef *p_spi, + GPIO_TypeDef *p_slave_select_port, + uint16_t slave_select_pin) + : CController(name, run_period_ms), + mp_hw(p_hardware) { - // TODO Auto-generated constructor stub - reset(); + // TODO Auto-generated constructor stub + reset(); + + CBME280 hum_temp_reader(p_spi, p_slave_select_port, slave_select_pin); + hum_sensor = &hum_temp_reader; } /** @@ -37,53 +42,54 @@ CHumidityController::CHumidityController( */ void CHumidityController::run() { - float actual_humidity; - for (int i = 0; i < CHANNEL_NUMBER; i++) - { - float power = 0; - actual_humidity = hum_sensor->getHumidity(); - float actual_temperature = hum_sensor->getTemperature(); - if (m_power_override[i] == DISABLE_OVERRIDE && - target_humidity != DISABLE_TARGET) - { - if (actual_humidity != target_humidity) - { - if(actual_humidity < target_humidity) - { - power = m_control_loop[i].run(actual_temperature, - MIN_TEMPERATURE); - } - else - { - power = m_control_loop[i].run(actual_temperature, - MAX_TEMPERATURE); - } - } - else - { - break; - } - } - else - { - power = m_power_override[i]; - } - mp_hw->setHardPwmOutput(power, i); - } - while(actual_humidity != target_humidity){ - run(); - } + float actual_humidity; + for (int i = 0; i < CHANNEL_NUMBER; i++) + { + float power = 0; + actual_humidity = hum_sensor->getHumidity(); + float actual_temperature = hum_sensor->getTemperature(); + if (m_power_override[i] == DISABLE_OVERRIDE && + target_humidity != DISABLE_TARGET) + { + if (actual_humidity != target_humidity) + { + if (actual_humidity < target_humidity) + { + power = m_control_loop[i].run(actual_temperature, + MIN_TEMPERATURE); + } + else + { + power = m_control_loop[i].run(actual_temperature, + MAX_TEMPERATURE); + } + } + else + { + break; + } + } + else + { + power = m_power_override[i]; + } + mp_hw->setHardPwmOutput(power, i); + } + while (actual_humidity != target_humidity) + { + run(); + } } bool CHumidityController::newCommand(ICommand *p_command, - IComChannel *p_comchannel) + IComChannel *p_comchannel) { - bool b_command_recognised = false; - ICommand::command_error_code_t result = ICommand::COMMAND_OK; - /** - * Query about current state of all active channels. - * - */ + bool b_command_recognised = false; + ICommand::command_error_code_t result = ICommand::COMMAND_OK; + /** + * Query about current state of all active channels. + * + */ if (p_command->getName()->compare("?humidity") == 0) { sendStatus(p_comchannel); @@ -91,10 +97,10 @@ bool CHumidityController::newCommand(ICommand *p_command, } if (p_command->getName()->compare("humidity") == 0) - { - result = setHumidity(p_command); - b_command_recognised = true; - } + { + result = setHumidity(p_command); + b_command_recognised = true; + } if (p_command->getName()->compare("heater") == 0) { @@ -126,18 +132,19 @@ bool CHumidityController::newCommand(ICommand *p_command, void CHumidityController::reset() { - for (int i = 0; i < CHANNEL_NUMBER; i++) - { - target_humidity = DISABLE_TARGET; - m_power_override[i] = DISABLE_OVERRIDE; - m_control_loop[i].reset(); - } + for (int i = 0; i < CHANNEL_NUMBER; i++) + { + target_humidity = DISABLE_TARGET; + m_power_override[i] = DISABLE_OVERRIDE; + m_control_loop[i].reset(); + } } -void CHumidityController::sendStatus(IComChannel *p_comchannel){ +void CHumidityController::sendStatus(IComChannel *p_comchannel) +{ etl::string message; char value[10]; - //send target humidity + // send target humidity message.assign("Target: "); sprintf(value, "%2.1f", target_humidity); message.append(value); @@ -182,13 +189,13 @@ void CHumidityController::sendStatus(IComChannel *p_comchannel){ ICommand::command_error_code_t CHumidityController::setHumidity( ICommand *p_command) { - // Sanitise command arguments - if ((p_command->getArgumentCount() < 1) || - (p_command->getArgumentCount() > 2)) - { - return ICommand::ERROR_ARG_COUNT; - } - target_humidity = (*p_command)[0]; + // Sanitise command arguments + if ((p_command->getArgumentCount() < 1) || + (p_command->getArgumentCount() > 2)) + { + return ICommand::ERROR_ARG_COUNT; + } + target_humidity = (*p_command)[0]; if (target_humidity > MAX_HUMIDITY) { @@ -252,4 +259,3 @@ ICommand::command_error_code_t CHumidityController::overrideHeater( } return ICommand::COMMAND_OK; } - diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h index dc6043fb..7569636a 100644 --- a/Controllers/CHumidityController.h +++ b/Controllers/CHumidityController.h @@ -8,38 +8,38 @@ #ifndef CHUMIDITYCONTROLLER_H_ #define CHUMIDITYCONTROLLER_H_ +#include "CBME280.h" #include "CController.h" #include "CPIDLoop.h" #include "IHardwareMap.h" -#include "CBME280.h" -#include "main.h" #define CHANNEL_NUMBER 8 class CHumidityController : public CController { public: - CHumidityController(IHardwareMap *p_hardwaremap, - etl::string name, - uint32_t run_period_ms); - virtual void run(); - virtual bool newCommand(ICommand *p_command, IComChannel *p_comchannel); - virtual void reset(); + CHumidityController(IHardwareMap *p_hardwaremap, + etl::string name, + uint32_t run_period_ms, + SPI_HandleTypeDef *p_spi, + GPIO_TypeDef *p_slave_select_port, + uint16_t slave_select_pin); + virtual void run(); + virtual bool newCommand(ICommand *p_command, IComChannel *p_comchannel); + virtual void reset(); private: - void sendStatus(IComChannel *p_comchannel); - ICommand::command_error_code_t setHumidity(ICommand *p_command); - ICommand::command_error_code_t overrideHeater(ICommand *p_command); + void sendStatus(IComChannel *p_comchannel); + ICommand::command_error_code_t setHumidity(ICommand *p_command); + ICommand::command_error_code_t overrideHeater(ICommand *p_command); - IHardwareMap *mp_hw; + IHardwareMap *mp_hw; - // TODO Instantiate BME280 class? - CBME280 *hum_sensor; + CBME280 *hum_sensor; float target_humidity; float m_power_override[CHANNEL_NUMBER]; CPIDLoop m_control_loop[CHANNEL_NUMBER]; }; - #endif /* CHUMIDITYCONTROLLER_H_ */ From b9f5c7586f1414f76d67a36009ef6957cff1c88a Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Fri, 30 Sep 2022 11:58:23 -0300 Subject: [PATCH 18/28] WIP: Humidity controller --- Controllers/CHumidityController.cpp | 125 +++++++--------------------- Controllers/CHumidityController.h | 10 +-- 2 files changed, 36 insertions(+), 99 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index a4f7349a..9b8d6de1 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -32,8 +32,8 @@ CHumidityController::CHumidityController(IHardwareMap *p_hardware, // TODO Auto-generated constructor stub reset(); - CBME280 hum_temp_reader(p_spi, p_slave_select_port, slave_select_pin); - hum_sensor = &hum_temp_reader; + CBME280 humidity_sensor(p_spi, p_slave_select_port, slave_select_pin); + mp_humidity_sensor = &humidity_sensor; } /** @@ -42,43 +42,24 @@ CHumidityController::CHumidityController(IHardwareMap *p_hardware, */ void CHumidityController::run() { - float actual_humidity; - for (int i = 0; i < CHANNEL_NUMBER; i++) + float power = 0; + if (m_power_override == DISABLE_OVERRIDE) { - float power = 0; - actual_humidity = hum_sensor->getHumidity(); - float actual_temperature = hum_sensor->getTemperature(); - if (m_power_override[i] == DISABLE_OVERRIDE && - target_humidity != DISABLE_TARGET) + if (m_target_humidity != DISABLE_TARGET) { - if (actual_humidity != target_humidity) + float actual_humidity = mp_humidity_sensor->getHumidity(); + if ((MIN_HUMIDITY <= actual_humidity) && + (actual_humidity <= MAX_humidity)) { - if (actual_humidity < target_humidity) - { - power = m_control_loop[i].run(actual_temperature, - MIN_TEMPERATURE); - } - else - { - power = m_control_loop[i].run(actual_temperature, - MAX_TEMPERATURE); - } + power = m_control_loop.run(m_target_humidity, actual_humidity); } - else - { - break; - } - } - else - { - power = m_power_override[i]; } - mp_hw->setHardPwmOutput(power, i); } - while (actual_humidity != target_humidity) + else { - run(); + power = m_power_override; } + mp_hw->setHardPwmOutput(power, CHANNEL_NUMBER - 1); } bool CHumidityController::newCommand(ICommand *p_command, @@ -132,12 +113,9 @@ bool CHumidityController::newCommand(ICommand *p_command, void CHumidityController::reset() { - for (int i = 0; i < CHANNEL_NUMBER; i++) - { - target_humidity = DISABLE_TARGET; - m_power_override[i] = DISABLE_OVERRIDE; - m_control_loop[i].reset(); - } + m_target_humidity = DISABLE_TARGET; + m_power_override = DISABLE_OVERRIDE; + m_control_loop.reset(); } void CHumidityController::sendStatus(IComChannel *p_comchannel) @@ -146,39 +124,26 @@ void CHumidityController::sendStatus(IComChannel *p_comchannel) char value[10]; // send target humidity message.assign("Target: "); - sprintf(value, "%2.1f", target_humidity); + sprintf(value, "%2.1f", m_target_humidity); message.append(value); p_comchannel->send(message); // Send actual humidity message.assign("Humidity: "); - sprintf(value, "%2.1f, ", hum_sensor->getHumidity()); + sprintf(value, "%2.1f, ", m_humidity_sensor->getHumidity()); message.append(value); p_comchannel->send(message); // Send heater power message.assign("Power: "); float power; - for (int i = 0; i < CHANNEL_NUMBER - 1; i++) - { - if (m_power_override[i] == DISABLE_OVERRIDE) - { - power = mp_hw->getHardPwmOutput(i); - } - else - { - power = m_power_override[i]; - } - sprintf(value, "%4.1f, ", power); - message.append(value); - } - if (m_power_override[CHANNEL_NUMBER - 1] == DISABLE_OVERRIDE) + if (m_power_override == DISABLE_OVERRIDE) { power = mp_hw->getHardPwmOutput(CHANNEL_NUMBER - 1); } else { - power = m_power_override[CHANNEL_NUMBER - 1]; + power = m_power_override; } - sprintf(value, "%4.1f\n", power); + sprintf(value, "%4.1f, ", power); message.append(value); p_comchannel->send(message); } @@ -190,20 +155,20 @@ ICommand::command_error_code_t CHumidityController::setHumidity( ICommand *p_command) { // Sanitise command arguments - if ((p_command->getArgumentCount() < 1) || - (p_command->getArgumentCount() > 2)) + if (p_command->getArgumentCount != 1) { return ICommand::ERROR_ARG_COUNT; } - target_humidity = (*p_command)[0]; + m_target_humidity = *p_command; - if (target_humidity > MAX_HUMIDITY) + if (m_target_humidity > MAX_HUMIDITY) { - target_humidity = MAX_HUMIDITY; + m_target_humidity = MAX_HUMIDITY; } - if ((target_humidity < MIN_HUMIDITY) && (target_humidity != DISABLE_TARGET)) + if ((m_target_humidity < MIN_HUMIDITY) && + (m_target_humidity != DISABLE_TARGET)) { - target_humidity = MIN_HUMIDITY; + m_target_humidity = MIN_HUMIDITY; } return ICommand::COMMAND_OK; @@ -213,30 +178,12 @@ ICommand::command_error_code_t CHumidityController::overrideHeater( ICommand *p_command) { // Sanitise command arguments - if ((p_command->getArgumentCount() < 1) || - (p_command->getArgumentCount() > 2)) + if (p_command->getArgumentCount() != 1) { return ICommand::ERROR_ARG_COUNT; } - float power = (*p_command)[0]; - uint8_t channel = (uint8_t)(*p_command)[1]; - if (channel > CHANNEL_NUMBER) - { - return ICommand::ERROR_OUT_OF_BOUNDS; - } - if (p_command->getArgumentCount() == 1) - { - channel = 0; - } - else - { - // compare typecast value to original to find out if there is - // fraction. - if (channel != (*p_command)[1]) - { - return ICommand::ERROR_TYPE_MISMATCH; - } - } + float power = *p_command; + // Execute command if (power > MAX_POWER) { @@ -246,16 +193,6 @@ ICommand::command_error_code_t CHumidityController::overrideHeater( { power = MIN_POWER; } - if (channel == 0) - { - for (int i = 0; i < CHANNEL_NUMBER; i++) - { - m_power_override[i] = power; - } - } - else - { - m_power_override[channel - 1] = power; - } + m_power_override = power; return ICommand::COMMAND_OK; } diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h index 7569636a..0a2021b7 100644 --- a/Controllers/CHumidityController.h +++ b/Controllers/CHumidityController.h @@ -13,7 +13,7 @@ #include "CPIDLoop.h" #include "IHardwareMap.h" -#define CHANNEL_NUMBER 8 +#define CHANNEL_NUMBER 1 class CHumidityController : public CController { @@ -35,11 +35,11 @@ class CHumidityController : public CController IHardwareMap *mp_hw; - CBME280 *hum_sensor; + CBME280 *m_humidity_sensor; - float target_humidity; - float m_power_override[CHANNEL_NUMBER]; - CPIDLoop m_control_loop[CHANNEL_NUMBER]; + float m_target_humidity; + float m_power_override; + CPIDLoop m_control_loop; }; #endif /* CHUMIDITYCONTROLLER_H_ */ From 7541937c40779793902f5f708a9f98faf24e00a5 Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sun, 2 Oct 2022 13:12:13 +0100 Subject: [PATCH 19/28] feature: add humidifier interface methods to the hardware maps. --- Hardware/CMockHardwareMap.cpp | 5 +++++ Hardware/CMockHardwareMap.h | 1 + Hardware/CRealHardwareMap.cpp | 5 +++++ Hardware/CRealHardwareMap.h | 1 + Hardware/IHardwareMap.h | 9 ++++++++- 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Hardware/CMockHardwareMap.cpp b/Hardware/CMockHardwareMap.cpp index 9d17f32f..976753f1 100644 --- a/Hardware/CMockHardwareMap.cpp +++ b/Hardware/CMockHardwareMap.cpp @@ -115,6 +115,11 @@ void CMockHardwareMap::enableControlPower(bool b_enable) mb_power_enable = b_enable; } +void CMockHardwareMap::setHumidifierPower(float power) +{ + // TODO: This should modify internal model variables for humidity. +} + void CMockHardwareMap::run() { float total_radiator_flow = 0; diff --git a/Hardware/CMockHardwareMap.h b/Hardware/CMockHardwareMap.h index d280619b..9481f793 100644 --- a/Hardware/CMockHardwareMap.h +++ b/Hardware/CMockHardwareMap.h @@ -34,6 +34,7 @@ class CMockHardwareMap : public IHardwareMap, public CController #endif virtual void setBreathingLight(float duty_cycle); virtual void enableControlPower(bool b_enable); + virtual void setHumidifierPower(float power); /* CController methods. */ // etl::string getName() const; // virtual bool tick(uint32_t current_time); diff --git a/Hardware/CRealHardwareMap.cpp b/Hardware/CRealHardwareMap.cpp index 4a16f8bf..84d3d681 100644 --- a/Hardware/CRealHardwareMap.cpp +++ b/Hardware/CRealHardwareMap.cpp @@ -167,3 +167,8 @@ void CRealHardwareMap::enableControlPower(bool b_enable) { m_power_enable.set(b_enable); } + +void CRealHardwareMap::setHumidifierPower(float power) +{ + // TODO: here be implementation of the power interface. +} diff --git a/Hardware/CRealHardwareMap.h b/Hardware/CRealHardwareMap.h index 75856b15..2fdad159 100644 --- a/Hardware/CRealHardwareMap.h +++ b/Hardware/CRealHardwareMap.h @@ -40,6 +40,7 @@ class CRealHardwareMap : public IHardwareMap #endif virtual void setBreathingLight(float duty_cycle); virtual void enableControlPower(bool b_enable); + virtual void setHumidifierPower(float power); private: typedef struct TIMER_INIT_MAP_T diff --git a/Hardware/IHardwareMap.h b/Hardware/IHardwareMap.h index e2675438..0fe27156 100644 --- a/Hardware/IHardwareMap.h +++ b/Hardware/IHardwareMap.h @@ -19,7 +19,7 @@ /** * @note Declare this value to the number of soft PWM outputs that are needed. */ -//#define SOFT_PWM_OUTPUTS 0 +// #define SOFT_PWM_OUTPUTS 0 class IHardwareMap { @@ -117,6 +117,13 @@ class IHardwareMap * @param b_enable Set to true to enable, false to disable. */ virtual void enableControlPower(bool b_enable) = 0; + /** + * @brief Set power to the humidifier. This controls either boiler power or + * ultrasonic atomiser depending on exact hardware implementation. + * + * @param power Value in percent between 0 and 100. + */ + virtual void setHumidifierPower(float power) = 0; }; #endif /* IHARDWAREMAP_H_ */ From fd3b55ffc66d2416edaad2f973e1711c3292be5d Mon Sep 17 00:00:00 2001 From: Salavat Magazov Date: Sun, 2 Oct 2022 13:56:26 +0100 Subject: [PATCH 20/28] feature: add real hardware map implementation of the humidifier. --- Hardware/CRealHardwareMap.cpp | 27 +++++++++++++++++++++++++-- Hardware/CRealHardwareMap.h | 1 + 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Hardware/CRealHardwareMap.cpp b/Hardware/CRealHardwareMap.cpp index 84d3d681..3a93ade1 100644 --- a/Hardware/CRealHardwareMap.cpp +++ b/Hardware/CRealHardwareMap.cpp @@ -33,6 +33,12 @@ #define AD22100_SCALE ((V_REF / 5.0) * (1 / 22.5E-3)) #define AD22100_OFFSET ((V_REF / 5.0) * (-1.375 / 22.5E-3)) +/* This section maps generic names of the pins to something that makes sense. + * We'll do it this way for now until hardware configuration settles down at + * which point the pin names will be renamed. */ +#define EVAPORATOR_GPIO_Port ENABLE_8_GPIO_Port +#define EVAPORATOR_Pin ENABLE_8_Pin + const CRealHardwareMap::timer_init_map_t CRealHardwareMap::s_timer_init_map[] = {{&htim1, TIM_CHANNEL_1}, {&htim4, TIM_CHANNEL_1}, @@ -76,7 +82,8 @@ void CRealHardwareMap::init() s_gpio_init_map[i].pin); } m_breathing_light.init(&htim2, TIM_CHANNEL_1); - m_power_enable.init(BREATHING_GPIO_Port, BREATHING_Pin); + m_power_enable.init(PWR_EN_GPIO_Port, PWR_EN_Pin); + m_humidifier_enable.init(EVAPORATOR_GPIO_Port, EVAPORATOR_Pin); } /** @@ -168,7 +175,23 @@ void CRealHardwareMap::enableControlPower(bool b_enable) m_power_enable.set(b_enable); } +/** + * @brief This assumes that the humidifier is implemented as an atomiser. + * @note The longer the atomiser is enabled the more vapour it'll generate. This + * way PID control is still possible, but care should be taken to not set + * integral component too high since atomiser itself will work as an integrator. + * + * @param power Is essentially a boolean value. Anything above zero enables + * atomiser. + */ void CRealHardwareMap::setHumidifierPower(float power) { - // TODO: here be implementation of the power interface. + if (power > 0) + { + m_humidifier_enable.set(true); + } + else + { + m_humidifier_enable.set(false); + } } diff --git a/Hardware/CRealHardwareMap.h b/Hardware/CRealHardwareMap.h index 2fdad159..6a7fff5a 100644 --- a/Hardware/CRealHardwareMap.h +++ b/Hardware/CRealHardwareMap.h @@ -61,6 +61,7 @@ class CRealHardwareMap : public IHardwareMap CGpioWrapper m_polarity_switch[HARD_PWM_OUTPUTS]; CHardPwmOutput m_breathing_light; CGpioWrapper m_power_enable; + CGpioWrapper m_humidifier_enable; #ifdef SOFT_PWM_OUTPUTS CSoftPwmOutput m_soft_pwm_output[SOFT_PWM_OUTPUTS]; #endif From eabb57302d26afd1a3bb455a8dd7b205b59027cb Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Sun, 16 Oct 2022 09:45:33 -0300 Subject: [PATCH 21/28] Implemented with 1 channel and humidifier abstracted by Hardware Map classes --- Controllers/CHumidityController.cpp | 7 +++-- Controllers/CHumidityController.h | 1 + Lib/Inc/CHumidifier.h | 27 ++++++++++++++++++ Lib/Src/CHumidifier.cpp | 43 +++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 Lib/Inc/CHumidifier.h create mode 100644 Lib/Src/CHumidifier.cpp diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index 9b8d6de1..655c4174 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -8,6 +8,7 @@ #include "CHumidityController.h" #include #include "CBME280.h" +#include "CHumidifier.h" #include "ICommand.h" #include "IHardwareMap.h" @@ -33,7 +34,7 @@ CHumidityController::CHumidityController(IHardwareMap *p_hardware, reset(); CBME280 humidity_sensor(p_spi, p_slave_select_port, slave_select_pin); - mp_humidity_sensor = &humidity_sensor; + m_humidity_sensor = &humidity_sensor; } /** @@ -59,7 +60,7 @@ void CHumidityController::run() { power = m_power_override; } - mp_hw->setHardPwmOutput(power, CHANNEL_NUMBER - 1); + mp_hw->setHumidifierPower(power); } bool CHumidityController::newCommand(ICommand *p_command, @@ -174,7 +175,7 @@ ICommand::command_error_code_t CHumidityController::setHumidity( return ICommand::COMMAND_OK; } -ICommand::command_error_code_t CHumidityController::overrideHeater( +ICommand::command_error_code_t CHumidityController::overrideHumidifier( ICommand *p_command) { // Sanitise command arguments diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h index 0a2021b7..6574653b 100644 --- a/Controllers/CHumidityController.h +++ b/Controllers/CHumidityController.h @@ -10,6 +10,7 @@ #include "CBME280.h" #include "CController.h" +#include "CHumidifier.h" #include "CPIDLoop.h" #include "IHardwareMap.h" diff --git a/Lib/Inc/CHumidifier.h b/Lib/Inc/CHumidifier.h new file mode 100644 index 00000000..12530d2c --- /dev/null +++ b/Lib/Inc/CHumidifier.h @@ -0,0 +1,27 @@ +/** + * @file CHumidifier.h + * + */ + +/* + * CHumidifier.h + * + * Created on: 26 Sep 2022 + * Author: salavat.magazov + */ + +#ifndef CHUMIDIFIER_H_ +#define CHUMIDIFIER_H_ + +class CHumidifier +{ +public: + CHumidifier(); + virtual ~CHumidifier(); + + void run(); + + void addVapour(float quantity); +}; + +#endif /* CHUMIDIFIER_H_ */ diff --git a/Lib/Src/CHumidifier.cpp b/Lib/Src/CHumidifier.cpp new file mode 100644 index 00000000..d31a1ba1 --- /dev/null +++ b/Lib/Src/CHumidifier.cpp @@ -0,0 +1,43 @@ +/** + * @file CHumidifier.cpp + * + */ + +/* + * CHumidifier.cpp + * + * Created on: 26 Sep 2022 + * Author: salavat.magazov + */ + +#include "CHumidifier.h" + +CHumidifier::CHumidifier() +{ + // TODO Auto-generated constructor stub +} + +CHumidifier::~CHumidifier() +{ + // TODO Auto-generated destructor stub +} + +/** + * @brief Maintenance routine that monitors the humidifier operation and adjusts + * behaviour as necessary. + * + */ +void CHumidifier::run() {} + +/** + * @brief Add some quantity of vapour to the system. + * + * @param quantity Amount of vapour that is required. + * + * @note At this point it is unclear how the humidifier will work, so quantity + * is somewhat ill-defined. + */ +void CHumidifier::addVapour(float quantity) +{ + return; +} From b829813abf3781e7cdbbbd89106f11ec2d506e51 Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Sun, 16 Oct 2022 09:55:13 -0300 Subject: [PATCH 22/28] Fixed commenting --- Controllers/CHumidityController.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index 655c4174..af630bc9 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -68,10 +68,6 @@ bool CHumidityController::newCommand(ICommand *p_command, { bool b_command_recognised = false; ICommand::command_error_code_t result = ICommand::COMMAND_OK; - /** - * Query about current state of all active channels. - * - */ if (p_command->getName()->compare("?humidity") == 0) { sendStatus(p_comchannel); From 8d051b06df5ca015b5564a66a003f993da8ea7f8 Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Tue, 27 Dec 2022 20:11:06 -0400 Subject: [PATCH 23/28] fix: Early SPI initialization error --- Lib/Inc/CBME280.h | 9 +++++---- Lib/Src/CBME280.cpp | 38 +++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Lib/Inc/CBME280.h b/Lib/Inc/CBME280.h index 76186f15..99902802 100644 --- a/Lib/Inc/CBME280.h +++ b/Lib/Inc/CBME280.h @@ -63,12 +63,12 @@ class CBME280 }; public: - CBME280(SPI_HandleTypeDef *p_spi, - GPIO_TypeDef *p_slave_select_port, - uint16_t slave_select_pin); + CBME280(); virtual ~CBME280(); - bool init(); + bool init(SPI_HandleTypeDef *p_spi, + GPIO_TypeDef *p_slave_select_port, + uint16_t slave_select_pin); bool run(); /** @@ -115,6 +115,7 @@ class CBME280 void calculateT(); void calculateP(); void calculateH(); + bool init(); SPI_HandleTypeDef *mp_spi; CGpioWrapper m_slave_select; diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index 7d26ce80..89b7aefc 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -60,20 +60,30 @@ uint8_t CBME280::s_sensor_count = 0; /** * @brief Construct a sensor driver class instance. * + */ +CBME280::CBME280() : m_state(INIT_PENDING) {} + +CBME280::~CBME280() +{ + // TODO Auto-generated destructor stub +} +/** + * @brief Begin sensor initialization + * * @param p_spi Pointer to HAL handler for SPI channel. * @param p_slave_select_port Pointer to GPIO port for SS pin. * @param slave_select_pin Mask of the SS pin. + * @return */ -CBME280::CBME280(SPI_HandleTypeDef *p_spi, - GPIO_TypeDef *p_slave_select_port, - uint16_t slave_select_pin) - : mp_spi(p_spi), - m_slave_select(p_slave_select_port, slave_select_pin), - m_state(INIT_PENDING) +bool CBME280::init(SPI_HandleTypeDef *p_spi, + GPIO_TypeDef *p_slave_select_port, + uint16_t slave_select_pin) { + mp_spi = p_spi; + m_slave_select.init(p_slave_select_port, slave_select_pin); if (mp_spi == nullptr) { - Error_Handler(); + return false; } m_slave_select.set(true); if (s_sensor_count < MAX_SENSORS) @@ -83,18 +93,12 @@ CBME280::CBME280(SPI_HandleTypeDef *p_spi, } else { - Error_Handler(); + return false; } } - -CBME280::~CBME280() -{ - // TODO Auto-generated destructor stub -} - /** - * @brief Initialise the sensor. This must be successfully completed before - * sensor can be accessed for data. + * @brief Finish sensor initialization. This must be successfully completed + * before sensor can be accessed for data. * * @return True if initialisation is successful, false otherwise. */ @@ -107,7 +111,7 @@ bool CBME280::init() */ /* This communication via SPI is going to be done without interrupts.*/ // TODO: how do we ensure SPI is available? Perhaps need a wrapper around - // SPI with a mutex. + if (HAL_SPI_GetState(mp_spi) != HAL_SPI_STATE_READY) { return false; From 1fe05a7409a4ceb73b8cadd1ddd522ef6c68d279 Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Tue, 27 Dec 2022 20:23:06 -0400 Subject: [PATCH 24/28] feature: getHumidifierPower --- Hardware/CMockHardwareMap.h | 1 + Hardware/CRealHardwareMap.cpp | 9 +++++++++ Hardware/CRealHardwareMap.h | 1 + Hardware/IHardwareMap.h | 6 ++++++ 4 files changed, 17 insertions(+) diff --git a/Hardware/CMockHardwareMap.h b/Hardware/CMockHardwareMap.h index 9481f793..e2573f0b 100644 --- a/Hardware/CMockHardwareMap.h +++ b/Hardware/CMockHardwareMap.h @@ -35,6 +35,7 @@ class CMockHardwareMap : public IHardwareMap, public CController virtual void setBreathingLight(float duty_cycle); virtual void enableControlPower(bool b_enable); virtual void setHumidifierPower(float power); + virtual bool getHumidifierPower(); /* CController methods. */ // etl::string getName() const; // virtual bool tick(uint32_t current_time); diff --git a/Hardware/CRealHardwareMap.cpp b/Hardware/CRealHardwareMap.cpp index 3a93ade1..4ee9b1b1 100644 --- a/Hardware/CRealHardwareMap.cpp +++ b/Hardware/CRealHardwareMap.cpp @@ -195,3 +195,12 @@ void CRealHardwareMap::setHumidifierPower(float power) m_humidifier_enable.set(false); } } +/** + * @brief Get the power state of the humidifier. + * + * @return True: Humidifier active. False: Humidifier inactive. + */ +bool CRealHardwareMap::getHumidifierPower() +{ + return m_humidifier_enable.get(); +} diff --git a/Hardware/CRealHardwareMap.h b/Hardware/CRealHardwareMap.h index 6a7fff5a..e5e57c21 100644 --- a/Hardware/CRealHardwareMap.h +++ b/Hardware/CRealHardwareMap.h @@ -41,6 +41,7 @@ class CRealHardwareMap : public IHardwareMap virtual void setBreathingLight(float duty_cycle); virtual void enableControlPower(bool b_enable); virtual void setHumidifierPower(float power); + virtual bool getHumidifierPower(); private: typedef struct TIMER_INIT_MAP_T diff --git a/Hardware/IHardwareMap.h b/Hardware/IHardwareMap.h index 0fe27156..5ad2281f 100644 --- a/Hardware/IHardwareMap.h +++ b/Hardware/IHardwareMap.h @@ -124,6 +124,12 @@ class IHardwareMap * @param power Value in percent between 0 and 100. */ virtual void setHumidifierPower(float power) = 0; + /** + * @brief Get power status of the humidifier + * + * @return Value of power output + */ + virtual bool getHumidifierPower() = 0; }; #endif /* IHARDWAREMAP_H_ */ From e7eac1c162bd335461e666ecbf026298ae060b3e Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Thu, 29 Dec 2022 18:52:06 -0400 Subject: [PATCH 25/28] fix: HumidityController --- Controllers/CHumidityController.cpp | 18 +++++++----------- Controllers/CHumidityController.h | 4 ++-- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index af630bc9..df471221 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -34,7 +34,7 @@ CHumidityController::CHumidityController(IHardwareMap *p_hardware, reset(); CBME280 humidity_sensor(p_spi, p_slave_select_port, slave_select_pin); - m_humidity_sensor = &humidity_sensor; + mp_humidity_sensor = &humidity_sensor; } /** @@ -49,11 +49,7 @@ void CHumidityController::run() if (m_target_humidity != DISABLE_TARGET) { float actual_humidity = mp_humidity_sensor->getHumidity(); - if ((MIN_HUMIDITY <= actual_humidity) && - (actual_humidity <= MAX_humidity)) - { - power = m_control_loop.run(m_target_humidity, actual_humidity); - } + power = m_control_loop.run(m_target_humidity, actual_humidity); } } else @@ -82,7 +78,7 @@ bool CHumidityController::newCommand(ICommand *p_command, if (p_command->getName()->compare("heater") == 0) { - result = overrideHeater(p_command); + result = overrideHumidifier(p_command); b_command_recognised = true; } if (b_command_recognised) @@ -126,7 +122,7 @@ void CHumidityController::sendStatus(IComChannel *p_comchannel) p_comchannel->send(message); // Send actual humidity message.assign("Humidity: "); - sprintf(value, "%2.1f, ", m_humidity_sensor->getHumidity()); + sprintf(value, "%2.1f, ", mp_humidity_sensor->getHumidity()); message.append(value); p_comchannel->send(message); // Send heater power @@ -152,11 +148,11 @@ ICommand::command_error_code_t CHumidityController::setHumidity( ICommand *p_command) { // Sanitise command arguments - if (p_command->getArgumentCount != 1) + if (p_command->getArgumentCount() != 1) { return ICommand::ERROR_ARG_COUNT; } - m_target_humidity = *p_command; + m_target_humidity = (*p_command)[0]; if (m_target_humidity > MAX_HUMIDITY) { @@ -179,7 +175,7 @@ ICommand::command_error_code_t CHumidityController::overrideHumidifier( { return ICommand::ERROR_ARG_COUNT; } - float power = *p_command; + float power = (*p_command)[0]; // Execute command if (power > MAX_POWER) diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h index 6574653b..6556075b 100644 --- a/Controllers/CHumidityController.h +++ b/Controllers/CHumidityController.h @@ -32,11 +32,11 @@ class CHumidityController : public CController private: void sendStatus(IComChannel *p_comchannel); ICommand::command_error_code_t setHumidity(ICommand *p_command); - ICommand::command_error_code_t overrideHeater(ICommand *p_command); + ICommand::command_error_code_t overrideHumidifier(ICommand *p_command); IHardwareMap *mp_hw; - CBME280 *m_humidity_sensor; + CBME280 *mp_humidity_sensor; float m_target_humidity; float m_power_override; From ae24b4b64411429f04b04f5e97ae24d153d28079 Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Thu, 29 Dec 2022 18:59:48 -0400 Subject: [PATCH 26/28] fix: HumidityController --- Controllers/CHumidityController.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index df471221..2c335f86 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -33,8 +33,9 @@ CHumidityController::CHumidityController(IHardwareMap *p_hardware, // TODO Auto-generated constructor stub reset(); - CBME280 humidity_sensor(p_spi, p_slave_select_port, slave_select_pin); - mp_humidity_sensor = &humidity_sensor; + // TODO Fix this constructor + // CBME280 humidity_sensor(p_spi, p_slave_select_port, slave_select_pin); + // mp_humidity_sensor = &humidity_sensor; } /** From e358cf03b4bb06cb210762d56ff2da4e379eb7ee Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Thu, 29 Dec 2022 19:10:55 -0400 Subject: [PATCH 27/28] fix: Early SPI initialization error --- Lib/Src/CBME280.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/Src/CBME280.cpp b/Lib/Src/CBME280.cpp index 89b7aefc..06e0796c 100644 --- a/Lib/Src/CBME280.cpp +++ b/Lib/Src/CBME280.cpp @@ -95,6 +95,7 @@ bool CBME280::init(SPI_HandleTypeDef *p_spi, { return false; } + return true; } /** * @brief Finish sensor initialization. This must be successfully completed From 78eac0654b2817613a822e6f40e02fe1a0945d47 Mon Sep 17 00:00:00 2001 From: Samuel Kayode Date: Fri, 17 Feb 2023 21:01:45 -0400 Subject: [PATCH 28/28] format: changed variable types for safer implementation --- Controllers/CHumidityController.cpp | 13 ------------- Controllers/CHumidityController.h | 9 +++++++-- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Controllers/CHumidityController.cpp b/Controllers/CHumidityController.cpp index 2c335f86..8cb23f90 100644 --- a/Controllers/CHumidityController.cpp +++ b/Controllers/CHumidityController.cpp @@ -7,19 +7,6 @@ #include "CHumidityController.h" #include -#include "CBME280.h" -#include "CHumidifier.h" -#include "ICommand.h" -#include "IHardwareMap.h" - -#define MIN_TEMPERATURE 10 -#define MAX_TEMPERATURE 50 -#define MIN_POWER 0 -#define MAX_POWER 100 -#define DISABLE_OVERRIDE -1 -#define DISABLE_TARGET 0 -#define MIN_HUMIDITY 85 -#define MAX_HUMIDITY 95 CHumidityController::CHumidityController(IHardwareMap *p_hardware, etl::string name, diff --git a/Controllers/CHumidityController.h b/Controllers/CHumidityController.h index 6556075b..798cebc4 100644 --- a/Controllers/CHumidityController.h +++ b/Controllers/CHumidityController.h @@ -14,8 +14,6 @@ #include "CPIDLoop.h" #include "IHardwareMap.h" -#define CHANNEL_NUMBER 1 - class CHumidityController : public CController { public: @@ -30,6 +28,13 @@ class CHumidityController : public CController virtual void reset(); private: + static constexpr uint8_t CHANNEL_NUMBER = 1; + static constexpr uint8_t MAX_HUMIDITY = 95; + static constexpr uint8_t MIN_HUMIDITY = 85; + static constexpr uint8_t MAX_POWER = 100; + static constexpr uint8_t MIN_POWER = 0; + static constexpr uint8_t DISABLE_OVERRIDE = -1; + static constexpr uint8_t DISABLE_TARGET = 0; void sendStatus(IComChannel *p_comchannel); ICommand::command_error_code_t setHumidity(ICommand *p_command); ICommand::command_error_code_t overrideHumidifier(ICommand *p_command);