hello, I have been trying to control two stepper motors in my balancing robot project. I first tried to do it with ISR and counting the interruptions, however that makes the whole system non linear which is hard for PID. There is a program on github thats seems to do the trick but I cant figure out what's going on in the code. Here is linkt to the repository on github https://github.com/JJulio/b-robot/blob/master/B_ROBOT/B_ROBOT.ino
If anyone knows whats going on with the perdiods/subperiods I would be veryu grateful for some explanations or sources with information about it
ISR(TIMER1_COMPA_vect)
{
counter_m[0]++;
counter_m[1]++;
if (counter_m[0] >= period_m[0][period_m_index[0]])
{
counter_m[0] = 0;
if (period_m[0][0]==ZERO_SPEED)
return;
if (dir_m[0])
SET(PORTB,4); // DIR Motor 1
else
CLR(PORTB,4);
// We need to wait at lest 200ns to generate the Step pulse...
period_m_index[0] = (period_m_index[0]+1)&0x07; // period_m_index from 0 to 7
//delay_200ns();
SET(PORTD,7); // STEP Motor 1
delayMicroseconds(1);
CLR(PORTD,7);
}
if (counter_m[1] >= period_m[1][period_m_index[1]])
{
counter_m[1] = 0;
if (period_m[1][0]==ZERO_SPEED)
return;
if (dir_m[1])
SET(PORTC,7); // DIR Motor 2
else
CLR(PORTC,7);
period_m_index[1] = (period_m_index[1]+1)&0x07;
//delay_200ns();
SET(PORTD,6); // STEP Motor 1
delayMicroseconds(1);
CLR(PORTD,6);
}
}
// Dividimos en 8 subperiodos para aumentar la resolucion a velocidades altas (periodos pequeños)
// subperiod = ((1000 % vel)*8)/vel;
// Examples 4 subperiods:
// 1000/260 = 3.84 subperiod = 3
// 1000/240 = 4.16 subperiod = 0
// 1000/220 = 4.54 subperiod = 2
// 1000/300 = 3.33 subperiod = 1
void calculateSubperiods(uint8_t motor)
{
int subperiod;
int absSpeed;
uint8_t j;
if (speed_m[motor] == 0)
{
for (j=0;j<8;j++)
period_m[motor][j] = ZERO_SPEED;
return;
}
if (speed_m[motor] > 0 ) // Positive speed
{
dir_m[motor] = 1;
absSpeed = speed_m[motor];
}
else // Negative speed
{
dir_m[motor] = 0;
absSpeed = -speed_m[motor];
}
for (j=0;j<8;j++)
period_m[motor][j] = 1000/absSpeed;
// Calculate the subperiod. if module <0.25 => subperiod=0, if module < 0.5 => subperiod=1. if module < 0.75 subperiod=2 else subperiod=3
subperiod = ((1000 % absSpeed)*8)/absSpeed; // Optimized code to calculate subperiod (integer math)
if (subperiod>0)
period_m[motor][1]++;
if (subperiod>1)
period_m[motor][5]++;
if (subperiod>2)
period_m[motor][3]++;
if (subperiod>3)
period_m[motor][7]++;
if (subperiod>4)
period_m[motor][0]++;
if (subperiod>5)
period_m[motor][4]++;
if (subperiod>6)
period_m[motor][2]++;
// DEBUG
/*
if ((motor==0)&&((debug_counter%10)==0)){
Serial.print(1000.0/absSpeed);Serial.print("\t");Serial.print(absSpeed);Serial.print("\t");
Serial.print(period_m[motor][0]);Serial.print("-");
Serial.print(period_m[motor][1]);Serial.print("-");
Serial.print(period_m[motor][2]);Serial.print("-");
Serial.println(period_m[motor][3]);
}
*/
}
also, why calculating the subperiods is so out of order - first is 1 then 5, then 3 and so on... the 6 is missing, please help