MCP9808: Create driver for MCP9808 temperature sensor

This commit is contained in:
TedObrien 2025-02-04 11:43:01 +00:00 committed by Jacob Dahl
parent 561a83cf6c
commit a94ee4382b
13 changed files with 447 additions and 0 deletions

View File

@ -154,6 +154,12 @@ then
fi
fi
# Microchip MCP9808 temperature sensor external I2C
if param compare -s SENS_EN_MCP9808 1
then
mcp9808 start -X
fi
# TE MS4515 differential pressure sensor external I2C
if param compare -s SENS_EN_MS4515 1
then

View File

@ -43,6 +43,7 @@ CONFIG_DRIVERS_PWM_OUT=y
CONFIG_DRIVERS_PX4IO=y
CONFIG_COMMON_RC=y
CONFIG_DRIVERS_SAFETY_BUTTON=y
CONFIG_DRIVERS_TEMPERATURE_SENSOR_MCP9808=y
CONFIG_DRIVERS_TONE_ALARM=y
CONFIG_DRIVERS_UAVCAN=y
CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2

View File

@ -207,6 +207,7 @@ set(msg_files
SensorSelection.msg
SensorsStatus.msg
SensorsStatusImu.msg
SensorTemp.msg
SensorUwb.msg
SensorAirflow.msg
SystemPower.msg

6
msg/SensorTemp.msg Normal file
View File

@ -0,0 +1,6 @@
uint64 timestamp # time since system start (microseconds)
uint64 timestamp_sample # Time at which measurement was taken
uint32 device_id # unique device ID for the sensor that does not change between power cycles
float32 temperature # Temperature provided by sensor (Celsius)

View File

@ -262,6 +262,8 @@
#define DRV_ADC_DEVTYPE_ADS7953 0xED
#define DRV_TEMP_DEVTYPE_MCP9808 0xEE
#define DRV_DEVTYPE_UNUSED 0xff
#endif /* _DRV_SENSOR_H */

View File

@ -0,0 +1,3 @@
menu "TEMPERATURE_SENSOR"
rsource "*/Kconfig"
endmenu #TEMPERATURE_SENSOR

View File

@ -0,0 +1,44 @@
############################################################################
#
# Copyright (c) 2024 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
px4_add_module(
MODULE drivers__temperature_sensor__mcp9808
MAIN mcp9808
COMPILE_FLAGS
SRCS
mcp9808_main.cpp
mcp9808.cpp
mcp9808.h
DEPENDS
px4_work_queue
)

View File

@ -0,0 +1,5 @@
menuconfig DRIVERS_TEMPERATURE_SENSOR_MCP9808
bool "MCP9808 temperature sensor"
default n
---help---
Enable support MCP9808 temperature sensor

View File

@ -0,0 +1,124 @@
/****************************************************************************
*
* Copyright (c) 2024 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include "mcp9808.h"
int MCP9808::probe()
{
uint16_t manuf_id, device_id;
int ret = read_reg(Register::MANUF_ID, manuf_id);
if (ret != PX4_OK) {
return ret;
}
ret = read_reg(Register::DEVICE_ID, device_id);
if (ret != PX4_OK) {
return ret;
}
// Verify manufacturer and device ID
if (manuf_id != 0x0054 || device_id != 0x0400) {
PX4_ERR("MCP9808 not found (manuf_id: 0x%04X, device_id: 0x%04X)", manuf_id, device_id);
return PX4_ERROR;
}
PX4_INFO("MCP9808 found (manuf_id: 0x%04X, device_id: 0x%04X)", manuf_id, device_id);
return PX4_OK;
}
int MCP9808::init()
{
int ret = I2C::init();
if (ret != PX4_OK) {
PX4_ERR("I2C init failed");
return ret;
}
PX4_INFO("I2C initialized successfully");
ret = write_reg(Register::CONFIG, 0x0000); // Ensure default configuration
if (ret != PX4_OK) {
PX4_ERR("Configuration failed");
return ret;
}
_to_sensor_temp.advertise();
ScheduleOnInterval(100_ms); // Sample at 10 Hz
return PX4_OK;
}
float MCP9808::read_temperature()
{
uint16_t temp_raw;
if (read_reg(Register::AMBIENT_TEMP, temp_raw) != PX4_OK) {
return NAN;
}
float temp = (temp_raw & 0x0FFF) / 16.0f;
if (temp_raw & 0x1000) {
temp -= 256.0f;
}
return temp;
}
int MCP9808::read_reg(Register address, uint16_t &data)
{
uint8_t addr = static_cast<uint8_t>(address);
uint8_t buffer[2]; // Buffer to hold the raw data
// Read 2 bytes from the register
int ret = transfer(&addr, 1, buffer, 2);
if (ret != PX4_OK) {
return ret;
}
// Combine bytes (big-endian)
data = (buffer[0] << 8) | buffer[1];
return PX4_OK;
}
int MCP9808::write_reg(Register address, uint16_t value)
{
uint8_t buf[3] = {static_cast<uint8_t>(address), static_cast<uint8_t>(value >> 8), static_cast<uint8_t>(value & 0xFF)};
return transfer(buf, sizeof(buf), nullptr, 0);
}

View File

@ -0,0 +1,83 @@
/****************************************************************************
*
* Copyright (c) 2024 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#pragma once
#include <stdint.h>
#include <drivers/device/i2c.h>
#include <px4_platform_common/i2c_spi_buses.h>
#include <uORB/topics/sensor_temp.h>
#include <uORB/PublicationMulti.hpp>
#include <lib/perf/perf_counter.h>
#include <drivers/drv_hrt.h>
using namespace time_literals;
class MCP9808 : public device::I2C, public I2CSPIDriver<MCP9808>
{
public:
MCP9808(const I2CSPIDriverConfig &config);
~MCP9808() override;
int init() override;
int probe() override;
void RunImpl();
static void print_usage();
protected:
void print_status() override;
void exit_and_cleanup() override;
private:
enum class Register : uint8_t {
CONFIG = 0x01,
AMBIENT_TEMP = 0x05,
MANUF_ID = 0x06,
DEVICE_ID = 0x07,
RESOLUTION = 0x08
};
uORB::PublicationMulti<sensor_temp_s> _to_sensor_temp{ORB_ID(sensor_temp)};
perf_counter_t _cycle_perf;
sensor_temp_s _sensor_temp{};
int read_reg(Register address, uint16_t &data);
int write_reg(Register address, uint16_t value);
float read_temperature();
uint32_t measurement_time = 0;
};

View File

@ -0,0 +1,130 @@
/****************************************************************************
*
* Copyright (c) 2024 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file mcp9808_main.cpp
* @author TedObrien
*
* Driver for the Microchip MCP9080 Temperature Sensor connected via I2C.
*/
#include "mcp9808.h"
#include <px4_platform_common/module.h>
MCP9808::MCP9808(const I2CSPIDriverConfig &config) :
I2C(config),
I2CSPIDriver(config),
_cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample"))
{
_sensor_temp.device_id = this->get_device_id();
}
MCP9808::~MCP9808()
{
ScheduleClear();
perf_free(_cycle_perf);
}
void MCP9808::exit_and_cleanup()
{
I2CSPIDriverBase::exit_and_cleanup(); // nothing to do
}
void MCP9808::RunImpl()
{
perf_begin(_cycle_perf);
// publish at around 5HZ
if ((hrt_absolute_time() - measurement_time) > 200_ms) {
measurement_time = hrt_absolute_time(); // get the time the measurement was taken
float temperature = read_temperature();
_sensor_temp.timestamp = hrt_absolute_time();
_sensor_temp.timestamp_sample = measurement_time;
_sensor_temp.temperature = temperature;
_to_sensor_temp.publish(_sensor_temp);
}
perf_end(_cycle_perf);
}
void MCP9808::print_usage()
{
PRINT_MODULE_USAGE_NAME("mcp9808", "driver");
PRINT_MODULE_USAGE_COMMAND("start");
PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false);
PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x18);
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
}
void MCP9808::print_status()
{
I2CSPIDriverBase::print_status();
perf_print_counter(_cycle_perf);
}
extern "C" int mcp9808_main(int argc, char *argv[])
{
using ThisDriver = MCP9808;
BusCLIArguments cli{true, false};
cli.default_i2c_frequency = 400000;
cli.i2c_address = 0x18;
const char *verb = cli.parseDefaultArguments(argc, argv);
if (!verb) {
ThisDriver::print_usage();
return -1;
}
BusInstanceIterator iterator(MODULE_NAME, cli, DRV_TEMP_DEVTYPE_MCP9808);
if (!strcmp(verb, "start")) {
return ThisDriver::module_start(cli, iterator);
}
if (!strcmp(verb, "stop")) {
return ThisDriver::module_stop(iterator);
}
if (!strcmp(verb, "status")) {
return ThisDriver::module_status(iterator);
}
ThisDriver::print_usage();
return -1;
}

View File

@ -0,0 +1,41 @@
/****************************************************************************
*
* Copyright (c) 2024 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* Enable MCP9808 temperature sensor (external I2C)
*
* @reboot_required true
* @group Sensors
* @boolean
*/
PARAM_DEFINE_INT32(SENS_EN_MCP9808, 0);

View File

@ -123,6 +123,7 @@ void LoggedTopics::add_default_topics()
add_optional_topic("sensor_gyro_fft", 50);
add_topic("sensor_selection");
add_topic("sensors_status_imu", 200);
add_optional_topic("sensor_temp", 10);
add_optional_topic("spoilers_setpoint", 1000);
add_topic("system_power", 500);
add_optional_topic("takeoff_status", 1000);