Hi, so I am trying to run two stepper motors for a self-balancing robot. My problem is that the time it takes to go through the loop() code is longer than the pulse time needed to drive the stepper motors at the desired speed. It takes about 2-4ms to run the loop() code but I need to do digital.Write(HIGH) and LOW with only a 400us gap between them ideally (That is about the max stepper speed I was able to obtain using no other code).
I have looked at using PWM even though it seems that it is not generating the same signals as the alternating digitalWrite signals but it makes a lot of noise in the stepper motor and drives at weird speeds it seemed.
So my question is, what is the best way to drive the stepper motors with the digital write without worrying about the loop time.
Here is my current code:
#include <Arduino_LSM9DS1.h>
//#include <mbed.h>
float x, y, z, xg, yg, zg, AccAngle,angle,speed, delT,err, offset, P, I, D, Command,lastSensorTime, lasttime, dt, serror, deriv, err1, err2, err3;
const int stepPin1 = 2;
const int dirPin1 = 3;
const int stepPin2 = 4;
const int dirPin2 = 5;
int i=1;
//mbed::PwmOut d2(P1_11);
void setup() {
IMU.begin();
Serial.begin(9600);
//pinMode(stepPin1,OUTPUT);
pinMode(dirPin1,OUTPUT);
pinMode(stepPin2,OUTPUT);
pinMode(dirPin2,OUTPUT);
digitalWrite(dirPin1,HIGH);
digitalWrite(dirPin2,LOW);
}
void loop() {
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(xg, yg, zg);
}
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
}
AccAngle=(atan2(z,-x))*180/PI;
angle=0.98*(angle+(y/(IMU.gyroscopeSampleRate())))+(0.02*AccAngle);
//Serial.println(err);
offset=3.0;
err=angle+offset;
err3=err2;
err2=err1;
err1=err;
dt=micros()-lasttime;
lasttime=micros();
Serial.println(dt);
//PID Controller
P=-0.04;
I=0.0;
D=0.0;
serror=serror+(err*dt);
deriv=((3*err1)-(4*err2)+(err3))/(2*dt);
Command=(P*err)+(I*serror)+(D*deriv);
accel(Command);
}
void velocity(float speed) {
if (speed<0.0) {
digitalWrite(dirPin1,HIGH);
digitalWrite(dirPin2,LOW);
}
else {
digitalWrite(dirPin1,LOW);
digitalWrite(dirPin2,HIGH);
}
if (abs(speed)<=1000.0) {
delT=4000000.0/(abs(speed));
}
else {
delT=4000.0;
}
//d2.write(0.1f);
//d2.period_us(1000);
if (micros()-lastSensorTime>=delT){
lastSensorTime+=delT;
if (i==2) {
digitalWrite(stepPin1,HIGH);
digitalWrite(stepPin2, HIGH);
i=1;
}
else if (i==1) {
digitalWrite(stepPin1,LOW);
digitalWrite(stepPin2,LOW);
i=2;
}
}
}
void accel(float force) {
speed=speed+force;
if (speed>1000){
speed=1000;
}
else if (speed<-1000){
speed=-1000;
}
velocity(speed);
}