#ifndef STA_SENSORS_MS5607_HPP #define STA_SENSORS_MS5607_HPP #include #include #include // Important: The pin CSB shall be connected to VDD or GND (do not leave unconnected!). /** * @brief MS56xx address when the CS pin is connected to GND. * */ #define MS56XX_ADDRESS_CS_LOW 0x1110111 /** * @brief MS56xx address when the CS pin is connected to VDD. * */ #define MS56XX_ADDRESS_CS_HIGH 0x1110110 namespace sta { /** * @brief Driver class for communicating with the MS56xx pressure sensor via SPI. * */ class MS56xx { public: /** * @brief Signature for delay msec function. */ using DelayUsFunc = void (*)(uint32_t); /** * @brief Different OSR levels for the sensor * */ enum OsrLevel { _256 = 0, _512 = 1, _1024 = 2, _2048 = 3, _4096 = 4 }; /** * @brief Different units supported by the pressure sensor. * */ enum Unit { hPa, Pa, mbar }; /** * @brief All possible commands to send to the sensor * */ enum Operations { RESET = 0x1E, READ_PROM = 0xA2, D1_CONVERSION = 0x40, D2_CONVERSION = 0x50, ADC_RESULT = 0x00 }; /** * @brief SPI driver for the MS56xx pressure sensor series. * * @param device The SPI device for bus communication. * @param delay Function for triggering microsecond delays. * @param osr The oversampling rate for the sensor. * * @note Set PS pin to low for SPI. Maximum SPI frequency 20MHz, mode 0 and 3 are supported. */ MS56xx(SPIDevice * device, DelayUsFunc delay, OsrLevel osr = OsrLevel::_1024); /** * @brief I2C driver for the MS56xx pressure sensor series. * * @param device The I2C device for bus communication. * @param delay Function for triggering microsecond delays. * @param osr The oversampling rate for the sensor. * * @note Set PS pin to high for I2C. Chip select pin represents LSB of address. */ MS56xx(I2CDevice * device, DelayUsFunc delay, OsrLevel osr = OsrLevel::_1024); /** * @brief Initialize the driver. Computes the pressure value at altitude 0. * * @return True if successful, false otherwise. */ bool init(); /** * @brief Set the oversampling rate. * * @param osr The new oversampling rate. */ void setOsr(OsrLevel osr); /** * @brief Reads the current pressure value from the sensor. * * @param temperature The temperature in Celsius * 100 (e.g. 20.3 deg. C -> 2030) * @param unit Specifies the unit for the pressure measurement. Default is hPa. * @return uint32_t The measured value in the specified unit. */ int32_t getPressure(int32_t temperature, Unit unit = Unit::hPa); /** * @brief Reads the current pressure value from the sensor. Obtains the temperature value from the interal sensor. * * @param unit Specifies the unit for the pressure measurement. Default is hPa. * @return int32_t The measured value in the specified unit. */ int32_t getPressure(Unit unit = Unit::hPa); /** * @brief Reads the current temperature value from the sensor. * * @return int32_t The measured temperature. * @note There are better sensors for temperature measurements than the MS56xx. */ int32_t getTemperature(); /** * @brief Set the Pressure Reference object * * @param pressRef The reference pressure value measured at a reference altitude. * @param altRef The reference altitude for the reference pressure. */ /** * @brief Provide a reference pressure value at a reference altitude in order to estimate the sealevel pressure. * * @param pressRef The reference pressure value measured at a reference altitude. * @param altRef The reference altitude for the reference pressure. * @param unit The unit of the provided pressure value. */ void setPressureReference(float pressRef, float altRef, Unit unit = Unit::hPa); /** * @brief Estimate the current altitude based on the pressure readings. * * @param temperature A temperature measurement from an external source. * @return float The altitude estimate in meters. */ float getAltitudeEstimate(int32_t temperature); /** * @brief Estimate the current altitude based on the pressure readings. * * @return float The altitude estimate in meters. */ float getAltitudeEstimate(); private: /** * @brief Reset the sensor. * */ void reset(); /** * @brief Read all constants from the PROM * */ void readPROM(); /** * @brief * * @param ms */ void pulseCS(uint32_t ms=1); /** * @brief Compute the pressure values from the ADC output. * * @param d1 * @param dT * @param unit The unit to return the pressure values in. * @return int32_t */ int32_t calculatePressure(uint32_t d1, int32_t dT, Unit unit); /** * @brief Compute the temperature values from the ADC output * * @param d2 * @return int32_t */ int32_t calculateTemperature(uint32_t d2); /** * @brief * * @param temp * @return int32_t */ int32_t reverseTempCalc(int32_t temp); uint16_t uint_8BufferTouint16_t(uint8_t* buffer); private: bool busCommand(uint8_t command); bool busRead(uint8_t reg, uint8_t * buffer, size_t length); bool busWrite(uint8_t reg, uint8_t * buffer, size_t length); private: // STA internal object for SPi abstraction Device * device_; DelayUsFunc delay_; OsrLevel osr_; // Pressure at sealevel. int32_t sealevel_; // 6 Different constants; Includes Offsets, references etc. uint16_t sens, off, tcs, tco, t_ref, tempsens; // Constants for waiting const uint32_t RESET_DELAY = 2800; // in uS // Function to get the delay times needed for different OSR Levels // Values not found in datasheet (facepalm) // Thus partly googled, partly tested out static uint8_t delayTimes(OsrLevel level) { switch (level) { case _256: return 1; case _512: return 2; case _1024: return 3; case _2048: return 5; case _4096: return 10; } } }; } #endif // ifndef STA_SENSORS_MS5607_HPP