diff --git a/CMakeLists.txt b/CMakeLists.txt index 6798867219d444c49cf6c84becb4e1c970dd684c..109b9ba29f8b07600c8b8464d6aed6da55db9937 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -374,6 +374,9 @@ sbs_target(test-lis3mdl stm32f429zi_skyward_death_stack_x) add_executable(test-lis331hh src/tests/sensors/test-lis331hh.cpp) sbs_target(test-lis331hh stm32f205rc_skyward_ciuti) +add_executable(test-lps331ap src/tests/sensors/test-lps331ap.cpp) +sbs_target(test-lps331ap stm32f429zi_stm32f4discovery) + add_executable(test-max6675 src/tests/sensors/test-max6675.cpp) sbs_target(test-max6675 stm32f429zi_stm32f4discovery) diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake index 2036b43467026eca06f315b8d689f7f81484e08c..5daaab18e1681713b0d138029da8547541920e9c 100644 --- a/cmake/boardcore.cmake +++ b/cmake/boardcore.cmake @@ -90,6 +90,7 @@ foreach(OPT_BOARD ${BOARDS}) ${SBS_BASE}/src/shared/sensors/HX711/HX711.cpp ${SBS_BASE}/src/shared/sensors/LIS3MDL/LIS3MDL.cpp ${SBS_BASE}/src/shared/sensors/LIS331HH/LIS331HH.cpp + ${SBS_BASE}/src/shared/sensors/LPS331AP/LPS331AP.cpp ${SBS_BASE}/src/shared/sensors/MAX6675/MAX6675.cpp ${SBS_BASE}/src/shared/sensors/MAX31855/MAX31855.cpp ${SBS_BASE}/src/shared/sensors/MBLoadCell/MBLoadCell.cpp diff --git a/src/shared/sensors/LPS331AP/LPS331AP.cpp b/src/shared/sensors/LPS331AP/LPS331AP.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c46041ab839a927ac2960b5fb199d59affe29eb --- /dev/null +++ b/src/shared/sensors/LPS331AP/LPS331AP.cpp @@ -0,0 +1,119 @@ + +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "LPS331AP.h" + +#include <drivers/timer/TimestampTimer.h> + +namespace Boardcore +{ + +LPS331AP::LPS331AP(I2C& bus, ODR odr) : bus(bus), odr(odr) {} + +bool LPS331AP::init() +{ + if (!checkWhoAmI()) + { + return false; + } + + uint8_t ctrlReg1 = 0; + ctrlReg1 |= 0x80; // Active mode + ctrlReg1 |= static_cast<uint8_t>(odr) << 4; + + if (!bus.writeRegister(slaveConfig, REG_CTRL_REG1, ctrlReg1)) + { + + lastError = SensorErrors::BUS_FAULT; + return false; + } + + // Maximum possible oversampling to lower the noise + uint8_t ctrlConf = odr != ODR::ODR_25Hz ? 0x69 : 0x7a; + + if (!bus.writeRegister(slaveConfig, REG_RES_CONF, ctrlConf)) + { + lastError = SensorErrors::BUS_FAULT; + return false; + } + + return true; +} + +bool LPS331AP::selfTest() { return checkWhoAmI(); } + +LPS331APData LPS331AP::sampleImpl() +{ + uint8_t buffer[5]; + if (bus.readFromRegister(slaveConfig, REG_PRESS_XLSB, buffer, 5)) + { + LPS331APData data; + + int32_t pressure = 0; + pressure |= static_cast<uint32_t>(buffer[0]) << 16; + pressure |= static_cast<uint32_t>(buffer[1]) << 8; + pressure |= static_cast<uint32_t>(buffer[2]); + + int32_t temperature = 0; + temperature |= static_cast<uint32_t>(buffer[3]) << 8; + temperature |= static_cast<uint32_t>(buffer[4]); + + data.pressureTimestamp = TimestampTimer::getTimestamp(); + data.temperatureTimestamp = TimestampTimer::getTimestamp(); + data.pressure = pressure / 4096.0f; + data.temperature = temperature / 480.0f + 42.5f; + + return data; + } + else + { + lastError = SensorErrors::BUS_FAULT; + return lastSample; + } +} + +bool LPS331AP::checkWhoAmI() +{ + uint8_t whoAmIValue; + + if (bus.readRegister(slaveConfig, REG_WHO_AM_I, whoAmIValue)) + { + if (whoAmIValue == WHO_AM_I_VAL) + { + return true; + } + else + { + LOG_ERR(logger, "Invalid WHO AM I"); + lastError = SensorErrors::INVALID_WHOAMI; + return false; + } + } + else + { + lastError = SensorErrors::BUS_FAULT; + return false; + } +} + +} // namespace Boardcore diff --git a/src/shared/sensors/LPS331AP/LPS331AP.h b/src/shared/sensors/LPS331AP/LPS331AP.h new file mode 100644 index 0000000000000000000000000000000000000000..9c5ab5ffe200b3aa4114bbd9f967b653f7690b59 --- /dev/null +++ b/src/shared/sensors/LPS331AP/LPS331AP.h @@ -0,0 +1,75 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Authors: Alberto Nidasio + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <diagnostic/PrintLogger.h> +#include <drivers/i2c/I2C.h> +#include <sensors/Sensor.h> + +#include "LPS331APData.h" + +namespace Boardcore +{ + +class LPS331AP : public Sensor<LPS331APData> +{ +public: + enum class ODR : uint8_t + { + ODR_1HZ = 0x01, + ODR_7Hz = 0x05, + ODR_12_5Hz = 0x06, + ODR_25Hz = 0x07, + }; + + explicit LPS331AP(I2C& bus, ODR odr = ODR::ODR_25Hz); + + bool init() override; + + bool selfTest() override; + +private: + LPS331APData sampleImpl() override; + + bool checkWhoAmI(); + + static constexpr uint8_t WHO_AM_I_VAL = 0x58; ///< Who am I value + + enum Registers : uint8_t + { + REG_WHO_AM_I = 0x8f, + REG_RES_CONF = 0x10, + REG_CTRL_REG1 = 0x20, + REG_PRESS_XLSB = 0x28, + }; + + I2C& bus; + I2CDriver::I2CSlaveConfig slaveConfig{0x5c, I2CDriver::Addressing::BIT7, + I2CDriver::Speed::STANDARD}; + + ODR odr; + + PrintLogger logger = Logging::getLogger("lps331ap"); +}; + +} // namespace Boardcore diff --git a/src/shared/sensors/LPS331AP/LPS331APData.h b/src/shared/sensors/LPS331AP/LPS331APData.h new file mode 100644 index 0000000000000000000000000000000000000000..1cdcbbd5664381517ef4967d9fcb1a1e5b40ea0b --- /dev/null +++ b/src/shared/sensors/LPS331AP/LPS331APData.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Authors: Alberto Nidasio + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <sensors/SensorData.h> + +namespace Boardcore +{ + +struct LPS331APData : public PressureData, TemperatureData +{ + + LPS331APData() : PressureData{0, 0.0}, TemperatureData{0, 0.0} {} + + LPS331APData(uint64_t pressureTimestamp, float pressure, + uint64_t temperatureTimestamp, float temperature) + : PressureData{pressureTimestamp, pressure}, TemperatureData{ + temperatureTimestamp, + temperature} + { + } + + static std::string header() + { + return "pressureTimestamp,pressure,temperatureTimestamp,temperature\n"; + } + + void print(std::ostream& os) const + { + os << pressureTimestamp << "," << pressure << "," + << temperatureTimestamp << "," << temperature << "\n"; + } +}; + +} // namespace Boardcore diff --git a/src/tests/sensors/test-lps331ap.cpp b/src/tests/sensors/test-lps331ap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7e07db1aa793890544983635d15dd5659339c90 --- /dev/null +++ b/src/tests/sensors/test-lps331ap.cpp @@ -0,0 +1,57 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <miosix.h> +#include <sensors/LPS331AP/LPS331AP.h> + +using namespace miosix; +using namespace Boardcore; + +GpioPin scl(GPIOA_BASE, 8); +GpioPin sda(GPIOC_BASE, 9); + +int main() +{ + I2C bus(I2C3, scl, sda); + LPS331AP lps331(bus); + + if (!lps331.init()) + { + printf("Init failed\n"); + } + + if (!lps331.selfTest()) + { + printf("Self test failed\n"); + } + + while (true) + { + lps331.sample(); + + auto data = lps331.getLastSample(); + printf("[%.2f]: %.2fPa %.2f°\n", data.pressureTimestamp / 1e6, + data.pressure, data.temperature); + + Thread::sleep(50); // 25Hz + } +}