How to remove jitter in a train of pulses in Arduino UNO?

580 views Asked by At

This is my first practical project with an Arduino UNO, and the truth is that I have not touched anything easy :( I need to convert my Arduino into a 14-bit encoder driver for this I need to generate a 14-pulse train to A fixed frequency greater than 30 Khz and to establish between each train a dead time of 50 microseconds, or until a little more. In all the variants that I have realized I have stumbled on my oscilloscope with an annoying jitter or phase shift in the wave, which should be as clean as possible. This was my first crude variant:

void setup() {
    pinMode(11, OUTPUT);
}

void loop() {
    for (int i=0; i<15; i++){
        digitalWrite(11, HIGH);
        delayMicroseconds(12);
        digitalWrite(11, LOW);
        delayMicroseconds(12);
    }
delayMicroseconds(50);
}

Then I tried to solve it using the timer to make the wave, and there seems to be a time offset product to stop and summarize the timer to make up the dead time. I use the TimerOne library which I download at: https://github.com/PaulStoffregen/TimerOne

#include <TimerOne.h>
const byte CLOCKOUT = 11;
volatile long counter=0;

void setup() {
    Timer1.initialize(15);         //Cada 15 microsegundos cambio el estado del pin en la funcion onda dando un periodo
    Timer1.attachInterrupt(Onda);  //de 30 microsegundos
    pinMode (CLOCKOUT, OUTPUT);
    digitalWrite(CLOCKOUT,HIGH);
}

void loop() {
    if (counter>=29){                //con 29 cambios logro los pulsos que necesito
        Timer1.stop();               //Aqui creo el tiempo muerto, el cual esta debe estar en HIGH
        digitalWrite(CLOCKOUT,HIGH);
        counter=0;
        delayMicroseconds(50);
        Timer1.resume();
    }
}

void Onda(){
    digitalWrite(CLOCKOUT, digitalRead(CLOCKOUT) ^ 1);   //Cambio el estado del pin
    counter+=1;
}
1

There are 1 answers

1
cgalcala On

I found a better solution using timer2 in CTC mode

#include <avr/io.h>
#include <avr/interrupt.h>

volatile byte counter=0;

void setup() {
   pinMode(11, OUTPUT);
   Serial.begin(57600);
   digitalWrite(11,HIGH);

   noInterrupts(); 


     TCCR2A = 0;
     TCCR2B = 0;
     TCNT2 = 0;

     TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
     TCCR2B = _BV(WGM22) | _BV(CS22);
     OCR2A = 4;
     TIMSK2 |= (1 << OCIE2A);

     interrupts(); // enable all interrupts

      }
    ISR (TIMER2_COMPA_vect){   
          counter+=1;
          if (counter==31){
            //PORTB = B00001000;
             OCR2A = 110;
              }
           else{
             if (counter>31){
                OCR2A = 6;
               counter=0;
                 }
             }

          }

      void loop() {
        Serial.print(counter);


        }