You can refer to the below program which i wrote to control the position of the motor using serial input. `#include <SPI.h>
#include <mcp2515.h>
#define P_MIN -12.5f
#define P_MAX 12.5f
#define V_MIN -50.0f
#define V_MAX 50.0f
#define KP_MIN 0.0f
#define KP_MAX 500.0f
#define KD_MIN 0.0f
#define KD_MAX 5.0f
#define T_MIN -10.0f
#define T_MAX 10.0f
struct can_frame canMsg;
MCP2515 mcp2515(9);
void setup() {
while (!Serial);
Serial.begin(115200);
Serial1.begin(38400);
delay(1000);
while (!Serial);
mcp2515.reset();
mcp2515.setBitrate(CAN_1000KBPS);
mcp2515.setNormalMode();
Serial.println("CAN BUS INIT Succesfully");
Serial1.println("CAN BUS INIT Succesfully");
delay(1000);
//setMotorZero(1);
//Serial.println("Motor set to curr position as zero");
//delay(1000);
enterMotorMode(1);
Serial.println("Motor set to MIT Control Mode");
Serial1.println("Motor set to MIT Control Mode");
delay(1000);
//enterMotorMode(2);
}
void loop()
{
if (Serial1.available() > 0) {
// Default values for vel, kp, kd, torq
float pos, vel = 3, kp = 1, kd = 1, torq = 0;
int mot_id = 1;
String inputString = Serial1.readStringUntil('\n'); // Read the input
Serial.print("Received: "); // Echo received data
Serial.println(inputString);
pos = inputString.toFloat(); // Convert input string to float
sendToMotor(mot_id, pos, vel, kp, kd, torq);
Serial.print("Motor Position sent: ");
Serial.println(pos);
Serial1.print("Motor Position sent: ");
Serial1.println(pos);
}
//sendToMotor(1, 3, 3, 1, 1, 0);
//Serial.println("Motor Position sent 1");
//delay(5000);
//sendToMotor(1, 6, 3, 1, 1, 1);
// delay(5000);
// Serial.println("Motor Position sent 1");
//sendToMotor(1, 0, 3, 1, 1, 1);
// delay(5000);
//Serial.println("Motor Position sent 2");
//sendToMotor(1, 12, 3, 1, 1, 1);
// delay(5000);
//Serial.println("Motor Position sent 3");
//delay(5000);
//sendToMotor(2, 0, 6.28, 0, 5, 0);
//sendToMotor(1, 0, 6.28, 0, 3, 0);
//sendToMotor(2, 0, 6.28, 0, 3, 0);
//delay(1200);
}
void setMotorZero(int mot_id){
struct can_frame cf1;
cf1.can_id = mot_id;
cf1.can_dlc = 8;
cf1.data[0] = 0xFF;
cf1.data[1] = 0xFF;
cf1.data[2] = 0xFF;
cf1.data[3] = 0xFF;
cf1.data[4] = 0xFF;
cf1.data[5] = 0xFF;
cf1.data[6] = 0xFF;
cf1.data[7] = 0xFE;
mcp2515.sendMessage(&cf1);
}
void enterMotorMode(int mot_id){
struct can_frame cf2;
cf2.can_id = mot_id;
cf2.can_dlc = 8;
cf2.data[0] = 0xFF;
cf2.data[1] = 0xFF;
cf2.data[2] = 0xFF;
cf2.data[3] = 0xFF;
cf2.data[4] = 0xFF;
cf2.data[5] = 0xFF;
cf2.data[6] = 0xFF;
cf2.data[7] = 0xFC;
mcp2515.sendMessage(&cf2);
}
void sendToMotor(int mot_id, float pos, float vel, float kp, float kd, float torq){
struct can_frame cf;
unsigned int con_pos = float_to_uint(constrain(pos, P_MIN, P_MAX), P_MIN, P_MAX, 16);
unsigned int con_vel = float_to_uint(constrain(vel, V_MIN, V_MAX), V_MIN, V_MAX, 12);
unsigned int con_kp = float_to_uint(constrain(kp, KP_MIN, KP_MAX), KP_MIN, KP_MAX, 12);
unsigned int con_kd = float_to_uint(constrain(kd, KD_MIN, KD_MAX), KD_MIN, KD_MAX, 12);
unsigned int con_torq = float_to_uint(constrain(torq, T_MIN, T_MAX), T_MIN, T_MAX, 12);
cf.can_id = mot_id;
cf.can_dlc = 8;
cf.data[0] = con_pos>>8;
cf.data[1] = con_pos & 0xFF;
cf.data[2] = con_vel >> 4;
cf.data[3] = ((con_vel&0xF)<<4) | (con_kp>>8);
cf.data[4] = con_kp&0xFF;
cf.data[5] = con_kd>>4;
cf.data[6] = ((con_kd&0xF)<<4) | (con_torq>>8);
cf.data[7] = con_torq&0xFF;
mcp2515.sendMessage(&cf);
}
int float_to_uint(float x, float x_min, float x_max, int bits){
// Converts a float to an unsigned int, given range and number of bits
float span = x_max - x_min;
float offset = x_min;
unsigned int pgg = 0;
if(bits == 12){
pgg = (unsigned int) ((x-offset)*4095.0/span);
}else if(bits == 16){
pgg = (unsigned int) ((x-offset)*65535.0/span);
}
return pgg;
}
`