From 2e34b11ba44ac0c48a618bcf8206a1c5c84edf77 Mon Sep 17 00:00:00 2001 From: sarahvilete Date: Thu, 21 Apr 2022 16:43:55 +0200 Subject: [PATCH] Max31855 driver with example for the Nucleo-G474RE board --- README.md | 13 ++- examples/nucleo_g474re/max31855/main.cpp | 99 +++++++++++++++++ examples/nucleo_g474re/max31855/project.xml | 14 +++ src/modm/driver/temperature/max31855.hpp | 104 ++++++++++++++++++ src/modm/driver/temperature/max31855.lb | 32 ++++++ src/modm/driver/temperature/max31855_impl.hpp | 55 +++++++++ 6 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 examples/nucleo_g474re/max31855/main.cpp create mode 100644 examples/nucleo_g474re/max31855/project.xml create mode 100644 src/modm/driver/temperature/max31855.hpp create mode 100644 src/modm/driver/temperature/max31855.lb create mode 100644 src/modm/driver/temperature/max31855_impl.hpp diff --git a/README.md b/README.md index 6a13eba3db..7f8305808c 100644 --- a/README.md +++ b/README.md @@ -683,46 +683,47 @@ you specific needs. LSM6DS33 LTC2984 +MAX31855 MAX6966 MAX7219 MCP23x17 -MCP2515 +MCP2515 MCP7941x MMC5603 NOKIA5110 NRF24 TFT-DISPLAY -PAT9125EL +PAT9125EL PCA8574 PCA9535 PCA9548A PCA9685 SH1106 -SIEMENS-S65 +SIEMENS-S65 SIEMENS-S75 SK6812 SK9822 SSD1306 ST7586S -STTS22H +STTS22H STUSB4500 SX1276 TCS3414 TCS3472 TLC594x -TMP102 +TMP102 TMP12x TMP175 TOUCH2046 VL53L0 VL6180 -WS2812 +WS2812 diff --git a/examples/nucleo_g474re/max31855/main.cpp b/examples/nucleo_g474re/max31855/main.cpp new file mode 100644 index 0000000000..f365e03b71 --- /dev/null +++ b/examples/nucleo_g474re/max31855/main.cpp @@ -0,0 +1,99 @@ +// coding: utf-8 +/* + * Copyright (c) 2022, Sarah Vilete + * Copyright (c) 2022, Rasmus Kleist Hørlyck Sørensen + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include + +using SpiMaster = modm::platform::SpiMaster2; + +using Cs = modm::platform::GpioA10; +using Miso = modm::platform::GpioB14; +using Sck = modm::platform::GpioB13; + +using namespace Board; + +class ThermocoupleThread : public modm::pt::Protothread +{ +public: + ThermocoupleThread() : thermocouple(data) {} + + bool + run() + { + PT_BEGIN(); + + thermocouple.initialize(); + + MODM_LOG_INFO << "Max38155 initialized succeded" << modm::endl; + + while (true) + { + PT_CALL(thermocouple.readout()); + + switch (data.getFault()) + { + case modm::max31855::Fault::ShortCircuitVcc: + MODM_LOG_ERROR << "Thermocouple error short circuit vcc" << modm::endl; + break; + + case modm::max31855::Fault::ShortCircuitGnd: + MODM_LOG_ERROR << "Thermocouple error short circuit gnd" << modm::endl; + break; + + case modm::max31855::Fault::OpenCircuit: + MODM_LOG_ERROR << "Thermocouple error open circuit" << modm::endl; + break; + + default: + MODM_LOG_INFO << "Thermocouple Temperature: " << data.getThermocoupleTemperature() << " degrees Centigrade" << modm::endl; + MODM_LOG_INFO << "Internal Temperature: " << data.getReferenceJunctionTemperature() << " degrees Centigrade" << modm::endl; + break; + } + + timeout.restart(std::chrono::milliseconds(1000)); + PT_WAIT_UNTIL(timeout.isExpired()); + } + + PT_END(); + } + +private: + modm::max31855::Data data; + modm::Max31855 thermocouple; + + modm::ShortTimeout timeout; +} thermocoupleThread; + +int +main() +{ + Board::initialize(); + Cs::setOutput(modm::Gpio::High); + + SpiMaster::connect(); + SpiMaster::initialize(); + + MODM_LOG_INFO << "==========MAX 31855 Test==========" << modm::endl; + MODM_LOG_DEBUG << "Debug logging here" << modm::endl; + MODM_LOG_INFO << "Info logging here" << modm::endl; + MODM_LOG_WARNING << "Warning logging here" << modm::endl; + MODM_LOG_ERROR << "Error logging here" << modm::endl; + MODM_LOG_INFO << "===============================" << modm::endl; + + while (true) + { + thermocoupleThread.run(); + } + + return 0; +} \ No newline at end of file diff --git a/examples/nucleo_g474re/max31855/project.xml b/examples/nucleo_g474re/max31855/project.xml new file mode 100644 index 0000000000..506a31d432 --- /dev/null +++ b/examples/nucleo_g474re/max31855/project.xml @@ -0,0 +1,14 @@ + + modm:nucleo-g474re + + + + + modm:driver:max31855 + modm:platform:gpio + modm:platform:spi:2 + modm:processing:protothread + modm:processing:timer + modm:build:scons + + \ No newline at end of file diff --git a/src/modm/driver/temperature/max31855.hpp b/src/modm/driver/temperature/max31855.hpp new file mode 100644 index 0000000000..8e911df458 --- /dev/null +++ b/src/modm/driver/temperature/max31855.hpp @@ -0,0 +1,104 @@ +// coding: utf-8 +// ---------------------------------------------------------------------------- +/* + * Copyright (c) 2022, Sarah Vilete + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_MAX31855_HPP +#define MODM_MAX31855_HPP + +#include +#include + +namespace modm +{ + +/// @ingroup modm_driver_max31855 +struct max31855 +{ + /// Thermocouple fault bits + enum class + Fault : uint8_t + { + ShortCircuitVcc = Bit2, + ShortCircuitGnd = Bit1, + OpenCircuit = Bit0 + }; + + struct modm_packed + Data + { + /// @return value associated with the respective fault + constexpr Fault getFault() const + { + return static_cast(data[3] & 0b111); + } + + /// @return the thermocouple temperature scaled according to the device documentation + constexpr float + getThermocoupleTemperature() const + { + // convert raw 14 bit readout in 2's complement to a 16 bit signed + const int16_t rawTemp = static_cast((data[0] << 8) | (data[1] & 0b11111100)) / 4; + return 0.25f * rawTemp; + } + + /// @return the reference junction temperature scaled according to the device documentation + constexpr float + getReferenceJunctionTemperature() const + { + // convert raw 12 bit readout in 2's complement to a 16 bit signed + const int16_t rawTemp = static_cast((data[2] << 8) | (data[3] & 0b11110000)) / 16; + return 0.0625f * rawTemp; + } + + uint8_t data[4]; + }; +}; // struct max31855 + +/** + * @tparam SpiMaster + * @tparam Cs + * + * @author Sarah Vilete + * @ingroup modm_driver_max31855 + */ +template +class Max31855 : public max31855, public modm::SpiDevice, protected modm::NestedResumable<1> +{ +public: + /** + * @param data pointer to buffer of the internal data of type Data + */ + Max31855(Data &data); + + /// Call this function once before using the device + void + initialize(); + + /// Read the raw data from the sensor + modm::ResumableResult + readout(); + +public: + /// Get the data object for this sensor + inline Data& + getData() + { return data; } + +private: + Data &data; +}; + +} // namespace modm + +#include "max31855_impl.hpp" + +#endif // MODM_MAX31855_HPP \ No newline at end of file diff --git a/src/modm/driver/temperature/max31855.lb b/src/modm/driver/temperature/max31855.lb new file mode 100644 index 0000000000..9d4bd5e5ba --- /dev/null +++ b/src/modm/driver/temperature/max31855.lb @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2022, Rasmus Kleist Hørlyck Sørensen +# +# This file is part of the modm project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# ----------------------------------------------------------------------------- + + +def init(module): + module.name = ":driver:max31855" + module.description = """\ +# MAX31855 Thermocouple-to-Digital Converter + +[Datasheet](https://datasheets.maximintegrated.com/en/ds/MAX31855.pdf) +""" + +def prepare(module, options): + module.depends( + ":architecture:gpio", + ":architecture:spi.device", + ":processing:resumable") + return True + +def build(env): + env.outbasepath = "modm/src/modm/driver/temperature" + env.copy("max31855.hpp") + env.copy("max31855_impl.hpp") \ No newline at end of file diff --git a/src/modm/driver/temperature/max31855_impl.hpp b/src/modm/driver/temperature/max31855_impl.hpp new file mode 100644 index 0000000000..40d9bca091 --- /dev/null +++ b/src/modm/driver/temperature/max31855_impl.hpp @@ -0,0 +1,55 @@ +// coding: utf-8 +// ---------------------------------------------------------------------------- +/* + * Copyright (c) 2022, Sarah Vilete + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_MAX31855_HPP +# error "Don't include this file directly, use 'max31855.hpp' instead!" +#endif + +namespace modm +{ + +template +Max31855::Max31855(Data &data) : data(data) +{ +} + +// ----------------------------------------------------------------------------- + +template +void +Max31855::initialize() +{ + Cs::setOutput(modm::Gpio::High); +} + +// ----------------------------------------------------------------------------- + +template +modm::ResumableResult +Max31855::readout() +{ + RF_BEGIN(); + RF_WAIT_UNTIL(this->acquireMaster()); + + Cs::reset(); + RF_CALL(SpiMaster::transfer(nullptr, data.data, 4)); + + if (this->releaseMaster()) + { + Cs::set(); + } + + RF_END(); +} + +} // namespace modm \ No newline at end of file