Hello so I'm trying to do the inverted pendulum porject, here is my assembly
I'm trying to use a 1 amp Nema17 with a498 driver with 24 volt 1.5 amp power supply on a arduino uno. I'm using the stepper library with the following code to just test out the speed of the motor with no load.
#include <AccelStepper.h>
const int step_pin = 4;
const int dir_pin = 5;
const int ms1 = 6;
const int ms2 = 7;
const int ms3 = 8;
AccelStepper stepper(1,step_pin,dir_pin);
const float conversion = 0.1; //steps to arc length (mm)
const float safe_range = 200.0; //mm
bool run = true; //flag varible to turn off
int acceleration = 1000;
int maxspeed = 4000;
int speed = 3700;
int steps = 1200;
void setup()
{
Serial.begin(9600);
//setup microstepping
pinMode(ms1,OUTPUT);
pinMode(ms2,OUTPUT);
pinMode(ms3,OUTPUT);
digitalWrite(ms1,HIGH);
digitalWrite(ms2,LOW);
digitalWrite(ms3,LOW);
//setup speed + acceleration
stepper.setMaxSpeed(maxspeed);
stepper.setAcceleration(acceleration);
stepper.setSpeed(speed);
//stepper.move(steps);
delay(2000);
}
void loop()
{
//float step = stepper.currentPosition();
//float s = step*conversion;
if ((Serial.available() > 0))
{
run = false;
}
if (run == true)
{
stepper.runSpeed();
}
}
float absolute_value(float value)
{
if (value < 0.0)
{
value = -value;
}
return value;
}
And it stalls at 3700 steps per second. I've tried to use the motor with the encoder to implement a PID controller, here is the code
#include <AccelStepper.h>
//define pins
#define ENCA 2
#define ENCB 3
const int step_pin = 4;
const int dir_pin = 5;
const int ms1 = 6;
const int ms2 = 7;
const int ms3 = 8;
//stepper parameters
AccelStepper stepper(1,step_pin,dir_pin);
const float conversion = 0.2; //steps to arc length (mm)
const float safe_range = 150.0; //mm
bool run = true; //flag varible to turn off
int acceleration = 10000;
const int maxspeed = 1000;
int steps = 50;
int timestep_count = 0;
int timestep_limit = 5;
//encoder parameters
float count = 0;
const float resolution = 0.3;
const float theta_range = 30.0;
long prev_T = 0.0;
float prev_error = 0.0;
//PD controller gains
const float P = 10.0;
const float D = 10.0;
void setup()
{
Serial.begin(9600);
//STEPPER
//setup microstepping
pinMode(ms1,OUTPUT);
pinMode(ms2,OUTPUT);
pinMode(ms3,OUTPUT);
digitalWrite(ms1,LOW);
digitalWrite(ms2,LOW);
digitalWrite(ms3,LOW);
//setup speed + acceleration
stepper.setMaxSpeed(maxspeed);
//ENCODER
pinMode(ENCA,INPUT_PULLUP);
pinMode(ENCB,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,CHANGE);
delay(1000);
prev_T = micros();
}
void loop()
{
//record time difference
long cur_T = micros();
float T = ((float)(cur_T - prev_T))/(1.0e6); //delta T in seconds
//compute error and derivative
float angle = count*resolution;
float error = -angle;
float delta_error = (error - prev_error)/T;
prev_error = error;
prev_T = cur_T;
//compute control signal
int u = P*error + D*delta_error;
if (u == 0)
{
u = 1;
}
stepper.setSpeed(limit(-maxspeed,maxspeed,u));
float step = stepper.currentPosition();
float s = step*conversion;
if ((absolute_value(s) >= safe_range))
{
run = false;
}
if ((run == true) && (abs(angle) <= theta_range))
{
stepper.runSpeed();
}
Serial.println(u);
}
int limit(int min, int max, int value)
{
if (value < min)
{
value = min;
}
else if(value > max)
{
value = max;
}
return value;
}
int sign(int a)
{
if (a >= 0)
{
return 1;
}
return -1;
}
float absolute_value(float value)
{
if (value < 0.0)
{
value = -value;
}
return value;
}
void readEncoder()
{
int a_state = digitalRead(ENCA);
int b_state = digitalRead(ENCB);
if (a_state == b_state) //CCW
{
count = count - 1;
}
else //CW
{
count = count + 1;
}
}
Although the motor moves in the right direction, it feels choppy and I don' feel confident it can reach the desired speeds to balance. Would a DC motor be better? The only concern I have with DC is that it has lower torque so I'm worried my cart would be too heavy. Any advice would be appreciated, thanks
