Hi,
Quick question,
I'm trying to emulate the resolution of a 16 bit timer using timer 0 or 2 on Arduino Nano, as I am already using timer 1 for something else.
This is actually part of a bigger project where I am electrically gearing two stepper motors, and using timer 1 with changing interrupt delays to accelerate one stepper motor up to max speed, and another timer to "follow" the first stepper motor as at accelerates and reaches top speed using a constant frequency ratio between the two steppers.
The code below illustrates what I'm trying to do with one of the 8 bit timers.
an array of values is set in the main loop, and the timer interrupts use these to determine when to set pin 5 high and then low again by accumulating multiple interrupts before changing the pin state and the overflow limit.
Similar code with timer 1 works fine, but because it's 16bit, the maximum overflow is always higher than the TOP value I'm setting for the interrupt.
The code below gives a 60Hz output, but should be giving more than 4Khz when it reaches highest frequency.
Can anyone shed any light on this? is it an issue with the number of clock cycles being used to set the variables in the interupt?
volatile long TriggerAry [3] = {0, 0, 0};
long valcount = 19999;//800hz
long mincount = 3635; //4.396khz
bool TriggarTimer = false;
int loopcounter = 0;
// using pin 5
void setup() {
pinMode(5, OUTPUT);
TriggerAry[0] = valcount / 256;
TriggerAry[1] = 255;
TriggerAry[2] = valcount - (TriggerAry[0] * 256) - 1L;
TCCR0A = 0;
TCCR0B = 0;
TCNT0 = 0;
OCR0A = TriggerAry[1];
OCR0B = 31;
TCCR0B |= (1 << WGM01);
TCCR0B |= (0 << CS02) | (0 << CS01) | (1 << CS00); // x1 prescaler
TIMSK0 |= (1 << OCIE0A);
TIMSK0 |= (1 << OCIE0B);
sei();
}
void loop() {
if (valcount > mincount) {
valcount = valcount - 10;
}
TriggerAry[0] = valcount / 256;
TriggerAry[1] = 255;
// TriggerAry[2] = (valcount % 256)-1L - appears slower than....
TriggerAry[2] = valcount - (TriggerAry[0] * 256) - 1L;
}
ISR(TIMER0_COMPA_vect) {
if (TriggarTimer == true)
{
PORTD |= 0x20;
TriggarTimer = false;
}
}
ISR(TIMER0_COMPB_vect) {
if (loopcounter > TriggerAry[0])
{ PORTD &= 0xDF; //off
OCR0A = TriggerAry[2];
loopcounter = 0;
TriggarTimer = true;
}
else
{ OCR0A = TriggerAry[1];
loopcounter++;
}
}