Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add get_adc_voltage() #707

Merged
merged 2 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Firmware/communication/can/can_simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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<uint8_t>(msg, 0, 8, true);
if (gpio_num < GPIO_COUNT) {
auto voltage = get_adc_voltage(get_gpio(gpio_num));
can_setSignal<float>(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
}
Expand Down
5 changes: 4 additions & 1 deletion Firmware/communication/can/can_simple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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
Wetmelon marked this conversation as resolved.
Show resolved Hide resolved
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);
Expand Down Expand Up @@ -106,4 +109,4 @@ class CANSimple {
bool extended_node_ids_[AXIS_COUNT];
};

#endif
#endif
2 changes: 2 additions & 0 deletions docs/analog-input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <rc-pwm-doc>` 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 <can-protocol-doc>` for guidance on how to use the CAN Protocol.
1 change: 1 addition & 0 deletions docs/can-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/figures/can-protocol.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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,-,-,-,-,-,-
7 changes: 6 additions & 1 deletion tools/create_can_dbc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -184,7 +188,8 @@
clearErrorsMsg,
setLinearCountMsg,
setPosGainMsg,
setVelGainsMsg
setVelGainsMsg,
getADCVoltageMsg
]
)

Expand Down