Hello.
I am trying to send certain commands to the odrive from the Arduino like a reboot when a button is pushed but I can’t figure it out.
Here is my code…
#include <SoftwareSerial.h>
#include <ODriveArduino.h>
// Printing with stream operator
template<class T> inline Print& operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
template<> inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }
//Connect pin 8 on arduino to pin 1 in GPIO section on Odrive and pin 9 to pin 2
SoftwareSerial odrive_serial(8, 9); //RX (ODrive TX), TX (ODrive RX)
//for the throttle wire the orange wire to 5V, the black to ground, and the orange to A0
// ODrive object
ODriveArduino odrive(odrive_serial);
int n=0;
int motornum = 0;
int requested_state;
int axis=0;
int reset_button=10;
void setup() {
// ODrive uses 115200 baud
odrive_serial.begin(115200);//is used to send commands to odrive
Serial.begin(115200);
odrive_serial << "w axis" << axis << ".controller.config.vel_limit " << 22000.0f << '\n'; //sets velocity limit
odrive_serial << "w axis" << axis << ".motor.config.current_lim " << 60.0f << '\n'; //sets current limit
odrive_serial << "w axis" << axis <<".motor.config.pre_calibrated = True"<<'\n'; //tells odrive its motor is calibrated
odrive_serial << "w axis" << axis <<".encoder.config.pre_calibrated = True"<<'\n'; //tells odrive its encoder is calibrated (both steps must be done to enter motor into closed loop control later)
requested_state = ODriveArduino::AXIS_STATE_IDLE;
odrive.run_state(motornum, requested_state, false);
}
void loop() {
if (digitalRead(reset_button)== LOW){
Serial.println("running");
float vel= analogRead(A0); //read value from hall effect sensor in throttle (values are between 177 and 880)
if(vel<190){ //makes neutral positions of throttle so that motor is in idle mode
requested_state = ODriveArduino::AXIS_STATE_IDLE;
odrive.run_state(motornum, requested_state, false);
}
else { //makes anything above 190 cloesed look control to use velocity control
requested_state = ODriveArduino::AXIS_STATE_CLOSED_LOOP_CONTROL;
odrive.run_state(motornum, requested_state, false);
vel= map(vel,190,880,0,700); //maps values of 190 to 880 (the throttle) to 0 to 700 the counts/s for motor
odrive.SetVelocity(0, vel); //sets motor 0's velocity to maped value above
}
if(digitalRead(reset_button)== HIGH){
odrive_serial << "reboot()"<< '\n';
Serial.println("rebooting");
}
}
}
I thought that this…
odrive_serial << "reboot()"<< '\n';
would do it but I guess not.
This made me question even if this (below), did what I wanted it to do…
odrive_serial << "w axis" << axis <<".motor.config.pre_calibrated = True"<<'\n'; //tells odrive its motor is calibrated
odrive_serial << "w axis" << axis <<".encoder.config.pre_calibrated = True"<<'\n'; //tells odrive its encoder is calibrated (both steps must be done to enter motor into closed loop control later)
My other question is how do I get the odrive to send the encoder velocity estimate to the arduino to use the data.
I know that you can use odrv0.axis0.encoder.vel_estimate in anaconda to pull the data but how do I do that in arduino.
I found this post https://discourse.odriverobotics.com/t/small-guide-on-how-to-use-odrivearduino-commands/1571 where it says…
And to get the encoder position and add it to a variable use two commands like this:
odrive_serial.write(“r axis0.encoder.pos_estimate\n”);
endstopPos = odrive.readFloat();
but that did not work.