diff --git a/msg/CMakeLists.txt b/msg/CMakeLists.txt index 52cb19beaf..a698de2a5e 100644 --- a/msg/CMakeLists.txt +++ b/msg/CMakeLists.txt @@ -41,6 +41,7 @@ set(msg_files adc_report.msg airspeed.msg airspeed_validated.msg + analog_voltage_current.msg battery_status.msg camera_capture.msg camera_trigger.msg diff --git a/msg/analog_voltage_current.msg b/msg/analog_voltage_current.msg new file mode 100644 index 0000000000..2e927dcfce --- /dev/null +++ b/msg/analog_voltage_current.msg @@ -0,0 +1,4 @@ +uint64 timestamp # time since system start (microseconds) + +uint16[2] voltage +uint16[2] current diff --git a/src/drivers/uavcan/CMakeLists.txt b/src/drivers/uavcan/CMakeLists.txt index 8ecc63fdf8..3e534ea0b1 100644 --- a/src/drivers/uavcan/CMakeLists.txt +++ b/src/drivers/uavcan/CMakeLists.txt @@ -126,14 +126,15 @@ px4_add_module( actuators/hardpoint.cpp # Sensors - sensors/sensor_bridge.cpp - sensors/differential_pressure.cpp + sensors/adc.cpp + sensors/airspeed.cpp sensors/baro.cpp sensors/battery.cpp - sensors/airspeed.cpp + sensors/differential_pressure.cpp sensors/flow.cpp sensors/gnss.cpp sensors/mag.cpp + sensors/sensor_bridge.cpp DEPENDS px4_uavcan_dsdlc diff --git a/src/drivers/uavcan/dsdl/com/volansi/equipment/adc/20201.Report.uavcan b/src/drivers/uavcan/dsdl/com/volansi/equipment/adc/20201.Report.uavcan new file mode 100644 index 0000000000..6bb74f5acf --- /dev/null +++ b/src/drivers/uavcan/dsdl/com/volansi/equipment/adc/20201.Report.uavcan @@ -0,0 +1,6 @@ +uint2 UNITS_RAW = 0 +uint2 UNITS_MV = 1 +uint2 UNITS_MA = 2 +uint2[2] unit_type + +int16[2] values # TODO: do we want to include all of the ADC measurements or just two for voltage/current on power port? diff --git a/src/drivers/uavcan/sensors/adc.cpp b/src/drivers/uavcan/sensors/adc.cpp new file mode 100644 index 0000000000..c457d295c2 --- /dev/null +++ b/src/drivers/uavcan/sensors/adc.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** + * + * Copyright (c) 2020 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 +#include "adc.hpp" + +const char *const UavcanAdcBridge::NAME = "adc"; + +UavcanAdcBridge::UavcanAdcBridge(uavcan::INode &node) : + UavcanCDevSensorBridgeBase("uavcan_airspeed", "/dev/uavcan/adc", "/dev/adc", ORB_ID(analog_voltage_current)), + _sub_adc_data(node) +{ } + +int UavcanAdcBridge::init() +{ + int res = device::CDev::init(); + + if (res < 0) { + return res; + } + + res = _sub_adc_data.start(AdcCbBinder(this, &UavcanAdcBridge::adc_sub_cb)); + + if (res < 0) { + DEVICE_LOG("failed to start uavcan sub: %d", res); + return res; + } + + return 0; +} + +void +UavcanAdcBridge::adc_sub_cb(const + uavcan::ReceivedDataStructure &msg) +{ + analog_voltage_current_s report{}; + + static constexpr int numIndices = 2; + static constexpr uint16_t mV = com::volansi::equipment::adc::Report::UNITS_MV; + static constexpr uint16_t mA = com::volansi::equipment::adc::Report::UNITS_MA; + + for (int i = 0; i < numIndices; i++) { + + // TODO: do we want to publish raw ADC values? What about temperature? + if (msg.unit_type[i] == mV) { + report.voltage[i] = msg.values[i]; + + } else if (msg.unit_type[i] == mA) { + report.current[i] = msg.values[i]; + } + } + + publish(msg.getSrcNodeID().get(), &report); +} diff --git a/src/drivers/uavcan/sensors/adc.hpp b/src/drivers/uavcan/sensors/adc.hpp new file mode 100644 index 0000000000..807ae14d1f --- /dev/null +++ b/src/drivers/uavcan/sensors/adc.hpp @@ -0,0 +1,66 @@ +/**************************************************************************** + * + * Copyright (c) 2020 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. + * + ****************************************************************************/ + +/** + * @author RJ Gritter + */ + +#pragma once + +#include "sensor_bridge.hpp" +#include + +#include + +class UavcanAdcBridge : public UavcanCDevSensorBridgeBase +{ +public: + static const char *const NAME; + + UavcanAdcBridge(uavcan::INode &node); + + const char *get_name() const override { return NAME; } + + int init() override; + +private: + + void adc_sub_cb(const uavcan::ReceivedDataStructure &msg); + + typedef uavcan::MethodBinder < UavcanAdcBridge *, + void (UavcanAdcBridge::*) + (const uavcan::ReceivedDataStructure &) > + AdcCbBinder; + + uavcan::Subscriber _sub_adc_data; +}; diff --git a/src/drivers/uavcan/sensors/sensor_bridge.cpp b/src/drivers/uavcan/sensors/sensor_bridge.cpp index bf1c0f4ede..27cb18c41f 100644 --- a/src/drivers/uavcan/sensors/sensor_bridge.cpp +++ b/src/drivers/uavcan/sensors/sensor_bridge.cpp @@ -38,6 +38,7 @@ #include "sensor_bridge.hpp" #include +#include "adc.hpp" #include "differential_pressure.hpp" #include "baro.hpp" #include "battery.hpp" @@ -58,6 +59,7 @@ void IUavcanSensorBridge::make_all(uavcan::INode &node, List uavcan::equipment::gnss::Fix2 + if (_adc_report_sub.updated()) { + adc_report_s adc_report; + + if (_adc_report_sub.copy(&adc_report)) { + + // We could probably convince people an ADC uavcan data type + // would be useful to have in tree... + com::volansi::equipment::adc::Report report{}; + + int32_t adc1_units = 0; + int32_t adc2_units = 0; + (void)param_get(param_find("ADC1_UNIT_TYPE"), &adc1_units); + (void)param_get(param_find("ADC2_UNIT_TYPE"), &adc2_units); + + report.unit_type[0] = (unsigned)adc1_units; + report.unit_type[1] = (unsigned)adc2_units; + + // Always indices 0 and 1? + report.values[0] = adc_report.raw_data[0]; + report.values[1] = adc_report.raw_data[1]; + + _adc_report_publisher.broadcast(report); + } + } +} + void UavcanNode::print_info() { pthread_mutex_lock(&_node_mutex); diff --git a/src/drivers/uavcannode/UavcanNode.hpp b/src/drivers/uavcannode/UavcanNode.hpp index e77dd44485..8303715828 100644 --- a/src/drivers/uavcannode/UavcanNode.hpp +++ b/src/drivers/uavcannode/UavcanNode.hpp @@ -64,6 +64,7 @@ #include #include #include +#include #include @@ -71,10 +72,11 @@ #include #include +#include #include -#include #include #include +#include #include #include #include @@ -152,6 +154,7 @@ private: void send_magnetic_field_strength2(); void send_gnss_fix2(); void send_range_sensor_measurement(); + void send_adc_measurements(); px4::atomic_bool _task_should_exit{false}; ///< flag to indicate to tear down the CAN driver @@ -183,6 +186,8 @@ private: uavcan::Publisher _air_data_static_temperature_publisher; uavcan::Publisher _raw_air_data_publisher; uavcan::Publisher _range_sensor_measurement; + uavcan::Publisher _adc_report_publisher; + hrt_abstime _last_static_temperature_publish{0}; @@ -199,6 +204,8 @@ private: uORB::SubscriptionCallbackWorkItem _sensor_baro_sub{this, ORB_ID(sensor_baro)}; uORB::SubscriptionCallbackWorkItem _sensor_mag_sub{this, ORB_ID(sensor_mag)}; uORB::SubscriptionCallbackWorkItem _vehicle_gps_position_sub{this, ORB_ID(vehicle_gps_position)}; + uORB::SubscriptionCallbackWorkItem _adc_report_sub{this, ORB_ID(adc_report)}; + perf_counter_t _cycle_perf; perf_counter_t _interval_perf; diff --git a/src/drivers/uavcannode/dsdl/com/volansi/equipment/adc/20201.Report.uavcan b/src/drivers/uavcannode/dsdl/com/volansi/equipment/adc/20201.Report.uavcan new file mode 100644 index 0000000000..6bb74f5acf --- /dev/null +++ b/src/drivers/uavcannode/dsdl/com/volansi/equipment/adc/20201.Report.uavcan @@ -0,0 +1,6 @@ +uint2 UNITS_RAW = 0 +uint2 UNITS_MV = 1 +uint2 UNITS_MA = 2 +uint2[2] unit_type + +int16[2] values # TODO: do we want to include all of the ADC measurements or just two for voltage/current on power port? diff --git a/src/drivers/uavcannode/uavcannode_params.c b/src/drivers/uavcannode/uavcannode_params.c index d16284c1e9..529698d3fe 100644 --- a/src/drivers/uavcannode/uavcannode_params.c +++ b/src/drivers/uavcannode/uavcannode_params.c @@ -50,3 +50,13 @@ PARAM_DEFINE_INT32(CANNODE_NODE_ID, 120); * @group UAVCAN */ PARAM_DEFINE_INT32(CANNODE_BITRATE, 1000000); + +/** + * Units associated with ADC measurement. + * 0 - raw + * 1 - mV + * 2 - mA + * @group UAVCAN + */ +PARAM_DEFINE_INT32(ADC1_UNIT_TYPE, 1); +PARAM_DEFINE_INT32(ADC2_UNIT_TYPE, 2);