// -------------------------------------------------------------------------------------------------------------------- /// \file bme280.cpp /// \brief Description // -------------------------------------------------------------------------------------------------------------------- // // vbchaos software design // // -------------------------------------------------------------------------------------------------------------------- /// $Revision: $ /// $Author: $ /// $Date: $ // (c) 2023 vbchaos // -------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------- // Include files // -------------------------------------------------------------------------------------------------------------------- #include #include "logger.h" // -------------------------------------------------------------------------------------------------------------------- // Constant and macro definitions // -------------------------------------------------------------------------------------------------------------------- // List of registers #define ADDRESS_COMP_PARAMETERS ((uint32_t)0x88) #define ADDRESS_REG_ID ((uint32_t)0xD0) #define ADDRESS_REG_RESET ((uint32_t)0xE0) #define ADDRESS_REG_STATUS ((uint32_t)0xF3) #define ADDRESS_REG_CTRL_MEAS ((uint32_t)0xF4) #define ADDRESS_REG_CONFIG ((uint32_t)0xF5) #define ADDRESS_REG_PRESSURE_MSB ((uint32_t)0xF7) #define ADDRESS_REG_PRESSURE_LSB ((uint32_t)0xF8) #define ADDRESS_REG_PRESSURE_XLSB ((uint32_t)0xF9) #define ADDRESS_REG_TEMPERATURE_MSB ((uint32_t)0xFA) #define ADDRESS_REG_TEMPERATURE_LSB ((uint32_t)0xFB) #define ADDRESS_REG_TEMPERATURE_XLSB ((uint32_t)0xFC) // -------------------------------------------------------------------------------------------------------------------- // Type definitions // -------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------- // File-scope variables // -------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------- // Function declarations // -------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------- // Function definitions // -------------------------------------------------------------------------------------------------------------------- BMP280::BMP280(I2C* bus, uint8_t slaveAddress) { // Take over the bus BMP280::bus = bus; // Take over the device slave address BMP280::slaveAddress = slaveAddress; // Reset the driver itself resetDriver(); // Reset the device } void BMP280::resetSensor(void) { resetDevice(); } bool BMP280::initialize(void) { bool returnValue = true; // First read the device ID getDeviceID(); // Device ID must match, otherwise there is a component error if (memorymap.id != BMP280_DEVICE_ID) { returnValue = false; } if (returnValue) { // Get the compensation values from the device getCompensationValues(); } return returnValue; } bool BMP280::setSensorMode(BMP280_Mode_t mode) { bool returnValue = true; memorymap.ctrl_meas.mode = mode; setSensorControlMeasurement(); return returnValue; } bool BMP280::setSensorTemperatureOversampling(BMP280_Oversampling_t oversampling) { bool returnValue = true; memorymap.ctrl_meas.oversampling_temp = oversampling; setSensorControlMeasurement(); return returnValue; } int BMP280::getTemperature(void) { // Get latest raw values from device BMP280::getTemperatureValues(); // Calculate temperature BMP280::compensateTemperature(); // return the value return temperature; } void BMP280::resetDriver(void) { // Reset the parameters BMP280::compensationParameters = {}; // Reset the device memory map BMP280::memorymap = {}; // Reset the mode BMP280::mode = STANDBY; // Reset calculation values t_fine = 0; temperature = 0; } void BMP280::getDeviceID(void) { bus->read_register(slaveAddress, ADDRESS_REG_ID, &memorymap.id, 1); } void BMP280::resetDevice(void) { uint8_t resetValue = BMP280_RESET_VALUE; bus->write_register(slaveAddress, ADDRESS_REG_RESET, &resetValue, 1); } void BMP280::setSensorControlMeasurement(void) { bus->write_register(slaveAddress, ADDRESS_REG_CTRL_MEAS, (uint8_t*)&memorymap.ctrl_meas, 1); } void BMP280::setSensorConfiguration(void) { bus->write_register(slaveAddress, ADDRESS_REG_CONFIG, (uint8_t*)&memorymap.config, 1); } void BMP280::getCompensationValues(void) { bus->read_register(slaveAddress, ADDRESS_COMP_PARAMETERS, (uint8_t*)&compensationParameters, sizeof(compensationParameters)); LOGGER_DEBUG("Got compensation values: %04X %04X %04X", compensationParameters.dig_T1, compensationParameters.dig_T2, compensationParameters.dig_T3); } void BMP280::getPreasureValues(void) { bus->read_register(slaveAddress, ADDRESS_REG_PRESSURE_LSB, (uint8_t*)&memorymap.pressure_raw, sizeof(memorymap.pressure_raw)); } void BMP280::getTemperatureValues(void) { bus->read_register(slaveAddress, ADDRESS_REG_TEMPERATURE_MSB, (uint8_t*)&memorymap.temperature_raw, sizeof(memorymap.temperature_raw)); } void BMP280::compensateTemperature(void) { int adc_T = 0; // Create a single temperature value from the individual memory entries adc_T |= memorymap.temperature_raw.msb << 12; adc_T |= memorymap.temperature_raw.lsb << 4; // XLSB is only a nibble adc_T |= memorymap.temperature_raw.xlsb >> 4; int var1 = ((((adc_T >> 3) - ((int)compensationParameters.dig_T1<<1))) * ((int)compensationParameters.dig_T2)) >> 11; int var2 = (((((adc_T>>4) - ((int)compensationParameters.dig_T1)) * ((adc_T>>4) - ((int)compensationParameters.dig_T1))) >> 12) * ((int)compensationParameters.dig_T3)) >> 14; t_fine = var1 + var2; temperature = (t_fine * 5 + 128) >> 8; }