Hey,
I am currently building a line-following robot and having problems on the software-side of the project.
I have connected two stepper motors via a4988s on my board, they both have a STEP pin that needs to be pulled high and low at a certain frequency.
I get sensor readings from a sensorboard I built my own.
So what I need to do is: Read the I2C register (just one byte), approximately every 50ms, do some calculations (about a dozen additions/multiplications, really not much) and then set the output frequencies according to the speed the steppers should move.
My idea was to user Timer1 with a function attached and setPeriod to change the pulse speed, but I need at least two timers since both motors should move at different speeds and the attached function must not disturb my I2C communication.
Another idea would be using micros (the time between two pulses is always 500us or higher), but I thought that may lead to the motor not moving smoothly.
What would be the most elegant solution to this problem?
Bets regards,
Arduinojoey
EDIT: code examples
Using Timer1:
// defines pins numbers
const int stepPin1 = 5;
const int dirPin1 = 2;
int state = LOW;
void setup() {
// Sets the two pins as Outputs
pinMode(stepPin1,OUTPUT);
pinMode(dirPin1,OUTPUT);
digitalWrite(dirPin1,LOW);
Timer1.initialize(500);
Timer1.attachInterrupt(motorStep);
}
void loop() {
}
void motorStep() {
digitalWrite(stepPin1, state);
state = 1-state;
}
This works great for one single motor, but I cannot drive two motors like this.
Using micros():
#define FACTOR 5.05 // conversion from mm to motor steps
// defines pins numbers
const int stepPin1 = 5;
const int dirPin1 = 2;
const int stepPin2 = 6;
const int dirPin2 = 3;
void setup() {
// Sets the two pins as Outputs
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
delay(2000);
drive(200);
}
void loop() {
}
void drive(int mm) {
// set direction
if (mm > 0) {
digitalWrite(dirPin1, LOW);
digitalWrite(dirPin2, HIGH);
}
else {
digitalWrite(dirPin1, LOW);
digitalWrite(dirPin2, HIGH);
}
// spin motor
int steps = mm * FACTOR;
spin(steps, 500);
}
void spin(int steps, int interval) {
steps *= 2;
int i = 0;
int state = HIGH;
long last = micros();
while (i < steps) {
if ((micros() - last) >= interval) {
digitalWrite(stepPin1, state);
digitalWrite(stepPin2, state);
state = HIGH - state;
last = micros();
i++;
}
}
}
This works like a charm too, as long as both motors have the same speed and I do not need to check I2C. While getting it to work with two different speeds and I2C could be possible, I'd like to know if there is a more elegant solution.