From 09ff7cbeafb8aca614dda631a1c7a6d7e8699ec9 Mon Sep 17 00:00:00 2001 From: Daniel Burke Date: Tue, 15 Sep 2020 20:33:38 -0230 Subject: [PATCH 01/10] Begin implementing pressure sensor I2C interface The DPS310 will be used in the windtunnel project to measure pressure. There will be 25 such sensors, all on an I2C bus --- Node/Common/sensors/inc/DPS310.h | 55 +++++++++++++++++++++ Node/Common/sensors/inc/file.h | 1 - Node/Common/sensors/src/DPS310.cpp | 76 ++++++++++++++++++++++++++++++ Node/Common/sensors/src/file.cpp | 1 - 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 Node/Common/sensors/inc/DPS310.h delete mode 100644 Node/Common/sensors/inc/file.h create mode 100644 Node/Common/sensors/src/DPS310.cpp delete mode 100644 Node/Common/sensors/src/file.cpp diff --git a/Node/Common/sensors/inc/DPS310.h b/Node/Common/sensors/inc/DPS310.h new file mode 100644 index 0000000..5d1a17b --- /dev/null +++ b/Node/Common/sensors/inc/DPS310.h @@ -0,0 +1,55 @@ +#ifndef DPS310_H +#define DPS310_H +#include "Arduino.h" +#include "Wire.h" + +using byte_t = uint8_t; + +enum Register : uint8_t +{ + PSR_B2 = 0x00, + PSR_B1 = 0x01, + PSR_B0 = 0x02, + TMP_B2 = 0x03, + TMP_B1 = 0x04, + TMP_B0 = 0x05, + PRS_CFG = 0x06, + TMP_CFG = 0x07, + MEAS_CFG = 0x08, + CFG_REG = 0x09, + INT_STS = 0x0A, + FIFO_STS = 0x0B, + RESET = 0x0C +}; + +enum Coefficient_Reg : uint8_t +{ + C0 = 0x10, + C1 = 0x11, + C00 = 0x13, + C10 = 0x15, + C01 = 0x18, + C11 = 0x1A, + C20 = 0x1C, + C21 = 0x1E, + C30 = 0x20 +}; + +// Pressure sensors use the high speed clock by default +constexpr unsigned HIGH_SPEED_MODE = 3400000; + +/********************************************** + * I2C Interface for DPS310 Pressure Sensor * + **********************************************/ +class DPS310 +{ +public: + DPS310(); + DPS310(const uint8_t); + byte_t writeRegister(const Register, const uint8_t); + int32_t DPS310::readCalibrationCoefficient(const Coefficient_Reg); + +private: + uint8_t m_address; +}; +#endif \ No newline at end of file diff --git a/Node/Common/sensors/inc/file.h b/Node/Common/sensors/inc/file.h deleted file mode 100644 index fefa00a..0000000 --- a/Node/Common/sensors/inc/file.h +++ /dev/null @@ -1 +0,0 @@ -// This file is intentionally left blank \ No newline at end of file diff --git a/Node/Common/sensors/src/DPS310.cpp b/Node/Common/sensors/src/DPS310.cpp new file mode 100644 index 0000000..9da398e --- /dev/null +++ b/Node/Common/sensors/src/DPS310.cpp @@ -0,0 +1,76 @@ +#include "DPS310.h" + +DPS310::DPS310() + : m_address(77) +{} + +DPS310::DPS310(const uint8_t address) + : m_address(address) +{} + + +/** + * Returns a byte indicating transmission status: + * 0: Success + * 1: Data too long to fit in transmission buffer + * 2: Received NACK on transmit of address + * 3: Received NACK on transmit of data + * 4: Other error + */ +byte_t DPS310::writeRegister(const Register reg, const uint8_t value) +{ + Wire.beginTransmission(m_address); + Wire.write(value); + byte_t result = Wire.endTransmission(); + + return result; +} + +int32_t DPS310::readCalibrationCoefficient(const Coefficient_Reg reg) +{ + uint8_t high_byte = 0, middle_byte = 0, low_byte = 0; + int32_t result = 0; + switch (reg) + { + case C0: + { + Wire.beginTransmission(m_address); + Wire.write(C0); + Wire.requestFrom(m_address, 2); + high_byte = Wire.read(); + low_byte = Wire.read(); + result = (high_byte << 4) | ((low_byte & 0xf0) >> 4); + break; + } + case C1: + { + Wire.beginTransmission(m_address); + Wire.write(C1); + Wire.requestFrom(m_address, 2); + high_byte = Wire.read(); + low_byte = Wire.read(); + result = ((high_byte & 0x0f) << 8) | low_byte; + break; + } + case C00: + { + Wire.beginTransmission(m_address); + Wire.write(C00); + Wire.requestFrom(m_address, 3); + high_byte = Wire.read(); + middle_byte = Wire.read(); + low_byte = Wire.read(); + result = (high_byte << 12) | (middle_byte << 4) | ((low_byte & 0xf0) >> 4); + } + case C10: + { + Wire.beginTransmission(m_address); + Wire.write(C10); + Wire.requestFrom(m_address, 3); + high_byte = Wire.read(); + middle_byte = Wire.read(); + low_byte = Wire.read(); + result = ((high_byte & 0x0f) << 16) | (middle_byte << 8) | low_byte; + } + } +} \ No newline at end of file diff --git a/Node/Common/sensors/src/file.cpp b/Node/Common/sensors/src/file.cpp deleted file mode 100644 index fefa00a..0000000 --- a/Node/Common/sensors/src/file.cpp +++ /dev/null @@ -1 +0,0 @@ -// This file is intentionally left blank \ No newline at end of file From 0bb65f8f0950626d808f8fdabda71d36a9d754ca Mon Sep 17 00:00:00 2001 From: Daniel Burke Date: Sun, 27 Sep 2020 12:41:40 -0230 Subject: [PATCH 02/10] Continue defining methods for pressure sensor interface --- Node/Common/sensors/inc/DPS310.h | 15 +++++++-- Node/Common/sensors/src/DPS310.cpp | 50 +++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Node/Common/sensors/inc/DPS310.h b/Node/Common/sensors/inc/DPS310.h index 5d1a17b..7c7a563 100644 --- a/Node/Common/sensors/inc/DPS310.h +++ b/Node/Common/sensors/inc/DPS310.h @@ -35,19 +35,28 @@ enum Coefficient_Reg : uint8_t C30 = 0x20 }; +enum Configuration_Reg : uint8_t +{ + +}; + // Pressure sensors use the high speed clock by default constexpr unsigned HIGH_SPEED_MODE = 3400000; -/********************************************** +/**********************************************\ * I2C Interface for DPS310 Pressure Sensor * - **********************************************/ +\**********************************************/ class DPS310 { public: + static const unsigned s_defaultAddress = 77; + DPS310(); DPS310(const uint8_t); byte_t writeRegister(const Register, const uint8_t); - int32_t DPS310::readCalibrationCoefficient(const Coefficient_Reg); + int32_t readCalibrationCoefficient(const Coefficient_Reg); + byte_t configureTemp(byte_t, byte_t); + byte_t configurePressure(byte_t, byte_t); private: uint8_t m_address; diff --git a/Node/Common/sensors/src/DPS310.cpp b/Node/Common/sensors/src/DPS310.cpp index 9da398e..2194017 100644 --- a/Node/Common/sensors/src/DPS310.cpp +++ b/Node/Common/sensors/src/DPS310.cpp @@ -1,7 +1,7 @@ #include "DPS310.h" DPS310::DPS310() - : m_address(77) + : m_address(s_defaultAddress) {} DPS310::DPS310(const uint8_t address) @@ -72,5 +72,53 @@ int32_t DPS310::readCalibrationCoefficient(const Coefficient_Reg reg) low_byte = Wire.read(); result = ((high_byte & 0x0f) << 16) | (middle_byte << 8) | low_byte; } + case C11: + { + Wire.beginTransmission(m_address); + Wire.write(C11); + Wire.requestFrom(m_address, 2); + high_byte = Wire.read(); + low_byte = Wire.read(); + result = (high_byte << 8) | low_byte; + } + case C20: + { + Wire.beginTransmission(m_address); + Wire.write(C20); + Wire.requestFrom(m_address, 2); + high_byte = Wire.read(); + low_byte = Wire.read(); + result = (high_byte << 8) | low_byte; + } + case C21: + { + Wire.beginTransmission(m_address); + Wire.write(C21); + Wire.requestFrom(m_address, 2); + high_byte = Wire.read(); + low_byte = Wire.read(); + result = (high_byte << 8) | low_byte; + } + case C30: + { + Wire.beginTransmission(m_address); + Wire.write(C30); + Wire.requestFrom(m_address, 2); + high_byte = Wire.read(); + low_byte = Wire.read(); + result = (high_byte << 8) | low_byte; + } } + + return result; +} + +byte_t DPS310::configureTemp(byte_t tempRate, byte_t tempPrecision) +{ + return writeRegister(TMP_CFG, (tempRate & 0xf0) | (tempPrecision & 0x0f)); +} + +byte_t DPS310::configurePressure(byte_t pressureRate, byte_t pressurePrecision) +{ + return writeRegister(PRS_CFG, (pressureRate & 0xf0) | (pressurePrecision & 0x0f)); } \ No newline at end of file From e1d282105792acc2bff9b6f4bd875040124b943c Mon Sep 17 00:00:00 2001 From: Burke-Daniel <52763491+Burke-Daniel@users.noreply.github.com> Date: Wed, 30 Sep 2020 17:32:09 -0230 Subject: [PATCH 03/10] Add interface lib files from vendor --- Node/Common/sensors/inc/DPS310.h | 459 +++++++++++-- Node/Common/sensors/inc/DpsRegister.h | 19 + Node/Common/sensors/inc/dps310_config.h | 49 ++ Node/Common/sensors/inc/dps_config.h | 130 ++++ Node/Common/sensors/src/DPS310.cpp | 866 ++++++++++++++++++++---- 5 files changed, 1347 insertions(+), 176 deletions(-) create mode 100644 Node/Common/sensors/inc/DpsRegister.h create mode 100644 Node/Common/sensors/inc/dps310_config.h create mode 100644 Node/Common/sensors/inc/dps_config.h diff --git a/Node/Common/sensors/inc/DPS310.h b/Node/Common/sensors/inc/DPS310.h index 7c7a563..e12f111 100644 --- a/Node/Common/sensors/inc/DPS310.h +++ b/Node/Common/sensors/inc/DPS310.h @@ -1,64 +1,419 @@ -#ifndef DPS310_H -#define DPS310_H -#include "Arduino.h" -#include "Wire.h" +#ifndef DPS310_H_INCLUDED +#define DPS310_H_INCLUDED -using byte_t = uint8_t; +#include "dps_config.h" +#include "dps310_config.h" -enum Register : uint8_t -{ - PSR_B2 = 0x00, - PSR_B1 = 0x01, - PSR_B0 = 0x02, - TMP_B2 = 0x03, - TMP_B1 = 0x04, - TMP_B0 = 0x05, - PRS_CFG = 0x06, - TMP_CFG = 0x07, - MEAS_CFG = 0x08, - CFG_REG = 0x09, - INT_STS = 0x0A, - FIFO_STS = 0x0B, - RESET = 0x0C -}; +class TwoWire; -enum Coefficient_Reg : uint8_t +class Dps310 { - C0 = 0x10, - C1 = 0x11, - C00 = 0x13, - C10 = 0x15, - C01 = 0x18, - C11 = 0x1A, - C20 = 0x1C, - C21 = 0x1E, - C30 = 0x20 -}; +public: + /** + * I2C begin function with standard address + */ + void begin(TwoWire &bus); -enum Configuration_Reg : uint8_t -{ - -}; + /** + * Standard I2C begin function + * + * @param &bus: I2CBus which connects MC to the sensor + * @param slaveAddress: I2C address of the sensor (0x77 or 0x76) + */ + void begin(TwoWire &bus, uint8_t slaveAddress); -// Pressure sensors use the high speed clock by default -constexpr unsigned HIGH_SPEED_MODE = 3400000; + /** + * End function for Dps310 + * Sets the sensor to idle mode + */ + void end(void); -/**********************************************\ - * I2C Interface for DPS310 Pressure Sensor * -\**********************************************/ -class DPS310 -{ -public: - static const unsigned s_defaultAddress = 77; + /** + * returns the Product ID of the connected Dps310 sensor + */ + uint8_t getProductId(void); + + /** + * returns the Revision ID of the connected Dps310 sensor + */ + uint8_t getRevisionId(void); + + /** + * Sets the Dps310 to standby mode + * + * @return status code + */ + int16_t standby(void); + + /** + * performs one temperature measurement + * + * @param &result: reference to a float value where the result will be written + * @return status code + */ + int16_t measureTempOnce(float &result); + + /** + * performs one temperature measurement with specified oversamplingRate + * + * @param &result: reference to a float where the result will be written + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 + * The number of measurements equals to 2^n, if the value written to the register field is n. 2^n internal measurements are combined to return a more exact measurement + * @return status code + */ + int16_t measureTempOnce(float &result, uint8_t oversamplingRate); + + /** + * starts a single temperature measurement + * + * @return status code + */ + int16_t startMeasureTempOnce(void); + + /** + * starts a single temperature measurement with specified oversamplingRate + * + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 + * @return status code + */ + int16_t startMeasureTempOnce(uint8_t oversamplingRate); + + /** + * performs one pressure measurement + * + * @param &result: reference to a float value where the result will be written + * @return status code + */ + int16_t measurePressureOnce(float &result); - DPS310(); - DPS310(const uint8_t); - byte_t writeRegister(const Register, const uint8_t); - int32_t readCalibrationCoefficient(const Coefficient_Reg); - byte_t configureTemp(byte_t, byte_t); - byte_t configurePressure(byte_t, byte_t); + /** + * performs one pressure measurement with specified oversamplingRate + * + * @param &result: reference to a float where the result will be written + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return status code + */ + int16_t measurePressureOnce(float &result, uint8_t oversamplingRate); + + /** + * starts a single pressure measurement + * + * @return status code + */ + int16_t startMeasurePressureOnce(void); + + /** + * starts a single pressure measurement with specified oversamplingRate + * + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return status code + */ + int16_t startMeasurePressureOnce(uint8_t oversamplingRate); + + /** + * gets the result a single temperature or pressure measurement in °C or Pa + * + * @param &result: reference to a float value where the result will be written + * @return status code + */ + int16_t getSingleResult(float &result); + + /** + * starts a continuous temperature measurement with specified measurement rate and oversampling rate + * If measure rate is n and oversampling rate is m, the DPS310 performs 2^(n+m) internal measurements per second. + * The DPS310 cannot operate with high precision and high speed at the same time. Consult the datasheet for more information. + * + * @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * + * @return status code + * + */ + int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); + + /** + * starts a continuous temperature measurement with specified measurement rate and oversampling rate + * + * @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return status code + */ + int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); + + /** + * starts a continuous temperature and pressure measurement with specified measurement rate and oversampling rate for temperature and pressure measurement respectvely. + * + * @param tempMr measure rate for temperature + * @param tempOsr oversampling rate for temperature + * @param prsMr measure rate for pressure + * @param prsOsr oversampling rate for pressure + * @return status code + */ + int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); + + /** + * Gets the interrupt status flag of the FIFO + * + * @return 1 if the FIFO is full and caused an interrupt + * 0 if the FIFO is not full or FIFO interrupt is disabled + * -1 on fail + */ + int16_t getIntStatusFifoFull(void); + + /** + * Gets the interrupt status flag that indicates a finished temperature measurement + * + * @return 1 if a finished temperature measurement caused an interrupt; + * 0 if there is no finished temperature measurement or interrupts are disabled; + * -1 on fail. + */ + int16_t getIntStatusTempReady(void); + + /** + * Gets the interrupt status flag that indicates a finished pressure measurement + * + * @return 1 if a finished pressure measurement caused an interrupt; + * 0 if there is no finished pressure measurement or interrupts are disabled; + * -1 on fail. + */ + int16_t getIntStatusPrsReady(void); + + /** + * Function to fix a hardware problem on some devices + * You have this problem if you measure a temperature which is too high (e.g. 60°C when temperature is around 20°C) + * Call correctTemp() directly after begin() to fix this issue + */ + int16_t correctTemp(void); + + /** + * @brief Set the source of interrupt (FIFO full, measurement values ready) + * + * @param intr_source Interrupt source as defined by Interrupt_source_310_e + * @param polarity + * @return status code + */ + int16_t setInterruptSources(uint8_t intr_source, uint8_t polarity = 1); private: - uint8_t m_address; + //scaling factor table + static const int32_t scaling_facts[DPS__NUM_OF_SCAL_FACTS]; + + dps::Mode m_opMode; + + //flags + uint8_t m_initFail; + + uint8_t m_productID; + uint8_t m_revisionID; + + //settings + uint8_t m_tempMr; + uint8_t m_tempOsr; + uint8_t m_prsMr; + uint8_t m_prsOsr; + + // compensation coefficients for both dps310 and dps422 + int32_t m_c00; + int32_t m_c10; + int32_t m_c01; + int32_t m_c11; + int32_t m_c20; + int32_t m_c21; + int32_t m_c30; + + // last measured scaled temperature (necessary for pressure compensation) + float m_lastTempScal; + + //bus specific + uint8_t m_SpiI2c; //0=SPI, 1=I2C + + //used for I2C + TwoWire *m_i2cbus; + uint8_t m_slaveAddress; + + uint8_t m_tempSensor; + + //compensation coefficients + int32_t m_c0Half; + int32_t m_c1; + + /** + * Initializes the sensor. + * This function has to be called from begin() + * and requires a valid bus initialization. + */ + void init(void); + + /** + * reads the compensation coefficients from the sensor + * this is called once from init(), which is called from begin() + * + * @return 0 on success, -1 on fail + */ + int16_t readcoeffs(void); + + /** + * Sets the Operation Mode of the sensor + * + * @param opMode: the new OpMode as defined by dps::Mode; CMD_BOTH should not be used for DPS310 + * @return 0 on success, -1 on fail + */ + int16_t setOpMode(uint8_t opMode); + + /** + * Configures temperature measurement + * + * @param temp_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param temp_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * + * @return 0 normally or -1 on fail + */ + int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); + + /** + * Configures pressure measurement + * + * @param prs_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param prs_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return 0 normally or -1 on fail + */ + int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); + + int16_t flushFIFO(); + + float calcTemp(int32_t raw); + + float calcPressure(int32_t raw); + + int16_t enableFIFO(); + + int16_t disableFIFO(); + + /** + * calculates the time that the sensor needs for 2^mr measurements with an oversampling rate of 2^osr (see table "pressure measurement time (ms) versus oversampling rate") + * Note that the total measurement time for temperature and pressure must not be more than 1 second. + * Timing behavior of pressure and temperature sensors can be considered the same. + * + * @param mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return time that the sensor needs for this measurement + */ + uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); + + /** + * reads the next raw value from the FIFO + * + * @param value: the raw pressure or temperature value read from the pressure register blocks, where the LSB of PRS_B0 marks wheather the value is a temperatur or a pressure. + * + * @return -1 on fail + * 0 if result is a temperature raw value + * 1 if result is a pressure raw value + */ + int16_t getFIFOvalue(int32_t *value); + + /** + * Gets the results from continuous measurements and writes them to given arrays + * + * @param *tempBuffer: The start address of the buffer where the temperature results are written + * If this is NULL, no temperature results will be written out + * @param &tempCount: The size of the buffer for temperature results. + * When the function ends, it will contain the number of bytes written to the buffer. + * @param *prsBuffer: The start address of the buffer where the pressure results are written + * If this is NULL, no pressure results will be written out + * @param &prsCount: The size of the buffer for pressure results. + * When the function ends, it will contain the number of bytes written to the buffer. + * @param reg The FIFO empty register field; needed since this field is different for each sensor + * @return status code + */ + int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount, RegMask_t reg); + + /** + * reads a byte from the sensor + * + * @param regAdress: Address that has to be read + * @return register content or -1 on fail + */ + int16_t readByte(uint8_t regAddress); + + /** + * reads a block from the sensor + * + * @param regAdress: Address that has to be read + * @param length: Length of data block + * @param buffer: Buffer where data will be stored + * @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. + */ + int16_t readBlock(RegBlock_t regBlock, uint8_t *buffer); + + /** + * writes a byte to a given register of the sensor without checking + * + * @param regAdress: Address of the register that has to be updated + * @param data: Byte that will be written to the register + * @return 0 if byte was written successfully + * or -1 on fail + */ + int16_t writeByte(uint8_t regAddress, uint8_t data); + + /** + * writes a byte to a register of the sensor + * + * @param regAdress: Address of the register that has to be updated + * @param data: Byte that will be written to the register + * @param check: If this is true, register content will be read after writing + * to check if update was successful + * @return 0 if byte was written successfully + * or -1 on fail + */ + int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check); + + /** + * updates a bit field of the sensor without checking + * + * @param regMask: Mask of the register that has to be updated + * @param data: BitValues that will be written to the register + * @return 0 if byte was written successfully + * or -1 on fail + */ + int16_t writeByteBitfield(uint8_t data, RegMask_t regMask); + + /** + * updates a bit field of the sensor + * + * regMask: Mask of the register that has to be updated + * data: BitValues that will be written to the register + * check: enables/disables check after writing; 0 disables check. + * if check fails, -1 will be returned + * @return 0 if byte was written successfully + * or -1 on fail + */ + int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check); + + /** + * reads a bit field from the sensor + * regMask: Mask of the register that has to be updated + * data: BitValues that will be written to the register + * @return read and processed bits + * or -1 on fail + */ + int16_t readByteBitfield(RegMask_t regMask); + + /** + * @brief converts non-32-bit negative numbers to 32-bit negative numbers with 2's complement + * + * @param raw The raw number of less than 32 bits + * @param length The bit length + */ + void getTwosComplement(int32_t *raw, uint8_t length); + + /** + * @brief Get a raw result from a given register block + * + * @param raw The address where the raw value is to be written + * @param reg The register block to be read from + * @return status code + */ + int16_t getRawResult(int32_t *raw, RegBlock_t reg); }; + #endif \ No newline at end of file diff --git a/Node/Common/sensors/inc/DpsRegister.h b/Node/Common/sensors/inc/DpsRegister.h new file mode 100644 index 0000000..6cfb964 --- /dev/null +++ b/Node/Common/sensors/inc/DpsRegister.h @@ -0,0 +1,19 @@ +#ifndef DPSREGISTER_H_INCLUDED +#define DPSREGISTER_H_INCLUDED + +#include + +typedef struct +{ + uint8_t regAddress; + uint8_t mask; + uint8_t shift; +} RegMask_t; + +typedef struct +{ + uint8_t regAddress; + uint8_t length; +} RegBlock_t; + +#endif \ No newline at end of file diff --git a/Node/Common/sensors/inc/dps310_config.h b/Node/Common/sensors/inc/dps310_config.h new file mode 100644 index 0000000..e017fe9 --- /dev/null +++ b/Node/Common/sensors/inc/dps310_config.h @@ -0,0 +1,49 @@ +#ifndef DPS310_CONFIG_H_ +#define DPS310_CONFIG_H_ + +#define DPS310_NUM_OF_REGMASKS 16 + +enum Interrupt_source_310_e +{ + DPS310_NO_INTR = 0, + DPS310_PRS_INTR = 1, + DPS310_TEMP_INTR = 2, + DPS310_BOTH_INTR = 3, + DPS310_FIFO_FULL_INTR = 4, +}; + +namespace dps310 +{ + +enum Registers_e +{ + PROD_ID = 0, + REV_ID, + TEMP_SENSOR, // internal vs external + TEMP_SENSORREC, //temperature sensor recommendation + TEMP_SE, //temperature shift enable (if temp_osr>3) + PRS_SE, //pressure shift enable (if prs_osr>3) + FIFO_FL, //FIFO flush + FIFO_EMPTY, //FIFO empty + FIFO_FULL, //FIFO full + INT_HL, + INT_SEL, //interrupt select +}; + +const RegMask_t registers[DPS310_NUM_OF_REGMASKS] = { + {0x0D, 0x0F, 0}, // PROD_ID + {0x0D, 0xF0, 4}, // REV_ID + {0x07, 0x80, 7}, // TEMP_SENSOR + {0x28, 0x80, 7}, // TEMP_SENSORREC + {0x09, 0x08, 3}, // TEMP_SE + {0x09, 0x04, 2}, // PRS_SE + {0x0C, 0x80, 7}, // FIFO_FL + {0x0B, 0x01, 0}, // FIFO_EMPTY + {0x0B, 0x02, 1}, // FIFO_FULL + {0x09, 0x80, 7}, // INT_HL + {0x09, 0x70, 4}, // INT_SEL +}; + +const RegBlock_t coeffBlock = {0x10, 18}; +} // namespace dps310 +#endif \ No newline at end of file diff --git a/Node/Common/sensors/inc/dps_config.h b/Node/Common/sensors/inc/dps_config.h new file mode 100644 index 0000000..9df3992 --- /dev/null +++ b/Node/Common/sensors/inc/dps_config.h @@ -0,0 +1,130 @@ + +#ifndef DPS_CONSTS_H_ +#define DPS_CONSTS_H_ +#include "DpsRegister.h" + +/////////// DPS310 /////////// +#define DPS310__PROD_ID 0x00 +#define DPS310__SPI_WRITE_CMD 0x00U +#define DPS310__SPI_READ_CMD 0x80U +#define DPS310__SPI_RW_MASK 0x80U +#define DPS310__SPI_MAX_FREQ 1000000U + +#define DPS310__OSR_SE 3U + +// DPS310 has 10 milliseconds of spare time for each synchronous measurement / per second for asynchronous measurements +// this is for error prevention on friday-afternoon-products :D +// you can set it to 0 if you dare, but there is no warranty that it will still work +#define DPS310__BUSYTIME_FAILSAFE 10U +#define DPS310__MAX_BUSYTIME ((1000U - DPS310__BUSYTIME_FAILSAFE) * DPS__BUSYTIME_SCALING) + +#define DPS310__REG_ADR_SPI3W 0x09U +#define DPS310__REG_CONTENT_SPI3W 0x01U + +/////////// DPS422 /////////// +#define DPS422__PROD_ID 0x0A + +/////////// common /////////// + +// slave address same for 422 and 310 (to be proved for future sensors) +#define DPS__FIFO_SIZE 32 +#define DPS__STD_SLAVE_ADDRESS 0x77U +#define DPS__RESULT_BLOCK_LENGTH 3 +#define NUM_OF_COMMON_REGMASKS 16 + +#define DPS__MEASUREMENT_RATE_1 0 +#define DPS__MEASUREMENT_RATE_2 1 +#define DPS__MEASUREMENT_RATE_4 2 +#define DPS__MEASUREMENT_RATE_8 3 +#define DPS__MEASUREMENT_RATE_16 4 +#define DPS__MEASUREMENT_RATE_32 5 +#define DPS__MEASUREMENT_RATE_64 6 +#define DPS__MEASUREMENT_RATE_128 7 + +#define DPS__OVERSAMPLING_RATE_1 DPS__MEASUREMENT_RATE_1 +#define DPS__OVERSAMPLING_RATE_2 DPS__MEASUREMENT_RATE_2 +#define DPS__OVERSAMPLING_RATE_4 DPS__MEASUREMENT_RATE_4 +#define DPS__OVERSAMPLING_RATE_8 DPS__MEASUREMENT_RATE_8 +#define DPS__OVERSAMPLING_RATE_16 DPS__MEASUREMENT_RATE_16 +#define DPS__OVERSAMPLING_RATE_32 DPS__MEASUREMENT_RATE_32 +#define DPS__OVERSAMPLING_RATE_64 DPS__MEASUREMENT_RATE_64 +#define DPS__OVERSAMPLING_RATE_128 DPS__MEASUREMENT_RATE_128 + +//we use 0.1 ms units for time calculations, so 10 units are one millisecond +#define DPS__BUSYTIME_SCALING 10U + +#define DPS__NUM_OF_SCAL_FACTS 8 + +// status code +#define DPS__SUCCEEDED 0 +#define DPS__FAIL_UNKNOWN -1 +#define DPS__FAIL_INIT_FAILED -2 +#define DPS__FAIL_TOOBUSY -3 +#define DPS__FAIL_UNFINISHED -4 + +namespace dps +{ + +/** + * @brief Operating mode. + * + */ +enum Mode +{ + IDLE = 0x00, + CMD_PRS = 0x01, + CMD_TEMP = 0x02, + CMD_BOTH = 0x03, // only for DPS422 + CONT_PRS = 0x05, + CONT_TMP = 0x06, + CONT_BOTH = 0x07 +}; + +enum RegisterBlocks_e +{ + PRS = 0, // pressure value + TEMP, // temperature value +}; + +const RegBlock_t registerBlocks[2] = { + {0x00, 3}, + {0x03, 3}, +}; + +/** + * @brief registers for configuration and flags; these are the same for both 310 and 422, might need to be adapted for future sensors + * + */ +enum Config_Registers_e +{ + TEMP_MR = 0, // temperature measure rate + TEMP_OSR, // temperature measurement resolution + PRS_MR, // pressure measure rate + PRS_OSR, // pressure measurement resolution + MSR_CTRL, // measurement control + FIFO_EN, + + TEMP_RDY, + PRS_RDY, + INT_FLAG_FIFO, + INT_FLAG_TEMP, + INT_FLAG_PRS, +}; + +const RegMask_t config_registers[NUM_OF_COMMON_REGMASKS] = { + {0x07, 0x70, 4}, // TEMP_MR + {0x07, 0x07, 0}, // TEMP_OSR + {0x06, 0x70, 4}, // PRS_MR + {0x06, 0x07, 0}, // PRS_OSR + {0x08, 0x07, 0}, // MSR_CTRL + {0x09, 0x02, 1}, // FIFO_EN + + {0x08, 0x20, 5}, // TEMP_RDY + {0x08, 0x10, 4}, // PRS_RDY + {0x0A, 0x04, 2}, // INT_FLAG_FIFO + {0x0A, 0x02, 1}, // INT_FLAG_TEMP + {0x0A, 0x01, 0}, // INT_FLAG_PRS +}; + +} // namespace dps +#endif /* DPS_CONSTS_H_ */ diff --git a/Node/Common/sensors/src/DPS310.cpp b/Node/Common/sensors/src/DPS310.cpp index 2194017..3ca26c2 100644 --- a/Node/Common/sensors/src/DPS310.cpp +++ b/Node/Common/sensors/src/DPS310.cpp @@ -1,124 +1,742 @@ -#include "DPS310.h" - -DPS310::DPS310() - : m_address(s_defaultAddress) -{} - -DPS310::DPS310(const uint8_t address) - : m_address(address) -{} - - -/** - * Returns a byte indicating transmission status: - * 0: Success - * 1: Data too long to fit in transmission buffer - * 2: Received NACK on transmit of address - * 3: Received NACK on transmit of data - * 4: Other error - */ -byte_t DPS310::writeRegister(const Register reg, const uint8_t value) -{ - Wire.beginTransmission(m_address); - Wire.write(value); - byte_t result = Wire.endTransmission(); - - return result; -} - -int32_t DPS310::readCalibrationCoefficient(const Coefficient_Reg reg) -{ - uint8_t high_byte = 0, middle_byte = 0, low_byte = 0; - int32_t result = 0; - switch (reg) - { - case C0: - { - Wire.beginTransmission(m_address); - Wire.write(C0); - Wire.requestFrom(m_address, 2); - high_byte = Wire.read(); - low_byte = Wire.read(); - result = (high_byte << 4) | ((low_byte & 0xf0) >> 4); - break; - } - case C1: - { - Wire.beginTransmission(m_address); - Wire.write(C1); - Wire.requestFrom(m_address, 2); - high_byte = Wire.read(); - low_byte = Wire.read(); - result = ((high_byte & 0x0f) << 8) | low_byte; - break; - } - case C00: - { - Wire.beginTransmission(m_address); - Wire.write(C00); - Wire.requestFrom(m_address, 3); - high_byte = Wire.read(); - middle_byte = Wire.read(); - low_byte = Wire.read(); - result = (high_byte << 12) | (middle_byte << 4) | ((low_byte & 0xf0) >> 4); - } - case C10: - { - Wire.beginTransmission(m_address); - Wire.write(C10); - Wire.requestFrom(m_address, 3); - high_byte = Wire.read(); - middle_byte = Wire.read(); - low_byte = Wire.read(); - result = ((high_byte & 0x0f) << 16) | (middle_byte << 8) | low_byte; - } - case C11: - { - Wire.beginTransmission(m_address); - Wire.write(C11); - Wire.requestFrom(m_address, 2); - high_byte = Wire.read(); - low_byte = Wire.read(); - result = (high_byte << 8) | low_byte; - } - case C20: - { - Wire.beginTransmission(m_address); - Wire.write(C20); - Wire.requestFrom(m_address, 2); - high_byte = Wire.read(); - low_byte = Wire.read(); - result = (high_byte << 8) | low_byte; - } - case C21: - { - Wire.beginTransmission(m_address); - Wire.write(C21); - Wire.requestFrom(m_address, 2); - high_byte = Wire.read(); - low_byte = Wire.read(); - result = (high_byte << 8) | low_byte; - } - case C30: - { - Wire.beginTransmission(m_address); - Wire.write(C30); - Wire.requestFrom(m_address, 2); - high_byte = Wire.read(); - low_byte = Wire.read(); - result = (high_byte << 8) | low_byte; - } - } - - return result; -} - -byte_t DPS310::configureTemp(byte_t tempRate, byte_t tempPrecision) -{ - return writeRegister(TMP_CFG, (tempRate & 0xf0) | (tempPrecision & 0x0f)); -} - -byte_t DPS310::configurePressure(byte_t pressureRate, byte_t pressurePrecision) -{ - return writeRegister(PRS_CFG, (pressureRate & 0xf0) | (pressurePrecision & 0x0f)); -} \ No newline at end of file +#include "Dps310.h" +#include + +using namespace dps; +using namespace dps310; + +const int32_t Dps310::scaling_facts[DPS__NUM_OF_SCAL_FACTS] = {524288, 1572864, 3670016, 7864320, 253952, 516096, 1040384, 2088960}; + +Dps310::Dps310(void) +{ + //assume that initialization has failed before it has been done + m_initFail = 1U; +} + +Dps310::~Dps310(void) +{ + end(); +} + +void Dps310::end(void) +{ + standby(); +} + +uint8_t Dps310::getProductId(void) +{ + return m_productID; +} + +uint8_t Dps310::getRevisionId(void) +{ + return m_revisionID; +} + +int16_t Dps310::getContResults(float *tempBuffer, + uint8_t &tempCount, + float *prsBuffer, + uint8_t &prsCount) +{ + return Dps310::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); +} + +int16_t Dps310::getSingleResult(float &result) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + + //read finished bit for current opMode + int16_t rdy; + switch (m_opMode) + { + case CMD_TEMP: //temperature + rdy = readByteBitfield(config_registers[TEMP_RDY]); + break; + case CMD_PRS: //pressure + rdy = readByteBitfield(config_registers[PRS_RDY]); + break; + default: //DPS310 not in command mode + return DPS__FAIL_TOOBUSY; + } + //read new measurement result + switch (rdy) + { + case DPS__FAIL_UNKNOWN: //could not read ready flag + return DPS__FAIL_UNKNOWN; + case 0: //ready flag not set, measurement still in progress + return DPS__FAIL_UNFINISHED; + case 1: //measurement ready, expected case + Mode oldMode = m_opMode; + m_opMode = IDLE; //opcode was automatically reseted by DPS310 + int32_t raw_val; + switch (oldMode) + { + case CMD_TEMP: //temperature + getRawResult(&raw_val, registerBlocks[TEMP]); + result = calcTemp(raw_val); + return DPS__SUCCEEDED; // TODO + case CMD_PRS: //pressure + getRawResult(&raw_val, registerBlocks[PRS]); + result = calcPressure(raw_val); + return DPS__SUCCEEDED; // TODO + default: + return DPS__FAIL_UNKNOWN; //should already be filtered above + } + } + return DPS__FAIL_UNKNOWN; +} + +int16_t Dps310::measureTempOnce(float &result) +{ + return measureTempOnce(result, m_tempOsr); +} + +int16_t Dps310::measureTempOnce(float &result, uint8_t oversamplingRate) +{ + //Start measurement + int16_t ret = startMeasureTempOnce(oversamplingRate); + if (ret != DPS__SUCCEEDED) + { + return ret; + } + + //wait until measurement is finished + delay(calcBusyTime(0U, m_tempOsr) / DPS__BUSYTIME_SCALING); + delay(DPS310__BUSYTIME_FAILSAFE); + + ret = getSingleResult(result); + if (ret != DPS__SUCCEEDED) + { + standby(); + } + return ret; +} + +int16_t Dps310::startMeasureTempOnce(void) +{ + return startMeasureTempOnce(m_tempOsr); +} + +int16_t Dps310::startMeasureTempOnce(uint8_t oversamplingRate) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + + if (oversamplingRate != m_tempOsr) + { + //configuration of oversampling rate + if (configTemp(0U, oversamplingRate) != DPS__SUCCEEDED) + { + return DPS__FAIL_UNKNOWN; + } + } + + //set device to temperature measuring mode + return setOpMode(CMD_TEMP); +} + +int16_t Dps310::measurePressureOnce(float &result) +{ + return measurePressureOnce(result, m_prsOsr); +} + +int16_t Dps310::measurePressureOnce(float &result, uint8_t oversamplingRate) +{ + //start the measurement + int16_t ret = startMeasurePressureOnce(oversamplingRate); + if (ret != DPS__SUCCEEDED) + { + return ret; + } + + //wait until measurement is finished + delay(calcBusyTime(0U, m_prsOsr) / DPS__BUSYTIME_SCALING); + delay(DPS310__BUSYTIME_FAILSAFE); + + ret = getSingleResult(result); + if (ret != DPS__SUCCEEDED) + { + standby(); + } + return ret; +} + +int16_t Dps310::startMeasurePressureOnce(void) +{ + return startMeasurePressureOnce(m_prsOsr); +} + +int16_t Dps310::startMeasurePressureOnce(uint8_t oversamplingRate) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + //configuration of oversampling rate, lowest measure rate to avoid conflicts + if (oversamplingRate != m_prsOsr) + { + if (configPressure(0U, oversamplingRate)) + { + return DPS__FAIL_UNKNOWN; + } + } + //set device to pressure measuring mode + return setOpMode(CMD_PRS); +} + +int16_t Dps310::startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if (calcBusyTime(measureRate, oversamplingRate) >= DPS310__MAX_BUSYTIME) + { + return DPS__FAIL_UNFINISHED; + } + //update precision and measuring rate + if (configTemp(measureRate, oversamplingRate)) + { + return DPS__FAIL_UNKNOWN; + } + + if (enableFIFO()) + { + return DPS__FAIL_UNKNOWN; + } + //Start measuring in background mode + if (Dps310::setOpMode(CONT_TMP)) + { + return DPS__FAIL_UNKNOWN; + } + return DPS__SUCCEEDED; +} + +int16_t Dps310::startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if (calcBusyTime(measureRate, oversamplingRate) >= DPS310__MAX_BUSYTIME) + { + return DPS__FAIL_UNFINISHED; + } + //update precision and measuring rate + if (configPressure(measureRate, oversamplingRate)) + return DPS__FAIL_UNKNOWN; + //enable result FIFO + if (enableFIFO()) + { + return DPS__FAIL_UNKNOWN; + } + //Start measuring in background mode + if (Dps310::setOpMode(CONT_PRS)) + { + return DPS__FAIL_UNKNOWN; + } + return DPS__SUCCEEDED; +} + +int16_t Dps310::startMeasureBothCont(uint8_t tempMr, + uint8_t tempOsr, + uint8_t prsMr, + uint8_t prsOsr) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if (calcBusyTime(tempMr, tempOsr) + calcBusyTime(prsMr, prsOsr) >= DPS310__MAX_BUSYTIME) + { + return DPS__FAIL_UNFINISHED; + } + //update precision and measuring rate + if (configTemp(tempMr, tempOsr)) + { + return DPS__FAIL_UNKNOWN; + } + //update precision and measuring rate + if (configPressure(prsMr, prsOsr)) + return DPS__FAIL_UNKNOWN; + //enable result FIFO + if (enableFIFO()) + { + return DPS__FAIL_UNKNOWN; + } + //Start measuring in background mode + if (setOpMode(CONT_BOTH)) + { + return DPS__FAIL_UNKNOWN; + } + return DPS__SUCCEEDED; +} + +int16_t Dps310::standby(void) +{ + //abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //set device to idling mode + int16_t ret = setOpMode(IDLE); + if (ret != DPS__SUCCEEDED) + { + return ret; + } + ret = disableFIFO(); + return ret; +} + +int16_t Dps310::correctTemp(void) +{ + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + writeByte(0x0E, 0xA5); + writeByte(0x0F, 0x96); + writeByte(0x62, 0x02); + writeByte(0x0E, 0x00); + writeByte(0x0F, 0x00); + + //perform a first temperature measurement (again) + //the most recent temperature will be saved internally + //and used for compensation when calculating pressure + float trash; + measureTempOnce(trash); + + return DPS__SUCCEEDED; +} + +int16_t Dps310::getIntStatusFifoFull(void) +{ + return readByteBitfield(config_registers[INT_FLAG_FIFO]); +} + +int16_t Dps310::getIntStatusTempReady(void) +{ + return readByteBitfield(config_registers[INT_FLAG_TEMP]); +} + +int16_t Dps310::getIntStatusPrsReady(void) +{ + return readByteBitfield(config_registers[INT_FLAG_PRS]); +} + +//////// Declaration of private functions starts here //////// + +int16_t Dps310::setOpMode(uint8_t opMode) +{ + if (writeByteBitfield(opMode, config_registers[MSR_CTRL]) == -1) + { + return DPS__FAIL_UNKNOWN; + } + m_opMode = (Mode)opMode; + return DPS__SUCCEEDED; +} + +int16_t Dps310::configTemp(uint8_t tempMr, uint8_t tempOsr) +{ + tempMr &= 0x07; + tempOsr &= 0x07; + // two accesses to the same register; for readability + int16_t ret = writeByteBitfield(tempMr, config_registers[TEMP_MR]); + ret = writeByteBitfield(tempOsr, config_registers[TEMP_OSR]); + + //abort immediately on fail + if (ret != DPS__SUCCEEDED) + { + return DPS__FAIL_UNKNOWN; + } + m_tempMr = tempMr; + m_tempOsr = tempOsr; +} + +int16_t Dps310::configPressure(uint8_t prsMr, uint8_t prsOsr) +{ + prsMr &= 0x07; + prsOsr &= 0x07; + int16_t ret = writeByteBitfield(prsMr, config_registers[PRS_MR]); + ret = writeByteBitfield(prsOsr, config_registers[PRS_OSR]); + + //abort immediately on fail + if (ret != DPS__SUCCEEDED) + { + return DPS__FAIL_UNKNOWN; + } + m_prsMr = prsMr; + m_prsOsr = prsOsr; +} + +int16_t Dps310::enableFIFO() +{ + return writeByteBitfield(1U, config_registers[FIFO_EN]); +} + +int16_t Dps310::disableFIFO() +{ + int16_t ret = flushFIFO(); + ret = writeByteBitfield(0U, config_registers[FIFO_EN]); + return ret; +} + +uint16_t Dps310::calcBusyTime(uint16_t mr, uint16_t osr) +{ + //formula from datasheet (optimized) + return ((uint32_t)20U << mr) + ((uint32_t)16U << (osr + mr)); +} + +int16_t Dps310::getFIFOvalue(int32_t *value) +{ + uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; + + //abort on invalid argument or failed block reading + if (value == NULL || readBlock(registerBlocks[PRS], buffer) != DPS__RESULT_BLOCK_LENGTH) + return DPS__FAIL_UNKNOWN; + *value = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; + getTwosComplement(value, 24); + return buffer[2] & 0x01; +} + +int16_t Dps310::readByte(uint8_t regAddress) +{ + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); + m_i2cbus->endTransmission(false); + //request 1 byte from slave + if (m_i2cbus->requestFrom(m_slaveAddress, 1U, 1U) > 0) + { + return m_i2cbus->read(); //return this byte on success + } + else + { + return DPS__FAIL_UNKNOWN; //if 0 bytes were read successfully + } +} +void Dps310::begin(TwoWire &bus) +{ + begin(bus, DPS__STD_SLAVE_ADDRESS); +} + +void Dps310::begin(TwoWire &bus, uint8_t slaveAddress) +{ + //this flag will show if the initialization was successful + m_initFail = 0U; + + //Set I2C bus connection + m_SpiI2c = 1U; + m_i2cbus = &bus; + m_slaveAddress = slaveAddress; + + // Init bus + m_i2cbus->begin(); + + delay(50); //startup time of Dps310 + + init(); +} + +void Dps310::init(void) +{ + int16_t prodId = readByteBitfield(registers[PROD_ID]); + if (prodId < 0) + { + //Connected device is not a Dps310 + m_initFail = 1U; + return; + } + m_productID = prodId; + + int16_t revId = readByteBitfield(registers[REV_ID]); + if (revId < 0) + { + m_initFail = 1U; + return; + } + m_revisionID = revId; + + //find out which temperature sensor is calibrated with coefficients... + int16_t sensor = readByteBitfield(registers[TEMP_SENSORREC]); + if (sensor < 0) + { + m_initFail = 1U; + return; + } + + //...and use this sensor for temperature measurement + m_tempSensor = sensor; + if (writeByteBitfield((uint8_t)sensor, registers[TEMP_SENSOR]) < 0) + { + m_initFail = 1U; + return; + } + + //read coefficients + if (readcoeffs() < 0) + { + m_initFail = 1U; + return; + } + + //set to standby for further configuration + standby(); + + //set measurement precision and rate to standard values; + configTemp(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8); + configPressure(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8); + + //perform a first temperature measurement + //the most recent temperature will be saved internally + //and used for compensation when calculating pressure + float trash; + measureTempOnce(trash); + + //make sure the DPS310 is in standby after initialization + standby(); + + // Fix IC with a fuse bit problem, which lead to a wrong temperature + // Should not affect ICs without this problem + correctTemp(); +} + +int16_t Dps310::readcoeffs(void) +{ + // TODO: remove magic number + uint8_t buffer[18]; + //read COEF registers to buffer + int16_t ret = readBlock(coeffBlock, buffer); + + //compose coefficients from buffer content + m_c0Half = ((uint32_t)buffer[0] << 4) | (((uint32_t)buffer[1] >> 4) & 0x0F); + getTwosComplement(&m_c0Half, 12); + //c0 is only used as c0*0.5, so c0_half is calculated immediately + m_c0Half = m_c0Half / 2U; + + //now do the same thing for all other coefficients + m_c1 = (((uint32_t)buffer[1] & 0x0F) << 8) | (uint32_t)buffer[2]; + getTwosComplement(&m_c1, 12); + m_c00 = ((uint32_t)buffer[3] << 12) | ((uint32_t)buffer[4] << 4) | (((uint32_t)buffer[5] >> 4) & 0x0F); + getTwosComplement(&m_c00, 20); + m_c10 = (((uint32_t)buffer[5] & 0x0F) << 16) | ((uint32_t)buffer[6] << 8) | (uint32_t)buffer[7]; + getTwosComplement(&m_c10, 20); + + m_c01 = ((uint32_t)buffer[8] << 8) | (uint32_t)buffer[9]; + getTwosComplement(&m_c01, 16); + + m_c11 = ((uint32_t)buffer[10] << 8) | (uint32_t)buffer[11]; + getTwosComplement(&m_c11, 16); + m_c20 = ((uint32_t)buffer[12] << 8) | (uint32_t)buffer[13]; + getTwosComplement(&m_c20, 16); + m_c21 = ((uint32_t)buffer[14] << 8) | (uint32_t)buffer[15]; + getTwosComplement(&m_c21, 16); + m_c30 = ((uint32_t)buffer[16] << 8) | (uint32_t)buffer[17]; + getTwosComplement(&m_c30, 16); + return DPS__SUCCEEDED; +} + +int16_t Dps310::configTemp(uint8_t tempMr, uint8_t tempOsr) +{ + int16_t ret = Dps310::configTemp(tempMr, tempOsr); + + writeByteBitfield(m_tempSensor, registers[TEMP_SENSOR]); + //set TEMP SHIFT ENABLE if oversampling rate higher than eight(2^3) + if (tempOsr > DPS310__OSR_SE) + { + ret = writeByteBitfield(1U, registers[TEMP_SE]); + } + else + { + ret = writeByteBitfield(0U, registers[TEMP_SE]); + } + return ret; +} + +int16_t Dps310::configPressure(uint8_t prsMr, uint8_t prsOsr) +{ + int16_t ret = Dps310::configPressure(prsMr, prsOsr); + //set PM SHIFT ENABLE if oversampling rate higher than eight(2^3) + if (prsOsr > DPS310__OSR_SE) + { + ret = writeByteBitfield(1U, registers[PRS_SE]); + } + else + { + ret = writeByteBitfield(0U, registers[PRS_SE]); + } + return ret; +} + +int16_t Dps310::writeByte(uint8_t regAddress, uint8_t data) +{ + return writeByte(regAddress, data, 0U); +} + +int16_t Dps310::writeByte(uint8_t regAddress, uint8_t data, uint8_t check) +{ + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); //Write Register number to buffer + m_i2cbus->write(data); //Write data to buffer + if (m_i2cbus->endTransmission() != 0) //Send buffer content to slave + { + return DPS__FAIL_UNKNOWN; + } + else + { + if (check == 0) + return 0; //no checking + if (readByte(regAddress) == data) //check if desired by calling function + { + return DPS__SUCCEEDED; + } + else + { + return DPS__FAIL_UNKNOWN; + } + } +} + +float Dps310::calcTemp(int32_t raw) +{ + float temp = raw; + + //scale temperature according to scaling table and oversampling + temp /= scaling_facts[m_tempOsr]; + + //update last measured temperature + //it will be used for pressure compensation + m_lastTempScal = temp; + + //Calculate compensated temperature + temp = m_c0Half + m_c1 * temp; + + return temp; +} + +float Dps310::calcPressure(int32_t raw) +{ + float prs = raw; + + //scale pressure according to scaling table and oversampling + prs /= scaling_facts[m_prsOsr]; + + //Calculate compensated pressure + prs = m_c00 + prs * (m_c10 + prs * (m_c20 + prs * m_c30)) + m_lastTempScal * (m_c01 + prs * (m_c11 + prs * m_c21)); + + //return pressure + return prs; +} + +int16_t Dps310::flushFIFO() +{ + return writeByteBitfield(1U, registers[FIFO_FL]); +} + +int16_t Dps310::writeByteBitfield(uint8_t data, RegMask_t regMask) +{ + return writeByteBitfield(data, regMask.regAddress, regMask.mask, regMask.shift, 0U); +} + +int16_t Dps310::writeByteBitfield(uint8_t data, + uint8_t regAddress, + uint8_t mask, + uint8_t shift, + uint8_t check) +{ + int16_t old = readByte(regAddress); + if (old < 0) + { + //fail while reading + return old; + } + return writeByte(regAddress, ((uint8_t)old & ~mask) | ((data << shift) & mask), check); +} + +int16_t Dps310::readByteBitfield(RegMask_t regMask) +{ + int16_t ret = readByte(regMask.regAddress); + if (ret < 0) + { + return ret; + } + return (((uint8_t)ret) & regMask.mask) >> regMask.shift; +} + +int16_t Dps310::readBlock(RegBlock_t regBlock, uint8_t *buffer) +{ + //do not read if there is no buffer + if (buffer == NULL) + { + return 0; //0 bytes read successfully + } + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regBlock.regAddress); + m_i2cbus->endTransmission(false); + //request length bytes from slave + int16_t ret = m_i2cbus->requestFrom(m_slaveAddress, regBlock.length, 1U); + //read all received bytes to buffer + for (int16_t count = 0; count < ret; count++) + { + buffer[count] = m_i2cbus->read(); + } + return ret; +} + +void Dps310::getTwosComplement(int32_t *raw, uint8_t length) +{ + if (*raw & ((uint32_t)1 << (length - 1))) + { + *raw -= (uint32_t)1 << length; + } +} + +int16_t Dps310::getRawResult(int32_t *raw, RegBlock_t reg) +{ + uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; + if (readBlock(reg, buffer) != DPS__RESULT_BLOCK_LENGTH) + return DPS__FAIL_UNKNOWN; + + *raw = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; + getTwosComplement(raw, 24); + return DPS__SUCCEEDED; +} From 3116ab8507e37f1b9177c2c65543a2f70216ff9d Mon Sep 17 00:00:00 2001 From: Burke-Daniel <52763491+Burke-Daniel@users.noreply.github.com> Date: Wed, 30 Sep 2020 17:46:10 -0230 Subject: [PATCH 04/10] Compilation fixes --- Node/Common/sensors/inc/DPS310.h | 5 +++++ Node/Common/sensors/src/DPS310.cpp | 32 ------------------------------ 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/Node/Common/sensors/inc/DPS310.h b/Node/Common/sensors/inc/DPS310.h index e12f111..b8c4c7a 100644 --- a/Node/Common/sensors/inc/DPS310.h +++ b/Node/Common/sensors/inc/DPS310.h @@ -9,6 +9,9 @@ class TwoWire; class Dps310 { public: + Dps310(); + + ~Dps310(); /** * I2C begin function with standard address */ @@ -311,6 +314,8 @@ class Dps310 */ int16_t getFIFOvalue(int32_t *value); + int16_t Dps310::getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); + /** * Gets the results from continuous measurements and writes them to given arrays * diff --git a/Node/Common/sensors/src/DPS310.cpp b/Node/Common/sensors/src/DPS310.cpp index 3ca26c2..b95461b 100644 --- a/Node/Common/sensors/src/DPS310.cpp +++ b/Node/Common/sensors/src/DPS310.cpp @@ -574,38 +574,6 @@ int16_t Dps310::readcoeffs(void) return DPS__SUCCEEDED; } -int16_t Dps310::configTemp(uint8_t tempMr, uint8_t tempOsr) -{ - int16_t ret = Dps310::configTemp(tempMr, tempOsr); - - writeByteBitfield(m_tempSensor, registers[TEMP_SENSOR]); - //set TEMP SHIFT ENABLE if oversampling rate higher than eight(2^3) - if (tempOsr > DPS310__OSR_SE) - { - ret = writeByteBitfield(1U, registers[TEMP_SE]); - } - else - { - ret = writeByteBitfield(0U, registers[TEMP_SE]); - } - return ret; -} - -int16_t Dps310::configPressure(uint8_t prsMr, uint8_t prsOsr) -{ - int16_t ret = Dps310::configPressure(prsMr, prsOsr); - //set PM SHIFT ENABLE if oversampling rate higher than eight(2^3) - if (prsOsr > DPS310__OSR_SE) - { - ret = writeByteBitfield(1U, registers[PRS_SE]); - } - else - { - ret = writeByteBitfield(0U, registers[PRS_SE]); - } - return ret; -} - int16_t Dps310::writeByte(uint8_t regAddress, uint8_t data) { return writeByte(regAddress, data, 0U); From cef629375fe4de117fd3548d3c1d8d81b2063418 Mon Sep 17 00:00:00 2001 From: Burke-Daniel <52763491+Burke-Daniel@users.noreply.github.com> Date: Sat, 3 Oct 2020 17:07:05 -0230 Subject: [PATCH 05/10] Remove class qualifier in header --- Node/Common/sensors/inc/DPS310.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Node/Common/sensors/inc/DPS310.h b/Node/Common/sensors/inc/DPS310.h index b8c4c7a..6a4d463 100644 --- a/Node/Common/sensors/inc/DPS310.h +++ b/Node/Common/sensors/inc/DPS310.h @@ -314,7 +314,7 @@ class Dps310 */ int16_t getFIFOvalue(int32_t *value); - int16_t Dps310::getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); + int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); /** * Gets the results from continuous measurements and writes them to given arrays From 1979886c1cbb54ac8b9490eed146c9182b1a485c Mon Sep 17 00:00:00 2001 From: Burke-Daniel <52763491+Burke-Daniel@users.noreply.github.com> Date: Sat, 3 Oct 2020 17:07:28 -0230 Subject: [PATCH 06/10] Add pressure sensor instantiation to test --- Node/WindTunnel/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Node/WindTunnel/main.cpp b/Node/WindTunnel/main.cpp index 572e448..02d3288 100644 --- a/Node/WindTunnel/main.cpp +++ b/Node/WindTunnel/main.cpp @@ -1,8 +1,13 @@ #include +#include "DPS310.h" +#include "Wire.h" + +Dps310 pressure; void setup() { pinMode(LED_BUILTIN, OUTPUT); + pressure.begin(Wire); } void loop() From d28d9a00b649e9e65d4a79b4e93b84f015993cec Mon Sep 17 00:00:00 2001 From: Burke-Daniel <52763491+Burke-Daniel@users.noreply.github.com> Date: Sat, 3 Oct 2020 17:07:48 -0230 Subject: [PATCH 07/10] Add driver and sensor src files to build config --- Node/platformio.ini | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Node/platformio.ini b/Node/platformio.ini index 1c3ff31..0b08d28 100644 --- a/Node/platformio.ini +++ b/Node/platformio.ini @@ -18,6 +18,8 @@ board = sodaq_autonomo framework = arduino src_filter = + + + + + build_flags = -I./DTS/ -I./Common/drivers/inc @@ -29,6 +31,8 @@ board = uno framework = arduino src_filter = + + + + + build_flags = -I./DTS/ -I./Common/drivers/inc @@ -40,6 +44,8 @@ board = sodaq_autonomo framework = arduino src_filter = + + + + + build_flags = -I./Vacuum/ -I./Common/drivers/inc @@ -51,6 +57,8 @@ board = uno framework = arduino src_filter = + + + + + build_flags = -I./Vacuum/ -I./Common/drivers/inc @@ -62,6 +70,8 @@ board = sodaq_autonomo framework = arduino src_filter = + + + + + build_flags = -I./WindTunnel/ -I./Common/drivers/inc @@ -73,6 +83,8 @@ board = uno framework = arduino src_filter = + + + + + build_flags = -I./WindTunnel/ -I./Common/drivers/inc @@ -84,6 +96,8 @@ board = uno framework = arduino src_filter = + + + + + build_flags = -I./Examples/ -I./Common/drivers/inc From 2c734a08fb99ba54df2bacb8342370152deda9a9 Mon Sep 17 00:00:00 2001 From: Burke-Daniel <52763491+Burke-Daniel@users.noreply.github.com> Date: Sat, 3 Oct 2020 17:38:12 -0230 Subject: [PATCH 08/10] Add missing function definitions --- Node/Common/sensors/inc/DPS310.h | 9 ----- Node/Common/sensors/src/DPS310.cpp | 55 +++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/Node/Common/sensors/inc/DPS310.h b/Node/Common/sensors/inc/DPS310.h index 6a4d463..8cad4a9 100644 --- a/Node/Common/sensors/inc/DPS310.h +++ b/Node/Common/sensors/inc/DPS310.h @@ -188,15 +188,6 @@ class Dps310 */ int16_t correctTemp(void); - /** - * @brief Set the source of interrupt (FIFO full, measurement values ready) - * - * @param intr_source Interrupt source as defined by Interrupt_source_310_e - * @param polarity - * @return status code - */ - int16_t setInterruptSources(uint8_t intr_source, uint8_t polarity = 1); - private: //scaling factor table static const int32_t scaling_facts[DPS__NUM_OF_SCAL_FACTS]; diff --git a/Node/Common/sensors/src/DPS310.cpp b/Node/Common/sensors/src/DPS310.cpp index b95461b..af077a7 100644 --- a/Node/Common/sensors/src/DPS310.cpp +++ b/Node/Common/sensors/src/DPS310.cpp @@ -32,12 +32,65 @@ uint8_t Dps310::getRevisionId(void) return m_revisionID; } +int16_t Dps310::getContResults(float *tempBuffer, + uint8_t &tempCount, + float *prsBuffer, + uint8_t &prsCount, + RegMask_t fifo_empty_reg) +{ + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + //abort if device is not in background mode + if (!(m_opMode & 0x04)) + { + return DPS__FAIL_TOOBUSY; + } + + if (!tempBuffer || !prsBuffer) + { + return DPS__FAIL_UNKNOWN; + } + tempCount = 0U; + prsCount = 0U; + + //while FIFO is not empty + while (readByteBitfield(fifo_empty_reg) == 0) + { + int32_t raw_result; + float result; + //read next result from FIFO + int16_t type = getFIFOvalue(&raw_result); + switch (type) + { + case 0: //temperature + if (tempCount < DPS__FIFO_SIZE) + { + result = calcTemp(raw_result); + tempBuffer[tempCount++] = result; + } + break; + case 1: //pressure + if (prsCount < DPS__FIFO_SIZE) + { + result = calcPressure(raw_result); + prsBuffer[prsCount++] = result; + } + break; + case -1: //read failed + break; + } + } + return DPS__SUCCEEDED; +} + int16_t Dps310::getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount) { - return Dps310::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); + return getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); } int16_t Dps310::getSingleResult(float &result) From a3710c21c8998b24dc2b1c852b1263043d819e72 Mon Sep 17 00:00:00 2001 From: Matthew Swenson Date: Sun, 2 May 2021 14:46:59 -0400 Subject: [PATCH 09/10] code for reading sensors into ATMega and logging to serial --- .gitignore | 1 + Node/WindTunnel/WindTunnel.cpp | 76 ++++++++++++++++++++++++++++++++++ Node/platformio.ini | 41 +++++++++++------- 3 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 Node/WindTunnel/WindTunnel.cpp diff --git a/.gitignore b/.gitignore index 3850bf0..7d8e366 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ !important .vscode/tasks.json __pycache__ profiles.json +.DS_Store diff --git a/Node/WindTunnel/WindTunnel.cpp b/Node/WindTunnel/WindTunnel.cpp new file mode 100644 index 0000000..17284c8 --- /dev/null +++ b/Node/WindTunnel/WindTunnel.cpp @@ -0,0 +1,76 @@ +#include +#include // For I2C +#include "DPS310.h" + +Dps310 pvtSensor; + + +void setup() { + pinMode(A0, INPUT); //Distance + pinMode(A1, INPUT); // Distance + pinMode(A2, INPUT); // Distance + pinMode(A3, INPUT); // Distance + pinMode(A11, INPUT); // Diff pressure + pinMode(A12, INPUT); // Diff pressure + pinMode(A13, INPUT); // Strain gauge + pinMode(A14, INPUT); // Strain gauges + pinMode(A8, INPUT); // Accel x + pinMode(A9, INPUT); // Accel y + pinMode(A10, INPUT); // Accel z + + pvtSensor.begin(Wire); + Serial.begin(9600); + Wire.begin(); +} + +void loop() { + int distance1, distance2, distance3, distance4 = 0; // distance sensors + int diff1, diff2 = 0; // Diff pressure sensors + int amp; // Strain gauge + int accelX, accelY, accelZ = 0; // Accel + float pressure, temperature; + + pvtSensor.measureTempOnce(temperature); + pvtSensor.measurePressureOnce(pressure); + distance1 = analogRead(A0); + distance2 = analogRead(A1); + distance3 = analogRead(A2); + distance4 = analogRead(A3); + diff1 = analogRead(A11); + diff2 = analogRead(A12); + //Strain guage has a reference pin, so this is subtracted from the output pin to get the true value + amp = analogRead(A13) - analogRead(A14); + accelX = analogRead(A8); + accelY = analogRead(A9); + accelZ = analogRead(A10); + + Serial.print("Pressure: "); + Serial.println(pressure); + + Serial.print("Temperature: "); + Serial.println(temperature); + + Serial.print("Distance sensors: 1: "); + Serial.print(distance1); + Serial.print(" 2: "); + Serial.print(distance2); + Serial.print(" 3: "); + Serial.print(distance3); + Serial.print(" 4: "); + Serial.println(distance4); + + Serial.print("Differential pressure sensor 1: "); + Serial.print(diff1); + Serial.print(" 2: "); + Serial.println(diff2); + + Serial.print("Strain gauge: "); + Serial.println(amp); + + Serial.print("Acceleration x: "); + Serial.print(accelX); + Serial.print(" y: "); + Serial.print(accelY); + Serial.print(" z: "); + Serial.print(accelZ); +} diff --git a/Node/platformio.ini b/Node/platformio.ini index 0b08d28..37f865d 100644 --- a/Node/platformio.ini +++ b/Node/platformio.ini @@ -16,11 +16,11 @@ include_dir = Common platform = atmelsam board = sodaq_autonomo framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = -I./DTS/ -I./Common/drivers/inc -I./Common/sensors/inc @@ -29,11 +29,11 @@ build_flags = platform = atmelavr board = uno framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = -I./DTS/ -I./Common/drivers/inc -I./Common/sensors/inc @@ -42,11 +42,11 @@ build_flags = platform = atmelsam board = sodaq_autonomo framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = -I./Vacuum/ -I./Common/drivers/inc -I./Common/sensors/inc @@ -55,11 +55,11 @@ build_flags = platform = atmelavr board = uno framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = -I./Vacuum/ -I./Common/drivers/inc -I./Common/sensors/inc @@ -68,11 +68,11 @@ build_flags = platform = atmelsam board = sodaq_autonomo framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = -I./WindTunnel/ -I./Common/drivers/inc -I./Common/sensors/inc @@ -81,11 +81,24 @@ build_flags = platform = atmelavr board = uno framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = + -I./WindTunnel/ + -I./Common/drivers/inc + -I./Common/sensors/inc + +[env:WindTunnel-Mega] +platform = atmelavr +board = ATmega2560 +framework = arduino +src_filter = + + + + + + +build_flags = -I./WindTunnel/ -I./Common/drivers/inc -I./Common/sensors/inc @@ -94,11 +107,11 @@ build_flags = platform = atmelavr board = uno framework = arduino -src_filter = +src_filter = + + + -build_flags = +build_flags = -I./Examples/ -I./Common/drivers/inc -I./Common/sensors/inc From 3cb9b1aac3dbc12d4daa2ff4252ab02d5fbf4f2c Mon Sep 17 00:00:00 2001 From: mjswen0923 Date: Sun, 9 May 2021 13:55:54 -0400 Subject: [PATCH 10/10] builds on Mega, code to log sensors over serial --- Node/WindTunnel/WindTunnel.cpp | 76 ---------------------------------- Node/WindTunnel/main.cpp | 72 ++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 83 deletions(-) delete mode 100644 Node/WindTunnel/WindTunnel.cpp diff --git a/Node/WindTunnel/WindTunnel.cpp b/Node/WindTunnel/WindTunnel.cpp deleted file mode 100644 index 17284c8..0000000 --- a/Node/WindTunnel/WindTunnel.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include // For I2C -#include "DPS310.h" - -Dps310 pvtSensor; - - -void setup() { - pinMode(A0, INPUT); //Distance - pinMode(A1, INPUT); // Distance - pinMode(A2, INPUT); // Distance - pinMode(A3, INPUT); // Distance - pinMode(A11, INPUT); // Diff pressure - pinMode(A12, INPUT); // Diff pressure - pinMode(A13, INPUT); // Strain gauge - pinMode(A14, INPUT); // Strain gauges - pinMode(A8, INPUT); // Accel x - pinMode(A9, INPUT); // Accel y - pinMode(A10, INPUT); // Accel z - - pvtSensor.begin(Wire); - Serial.begin(9600); - Wire.begin(); -} - -void loop() { - int distance1, distance2, distance3, distance4 = 0; // distance sensors - int diff1, diff2 = 0; // Diff pressure sensors - int amp; // Strain gauge - int accelX, accelY, accelZ = 0; // Accel - float pressure, temperature; - - pvtSensor.measureTempOnce(temperature); - pvtSensor.measurePressureOnce(pressure); - distance1 = analogRead(A0); - distance2 = analogRead(A1); - distance3 = analogRead(A2); - distance4 = analogRead(A3); - diff1 = analogRead(A11); - diff2 = analogRead(A12); - //Strain guage has a reference pin, so this is subtracted from the output pin to get the true value - amp = analogRead(A13) - analogRead(A14); - accelX = analogRead(A8); - accelY = analogRead(A9); - accelZ = analogRead(A10); - - Serial.print("Pressure: "); - Serial.println(pressure); - - Serial.print("Temperature: "); - Serial.println(temperature); - - Serial.print("Distance sensors: 1: "); - Serial.print(distance1); - Serial.print(" 2: "); - Serial.print(distance2); - Serial.print(" 3: "); - Serial.print(distance3); - Serial.print(" 4: "); - Serial.println(distance4); - - Serial.print("Differential pressure sensor 1: "); - Serial.print(diff1); - Serial.print(" 2: "); - Serial.println(diff2); - - Serial.print("Strain gauge: "); - Serial.println(amp); - - Serial.print("Acceleration x: "); - Serial.print(accelX); - Serial.print(" y: "); - Serial.print(accelY); - Serial.print(" z: "); - Serial.print(accelZ); -} diff --git a/Node/WindTunnel/main.cpp b/Node/WindTunnel/main.cpp index 02d3288..757129b 100644 --- a/Node/WindTunnel/main.cpp +++ b/Node/WindTunnel/main.cpp @@ -2,18 +2,76 @@ #include "DPS310.h" #include "Wire.h" -Dps310 pressure; +Dps310 pvtSensor; void setup() { - pinMode(LED_BUILTIN, OUTPUT); - pressure.begin(Wire); + pinMode(A0, INPUT); //Distance + pinMode(A1, INPUT); // Distance + pinMode(A2, INPUT); // Distance + pinMode(A3, INPUT); // Distance + pinMode(A11, INPUT); // Diff pressure + pinMode(A12, INPUT); // Diff pressure + pinMode(A13, INPUT); // Strain gauge + pinMode(A7, INPUT); // Strain gauges + pinMode(A8, INPUT); // Accel x + pinMode(A9, INPUT); // Accel y + pinMode(A10, INPUT); // Accel z + + pvtSensor.begin(Wire); + Serial.begin(9600); + Wire.begin(); } void loop() { - digitalWrite(LED_BUILTIN, HIGH); - delay(1000); - digitalWrite(LED_BUILTIN, LOW); - delay(1000); + int distance1, distance2, distance3, distance4 = 0; // distance sensors + int diff1, diff2 = 0; // Diff pressure sensors + int amp; // Strain gauge + int accelX, accelY, accelZ = 0; // Accel + float pressure, temperature; + + pvtSensor.measureTempOnce(temperature); + pvtSensor.measurePressureOnce(pressure); + distance1 = analogRead(A0); + distance2 = analogRead(A1); + distance3 = analogRead(A2); + distance4 = analogRead(A3); + diff1 = analogRead(A11); + diff2 = analogRead(A12); + //Strain guage has a reference pin, so this is subtracted from the output pin to get the true value + amp = analogRead(A13) - analogRead(A7); + accelX = analogRead(A8); + accelY = analogRead(A9); + accelZ = analogRead(A10); + + Serial.print("Pressure: "); + Serial.println(pressure); + + Serial.print("Temperature: "); + Serial.println(temperature); + + Serial.print("Distance sensors: 1: "); + Serial.print(distance1); + Serial.print(" 2: "); + Serial.print(distance2); + Serial.print(" 3: "); + Serial.print(distance3); + Serial.print(" 4: "); + Serial.println(distance4); + + Serial.print("Differential pressure sensor 1: "); + Serial.print(diff1); + Serial.print(" 2: "); + Serial.println(diff2); + + Serial.print("Strain gauge: "); + Serial.println(amp); + + Serial.print("Acceleration x: "); + Serial.print(accelX); + Serial.print(" y: "); + Serial.print(accelY); + Serial.print(" z: "); + Serial.print(accelZ); }