I am using the ATMega32u4 to generate multiple pulses at 2.5 kHz. I am using Timer 3, which is a 16-bit timer and using a prescaler of 1, so I have a 0.0625uS resolution. I want to generate pulses with pretty high accuracy and consistency. I have my previous post here, which gave me accuracy. But when I look at the pulse with my oscilloscope it has some jitter. Youtube Video of Jitter.
My final goal is to create a pulse on multiple different pins in this configuration.
What I am assuming is that the reason there is jitter is that there are other interrupts going on in the background, that could be shifting when the pulse stops and starts by a few microseconds. Looking through the datasheet, I found this, which seems to show interrupt priority.
It seems that my TIMER3 COMPA and COMPB are very low down the list of priorities, is there a way to change this priority list? Or is there something else that is causing the jitter?
I have posted my code below:
#define pin2 12
#define pin3 6
#define pin4 8
#define REFRESH 6400
int PULSEIndex;
class Pulse {
public:
int pulseLength;
void Begin(byte GPIO_PIN) {
pinMode(GPIO_PIN, OUTPUT);
}
void writeMicro(double pulse) {
pulseLength = (pulse * 16);
}
};
Pulse PULSE1;
Pulse PULSE2;
Pulse PULSE3;
Pulse PULSE4;
void setup() {
PULSE1.Begin(pin1);
PULSE2.Begin(pin2);
PULSE3.Begin(pin3);
PULSE4.Begin(pin4);
// Reset Timer 3 Control Register to 0
TCCR3A = 0;
TCCR3B = 0;
// Set CTC Mode
TCCR3B &= ~(1 << WGM33); //0
TCCR3B |= (1 << WGM32); //1
// Set prescaler to 1
TCCR3B &= ~(1 << CS32); //0
TCCR3B &= ~(1 << CS31); //0
TCCR3B |= (1 << CS30); //1
//Reset Timer 3 and set compare value
TCNT3 = 0;
// Enable Timer 3 compare interrupt A and B
TIMSK3 |= (1 << OCIE3B);
TIMSK3 |= (1 << OCIE3A);
//Enable global interrupts
sei();
//Set Refresh Rate
OCR3A = REFRESH;
OCR3B = 1000;
}
void loop() {
PULSE1.writeMicro(40);
PULSE2.writeMicro(40);
PULSE3.writeMicro(40);
PULSE4.writeMicro(40);
delay(2);
}
ISR(TIMER3_COMPA_vect) {
digitalWrite(pin1, HIGH);
OCR3B = PULSE1.pulseLength;
}
ISR(TIMER3_COMPB_vect) {
if (PULSEIndex == 1) {
digitalWrite(pin1, LOW);
digitalWrite(pin2, HIGH);
OCR3B += PULSE2.pulseLength;
}
if (PULSEIndex == 2) {
digitalWrite(pin2, LOW);
digitalWrite(pin3, HIGH);
OCR3B += PULSE3.pulseLength;
}
if (PULSEIndex == 3) {
digitalWrite(pin3, LOW);
digitalWrite(pin4, HIGH);
OCR3B += PULSE4.pulseLength;
}
if (PULSEIndex == 4) {
digitalWrite(pin4, LOW);
}
PULSEIndex++;
if (PULSEIndex > 4) PULSEIndex = 1;
} ```
digitalWrite
is extremely slow, and at least for the first pulse it's nodigitalWrite(pin4, LOW);
, so there is few microseconds jitter. Just like that. Maybe consider MCU with DMA