How to make a varaible frequency time event with Timer0 and Timer2?

I’ve gotten it to work but whenever I try to change the frequency while its running the arduino completely freezes.

int count[4] = {0, 0, 0, 0};
int stepPins[4] = {6, 8, 10, 12};
int dirPins[4] = {5, 7, 9, 11};
int motorSpeeds[4] = {1, 100, 1, 1};

void setup() {
  Serial.begin(115200);

  for (int i = 0; i <= 3; i++) {
    pinMode(stepPins[i], OUTPUT);
    pinMode(dirPins[i], OUTPUT);
    digitalWrite(dirPins[i], HIGH);
  }

  TCCR2A = 0;
  TCCR2B = 0;
  OCR2A = 99;
  OCR2B = 99;
  TCCR2A |= (1 << WGM01);
  TIMSK2 |= (1 << OCIE2A) | (1 << OCIE2B); //enable OCR1A, OCR1B Interrupts
  TCCR2B |= (0 << CS02) | (1 << CS01) | (0 << CS00); //prescaler 256, CTC Mode

  TCCR0A = 0;
  TCCR0B = 0;
  OCR0A = 99;
  OCR0B = 99;
  TCCR0A |= (1 << WGM21);
  TIMSK0 |= (1 << OCIE0A) | (1 << OCIE0B); //enable OCR1A, OCR1B Interrupts
  TCCR0B |= (0 << CS22) | (1 << CS21) | (0 << CS20); //prescaler 256, CTC Mode

}

ISR(TIMER0_COMPA_vect) {
  if (count[0] == round(20000 / motorSpeeds[0])) {
    count[0] = 0;
    digitalWrite(stepPins[0], HIGH);
  } else {
    count[0] ++;
    digitalWrite(stepPins[0], LOW);
  }
}

ISR(TIMER0_COMPB_vect) {
  if (count[1] == round(20000 / motorSpeeds[1])) {
    count[1] = 0;
    digitalWrite(stepPins[1], HIGH);
  } else {
    count[1] ++;
    digitalWrite(stepPins[1], LOW);
  }
}

ISR(TIMER2_COMPA_vect) {
  if (count[2] == round(20000 / motorSpeeds[2])) {
    count[2] = 0;
    digitalWrite(stepPins[2], HIGH);
  } else {
    count[2] ++;
    digitalWrite(stepPins[2], LOW);
  }
}

ISR(TIMER2_COMPB_vect) {
  if (count[3] == round(20000 / motorSpeeds[3])) {
    count[3] = 0;
    digitalWrite(stepPins[3], HIGH);
  } else {
    count[3] ++;
    digitalWrite(stepPins[3], LOW);
  }
}
void loop() {
  Serial.println(motorSpeeds[1]);
  motorSpeeds[1] = Serial.parseInt();

}

If I comment motorSpeeds[1] = Serial.parseInt(); line it works but I can’t change the frequency just by reprogramming it.

Do you think that Serial.parseInt() is blocking further execution, because timer0 was used for the millis() function, but now it never "times out"?

The problem is not specifically with parseInt I tried changing the motorSpeed varaible a lot of ways but it always freezes. Does the millis(); function use Timer0?

barnabasavatar:
Does the millis(); function use Timer0?

Yes

Have you tried to parse your int using a terminus or fixed width?

barnabasavatar:
The problem is not specifically with parseInt I tried changing the motorSpeed varaible a lot of ways but it always freezes. Does the millis(); function use Timer0?

Usually. Probably depends which platform. On Mega328/168 boards it does.

Your Timer setup is very jumbled between timers and registers, and the comments are wrong. This may not be your issue, but it should be corrected so that you appear to know what you are doing :slight_smile:

  TCCR2A = 0;
  TCCR2B = 0;
  OCR2A = 99;
  OCR2B = 99;
 > TCCR2A |= (1 << WGM01);
  TIMSK2 |= (1 << OCIE2A) | (1 << OCIE2B); //enable OCR1A, OCR1B Interrupts
 > TCCR2B |= (0 << CS02) | (1 << CS01) | (0 << CS00); //prescaler 256, CTC Mode

  TCCR0A = 0;
  TCCR0B = 0;
  OCR0A = 99;
  OCR0B = 99;
 > TCCR0A |= (1 << WGM21);
  TIMSK0 |= (1 << OCIE0A) | (1 << OCIE0B); //enable OCR1A, OCR1B Interrupts
 > TCCR0B |= (0 << CS22) | (1 << CS21) | (0 << CS20); //prescaler 256, CTC Mode

These variables used in the isr should be declared volatile

volatile int count[4] = {0, 0, 0, 0};
volatile int motorSpeeds[4] = {1, 100, 1, 1};

The problem is not specifically with parseInt I tried changing the motorSpeed varaible a lot of ways but it always freezes.

What else have you tried? What do you mean by freezes? Do all motors stop when changing for one?