From 9698f57d36a63741870645c6d59bd8b7e5b5378d Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Mon, 15 Apr 2024 00:42:46 -0400 Subject: [PATCH 01/12] Added altimeter .hpp and .cpp files --- Altimeter/Inc/altimeter.hpp | 166 ++++++++++++++++++++++++++++++++++++ Altimeter/Src/altimeter.cpp | 166 ++++++++++++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 Altimeter/Inc/altimeter.hpp create mode 100644 Altimeter/Src/altimeter.cpp diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp new file mode 100644 index 0000000..1ed842e --- /dev/null +++ b/Altimeter/Inc/altimeter.hpp @@ -0,0 +1,166 @@ +#ifndef INC_ALTIMETER_HPP_ +#define INC_ALTIMETER_HPP_ + +#include "stm32l5xx_hal.h" +#include "cmsis_os.h" +#include +#include + + +#define RESET 0x1E + +/*PROM Addresses */ +#define PROM_READ_ADDRESS_0 0xA0 +#define PROM_READ_ADDRESS_1 0xA2 +#define PROM_READ_ADDRESS_2 0xA4 +#define PROM_READ_ADDRESS_3 0xA6 +#define PROM_READ_ADDRESS_4 0xA8 +#define PROM_READ_ADDRESS_5 0xAA +#define PROM_READ_ADDRESS_6 0xAC +#define PROM_READ_ADDRESS_7 0xAE + + +/*digital pressure/temperature commands at different sampling rates*/ +#define CONVERT_D1_OSR_256 0x40 +#define CONVERT_D1_OSR_512 0x42 +#define CONVERT_D1_OSR_1024 0x44 +#define CONVERT_D1_OSR_2048 0x46 +#define CONVERT_D1_OSR_4096 0x48 +#define CONVERT_D2_OSR_256 0x50 +#define CONVERT_D2_OSR_512 0x52 +#define CONVERT_D2_OSR_1024 0x54 +#define CONVERT_D2_OSR_2048 0x56 +#define CONVERT_D2_OSR_4096 0x58 + +#define ADC_READ 0x0 + +#define TIMEOUT 1 << 31 + +typedef struct cal_coeffs{ + uint16_t sens; + uint16_t off; + uint16_t tcs; + uint16_t tco; + uint16_t t_ref; + uint16_t temp_sens; +}cal_coeffs; + + + +/* To get temperature/pressure/altitude values, call (step 1) AltDevice, then (step 2) AltInit once. + * Then before getting (step 4) pressure/temp/altitude, (step 3) calculateTempPres should be called beforehand. + * */ + +class AltDevice{ +public: + /** + * Constructor for the AltDevice class + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * + * @return none + */ + AltDevice(GPIO_TypeDef *ps_port, uint16_t ps_pin); + + /** + * This function sends the reset command, populates the cal_coeffs + * struct members with the calibration coefficients in the sensor PROM, + * and gets the current elevation above sea level. + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * @param spi_handle -> hspix handle + * + * @return none + */ + void altInit(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + + /** + * Calculates datasheet variable values needed for temperature and pressure, + * and calculates temperature and pressure. It + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * @param spi_handle -> hspix handle + * + * @return none + */ + void calculateTempPres(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + + + /** + * @return the current pressure value + */ + float getPressure(); + + /** + * @return the current temperature value + */ + float getTemperature(); + + /** + * @return the current altitude above sea level. + */ + float getAltAboveSeaLvl(); + + /** + * @return the current altitude above zero point. + */ + float getAltitude(); + + +private: + cal_coeffs coeffs_; + float base_elev_; + float height_; + float temp_; + float pres_; + + /** + * Sends the reset command to the barometer. + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * @param spi_handle -> hspix handle + * + * @return none + */ + void reset(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + + /** + * Populates the struct with calibration coefficients. + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * @param spi_handle -> hspix handle + * + * @return none + */ + void getConvCoeffs(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + + /** + * Reads user-specified calibration coefficient from the PROM + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * @param spi_handle -> hspix handle + * + * @return calibration data + */ + uint16_t promRead(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t address); + + /** + * Reads uncompenssated temperature/pressure value from altimeter. + * + * @param ps_port -> protocol select port + * @param ps_pin -> protocol select pin + * @param spi_handle -> hspix handle + * + * @return uncompensated pressure/temperature value + */ + uint32_t uncompensatedPressureTemperature(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t conversion_command); +}; + + +#endif /* INC_ALTIMETER_HPP_ */ diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp new file mode 100644 index 0000000..ff91f0a --- /dev/null +++ b/Altimeter/Src/altimeter.cpp @@ -0,0 +1,166 @@ +#include + + +AltDevice::AltDevice(GPIO_TypeDef *ps_port, uint16_t ps_pin){ + HAL_GPIO_WritePin(ps_port, ps_pin, GPIO_PIN_RESET); +} + +void AltDevice::altInit(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ + reset(spi_handle, cs_port, cs_pin); + getConvCoeffs(spi_handle, cs_port, cs_pin); + + /*Get the average of 100 readings*/ + + float reading_sum = 0.0f; + for(int i = 0; i < 100; i++){ + calculateTempPres(spi_handle, cs_port, cs_pin); + reading_sum += getAltAboveSeaLvl(); + } + + base_elev_ = reading_sum / 100.0f; +} + +void AltDevice::reset(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ + + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + + uint8_t send_reset[3] = {RESET, 0xFF, 0xFF}; + uint8_t receive_data[3]; + + HAL_SPI_TransmitReceive(spi_handle, send_reset, receive_data, 3, TIMEOUT); + osDelay(3); + + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); +} + +void AltDevice::getConvCoeffs(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ + coeffs_.sens = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_1); + coeffs_.off = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_2); + coeffs_.tcs = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_3); + coeffs_.tco = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_4); + coeffs_.t_ref = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_5); + coeffs_.temp_sens = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_6); +} + + +uint16_t AltDevice::promRead(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t address){ + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + + uint8_t send_read_command[3] = {address, 0xFF, 0xFF}; + uint8_t coefficient_val[3]; + + HAL_SPI_TransmitReceive(spi_handle, send_read_command, coefficient_val, 3, TIMEOUT); + + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + + //Grab conversion coefficients. + uint16_t conversion_coefficient = (coefficient_val[1] << 8) | (coefficient_val[2]); + + return conversion_coefficient; +} + + + +uint32_t AltDevice::uncompensatedPressureTemperature(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t conversion_command){ + + uint8_t digital_pres_temp[1] = {conversion_command}; + uint8_t receive_buffer[1]; + + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + + /* send the digital pressure or temperature with the command */ + HAL_SPI_TransmitReceive(spi_handle, digital_pres_temp, receive_buffer, 1, TIMEOUT); + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + + /* at least 8.22 ms delay required for ADC conversion.*/ + osDelay(9); + + uint8_t tx_buffer[4] = {ADC_READ, 0xFF, 0xFF, 0xFF}; + uint8_t rx_buffer[4]; + + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + + /*Start adc conversion to get value */ + HAL_SPI_TransmitReceive(spi_handle, tx_buffer, rx_buffer, 4, TIMEOUT); + + HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + + //get 24-bit uncompensated pressure or temperature value value. + uint32_t uncompensated_value = (rx_buffer[1] << 16 | rx_buffer[2] << 8 | rx_buffer[3]); + + return uncompensated_value; +} + + +void AltDevice::calculateTempPres(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ + + + uint32_t digital_temperature = uncompensatedPressureTemperature(spi_handle, cs_port, cs_pin, CONVERT_D2_OSR_256); + uint32_t digital_pressure = uncompensatedPressureTemperature(spi_handle, cs_port, cs_pin, CONVERT_D1_OSR_256); + + float dt = digital_temperature - (float)coeffs_.t_ref * 256.0f; + float temp = 2000 + dt * (float) coeffs_.temp_sens / pow(2, 23); + + + float off = coeffs_.off * 65536.0f + (coeffs_.tco * dt) / 128.0f; + float sens = coeffs_.sens * 32768.0f + (coeffs_.tcs * dt) / 256.0f; + + /*Second order temperature compensation */ + if(temp < 2000){ + float t2 = (dt*dt) / 2147483648.0f; + float off2 = 5.0f * pow((temp - 2000), 2) / 2.0f; + float sens2 = 5.0f * pow((temp - 2000), 2) / 4.0f; + + + if(temp < 1500){ + off2 = off2 + 7 * pow((temp + 1500), 2); + sens2 = sens2 + 11 * pow((temp + 1500), 2) / 2; + } + + temp = temp - t2; + off = off - off2; + sens = sens - sens2; + + } + + float pressure = (digital_pressure * (sens / 2097152.0f) - off) / 32768.0f; + pressure /= 100.0f; + temp /= 100.0f; + + pres_ = pressure; + temp_ = temp; +} + + +float AltDevice::getPressure(){ + return pres_; +} + +float AltDevice::getTemperature(){ + return temp_; +} + +float AltDevice::getAltAboveSeaLvl(){ + + float reference_temp = 288.15f; /* Ref temperature in Kelvins */ + float temp_lapse_rate = 0.0065f; + float exp_gmrl = 5.2558; + + float reference_pressure = 101325.0f; /* in Pa */ + float current_pressure = getPressure() * 100.0f; + float exponent = (log(current_pressure) - log(reference_pressure)) / exp_gmrl; + + float height = reference_temp/temp_lapse_rate * (1 - pow(M_E, exponent)); + + return height; +} + + +float AltDevice::getAltitude(){ + height_ = getAltAboveSeaLvl(); + return {height_ - base_elev_}; +} + From 428b4bcf969400da41cd64ff14d1f16bf98c02bf Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Thu, 18 Apr 2024 20:08:02 -0400 Subject: [PATCH 02/12] Struct name changed to meet ZP style standards and device initiated once with spi handler and cs/ps port and pins --- Altimeter/Inc/altimeter.hpp | 60 +++++++++++++-------------- Altimeter/Src/altimeter.cpp | 83 ++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index 1ed842e..051dbbf 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -36,14 +36,14 @@ #define TIMEOUT 1 << 31 -typedef struct cal_coeffs{ +typedef struct CalCoeffs_t{ uint16_t sens; uint16_t off; uint16_t tcs; uint16_t tco; uint16_t t_ref; uint16_t temp_sens; -}cal_coeffs; +}CalCoeffs_t; @@ -51,42 +51,39 @@ typedef struct cal_coeffs{ * Then before getting (step 4) pressure/temp/altitude, (step 3) calculateTempPres should be called beforehand. * */ -class AltDevice{ +class MS5611{ public: /** * Constructor for the AltDevice class * + * It assigns the spi_handler and ports and pins + * related to the chip select and protocol pins. + * @param spi_handle -> hspix handle + * @param cs_port -> chip select pin port * @param ps_port -> protocol select port + * @param cs_pin -> chip select pin * @param ps_pin -> protocol select pin * * @return none */ - AltDevice(GPIO_TypeDef *ps_port, uint16_t ps_pin); + MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDef *ps_port, uint16_t cs_pin, uint16_t ps_pin); /** * This function sends the reset command, populates the cal_coeffs * struct members with the calibration coefficients in the sensor PROM, * and gets the current elevation above sea level. * - * @param ps_port -> protocol select port - * @param ps_pin -> protocol select pin - * @param spi_handle -> hspix handle - * * @return none */ - void altInit(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + void altInit(); /** * Calculates datasheet variable values needed for temperature and pressure, * and calculates temperature and pressure. It * - * @param ps_port -> protocol select port - * @param ps_pin -> protocol select pin - * @param spi_handle -> hspix handle - * * @return none */ - void calculateTempPres(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + void calculateTempPres(); /** @@ -111,12 +108,23 @@ class AltDevice{ private: - cal_coeffs coeffs_; + + /* Setup description comment */ + SPI_HandleTypeDef *spi_handle_; + GPIO_TypeDef *cs_port_; + GPIO_TypeDef *ps_port_; + uint16_t cs_pin_; + uint16_t ps_pin_; + + /* Description comment */ + CalCoeffs_t coeffs_; float base_elev_; float height_; float temp_; float pres_; + + /** * Sends the reset command to the barometer. * @@ -126,40 +134,28 @@ class AltDevice{ * * @return none */ - void reset(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + void reset(); /** * Populates the struct with calibration coefficients. * - * @param ps_port -> protocol select port - * @param ps_pin -> protocol select pin - * @param spi_handle -> hspix handle - * * @return none */ - void getConvCoeffs(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin); + void getConvCoeffs(); /** - * Reads user-specified calibration coefficient from the PROM - * - * @param ps_port -> protocol select port - * @param ps_pin -> protocol select pin - * @param spi_handle -> hspix handle + * Reads PROM data from user-specified 16-bit address. * * @return calibration data */ - uint16_t promRead(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t address); + uint16_t promRead(uint8_t address); /** * Reads uncompenssated temperature/pressure value from altimeter. * - * @param ps_port -> protocol select port - * @param ps_pin -> protocol select pin - * @param spi_handle -> hspix handle - * * @return uncompensated pressure/temperature value */ - uint32_t uncompensatedPressureTemperature(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t conversion_command); + uint32_t uncompensatedPressureTemperature(uint8_t conversion_command); }; diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index ff91f0a..475dd90 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -1,59 +1,66 @@ #include -AltDevice::AltDevice(GPIO_TypeDef *ps_port, uint16_t ps_pin){ - HAL_GPIO_WritePin(ps_port, ps_pin, GPIO_PIN_RESET); +MS5611::MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDef *ps_port, uint16_t cs_pin, uint16_t ps_pin){ + spi_handle_ = spi_handle; + cs_port_ = cs_port; + ps_port_ = ps_port; + cs_pin_ = cs_pin; + ps_pin_ = ps_pin; + HAL_GPIO_WritePin(ps_port_, ps_pin_, GPIO_PIN_RESET); } -void AltDevice::altInit(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ - reset(spi_handle, cs_port, cs_pin); - getConvCoeffs(spi_handle, cs_port, cs_pin); +void MS5611::altInit(){ + + + reset(); + getConvCoeffs(); /*Get the average of 100 readings*/ float reading_sum = 0.0f; for(int i = 0; i < 100; i++){ - calculateTempPres(spi_handle, cs_port, cs_pin); + calculateTempPres(); reading_sum += getAltAboveSeaLvl(); } base_elev_ = reading_sum / 100.0f; } -void AltDevice::reset(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ +void MS5611::reset(){ - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); uint8_t send_reset[3] = {RESET, 0xFF, 0xFF}; uint8_t receive_data[3]; - HAL_SPI_TransmitReceive(spi_handle, send_reset, receive_data, 3, TIMEOUT); + HAL_SPI_TransmitReceive(spi_handle_, send_reset, receive_data, 3, TIMEOUT); osDelay(3); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); } -void AltDevice::getConvCoeffs(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ - coeffs_.sens = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_1); - coeffs_.off = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_2); - coeffs_.tcs = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_3); - coeffs_.tco = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_4); - coeffs_.t_ref = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_5); - coeffs_.temp_sens = promRead(spi_handle, cs_port, cs_pin, PROM_READ_ADDRESS_6); +void MS5611::getConvCoeffs(){ + coeffs_.sens = promRead(PROM_READ_ADDRESS_1); + coeffs_.off = promRead(PROM_READ_ADDRESS_2); + coeffs_.tcs = promRead(PROM_READ_ADDRESS_3); + coeffs_.tco = promRead(PROM_READ_ADDRESS_4); + coeffs_.t_ref = promRead(PROM_READ_ADDRESS_5); + coeffs_.temp_sens = promRead(PROM_READ_ADDRESS_6); } -uint16_t AltDevice::promRead(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t address){ - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); +uint16_t MS5611::promRead(uint8_t address){ + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); uint8_t send_read_command[3] = {address, 0xFF, 0xFF}; uint8_t coefficient_val[3]; - HAL_SPI_TransmitReceive(spi_handle, send_read_command, coefficient_val, 3, TIMEOUT); + HAL_SPI_TransmitReceive(spi_handle_, send_read_command, coefficient_val, 3, TIMEOUT); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); //Grab conversion coefficients. uint16_t conversion_coefficient = (coefficient_val[1] << 8) | (coefficient_val[2]); @@ -63,17 +70,17 @@ uint16_t AltDevice::promRead(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_por -uint32_t AltDevice::uncompensatedPressureTemperature(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin, uint8_t conversion_command){ +uint32_t MS5611::uncompensatedPressureTemperature(uint8_t conversion_command){ uint8_t digital_pres_temp[1] = {conversion_command}; uint8_t receive_buffer[1]; - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); /* send the digital pressure or temperature with the command */ - HAL_SPI_TransmitReceive(spi_handle, digital_pres_temp, receive_buffer, 1, TIMEOUT); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_SPI_TransmitReceive(spi_handle_, digital_pres_temp, receive_buffer, 1, TIMEOUT); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); /* at least 8.22 ms delay required for ADC conversion.*/ osDelay(9); @@ -81,12 +88,12 @@ uint32_t AltDevice::uncompensatedPressureTemperature(SPI_HandleTypeDef *spi_hand uint8_t tx_buffer[4] = {ADC_READ, 0xFF, 0xFF, 0xFF}; uint8_t rx_buffer[4]; - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); /*Start adc conversion to get value */ - HAL_SPI_TransmitReceive(spi_handle, tx_buffer, rx_buffer, 4, TIMEOUT); + HAL_SPI_TransmitReceive(spi_handle_, tx_buffer, rx_buffer, 4, TIMEOUT); - HAL_GPIO_WritePin(cs_port, cs_pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); //get 24-bit uncompensated pressure or temperature value value. uint32_t uncompensated_value = (rx_buffer[1] << 16 | rx_buffer[2] << 8 | rx_buffer[3]); @@ -95,11 +102,11 @@ uint32_t AltDevice::uncompensatedPressureTemperature(SPI_HandleTypeDef *spi_hand } -void AltDevice::calculateTempPres(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, uint16_t cs_pin){ +void MS5611::calculateTempPres(){ - uint32_t digital_temperature = uncompensatedPressureTemperature(spi_handle, cs_port, cs_pin, CONVERT_D2_OSR_256); - uint32_t digital_pressure = uncompensatedPressureTemperature(spi_handle, cs_port, cs_pin, CONVERT_D1_OSR_256); + uint32_t digital_temperature = uncompensatedPressureTemperature(CONVERT_D2_OSR_256); + uint32_t digital_pressure = uncompensatedPressureTemperature(CONVERT_D1_OSR_256); float dt = digital_temperature - (float)coeffs_.t_ref * 256.0f; float temp = 2000 + dt * (float) coeffs_.temp_sens / pow(2, 23); @@ -135,15 +142,15 @@ void AltDevice::calculateTempPres(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *c } -float AltDevice::getPressure(){ +float MS5611::getPressure(){ return pres_; } -float AltDevice::getTemperature(){ +float MS5611::getTemperature(){ return temp_; } -float AltDevice::getAltAboveSeaLvl(){ +float MS5611::getAltAboveSeaLvl(){ float reference_temp = 288.15f; /* Ref temperature in Kelvins */ float temp_lapse_rate = 0.0065f; @@ -159,7 +166,7 @@ float AltDevice::getAltAboveSeaLvl(){ } -float AltDevice::getAltitude(){ +float MS5611::getAltitude(){ height_ = getAltAboveSeaLvl(); return {height_ - base_elev_}; } From 482d73a786b669e19f92558dfb1e1568031e6cc7 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Thu, 18 Apr 2024 21:55:25 -0400 Subject: [PATCH 03/12] defined magic numbers --- Altimeter/Src/altimeter.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 475dd90..c2d2574 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -63,7 +63,7 @@ uint16_t MS5611::promRead(uint8_t address){ HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); //Grab conversion coefficients. - uint16_t conversion_coefficient = (coefficient_val[1] << 8) | (coefficient_val[2]); + uint16_t conversion_coefficient = (coefficient_val[1] << 8) | (coefficient_val[2]) & 0x0000FFFF;; return conversion_coefficient; } @@ -96,7 +96,7 @@ uint32_t MS5611::uncompensatedPressureTemperature(uint8_t conversion_command){ HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); //get 24-bit uncompensated pressure or temperature value value. - uint32_t uncompensated_value = (rx_buffer[1] << 16 | rx_buffer[2] << 8 | rx_buffer[3]); + uint32_t uncompensated_value = (rx_buffer[1] << 16 | rx_buffer[2] << 8 | rx_buffer[3]) & 0x00FFFFFF; return uncompensated_value; } @@ -104,36 +104,39 @@ uint32_t MS5611::uncompensatedPressureTemperature(uint8_t conversion_command){ void MS5611::calculateTempPres(){ - uint32_t digital_temperature = uncompensatedPressureTemperature(CONVERT_D2_OSR_256); uint32_t digital_pressure = uncompensatedPressureTemperature(CONVERT_D1_OSR_256); - float dt = digital_temperature - (float)coeffs_.t_ref * 256.0f; - float temp = 2000 + dt * (float) coeffs_.temp_sens / pow(2, 23); - + const float TWO_POW_7 = 128.0f; + const float TWO_POW_8 = 256.0f; + const float TWO_POW_15 = 32768.0f; + const float TWO_POW_16 = 65536.0f; + const float TWO_POW_21 = 2097152.0f; + const float TWO_POW_23 = 8388608.0f; + const float TWO_POW_31 = 2147483648.0f; - float off = coeffs_.off * 65536.0f + (coeffs_.tco * dt) / 128.0f; - float sens = coeffs_.sens * 32768.0f + (coeffs_.tcs * dt) / 256.0f; + float dt = digital_temperature - (float)coeffs_.t_ref * TWO_POW_8; + float temp = 2000 + dt * (float) coeffs_.temp_sens / TWO_POW_23; + float off = coeffs_.off * TWO_POW_16 + (coeffs_.tco * dt) / TWO_POW_7; + float sens = coeffs_.sens * TWO_POW_15 + (coeffs_.tcs * dt) / TWO_POW_8; /*Second order temperature compensation */ if(temp < 2000){ - float t2 = (dt*dt) / 2147483648.0f; - float off2 = 5.0f * pow((temp - 2000), 2) / 2.0f; - float sens2 = 5.0f * pow((temp - 2000), 2) / 4.0f; - + float t2 = (dt*dt) / TWO_POW_31; + float off2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_1; + float sens2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_2; if(temp < 1500){ - off2 = off2 + 7 * pow((temp + 1500), 2); - sens2 = sens2 + 11 * pow((temp + 1500), 2) / 2; + off2 = off2 + 7 * pow((temp + 1500), TWO_POW_1); + sens2 = sens2 + 11 * pow((temp + 1500), TWO_POW_1) / TWO_POW_1; } temp = temp - t2; off = off - off2; sens = sens - sens2; - } - float pressure = (digital_pressure * (sens / 2097152.0f) - off) / 32768.0f; + float pressure = (digital_pressure * (sens / TWO_POW_21) - off) / TWO_POW_15; pressure /= 100.0f; temp /= 100.0f; From a96edd350debe2b898e07e2132d5003deb644ff3 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Thu, 18 Apr 2024 22:23:58 -0400 Subject: [PATCH 04/12] #defines changed to constexpr --- Altimeter/Inc/altimeter.hpp | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index 051dbbf..af4094a 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -7,34 +7,34 @@ #include -#define RESET 0x1E +constexpr uint8_t RESET_COMMAND = 0x1E; /*PROM Addresses */ -#define PROM_READ_ADDRESS_0 0xA0 -#define PROM_READ_ADDRESS_1 0xA2 -#define PROM_READ_ADDRESS_2 0xA4 -#define PROM_READ_ADDRESS_3 0xA6 -#define PROM_READ_ADDRESS_4 0xA8 -#define PROM_READ_ADDRESS_5 0xAA -#define PROM_READ_ADDRESS_6 0xAC -#define PROM_READ_ADDRESS_7 0xAE +constexpr uint8_t PROM_READ_ADDRESS_0 = 0xA0; +constexpr uint8_t PROM_READ_ADDRESS_1 = 0xA2; +constexpr uint8_t PROM_READ_ADDRESS_2 = 0xA4; +constexpr uint8_t PROM_READ_ADDRESS_3 = 0xA6; +constexpr uint8_t PROM_READ_ADDRESS_4 = 0xA8; +constexpr uint8_t PROM_READ_ADDRESS_5 = 0xAA; +constexpr uint8_t PROM_READ_ADDRESS_6 = 0xAC; +constexpr uint8_t PROM_READ_ADDRESS_7 = 0xAE; /*digital pressure/temperature commands at different sampling rates*/ -#define CONVERT_D1_OSR_256 0x40 -#define CONVERT_D1_OSR_512 0x42 -#define CONVERT_D1_OSR_1024 0x44 -#define CONVERT_D1_OSR_2048 0x46 -#define CONVERT_D1_OSR_4096 0x48 -#define CONVERT_D2_OSR_256 0x50 -#define CONVERT_D2_OSR_512 0x52 -#define CONVERT_D2_OSR_1024 0x54 -#define CONVERT_D2_OSR_2048 0x56 -#define CONVERT_D2_OSR_4096 0x58 - -#define ADC_READ 0x0 - -#define TIMEOUT 1 << 31 +constexpr uint8_t CONVERT_D1_OSR_256 = 0x40; +constexpr uint8_t CONVERT_D1_OSR_512 = 0x42; +constexpr uint8_t CONVERT_D1_OSR_1024 = 0x44; +constexpr uint8_t CONVERT_D1_OSR_2048 = 0x46; +constexpr uint8_t CONVERT_D1_OSR_4096 = 0x48; +constexpr uint8_t CONVERT_D2_OSR_256 = 0x50; +constexpr uint8_t CONVERT_D2_OSR_512 = 0x52; +constexpr uint8_t CONVERT_D2_OSR_1024 = 0x54; +constexpr uint8_t CONVERT_D2_OSR_2048 = 0x56; +constexpr uint8_t CONVERT_D2_OSR_4096 = 0x58; + +constexpr uint8_t ADC_READ = 0x0; + +constexpr uint32_t TIMEOUT = 1 << 31; typedef struct CalCoeffs_t{ uint16_t sens; From f54a5cec9110ac2b83a571e5033214206c882815 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Sun, 21 Apr 2024 21:53:56 -0400 Subject: [PATCH 05/12] cal_coeff struct members changed to private member variables of MS5611 class, and more descriptive naming for MS5611 calibration coefficients --- Altimeter/Inc/altimeter.hpp | 21 +++++++++----------- Altimeter/Src/altimeter.cpp | 39 ++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index af4094a..8ce73f4 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -36,16 +36,6 @@ constexpr uint8_t ADC_READ = 0x0; constexpr uint32_t TIMEOUT = 1 << 31; -typedef struct CalCoeffs_t{ - uint16_t sens; - uint16_t off; - uint16_t tcs; - uint16_t tco; - uint16_t t_ref; - uint16_t temp_sens; -}CalCoeffs_t; - - /* To get temperature/pressure/altitude values, call (step 1) AltDevice, then (step 2) AltInit once. * Then before getting (step 4) pressure/temp/altitude, (step 3) calculateTempPres should be called beforehand. @@ -116,8 +106,15 @@ class MS5611{ uint16_t cs_pin_; uint16_t ps_pin_; - /* Description comment */ - CalCoeffs_t coeffs_; + /*ms5611 calibration coefficients for pressure and temperature calculations */ + uint16_t pressure_sensitivity_; + uint16_t pressure_offset_; + uint16_t pres_sensitivity_temp_coeff_; /*Temperature coefficient of pressure sensitivity*/ + uint16_t pres_offset_temp_coeff_; /* temperature coefficient of temperature offset */ + uint16_t reference_temperature_; + uint16_t temp_coeff_of_temp_; /*Temperature coefficient of temperature */ + + /* barometer measurement variables */ float base_elev_; float height_; float temp_; diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index c2d2574..256d262 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -42,12 +42,12 @@ void MS5611::reset(){ } void MS5611::getConvCoeffs(){ - coeffs_.sens = promRead(PROM_READ_ADDRESS_1); - coeffs_.off = promRead(PROM_READ_ADDRESS_2); - coeffs_.tcs = promRead(PROM_READ_ADDRESS_3); - coeffs_.tco = promRead(PROM_READ_ADDRESS_4); - coeffs_.t_ref = promRead(PROM_READ_ADDRESS_5); - coeffs_.temp_sens = promRead(PROM_READ_ADDRESS_6); + pressure_sensitivity_ = promRead(PROM_READ_ADDRESS_1); + pressure_offset_ = promRead(PROM_READ_ADDRESS_2); + pres_sensitivity_temp_coeff_ = promRead(PROM_READ_ADDRESS_3); + pres_offset_temp_coeff_ = promRead(PROM_READ_ADDRESS_4); + reference_temperature_ = promRead(PROM_READ_ADDRESS_5); + temp_coeff_of_temp_ = promRead(PROM_READ_ADDRESS_6); } @@ -107,6 +107,8 @@ void MS5611::calculateTempPres(){ uint32_t digital_temperature = uncompensatedPressureTemperature(CONVERT_D2_OSR_256); uint32_t digital_pressure = uncompensatedPressureTemperature(CONVERT_D1_OSR_256); + const float TWO_POW_1 = 2.0f; + const float TWO_POW_2 = 4.0f; const float TWO_POW_7 = 128.0f; const float TWO_POW_8 = 256.0f; const float TWO_POW_15 = 32768.0f; @@ -115,28 +117,30 @@ void MS5611::calculateTempPres(){ const float TWO_POW_23 = 8388608.0f; const float TWO_POW_31 = 2147483648.0f; - float dt = digital_temperature - (float)coeffs_.t_ref * TWO_POW_8; - float temp = 2000 + dt * (float) coeffs_.temp_sens / TWO_POW_23; - float off = coeffs_.off * TWO_POW_16 + (coeffs_.tco * dt) / TWO_POW_7; - float sens = coeffs_.sens * TWO_POW_15 + (coeffs_.tcs * dt) / TWO_POW_8; + const float FIVE = 5.0f; + + float dt = digital_temperature - (float)reference_temperature_ * TWO_POW_8; + float temp = 2000 + dt * (float)temp_coeff_of_temp_ / TWO_POW_23; + float pressure_offset = pressure_offset_ * TWO_POW_16 + (pres_offset_temp_coeff_ * dt) / TWO_POW_7; + float pressure_sensitivity = pressure_sensitivity_ * TWO_POW_15 + (pres_sensitivity_temp_coeff_ * dt) / TWO_POW_8; /*Second order temperature compensation */ if(temp < 2000){ float t2 = (dt*dt) / TWO_POW_31; - float off2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_1; - float sens2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_2; + float pressure_offset_2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_1; + float pressure_sensitivity_2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_2; if(temp < 1500){ - off2 = off2 + 7 * pow((temp + 1500), TWO_POW_1); - sens2 = sens2 + 11 * pow((temp + 1500), TWO_POW_1) / TWO_POW_1; + pressure_offset_2 = pressure_offset_2 + 7 * pow((temp + 1500), TWO_POW_1); + pressure_sensitivity_2 = pressure_sensitivity_2 + 11 * pow((temp + 1500), TWO_POW_1) / TWO_POW_1; } temp = temp - t2; - off = off - off2; - sens = sens - sens2; + pressure_offset = pressure_offset - pressure_offset_2; + pressure_sensitivity = pressure_sensitivity - pressure_sensitivity_2; } - float pressure = (digital_pressure * (sens / TWO_POW_21) - off) / TWO_POW_15; + float pressure = (digital_pressure * (pressure_sensitivity / TWO_POW_21) - pressure_offset) / TWO_POW_15; pressure /= 100.0f; temp /= 100.0f; @@ -144,7 +148,6 @@ void MS5611::calculateTempPres(){ temp_ = temp; } - float MS5611::getPressure(){ return pres_; } From 6977b6369b2d2f622a51d32b50365950088dace8 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Sun, 21 Apr 2024 22:25:33 -0400 Subject: [PATCH 06/12] Changed ms5611 altitude names to be morme distinct and adjusted description formatting on calculateTempPres() function --- Altimeter/Inc/altimeter.hpp | 7 +++---- Altimeter/Src/altimeter.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index 8ce73f4..2b9662d 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -68,8 +68,7 @@ class MS5611{ void altInit(); /** - * Calculates datasheet variable values needed for temperature and pressure, - * and calculates temperature and pressure. It + * Calculates the temperature in degrees celsius and pressure in mbar. * * @return none */ @@ -89,12 +88,12 @@ class MS5611{ /** * @return the current altitude above sea level. */ - float getAltAboveSeaLvl(); + float getAltitudeAboveSeaLevel(); /** * @return the current altitude above zero point. */ - float getAltitude(); + float getAltitudeAboveGroundLevel(); private: diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 256d262..73556d8 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -21,14 +21,13 @@ void MS5611::altInit(){ float reading_sum = 0.0f; for(int i = 0; i < 100; i++){ calculateTempPres(); - reading_sum += getAltAboveSeaLvl(); + reading_sum += getAltitudeAboveSeaLevel(); } base_elev_ = reading_sum / 100.0f; } void MS5611::reset(){ - HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); @@ -156,7 +155,7 @@ float MS5611::getTemperature(){ return temp_; } -float MS5611::getAltAboveSeaLvl(){ +float MS5611::getAltitudeAboveSeaLevel(){ float reference_temp = 288.15f; /* Ref temperature in Kelvins */ float temp_lapse_rate = 0.0065f; @@ -172,8 +171,8 @@ float MS5611::getAltAboveSeaLvl(){ } -float MS5611::getAltitude(){ - height_ = getAltAboveSeaLvl(); +float MS5611::getAltitudeAboveGroundLevel(){ + height_ = getAltitudeAboveSeaLevel(); return {height_ - base_elev_}; } From 15bf1a9227278e4f19e73782247fb546c62043fd Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Sun, 21 Apr 2024 22:54:00 -0400 Subject: [PATCH 07/12] Temperature and pressure calculation function name changed and is called in getPressure() and getTempemrautre() functions --- Altimeter/Inc/altimeter.hpp | 9 ++++++++- Altimeter/Src/altimeter.cpp | 7 ++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index 2b9662d..9141d44 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -72,7 +72,7 @@ class MS5611{ * * @return none */ - void calculateTempPres(); + void calculateTemperatureAndPressure(); /** @@ -152,6 +152,13 @@ class MS5611{ * @return uncompensated pressure/temperature value */ uint32_t uncompensatedPressureTemperature(uint8_t conversion_command); + + /** + * Calculates the temperature in degrees celsius and pressure in mbar. + * + * @return none + */ + void calculateTemperatureAndPressure(); }; diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 73556d8..9c393c7 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -20,7 +20,7 @@ void MS5611::altInit(){ float reading_sum = 0.0f; for(int i = 0; i < 100; i++){ - calculateTempPres(); + calculateTemperatureAndPressure(); reading_sum += getAltitudeAboveSeaLevel(); } @@ -101,7 +101,7 @@ uint32_t MS5611::uncompensatedPressureTemperature(uint8_t conversion_command){ } -void MS5611::calculateTempPres(){ +void MS5611::calculateTemperatureAndPressure(){ uint32_t digital_temperature = uncompensatedPressureTemperature(CONVERT_D2_OSR_256); uint32_t digital_pressure = uncompensatedPressureTemperature(CONVERT_D1_OSR_256); @@ -148,10 +148,12 @@ void MS5611::calculateTempPres(){ } float MS5611::getPressure(){ + calculateTemperatureAndPressure(); return pres_; } float MS5611::getTemperature(){ + calculateTemperatureAndPressure(); return temp_; } @@ -170,7 +172,6 @@ float MS5611::getAltitudeAboveSeaLevel(){ return height; } - float MS5611::getAltitudeAboveGroundLevel(){ height_ = getAltitudeAboveSeaLevel(); return {height_ - base_elev_}; From 7d60810f2c8e2816aa1bdbc41271ba94a6574772 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Sun, 21 Apr 2024 23:10:04 -0400 Subject: [PATCH 08/12] Digital pressure/temperature read function name modified --- Altimeter/Inc/altimeter.hpp | 12 +----------- Altimeter/Src/altimeter.cpp | 6 +++--- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index 9141d44..ab10c3d 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -67,14 +67,6 @@ class MS5611{ */ void altInit(); - /** - * Calculates the temperature in degrees celsius and pressure in mbar. - * - * @return none - */ - void calculateTemperatureAndPressure(); - - /** * @return the current pressure value */ @@ -119,8 +111,6 @@ class MS5611{ float temp_; float pres_; - - /** * Sends the reset command to the barometer. * @@ -151,7 +141,7 @@ class MS5611{ * * @return uncompensated pressure/temperature value */ - uint32_t uncompensatedPressureTemperature(uint8_t conversion_command); + uint32_t readPressureTemperatureUncompensated(uint8_t conversion_command); /** * Calculates the temperature in degrees celsius and pressure in mbar. diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 9c393c7..32c50ed 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -69,7 +69,7 @@ uint16_t MS5611::promRead(uint8_t address){ -uint32_t MS5611::uncompensatedPressureTemperature(uint8_t conversion_command){ +uint32_t MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command){ uint8_t digital_pres_temp[1] = {conversion_command}; uint8_t receive_buffer[1]; @@ -103,8 +103,8 @@ uint32_t MS5611::uncompensatedPressureTemperature(uint8_t conversion_command){ void MS5611::calculateTemperatureAndPressure(){ - uint32_t digital_temperature = uncompensatedPressureTemperature(CONVERT_D2_OSR_256); - uint32_t digital_pressure = uncompensatedPressureTemperature(CONVERT_D1_OSR_256); + uint32_t digital_temperature = readPressureTemperatureUncompensated(CONVERT_D2_OSR_256); + uint32_t digital_pressure = readPressureTemperatureUncompensated(CONVERT_D1_OSR_256); const float TWO_POW_1 = 2.0f; const float TWO_POW_2 = 4.0f; From 5d39043198642e7df6f898df16bae481464f71e8 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Mon, 22 Apr 2024 23:14:14 -0400 Subject: [PATCH 09/12] More descriptive tx and rx buffer names, and Init code moved to constructor --- Altimeter/Inc/altimeter.hpp | 39 +++++++++-------------- Altimeter/Src/altimeter.cpp | 62 +++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 59 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index ab10c3d..cf45f6b 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -9,7 +9,7 @@ constexpr uint8_t RESET_COMMAND = 0x1E; -/*PROM Addresses */ +// PROM Addresses. constexpr uint8_t PROM_READ_ADDRESS_0 = 0xA0; constexpr uint8_t PROM_READ_ADDRESS_1 = 0xA2; constexpr uint8_t PROM_READ_ADDRESS_2 = 0xA4; @@ -20,7 +20,7 @@ constexpr uint8_t PROM_READ_ADDRESS_6 = 0xAC; constexpr uint8_t PROM_READ_ADDRESS_7 = 0xAE; -/*digital pressure/temperature commands at different sampling rates*/ +// digital pressure/temperature commands at different sampling rates. constexpr uint8_t CONVERT_D1_OSR_256 = 0x40; constexpr uint8_t CONVERT_D1_OSR_512 = 0x42; constexpr uint8_t CONVERT_D1_OSR_1024 = 0x44; @@ -36,18 +36,16 @@ constexpr uint8_t ADC_READ = 0x0; constexpr uint32_t TIMEOUT = 1 << 31; - -/* To get temperature/pressure/altitude values, call (step 1) AltDevice, then (step 2) AltInit once. - * Then before getting (step 4) pressure/temp/altitude, (step 3) calculateTempPres should be called beforehand. - * */ - class MS5611{ public: /** - * Constructor for the AltDevice class + * Constructor for the AltDevice class. + * It assigns the spi_handler and ports and pins related to the chip select and protocol pins. + * This function sends the reset command, populates the cal_coeffs + * struct members with the calibration coefficients in the sensor PROM, + * and gets the current elevation above sea level. * - * It assigns the spi_handler and ports and pins - * related to the chip select and protocol pins. + * * @param spi_handle -> hspix handle * @param cs_port -> chip select pin port * @param ps_port -> protocol select port @@ -58,15 +56,6 @@ class MS5611{ */ MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDef *ps_port, uint16_t cs_pin, uint16_t ps_pin); - /** - * This function sends the reset command, populates the cal_coeffs - * struct members with the calibration coefficients in the sensor PROM, - * and gets the current elevation above sea level. - * - * @return none - */ - void altInit(); - /** * @return the current pressure value */ @@ -90,22 +79,22 @@ class MS5611{ private: - /* Setup description comment */ + // Setup description comment. SPI_HandleTypeDef *spi_handle_; GPIO_TypeDef *cs_port_; GPIO_TypeDef *ps_port_; uint16_t cs_pin_; uint16_t ps_pin_; - /*ms5611 calibration coefficients for pressure and temperature calculations */ + // ms5611 calibration coefficients for pressure and temperature calculations. uint16_t pressure_sensitivity_; uint16_t pressure_offset_; - uint16_t pres_sensitivity_temp_coeff_; /*Temperature coefficient of pressure sensitivity*/ - uint16_t pres_offset_temp_coeff_; /* temperature coefficient of temperature offset */ + uint16_t pres_sensitivity_temp_coeff_; // Temperature coefficient of pressure sensitivity. + uint16_t pres_offset_temp_coeff_; // temperature coefficient of temperature offset. uint16_t reference_temperature_; - uint16_t temp_coeff_of_temp_; /*Temperature coefficient of temperature */ + uint16_t temp_coeff_of_temp_; // Temperature coefficient of temperature. - /* barometer measurement variables */ + // barometer measurement variables. float base_elev_; float height_; float temp_; diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 32c50ed..1adfdf0 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -8,19 +8,13 @@ MS5611::MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDe cs_pin_ = cs_pin; ps_pin_ = ps_pin; HAL_GPIO_WritePin(ps_port_, ps_pin_, GPIO_PIN_RESET); -} - -void MS5611::altInit(){ - reset(); getConvCoeffs(); - /*Get the average of 100 readings*/ - + // Get the average of 100 readings. float reading_sum = 0.0f; for(int i = 0; i < 100; i++){ - calculateTemperatureAndPressure(); reading_sum += getAltitudeAboveSeaLevel(); } @@ -31,10 +25,11 @@ void MS5611::reset(){ HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); - uint8_t send_reset[3] = {RESET, 0xFF, 0xFF}; - uint8_t receive_data[3]; + uint8_t tx_data[3] = {RESET_COMMAND, 0xFF, 0xFF}; + uint8_t rx_data[3]; + uint16_t data_size = 3; - HAL_SPI_TransmitReceive(spi_handle_, send_reset, receive_data, 3, TIMEOUT); + HAL_SPI_TransmitReceive(spi_handle_, tx_data, rx_data, data_size, TIMEOUT); osDelay(3); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); @@ -49,58 +44,57 @@ void MS5611::getConvCoeffs(){ temp_coeff_of_temp_ = promRead(PROM_READ_ADDRESS_6); } - uint16_t MS5611::promRead(uint8_t address){ HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); - uint8_t send_read_command[3] = {address, 0xFF, 0xFF}; - uint8_t coefficient_val[3]; + uint8_t tx_data[3] = {address, 0xFF, 0xFF}; + uint8_t rx_data[3]; + uint16_t data_size = 3; - HAL_SPI_TransmitReceive(spi_handle_, send_read_command, coefficient_val, 3, TIMEOUT); + HAL_SPI_TransmitReceive(spi_handle_, tx_data, rx_data, data_size, TIMEOUT); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); - //Grab conversion coefficients. - uint16_t conversion_coefficient = (coefficient_val[1] << 8) | (coefficient_val[2]) & 0x0000FFFF;; + // construct 16-bit calibration coefficient. + uint16_t calibration_coefficient = (rx_data[1] << 8) | (rx_data[2]) & 0x0000FFFF; - return conversion_coefficient; + return calibration_coefficient; } - - uint32_t MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command){ - uint8_t digital_pres_temp[1] = {conversion_command}; - uint8_t receive_buffer[1]; + uint8_t tx_data = conversion_command; + uint8_t rx_data; + uint16_t data_size = 1; HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); - /* send the digital pressure or temperature with the command */ - HAL_SPI_TransmitReceive(spi_handle_, digital_pres_temp, receive_buffer, 1, TIMEOUT); + // send the digital pressure or temperature with the command. + HAL_SPI_TransmitReceive(spi_handle_, tx_data, rx_data, data_size, TIMEOUT); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); - /* at least 8.22 ms delay required for ADC conversion.*/ + // at least 8.22 ms delay required for ADC conversion. osDelay(9); - uint8_t tx_buffer[4] = {ADC_READ, 0xFF, 0xFF, 0xFF}; - uint8_t rx_buffer[4]; + uint8_t tx_data_2[4] = {ADC_READ, 0xFF, 0xFF, 0xFF}; + uint8_t rx_data_2[4]; + data_size = 4; HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); - /*Start adc conversion to get value */ - HAL_SPI_TransmitReceive(spi_handle_, tx_buffer, rx_buffer, 4, TIMEOUT); + // Start adc conversion to get value + HAL_SPI_TransmitReceive(spi_handle_, tx_data_2, rx_data_2, data_size, TIMEOUT); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); - //get 24-bit uncompensated pressure or temperature value value. - uint32_t uncompensated_value = (rx_buffer[1] << 16 | rx_buffer[2] << 8 | rx_buffer[3]) & 0x00FFFFFF; + // get 24-bit uncompensated pressure or temperature value value. + uint32_t uncompensated_value = (rx_data_2[1] << 16 | rx_data_2[2] << 8 | rx_data_2[3]) & 0x00FFFFFF; return uncompensated_value; } - void MS5611::calculateTemperatureAndPressure(){ uint32_t digital_temperature = readPressureTemperatureUncompensated(CONVERT_D2_OSR_256); @@ -123,7 +117,7 @@ void MS5611::calculateTemperatureAndPressure(){ float pressure_offset = pressure_offset_ * TWO_POW_16 + (pres_offset_temp_coeff_ * dt) / TWO_POW_7; float pressure_sensitivity = pressure_sensitivity_ * TWO_POW_15 + (pres_sensitivity_temp_coeff_ * dt) / TWO_POW_8; - /*Second order temperature compensation */ + // Second order temperature compensation. if(temp < 2000){ float t2 = (dt*dt) / TWO_POW_31; float pressure_offset_2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_1; @@ -159,11 +153,11 @@ float MS5611::getTemperature(){ float MS5611::getAltitudeAboveSeaLevel(){ - float reference_temp = 288.15f; /* Ref temperature in Kelvins */ + float reference_temp = 288.15f; // Ref temperature in Kelvins. float temp_lapse_rate = 0.0065f; float exp_gmrl = 5.2558; - float reference_pressure = 101325.0f; /* in Pa */ + float reference_pressure = 101325.0f; // in Pa. float current_pressure = getPressure() * 100.0f; float exponent = (log(current_pressure) - log(reference_pressure)) / exp_gmrl; From 314a7111d146001553755121db514477340aeb40 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Thu, 25 Apr 2024 21:48:35 -0400 Subject: [PATCH 10/12] getAltitudeAboveSeaLevel() function variables now const --- Altimeter/Inc/altimeter.hpp | 8 +++++++- Altimeter/Src/altimeter.cpp | 21 ++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index cf45f6b..6b32acd 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -54,7 +54,11 @@ class MS5611{ * * @return none */ - MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDef *ps_port, uint16_t cs_pin, uint16_t ps_pin); + MS5611(SPI_HandleTypeDef *spi_handle, + GPIO_TypeDef *cs_port, + GPIO_TypeDef *ps_port, + uint16_t cs_pin, + uint16_t ps_pin); /** * @return the current pressure value @@ -100,6 +104,8 @@ class MS5611{ float temp_; float pres_; + HAL_StatusTypeDef spi_status_; + /** * Sends the reset command to the barometer. * diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 1adfdf0..755cbbb 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -14,7 +14,7 @@ MS5611::MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDe // Get the average of 100 readings. float reading_sum = 0.0f; - for(int i = 0; i < 100; i++){ + for (int i = 0; i < 100; i++) { reading_sum += getAltitudeAboveSeaLevel(); } @@ -118,12 +118,12 @@ void MS5611::calculateTemperatureAndPressure(){ float pressure_sensitivity = pressure_sensitivity_ * TWO_POW_15 + (pres_sensitivity_temp_coeff_ * dt) / TWO_POW_8; // Second order temperature compensation. - if(temp < 2000){ + if (temp < 2000) { float t2 = (dt*dt) / TWO_POW_31; float pressure_offset_2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_1; float pressure_sensitivity_2 = FIVE * pow((temp - 2000), TWO_POW_1) / TWO_POW_2; - if(temp < 1500){ + if (temp < 1500) { pressure_offset_2 = pressure_offset_2 + 7 * pow((temp + 1500), TWO_POW_1); pressure_sensitivity_2 = pressure_sensitivity_2 + 11 * pow((temp + 1500), TWO_POW_1) / TWO_POW_1; } @@ -152,16 +152,15 @@ float MS5611::getTemperature(){ } float MS5611::getAltitudeAboveSeaLevel(){ + const float REFERENCE_TEMP = 288.15f; /* Ref temperature in Kelvins */ + const float TEMP_LAPSE_RATE = 0.0065f; + const float EXP_GMRL = 5.2558; - float reference_temp = 288.15f; // Ref temperature in Kelvins. - float temp_lapse_rate = 0.0065f; - float exp_gmrl = 5.2558; + const float REFERENCE_PRESSURE = 101325.0f; /* in Pa */ + const float CURRENT_PRESSURE = getPressure() * 100.0f; + const float EXPONENT = (log(CURRENT_PRESSURE) - log(REFERENCE_PRESSURE)) / EXP_GMRL; - float reference_pressure = 101325.0f; // in Pa. - float current_pressure = getPressure() * 100.0f; - float exponent = (log(current_pressure) - log(reference_pressure)) / exp_gmrl; - - float height = reference_temp/temp_lapse_rate * (1 - pow(M_E, exponent)); + float height = REFERENCE_TEMP / TEMP_LAPSE_RATE * (1 - pow(M_E, EXPONENT)); return height; } From 9768b6444412473de294fcde21578e2c0be5fe68 Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Sun, 28 Apr 2024 01:02:04 -0400 Subject: [PATCH 11/12] Modified functions to allow for communication error checking --- Altimeter/Inc/altimeter.hpp | 101 +++++++++++++++---------- Altimeter/Src/altimeter.cpp | 145 +++++++++++++++++++++++++++--------- 2 files changed, 171 insertions(+), 75 deletions(-) diff --git a/Altimeter/Inc/altimeter.hpp b/Altimeter/Inc/altimeter.hpp index 6b32acd..a90317d 100644 --- a/Altimeter/Inc/altimeter.hpp +++ b/Altimeter/Inc/altimeter.hpp @@ -19,7 +19,6 @@ constexpr uint8_t PROM_READ_ADDRESS_5 = 0xAA; constexpr uint8_t PROM_READ_ADDRESS_6 = 0xAC; constexpr uint8_t PROM_READ_ADDRESS_7 = 0xAE; - // digital pressure/temperature commands at different sampling rates. constexpr uint8_t CONVERT_D1_OSR_256 = 0x40; constexpr uint8_t CONVERT_D1_OSR_512 = 0x42; @@ -34,16 +33,14 @@ constexpr uint8_t CONVERT_D2_OSR_4096 = 0x58; constexpr uint8_t ADC_READ = 0x0; -constexpr uint32_t TIMEOUT = 1 << 31; class MS5611{ public: /** - * Constructor for the AltDevice class. + * Constructor for the MS5611 class. * It assigns the spi_handler and ports and pins related to the chip select and protocol pins. - * This function sends the reset command, populates the cal_coeffs - * struct members with the calibration coefficients in the sensor PROM, - * and gets the current elevation above sea level. + * This function resets the device, populates reads calibration data from the device's PROM + * PROM, and gets the sensor's initial elevation above sea level. * * * @param spi_handle -> hspix handle @@ -54,89 +51,112 @@ class MS5611{ * * @return none */ - MS5611(SPI_HandleTypeDef *spi_handle, - GPIO_TypeDef *cs_port, - GPIO_TypeDef *ps_port, - uint16_t cs_pin, + MS5611(SPI_HandleTypeDef *spi_handle, + GPIO_TypeDef *cs_port, + GPIO_TypeDef *ps_port, + uint16_t cs_pin, uint16_t ps_pin); /** - * @return the current pressure value + * Calculates the pressure in mbar and assigns it to the variable passed by + * reference. + * + * @param pressure -> reference to pressure variable + * + * @return bool for if there were no communication failures with barometer. */ - float getPressure(); + bool getPressure(float &pressure); /** - * @return the current temperature value + * Calculates the temperature in celsius and assigns it to the variable passed by + * reference. + * + * @param temperature -> reference to temperature variable + * + * @return bool for if there were no communication failures with barometer. */ - float getTemperature(); + bool getTemperature(float &temperature); /** - * @return the current altitude above sea level. + * Calculates the height above sea level in meters and assigns it to the variable passed by + * reference. + * + * @param altitude_above_sea_level -> reference to altitude variable + * + * @return bool for if there were no communication failures with barometer. */ - float getAltitudeAboveSeaLevel(); + bool getAltitudeAboveSeaLevel(float &altitude_above_sea_level); /** - * @return the current altitude above zero point. + * Calculates the height above ground level in meters and assigns it to the variable passed by + * reference. + * + * @param altitude_above_ground_level -> reference to altitude variable + * + * @return bool for if there were no communication failures with barometer. */ - float getAltitudeAboveGroundLevel(); + bool getAltitudeAboveGroundLevel(float &altitude_above_ground_level); private: - // Setup description comment. + //pointer for spi handler. SPI_HandleTypeDef *spi_handle_; + + //chip select and protocol select ports and pins. GPIO_TypeDef *cs_port_; GPIO_TypeDef *ps_port_; uint16_t cs_pin_; uint16_t ps_pin_; - // ms5611 calibration coefficients for pressure and temperature calculations. - uint16_t pressure_sensitivity_; - uint16_t pressure_offset_; - uint16_t pres_sensitivity_temp_coeff_; // Temperature coefficient of pressure sensitivity. - uint16_t pres_offset_temp_coeff_; // temperature coefficient of temperature offset. - uint16_t reference_temperature_; - uint16_t temp_coeff_of_temp_; // Temperature coefficient of temperature. + //Holds the barometer PROM data. + uint16_t ms6511_prom_data_[8]; - // barometer measurement variables. + //barometer measurement variables. float base_elev_; - float height_; float temp_; float pres_; + //hal_spi_transmitreceive status HAL_StatusTypeDef spi_status_; + //to track communication failures + bool communication_success_; + /** - * Sends the reset command to the barometer. - * - * @param ps_port -> protocol select port - * @param ps_pin -> protocol select pin - * @param spi_handle -> hspix handle + * Sends the reset command to the barometer. The reset command makes sure that + * the PROM, which holds calibration data, gets loaded into the device's internal register. * * @return none */ void reset(); /** - * Populates the struct with calibration coefficients. + * Populates ms6511_prom_data_ with data from PROM * * @return none */ - void getConvCoeffs(); + void getPromData(); /** * Reads PROM data from user-specified 16-bit address. * - * @return calibration data + * @param address -> The address from which you want to read data. + * @param ms5611_prom_data -> pointer to ms5611_prom_data array. + * + * @return bool for if there were no communication failures with barometer. */ - uint16_t promRead(uint8_t address); + bool promRead(uint8_t address, uint16_t *ms5611_prom_data); /** - * Reads uncompenssated temperature/pressure value from altimeter. + * Reads uncompensated temperature/pressure value from altimeter. * - * @return uncompensated pressure/temperature value + * @param conversion_command -> command used to fetch digital temperature/pressure + * @param uncompensated_pressure_temperature -> reference to uncompensated pressure/temperature value + * + * @return bool for if there were no communication failures with barometer. */ - uint32_t readPressureTemperatureUncompensated(uint8_t conversion_command); + bool readPressureTemperatureUncompensated(uint8_t conversion_command, uint32_t &uncompensated_pressure_temperature); /** * Calculates the temperature in degrees celsius and pressure in mbar. @@ -148,3 +168,4 @@ class MS5611{ #endif /* INC_ALTIMETER_HPP_ */ + diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index 755cbbb..a2a60dc 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -9,16 +9,28 @@ MS5611::MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDe ps_pin_ = ps_pin; HAL_GPIO_WritePin(ps_port_, ps_pin_, GPIO_PIN_RESET); + communication_success_ = true; + reset(); - getConvCoeffs(); + getPromData(); - // Get the average of 100 readings. + // Grab the sensor's altitude above sea level while on some surface and assign it to base_elev_ + // Subtract this from measurements at greater heights for the height above that initial surface. float reading_sum = 0.0f; + float altitude_above_sea_level_measurement = 0; + int num_successful_measurements = 0; for (int i = 0; i < 100; i++) { - reading_sum += getAltitudeAboveSeaLevel(); + communication_success_ = true; + communication_success_ = getAltitudeAboveSeaLevel(altitude_above_sea_level_measurement); + if (communication_success_) { //add measurement if function call is successful. + reading_sum += altitude_above_sea_level_measurement; + num_successful_measurements += 1; + }else{ + communication_success_ = false; + } } - - base_elev_ = reading_sum / 100.0f; + //take the average of the number of successful measurements. + base_elev_ = reading_sum / num_successful_measurements; } void MS5611::reset(){ @@ -29,22 +41,29 @@ void MS5611::reset(){ uint8_t rx_data[3]; uint16_t data_size = 3; - HAL_SPI_TransmitReceive(spi_handle_, tx_data, rx_data, data_size, TIMEOUT); + spi_status_ = HAL_SPI_TransmitReceive_IT(spi_handle_, tx_data, rx_data, data_size); + if (spi_status_ != HAL_OK) { + communication_success_ = false; + } osDelay(3); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); } -void MS5611::getConvCoeffs(){ - pressure_sensitivity_ = promRead(PROM_READ_ADDRESS_1); - pressure_offset_ = promRead(PROM_READ_ADDRESS_2); - pres_sensitivity_temp_coeff_ = promRead(PROM_READ_ADDRESS_3); - pres_offset_temp_coeff_ = promRead(PROM_READ_ADDRESS_4); - reference_temperature_ = promRead(PROM_READ_ADDRESS_5); - temp_coeff_of_temp_ = promRead(PROM_READ_ADDRESS_6); +void MS5611::getPromData(){ + for (int i = 0; i < 8; ++i) { + communication_success_ = promRead(PROM_READ_ADDRESS_0 + 2 * i, ms6511_prom_data_ + i); + if (!communication_success_){ + return; + } + } } -uint16_t MS5611::promRead(uint8_t address){ +bool MS5611::promRead(uint8_t address, uint16_t *ms5611_prom_data){ + if (!communication_success_){ + return communication_success_; + } + HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); @@ -52,17 +71,25 @@ uint16_t MS5611::promRead(uint8_t address){ uint8_t rx_data[3]; uint16_t data_size = 3; - HAL_SPI_TransmitReceive(spi_handle_, tx_data, rx_data, data_size, TIMEOUT); + spi_status_ = HAL_SPI_TransmitReceive_IT(spi_handle_, tx_data, rx_data, data_size); + if (spi_status_ != HAL_OK) { + communication_success_ = false; + return communication_success_; + } HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); // construct 16-bit calibration coefficient. - uint16_t calibration_coefficient = (rx_data[1] << 8) | (rx_data[2]) & 0x0000FFFF; + *ms5611_prom_data = ((rx_data[1] << 8) | (rx_data[2])) & 0x0000FFFF; - return calibration_coefficient; + return communication_success_; } -uint32_t MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command){ +bool MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command, uint32_t &uncompensated_pressure_temperature){ + + if (!communication_success_){ + return communication_success_; + } uint8_t tx_data = conversion_command; uint8_t rx_data; @@ -72,7 +99,11 @@ uint32_t MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); // send the digital pressure or temperature with the command. - HAL_SPI_TransmitReceive(spi_handle_, tx_data, rx_data, data_size, TIMEOUT); + spi_status_ = HAL_SPI_TransmitReceive_IT(spi_handle_, &tx_data, &rx_data, data_size); + if (spi_status_ != HAL_OK) { + communication_success_ = false; + return communication_success_; + } HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); // at least 8.22 ms delay required for ADC conversion. @@ -85,20 +116,34 @@ uint32_t MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); // Start adc conversion to get value - HAL_SPI_TransmitReceive(spi_handle_, tx_data_2, rx_data_2, data_size, TIMEOUT); + spi_status_ = HAL_SPI_TransmitReceive_IT(spi_handle_, tx_data_2, rx_data_2, data_size); + if (spi_status_ != HAL_OK) { + communication_success_ = false; + return communication_success_; + } HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); // get 24-bit uncompensated pressure or temperature value value. - uint32_t uncompensated_value = (rx_data_2[1] << 16 | rx_data_2[2] << 8 | rx_data_2[3]) & 0x00FFFFFF; + uncompensated_pressure_temperature = (rx_data_2[1] << 16 | rx_data_2[2] << 8 | rx_data_2[3]) & 0x00FFFFFF; - return uncompensated_value; + return communication_success_; } void MS5611::calculateTemperatureAndPressure(){ - uint32_t digital_temperature = readPressureTemperatureUncompensated(CONVERT_D2_OSR_256); - uint32_t digital_pressure = readPressureTemperatureUncompensated(CONVERT_D1_OSR_256); + uint32_t digital_temperature = 0; + uint32_t digital_pressure = 0; + + communication_success_ = readPressureTemperatureUncompensated(CONVERT_D2_OSR_256, digital_temperature); + if (!communication_success_){ + return; + } + + communication_success_ = readPressureTemperatureUncompensated(CONVERT_D1_OSR_256, digital_pressure); + if (!communication_success_){ + return; + } const float TWO_POW_1 = 2.0f; const float TWO_POW_2 = 4.0f; @@ -112,6 +157,15 @@ void MS5611::calculateTemperatureAndPressure(){ const float FIVE = 5.0f; + // ms5611 calibration coefficients for pressure and temperature calculations. + uint16_t pressure_sensitivity_ = ms6511_prom_data_[1]; + uint16_t pressure_offset_ = ms6511_prom_data_[2]; + uint16_t pres_sensitivity_temp_coeff_ = ms6511_prom_data_[3]; //Temperature coefficient of pressure sensitivity. + uint16_t pres_offset_temp_coeff_ = ms6511_prom_data_[4]; // temperature coefficient of temperature offset. + uint16_t reference_temperature_ = ms6511_prom_data_[5]; + uint16_t temp_coeff_of_temp_ = ms6511_prom_data_[6]; // Temperature coefficient of temperature. + + float dt = digital_temperature - (float)reference_temperature_ * TWO_POW_8; float temp = 2000 + dt * (float)temp_coeff_of_temp_ / TWO_POW_23; float pressure_offset = pressure_offset_ * TWO_POW_16 + (pres_offset_temp_coeff_ * dt) / TWO_POW_7; @@ -141,32 +195,53 @@ void MS5611::calculateTemperatureAndPressure(){ temp_ = temp; } -float MS5611::getPressure(){ +bool MS5611::getPressure(float &pressure){ calculateTemperatureAndPressure(); - return pres_; + if (!communication_success_) { + return false; + } + pressure = pres_; + return true; } -float MS5611::getTemperature(){ +bool MS5611::getTemperature(float &temperature){ calculateTemperatureAndPressure(); - return temp_; + if (!communication_success_) { + return false; + } + temperature = temp_; + return true; } -float MS5611::getAltitudeAboveSeaLevel(){ +bool MS5611::getAltitudeAboveSeaLevel(float &altitude_above_sea_level){ + float pressure = 0.0f; + communication_success_ = getPressure(pressure); + + if (!communication_success_) { + return communication_success_; + } + const float REFERENCE_TEMP = 288.15f; /* Ref temperature in Kelvins */ const float TEMP_LAPSE_RATE = 0.0065f; const float EXP_GMRL = 5.2558; const float REFERENCE_PRESSURE = 101325.0f; /* in Pa */ - const float CURRENT_PRESSURE = getPressure() * 100.0f; + const float CURRENT_PRESSURE = pressure * 100.0f; const float EXPONENT = (log(CURRENT_PRESSURE) - log(REFERENCE_PRESSURE)) / EXP_GMRL; - float height = REFERENCE_TEMP / TEMP_LAPSE_RATE * (1 - pow(M_E, EXPONENT)); + altitude_above_sea_level = REFERENCE_TEMP / TEMP_LAPSE_RATE * (1 - pow(M_E, EXPONENT)); - return height; + return communication_success_; } -float MS5611::getAltitudeAboveGroundLevel(){ - height_ = getAltitudeAboveSeaLevel(); - return {height_ - base_elev_}; +bool MS5611::getAltitudeAboveGroundLevel(float &altitude_above_ground_level){ + float alt_above_sea_lvl = 0.0f; + communication_success_ = getAltitudeAboveSeaLevel(alt_above_sea_lvl); + if (!communication_success_) { + return communication_success_; + } + + altitude_above_ground_level = alt_above_sea_lvl - base_elev_; + return communication_success_; } From 27739b0ffe4723902feca13a77c2a8146f4bd48e Mon Sep 17 00:00:00 2001 From: FolaFatola Date: Sun, 28 Apr 2024 20:40:09 -0400 Subject: [PATCH 12/12] Name changes made to variables in calculateTemperatureAndPressure() function --- Altimeter/Src/altimeter.cpp | 51 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/Altimeter/Src/altimeter.cpp b/Altimeter/Src/altimeter.cpp index a2a60dc..9c4f634 100644 --- a/Altimeter/Src/altimeter.cpp +++ b/Altimeter/Src/altimeter.cpp @@ -16,21 +16,21 @@ MS5611::MS5611(SPI_HandleTypeDef *spi_handle, GPIO_TypeDef *cs_port, GPIO_TypeDe // Grab the sensor's altitude above sea level while on some surface and assign it to base_elev_ // Subtract this from measurements at greater heights for the height above that initial surface. - float reading_sum = 0.0f; + float base_elevation = 0.0f; float altitude_above_sea_level_measurement = 0; int num_successful_measurements = 0; - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 100; i++) { //take a few measurements to make sure they are accurate/consistent. communication_success_ = true; communication_success_ = getAltitudeAboveSeaLevel(altitude_above_sea_level_measurement); - if (communication_success_) { //add measurement if function call is successful. - reading_sum += altitude_above_sea_level_measurement; + if (communication_success_) { + base_elevation = altitude_above_sea_level_measurement; num_successful_measurements += 1; }else{ communication_success_ = false; } } - //take the average of the number of successful measurements. - base_elev_ = reading_sum / num_successful_measurements; + + base_elev_ = base_elevation; } void MS5611::reset(){ @@ -45,9 +45,9 @@ void MS5611::reset(){ if (spi_status_ != HAL_OK) { communication_success_ = false; } - osDelay(3); HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); + osDelay(3); } void MS5611::getPromData(){ @@ -78,6 +78,7 @@ bool MS5611::promRead(uint8_t address, uint16_t *ms5611_prom_data){ } HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); + osDelay(9); // construct 16-bit calibration coefficient. *ms5611_prom_data = ((rx_data[1] << 8) | (rx_data[2])) & 0x0000FFFF; @@ -93,6 +94,8 @@ bool MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command, ui uint8_t tx_data = conversion_command; uint8_t rx_data; + uint8_t tx_data_2[4] = {ADC_READ, 0xFF, 0xFF, 0xFF}; + uint8_t rx_data_2[4]; uint16_t data_size = 1; HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET); @@ -109,8 +112,6 @@ bool MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command, ui // at least 8.22 ms delay required for ADC conversion. osDelay(9); - uint8_t tx_data_2[4] = {ADC_READ, 0xFF, 0xFF, 0xFF}; - uint8_t rx_data_2[4]; data_size = 4; HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET); @@ -126,6 +127,7 @@ bool MS5611::readPressureTemperatureUncompensated(uint8_t conversion_command, ui // get 24-bit uncompensated pressure or temperature value value. uncompensated_pressure_temperature = (rx_data_2[1] << 16 | rx_data_2[2] << 8 | rx_data_2[3]) & 0x00FFFFFF; + osDelay(9); return communication_success_; } @@ -135,12 +137,12 @@ void MS5611::calculateTemperatureAndPressure(){ uint32_t digital_temperature = 0; uint32_t digital_pressure = 0; - communication_success_ = readPressureTemperatureUncompensated(CONVERT_D2_OSR_256, digital_temperature); + communication_success_ = readPressureTemperatureUncompensated(CONVERT_D2_OSR_4096, digital_temperature); if (!communication_success_){ return; } - communication_success_ = readPressureTemperatureUncompensated(CONVERT_D1_OSR_256, digital_pressure); + communication_success_ = readPressureTemperatureUncompensated(CONVERT_D1_OSR_4096, digital_pressure); if (!communication_success_){ return; } @@ -158,18 +160,18 @@ void MS5611::calculateTemperatureAndPressure(){ const float FIVE = 5.0f; // ms5611 calibration coefficients for pressure and temperature calculations. - uint16_t pressure_sensitivity_ = ms6511_prom_data_[1]; - uint16_t pressure_offset_ = ms6511_prom_data_[2]; - uint16_t pres_sensitivity_temp_coeff_ = ms6511_prom_data_[3]; //Temperature coefficient of pressure sensitivity. - uint16_t pres_offset_temp_coeff_ = ms6511_prom_data_[4]; // temperature coefficient of temperature offset. - uint16_t reference_temperature_ = ms6511_prom_data_[5]; - uint16_t temp_coeff_of_temp_ = ms6511_prom_data_[6]; // Temperature coefficient of temperature. + uint16_t pressure_sensitivity = ms6511_prom_data_[1]; + uint16_t pressure_offset = ms6511_prom_data_[2]; + uint16_t pres_sensitivity_temp_coeff = ms6511_prom_data_[3]; //Temperature coefficient of pressure sensitivity. + uint16_t pres_offset_temp_coeff = ms6511_prom_data_[4]; // temperature coefficient of temperature offset. + uint16_t reference_temperature = ms6511_prom_data_[5]; + uint16_t temp_coeff_of_temp = ms6511_prom_data_[6]; // Temperature coefficient of temperature. - float dt = digital_temperature - (float)reference_temperature_ * TWO_POW_8; - float temp = 2000 + dt * (float)temp_coeff_of_temp_ / TWO_POW_23; - float pressure_offset = pressure_offset_ * TWO_POW_16 + (pres_offset_temp_coeff_ * dt) / TWO_POW_7; - float pressure_sensitivity = pressure_sensitivity_ * TWO_POW_15 + (pres_sensitivity_temp_coeff_ * dt) / TWO_POW_8; + float dt = digital_temperature - (float)reference_temperature * TWO_POW_8; + float temp = 2000 + dt * (float)temp_coeff_of_temp / TWO_POW_23; + float f_pressure_offset = pressure_offset * TWO_POW_16 + (pres_offset_temp_coeff * dt) / TWO_POW_7; + float f_pressure_sensitivity = pressure_sensitivity * TWO_POW_15 + (pres_sensitivity_temp_coeff * dt) / TWO_POW_8; // Second order temperature compensation. if (temp < 2000) { @@ -183,11 +185,11 @@ void MS5611::calculateTemperatureAndPressure(){ } temp = temp - t2; - pressure_offset = pressure_offset - pressure_offset_2; - pressure_sensitivity = pressure_sensitivity - pressure_sensitivity_2; + f_pressure_offset = f_pressure_offset - pressure_offset_2; + f_pressure_sensitivity = f_pressure_sensitivity - pressure_sensitivity_2; } - float pressure = (digital_pressure * (pressure_sensitivity / TWO_POW_21) - pressure_offset) / TWO_POW_15; + float pressure = (digital_pressure * (f_pressure_sensitivity / TWO_POW_21) - f_pressure_offset) / TWO_POW_15; pressure /= 100.0f; temp /= 100.0f; @@ -244,4 +246,3 @@ bool MS5611::getAltitudeAboveGroundLevel(float &altitude_above_ground_level){ altitude_above_ground_level = alt_above_sea_lvl - base_elev_; return communication_success_; } -