Genreate a precise clock with Arduino

Hello everybody ! :slight_smile:

Today's problem for us : generate a clock of 5 kHz with an Arduino Nano.
We thought about using the library Timer to use the function : int oscillate(int pin, long interval, int valeurDeDepart, int nombreDeFois).
The problem is that in order to generate a 5kHz signal we need it to switch every 100 us and the function take as argument an int os ms ...

Does anyone have an idea of how we could do it ?

The ultimate goal is to make a sweep frequency from 5kHz to 50kHz so if by any chance someone know something about that with an Arduino that's nice :slight_smile:

Thank you !

Try 555timer

Mark

Please read the page Timers and counters by Nick Gammon

You can use the Simple timer output to generate the desired frequency.

const byte LED = 3;  // Timer 2 "B" output: OC2B

const long frequency = 50000L;  // Hz

void setup() 
 {
  pinMode (LED, OUTPUT);

  TCCR2A = bit (WGM20) | bit (WGM21) | bit (COM2B1); // fast PWM, clear OC2B on compare
  TCCR2B = bit (WGM22) | bit (CS21);         // fast PWM, prescaler of 8
  OCR2A =  ((F_CPU / 8) / frequency) - 1;    // zero relative  
  OCR2B = ((OCR2A + 1) / 2) - 1;             // 50% duty cycle
  }  // end of setup

void loop()
  {
  // do other stuff here
  }



// With a 16 MHz clock, this can generate frequencies in the range 62.5 kHz to 4 MHz (8 MHz ought to work but has artifacts on the measured output).

Or blink without delay using micros()

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long halfPeriod =100UL; // period = 200uS = 5KHz
void setup(){
pinMode (D2, OUTPUT);
}
void loop(){
while (1){ // gets rid of loop "jitter" (easy to see with a 'scope)
currentMicros = micros(); // capture the current "time"
elapsedMicros = currentMicros - previousMicros; // how long's it  been since last toggle?
if (elapsedMicros >= halfPeriod){
PIND = PIND | 0b00000100; // toggle D2 by writing 1 to its input register
previousMicros = previousMicros + halfPeriod; // set up next toggle time
    }
  }
}

You can read the datasheet and use Timer in CTC mode.
You have only to choose good pre-scaler value and configure 3 registers.

Datasheet is most powerfull than Wiring/arduino libraries.

68tjs:
You can read the datasheet and use Timer in CTC mode.
You have only to choose good pre-scaler value and configure 3 registers.

Datasheet is most powerfull than Wiring/arduino libraries.

The "Tone" function provides high level access to the Timer in CTC mode. I'm not sure if it reproduces 5 kHz exactly from a 16 MHz clock which would depend upon the timer pre-scale value, so you may have to go down a coding level anyway.

Why take a sledgehammer to drive a nail?

void signal()
	{
		// Timer 2, 8 bits
		TCCR2A = 0 ;   //  Raz franche  / Reset
		TCCR2B = 0 ;   //  Raz franche  / Reset
		
		//Choix du signal de sortie  mode CTC WGM22 = 0 , WGM21 = 1, WGM20 = 0
               // choice of CTC mode
		TCCR2A |= (1 << WGM21 ) ;
		
		//Prise de contrôle des sorties
               // output activation for timer 2
		TCCR2A |=  (1 << COM2A0) ; // OC2A  D11
		TCCR2A |=  (1 << COM2B0) ; // OC2B  D3
		
		// choix de la fréquence 1 kHz (976,56 Hz)
                // value to have F = 1kHz (exactly 976.56 Hz)
		OCR2A = 7 ;
		
		// Lancement du timer en lui fournissant une horloge
                // timer start when it receive a clock from the prescaler
		TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20) ;  // N = 1204
	
	}

Frequency :
Formula from datasheet Atmega 328
See 18.7.2 page 147/148

F2 = Fsyst / (2N(OCR2A +1)

Fsyst = 16 MHz

N = prescaler

Choice of prescaler see Table 18.9 page 157