Hey all. I've been working on this stroboscope project, using timer1 on the arduino nano. Anyways, when I try to divide the output frequency and set up timer1 to generate it, it turns off the output for around a second for no apparent reason. It doesn't do this every time, and sometimes it turns off longer than other times. The code:
volatile long previousMillis5 = 0;
volatile long previousMillis4 = 0;
volatile double strobe_frequency = 20;
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), multiplyByTwo, RISING);
attachInterrupt(digitalPinToInterrupt(3), divideByTwo, RISING);
}
volatile void multiplyByTwo() {
if ((strobe_frequency * 2.0) < 31250 && previousMillis4 + 200 < millis()) { //software debounce
strobe_frequency = strobe_frequency * 2.0;
previousMillis4 = millis();
}
}
volatile void divideByTwo() {
if ((strobe_frequency / 2.0) > 1 && previousMillis5 + 200 < millis()) { //software debounce
strobe_frequency = strobe_frequency / 2.0;
previousMillis5 = millis();
}
}
// the loop function runs over and over again forever
void loop() {
generateFrequency(strobe_frequency, 0.01);
}
volatile void generateFrequency(double frequency, double dutyCycle) {
pinMode(10, OUTPUT);
frequency = round(frequency * 100.0) / 100.0;
if (dutyCycle == 0) {
return;
}
if (frequency > 0 && frequency < 123) { //256 prescaler
long count = 16000000 / 256 / frequency;
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12);
OCR1B = (count * dutyCycle) - 1;
ICR1 = count - 1;
TCCR1A = _BV(COM1B1) | _BV(WGM11);
return;
}
if (frequency > 122 && frequency < 3907) { //8 prescaler
long count = 16000000 / 8 / frequency;
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
OCR1B = (count * dutyCycle) - 1;
ICR1 = count - 1;
TCCR1A = _BV(COM1B1) | _BV(WGM11);
return;
}
if (frequency > 3906 && frequency < 31250) { //no prescaler
long count = 16000000 / 1 / frequency;
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
OCR1B = (count * dutyCycle) - 1;
ICR1 = count - 1;
TCCR1A = _BV(COM1B1) | _BV(WGM11);
return;
}
}
Pulling pin 2 low doubles the frequency, and pulling pin 3 low divides it by two. I find dividing it by two to 80.00 from 160.00 Hz seems to produce this problem quite reliably.
I've tried just having a loop that changes the frequency to some pre set values, but that does not seem to cause this issue.