From 73b15f2fe6eac6a7c610491ae13652eb15bf7fbc Mon Sep 17 00:00:00 2001 From: Malaphor <55569990+Malaphor@users.noreply.github.com> Date: Thu, 18 Aug 2022 20:18:04 -0700 Subject: [PATCH 1/2] Add get_adc_voltage() --- Firmware/communication/can/can_simple.cpp | 21 +++++++++++++++++++++ Firmware/communication/can/can_simple.hpp | 5 ++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Firmware/communication/can/can_simple.cpp b/Firmware/communication/can/can_simple.cpp index 93b9f7bcd..b413c2c38 100644 --- a/Firmware/communication/can/can_simple.cpp +++ b/Firmware/communication/can/can_simple.cpp @@ -151,6 +151,9 @@ void CANSimple::do_command(Axis& axis, const can_Message_t& msg) { case MSG_SET_VEL_GAINS: set_vel_gains_callback(axis, msg); break; + case MSG_GET_ADC_VOLTAGE: + get_adc_voltage_callback(axis, msg); + break; default: break; } @@ -345,6 +348,24 @@ bool CANSimple::get_vbus_voltage_callback(const Axis& axis) { return canbus_->send_message(txmsg); } +bool CANSimple::get_adc_voltage_callback(const Axis& axis, const can_Message_t& msg) { + can_Message_t txmsg; + + txmsg.id = axis.config_.can.node_id << NUM_CMD_ID_BITS; + txmsg.id += MSG_GET_ADC_VOLTAGE; + txmsg.isExt = axis.config_.can.is_extended; + txmsg.len = 8; + + auto gpio_num = can_getSignal(msg, 0, 8, true); + if (gpio_num < GPIO_COUNT) { + auto voltage = get_adc_voltage(get_gpio(gpio_num)); + can_setSignal(txmsg, voltage, 0, 32, true); + return canbus_->send_message(txmsg); + } else { + return false; + } +} + void CANSimple::clear_errors_callback(Axis& axis, const can_Message_t& msg) { odrv.clear_errors(); // TODO: might want to clear axis errors only } diff --git a/Firmware/communication/can/can_simple.hpp b/Firmware/communication/can/can_simple.hpp index 83cd0551d..3c8192a2f 100644 --- a/Firmware/communication/can/can_simple.hpp +++ b/Firmware/communication/can/can_simple.hpp @@ -35,6 +35,7 @@ class CANSimple { MSG_SET_LINEAR_COUNT, MSG_SET_POS_GAIN, MSG_SET_VEL_GAINS, + MSG_GET_ADC_VOLTAGE, MSG_CO_HEARTBEAT_CMD = 0x700, // CANOpen NMT Heartbeat SEND }; @@ -62,6 +63,8 @@ class CANSimple { bool get_iq_callback(const Axis& axis); bool get_sensorless_estimates_callback(const Axis& axis); bool get_vbus_voltage_callback(const Axis& axis); + // msg.rtr bit must NOT be set + bool get_adc_voltage_callback(const Axis& axis, const can_Message_t& msg); // Set functions static void set_axis_nodeid_callback(Axis& axis, const can_Message_t& msg); @@ -106,4 +109,4 @@ class CANSimple { bool extended_node_ids_[AXIS_COUNT]; }; -#endif \ No newline at end of file +#endif From 398ee3d81d45aa489802ebefc46ffde016b2a89d Mon Sep 17 00:00:00 2001 From: Malaphor <55569990+Malaphor@users.noreply.github.com> Date: Tue, 30 Aug 2022 17:12:49 -0700 Subject: [PATCH 2/2] Added docs info --- docs/analog-input.rst | 2 ++ docs/can-protocol.rst | 1 + docs/figures/can-protocol.csv | 1 + tools/create_can_dbc.py | 7 ++++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/analog-input.rst b/docs/analog-input.rst index 7df9b6df3..21ad4bc8e 100644 --- a/docs/analog-input.rst +++ b/docs/analog-input.rst @@ -10,3 +10,5 @@ To read the voltage on GPIO1 in odrivetool the following would be entered: :code Similar to RC PWM input, analog inputs can also be used to feed any of the numerical properties that are visible in :code:`odrivetool`. This is done by configuring :code:`odrv0.config.gpio3_analog_mapping` and :code:`odrv0.config.gpio4_analog_mapping`. Refer to :ref:`RC PWM ` for instructions on how to configure the mappings. + +You may also retrieve voltage measurements from analog inputs via the CAN protocol by sending the Get ADC Voltage message with the GPIO number of the analog input you wish to read. Refer to :ref: `CAN Protocol ` for guidance on how to use the CAN Protocol. \ No newline at end of file diff --git a/docs/can-protocol.rst b/docs/can-protocol.rst index 128228c94..ac892b6e7 100644 --- a/docs/can-protocol.rst +++ b/docs/can-protocol.rst @@ -74,6 +74,7 @@ All multibyte values are little endian (aka Intel format, aka least significant * These messages are call & response. The Master node sends a message with the RTR bit set, and the axis responds with the same ID and specified payload. * These CANOpen messages are reserved to avoid bus collisions with CANOpen devices. They are not used by CAN Simple. * These messages can be sent to either address on a given ODrive board. + * You must send a valid GPIO pin number in the first byte to recieve coreect ADC voltage feedback. Since you're both sending and receiving data the RTR bit must be set to false. Cyclic Messages diff --git a/docs/figures/can-protocol.csv b/docs/figures/can-protocol.csv index f00da301b..1bf194ca1 100644 --- a/docs/figures/can-protocol.csv +++ b/docs/figures/can-protocol.csv @@ -104,4 +104,5 @@ IEEE 754 Float","32 32","1 1","0 0" +0x01C,Get ADC Voltage****,Master***,ADC Voltage,0,IEEE 754 Float,32,1,0 0x700,CANOpen Heartbeat Message**,Slave,-,-,-,-,-,- \ No newline at end of file diff --git a/tools/create_can_dbc.py b/tools/create_can_dbc.py index ccc0f5b5d..933545c80 100644 --- a/tools/create_can_dbc.py +++ b/tools/create_can_dbc.py @@ -157,6 +157,10 @@ velIntGain = cantools.database.can.Signal("Vel_Integrator_Gain", 32, 32, is_float=True) setVelGainsMsg = cantools.database.can.Message(0x01B, "Set_Vel_gains", 8, [velGain, velIntGain]) +# 0x01C - Get ADC Voltage +adcVoltage = cantools.database.can.Signal("ADC_Voltage", 0, 32, is_float=True) +getADCVoltageMsg = cantools.database.can.Message(0x01C, "Get_ADC_Voltage", 8, [adcVoltage]) + db = cantools.database.can.Database( [ heartbeatMsg, @@ -184,7 +188,8 @@ clearErrorsMsg, setLinearCountMsg, setPosGainMsg, - setVelGainsMsg + setVelGainsMsg, + getADCVoltageMsg ] )