diff --git a/bmx280.c b/bmx280.c index 57058a4..04b375f 100644 --- a/bmx280.c +++ b/bmx280.c @@ -381,6 +381,47 @@ esp_err_t bmx280_configure(bmx280_t* bmx280, bmx280_config_t *cfg) return ESP_OK; } +esp_err_t bmx280_setMode(bmx280_t* bmx280, bmx280_mode_t mode) +{ + uint8_t ctrl_mes; + esp_err_t err; + + if ((err = bmx280_read(bmx280, BMX280_REG_MESCTL, &ctrl_mes, 1)) != ESP_OK) + return err; + + ctrl_mes = (ctrl_mes & (~3)) | mode; + + return bmx280_write(bmx280, BMX280_REG_MESCTL, &ctrl_mes, 1); +} + +esp_err_t bmx280_getMode(bmx280_t* bmx280, bmx280_mode_t* mode) +{ + uint8_t ctrl_mes; + esp_err_t err; + + if ((err = bmx280_read(bmx280, BMX280_REG_MESCTL, &ctrl_mes, 1)) != ESP_OK) + return err; + + ctrl_mes &= 3; + + switch (ctrl_mes) + { + default: + return ctrl_mes; + case (BMX280_MODE_FORCE + 1): + return BMX280_MODE_FORCE; + } +} + +bool bmx280_isSampling(bmx280_t* bmx280) +{ + uint8_t status; + if (bmx280_read(bmx280, BMX280_REG_STATUS, &status, 1) == ESP_OK) + return (status & (1 << 3)) != 0; + else + return false; +} + // HERE BE DRAGONS // This code is revised from the Bosch code within the datasheet of the BME280. // I do not understand it enough to tell you what it does. @@ -438,3 +479,59 @@ uint32_t bme280_compensate_H_int32(bmx280_t *bmx280, int32_t adc_H) #endif // END OF DRAGONS + +esp_err_t bmx280_readout(bmx280_t *bmx280, int32_t *temperature, uint32_t *pressure, uint32_t *humidity) +{ + if (bmx280 == NULL) return ESP_ERR_INVALID_ARG; + if (!bmx280_validate(bmx280)) return ESP_ERR_INVALID_STATE; + + uint8_t buffer[3]; + esp_err_t error; + + if (temperature) + { + if ((error = bmx280_read(bmx280, BMX280_REG_TEMP_MSB, buffer, 3)) != ESP_OK) + return error; + + *temperature = BME280_compensate_T_int32(bmx280, + (buffer[0] << 12) | (buffer[1] << 4) | (buffer[0] >> 4) + ); + } + + if (pressure) + { + if ((error = bmx280_read(bmx280, BMX280_REG_PRES_MSB, buffer, 3)) != ESP_OK) + return error; + + *pressure = BME280_compensate_P_int64(bmx280, + (buffer[0] << 12) | (buffer[1] << 4) | (buffer[0] >> 4) + ); + } + + #if !(CONFIG_BMX280_EXPECT_BMP280) + #if CONFIG_BMX280_EXPECT_DETECT + if (bmx280_isBME(bmx280->chip_id)) + #elif CONFIG_BMX280_EXPECT_BME280 + #endif + { + if (humidity) + { + if ((error = bmx280_read(bmx280, BMX280_REG_HUMI_MSB, buffer, 2)) != ESP_OK) + return error; + + *humidity = bme280_compensate_H_int32(bmx280, + (buffer[0] << 8) | buffer[0] + ); + } + } + #if CONFIG_BMX280_EXPECT_DETECT + else if (humidity) + *humidity = UINT32_MAX; + #endif + #else + if (humidity) + *humidity = UINT32_MAX; + #endif + + return ESP_OK; +} diff --git a/include/bmx280.h b/include/bmx280.h index 97192f5..9a9b842 100644 --- a/include/bmx280.h +++ b/include/bmx280.h @@ -42,8 +42,23 @@ esp_err_t bmx280_init(bmx280_t* bmx280); */ esp_err_t bmx280_configure(bmx280_t* bmx280, bmx280_config_t *cfg); +/** + * Set the sensor mode of operation. + * @param bmx280 Driver structure. + * @param mode The mode to set the sensor to. + */ esp_err_t bmx280_setMode(bmx280_t* bmx280, bmx280_mode_t mode); +/** + * Get the sensor current mode of operation. + * @param bmx280 Driver structure. + * @param mode Pointer to write current mode to. + */ +esp_err_t bmx280_getMode(bmx280_t* bmx280, bmx280_mode_t* mode); +/** + * Returns true if sensor is currently sampling environment conditions. + * @param bmx280 Driver structure. + */ bool bmx280_isSampling(bmx280_t* bmx280); /** @@ -55,13 +70,29 @@ bool bmx280_isSampling(bmx280_t* bmx280); */ esp_err_t bmx280_readout(bmx280_t *bmx280, int32_t *temperature, uint32_t *pressure, uint32_t *humidity); -static inline void bmx280_readout2float(bmx280_t *bmx280, int32_t* tin, uint32_t *pin, uint32_t *hin, float *tout, float *pout, float *hout) +/** + * Convert sensor readout to floating point values. + * @param tin Input temperature. + * @param pin Input pressure. + * @param hin Input humidity. + * @param tout Output temperature. (C) + * @param pout Output pressure. (Pa) + * @param hout Output humidity. (%Rh) + */ +static inline void bmx280_readout2float(int32_t* tin, uint32_t *pin, uint32_t *hin, float *tout, float *pout, float *hout) { - *tout = (float)*tin * 0.1f; + *tout = (float)*tin * 0.01f; *pout = (float)*pin * (1.0f/256.0f); *hout = (*hin == UINT32_MAX) ? -1.0f : (float)*hin * (1.0f/1024.0f); } +/** + * Read sensor values as floating point numbers. + * @param bmx280 Driver structure. + * @param temperature The temperature in C. + * @param pressure The pressure in Pa. + * @param humidity The humidity in %RH. + */ static inline esp_err_t bmx280_readoutFloat(bmx280_t *bmx280, float* temperature, float* pressure, float* humidity) { int32_t t; uint32_t p, h; @@ -69,7 +100,7 @@ static inline esp_err_t bmx280_readoutFloat(bmx280_t *bmx280, float* temperature if (err == ESP_OK) { - bmx280_readout2float(bmx280, &t, &p, &h, temperature, pressure, humidity); + bmx280_readout2float(&t, &p, &h, temperature, pressure, humidity); } return err; diff --git a/include/bmx280_bits.h b/include/bmx280_bits.h index c53fdb2..7dc61ff 100644 --- a/include/bmx280_bits.h +++ b/include/bmx280_bits.h @@ -57,11 +57,11 @@ typedef enum bmx280_iirf_t { typedef enum bmx280_mode_t { /** Sensor does no measurements. */ - BMX280_MODE_SLEEP, + BMX280_MODE_SLEEP = 0, /** Sensor is in a forced measurement cycle. Sleeps after finishing. */ - BMX280_MODE_FORCE, + BMX280_MODE_FORCE = 1, /** Sensor does measurements. Never sleeps. */ - BMX280_MODE_CYCLE, + BMX280_MODE_CYCLE = 3, } bmx280_mode_t; typedef struct bmx280_config_t {