I have a sensorless motor attached to my drive and am trying to control it through an Arduino Mega. when I request AXIS_STATE_MOTOR_CALIBRATION the motor beeps after 10 seconds and then sits still for around 2 minute before requesting senseless mode and spinning up.
is there a way to skip sensorless calibration and start the motor running straight away or is there something I’m missing that is causing the motor to take a large amount of time to calibrate.
thanks in advance.
#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; }
// Serial to the ODrive
SoftwareSerial odrive_serial(8, 9); //RX (ODrive TX), TX (ODrive RX)
// Note: you must also connect GND on ODrive to GND on Arduino!
// ODrive object
ODriveArduino odrive(odrive_serial);
void setup() {
// ODrive uses 115200 baud
odrive_serial.begin(115200);
// Serial to PC
Serial.begin(115200);
while (!Serial) ; // wait for Arduino Serial Monitor to open
Serial.println("ODriveArduino");
Serial.println("Setting parameters...");
// In this example we set the same parameters to both motors.
// You can of course set them different if you want.
// See the documentation or play around in odrivetool to see the available parameters
/*for (int axis = 0; axis < 2; ++axis) {
odrive_serial << "w axis" << axis << ".controller.config.vel_limit " << 22000.0f << '\n';
odrive_serial << "w axis" << axis << ".motor.config.current_lim " << 22.0f << '\n';
odrive_serial << "w axis" << axis << ".motor.config.pole_pairs " << 3.0f << '\n';
odrive_serial << "w axis" << axis << ".config.spin_up_current " << 20.0f << '\n';
odrive_serial << "w axis" << axis << ".config.spin_up_acceleration " << 1000.0f << '\n';
odrive_serial << "w axis" << axis << ".config.spin_up_target_vel " << 300.0f << '\n';
odrive_serial << "w axis" << axis << ".controller.config.vel_integrator_gain " << 0.05f << '\n';
odrive_serial << "w axis" << axis << ".sensorless_estimator.config.pm_flux_linkage " << 0.000471221278f << '\n';
odrive_serial << "w axis" << axis << ".controller.config.vel_gain " << 0.01f << '\n';
odrive_serial << "w axis" << axis << ".controller.config.control_mode " << 2.0f << '\n';
odrive_serial << "w axis" << axis << ".controller.vel_setpoint " << 400.0f << '\n';
odrive_serial << "w axis" << axis << ".save_configuration() " << '\n';
//odrive_serial << "w axis" << axis << ".controller.set_vel_setpoint " << 1000, 0.2 << '\n';
// This ends up writing something like "w axis0.motor.config.current_lim 10.0\n"
}*/
Serial.println("Ready!");
Serial.println("Send the character '0' or '1' to calibrate respective motor (you must do this before you can command movement)");
Serial.println("Send the character 's' to exectue test move");
Serial.println("Send the character 'b' to read bus voltage");
Serial.println("Send the character 'p' to read motor positions in a 10s loop");
}
void loop() {
if (Serial.available()) {
char c = Serial.read();
// Run calibration sequence
if (c == '0' || c == '1') {
int motornum = c-'0';
int requested_state;
requested_state = ODriveArduino::AXIS_STATE_MOTOR_CALIBRATION;
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
odrive.run_state(motornum, requested_state, true);
requested_state = ODriveArduino::AXIS_STATE_SENSORLESS_CONTROL;
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
odrive.run_state(motornum, requested_state, false);
}
//
if (c == 's') {
Serial.println("Executing test move");
odrive.SetVelocity(0, 4000);
delay(5);
}
// Read bus voltage
if (c == 'b') {
Serial.println("Executing test move");
odrive.SetVelocity(0, 300);
delay(5);
}
// print motor positions in a 10s loop
if (c == 'p') {
Serial.println("Executing test move");
odrive.SetVelocity(0, -300);
delay(300);
odrive.SetVelocity(0, -2000);
// delay(50);
//odrive.SetVelocity(0, -2000);
}
Serial << '\n';
}
}