Generating frequency with UNO

Hi, I want to generate frequency between 20 KHz to 90 Khz. When I use this code for generating between 20Hz to 90 Hz everything is ok:

extern volatile unsigned long timer0_millis;
void setup() {
Serial.begin(9600);
pinMode(5,OUTPUT); 
resetInterrupts();
}
void loop() {
  for (float i=20;i<=90;i++){
    float a = 1/i;
    float t = a * 1000;
    float tdel = t / 2;
    Serial.println("Frequency = " + String(i) + " Hz");   
    while(timer0_millis <=5000){  
    digitalWrite(5,HIGH);
    delay(tdel);
    digitalWrite(5,LOW);
    delay(tdel);
    // Serial.println("delay = " + (String)tdel);
  }
  resetInterrupts();
  }
  Serial.println("our loop is finished.");
  delay(100);
}
void resetInterrupts(){
  noInterrupts ();
  timer0_millis = 0;
  interrupts();
  }

But, when I use delayMicroseconds(tdel); instead of delay(tdel); unfortunately I can't generate 20Khz to 90Khz. Would you help me please? This method is wrong? If yes, would you tell me how can generate frequency between 20Khz to 90 Khz with Arduino UNO? Thanks.

The most efficient way would be by using a hardware timer, that’s what they are meant for

There are libraries doing this, here is one for the mega (first Google hit - never used it) that could give you ideas

Can you explain why you think you need an interrupt?
You have a lot of float calculations. Those are slow...
Why not use integers?
You should not use delay. Delay will be added to your code execution time. You need to use a millis or micros timer. I timer will allow you to execute code, wait for the exact right moment and go on...

By the way, 100 kHz is 10 micro seconds... 5 high, 5 low. Micros() goes in steps of 4 microseconds...
So hardware timers may be your only option... (see post #2)

no, this method is merely too slow to generate such frequency.
Do not use delay() and digitalWrite() - all of this are very slow

@babilord

Would you like timer-based PWM as suggested by @J-M-L ?

And use direct port manipulation, you get a cleaner output square wave.

Tom... :smiley: :+1: :coffee: :australia:

Is it better than timer-based PWM in both accuracy and precision?

Yes definitely, look at an output with a scope, with direct port, then using digitalWrites, at high frequencies its chalk and cheese.

Many years ago I had to bit bang a SSI system, direct port was the only way to connect to it, digitalWrite pulses had terrible comparable rise times.

Tom... :smiley: :+1: :coffee: :australia:

How?

Continuous port manipulation requires continuation execution of codes which requires time and thus introduces inaccuracies in the output waveforms; whereas, timer-based PWM signals are not dependent on code execution except the initialization codes in the setup() function.

@TomGeorge @GolamMostafa
it looks like you didn't understand each other

Sorry I didn't explain far enough.

Use timer based PWM, but direct port manipulation to flip/flop the output instead of digitalWrite.

Tom.. :smiley: :+1: :coffee: :australia: