Arduino Uno frequency generation

Hello,

I want to generate square wave and be able to change frequency using potentiometer between around 24750Hz-25250Hz with step = 1Hz. I tried to calculate it and change frequency by adjusting prescaler and ICR1 but it changes in really random way now. Do you know what i can change in my code to make it work? :slight_smile:

float start=323.23;
float x=0;
float y=0;
int value=0;
float voltage = 0;
int var = 0;

void setup()
{ 
    Serial.begin(9600);

    TCCR1A = 0;           // undo the configuration done by...
    TCCR1B = 0;           // ...the Arduino core library
    TCNT1  = 0;           // reset timer
    TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
           | _BV(COM1B1)  // same on ch; B
           | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
    TCCR1B = _BV(WGM13)   // ditto
           | _BV(CS10);   // prescaler = 1
 

    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
    
}

void loop()
{   
  value = analogRead(A5);
  voltage = value * (5.0/1024.0); //value to voltage conversion
  Serialprintln(voltage);
  var = value/4 
  ICR1  = x;  
  x=start-(0.0256*var); 
  y=x/2;
  analogWrite25k( 9);
  
    
}

void analogWrite25k(int pin)
{
    switch (pin) {
        case 9:
            OCR1A = y;
            break;
        case 10:
            OCR1B = y;
            break;
        default:
            // no other pin will work
            break;
    }
}

The code you posted will not compile.

The first step would be to set up timer1 to produce a constant signal of about 25 kHz, and verify correct output. Have you done that? If so, post that code.

There is no point in using floating point numbers to process the ADC result, and send the result to the timer. The "mystery constants" make it completely unclear what you are trying to do.

Please add code comments to explain your thinking in the following, which is obscure to say the least:

  value = analogRead(A5);
  voltage = value * (5.0/1024.0); //value to voltage conversion
  Serialprintln(voltage);
  var = value/4
  ICR1  = x; 
  x=start-(0.0256*var);
  y=x/2;

Finally, please read the data sheet on updating the timer registers. You should certainly not do so every pass of loop(), and if you don't do the update at the correct moment, expect the timer to misbehave.

Sorry! I pasted wrong version of the code. Although the correct one generated nearly perfect 25khz square wave for ICR1 = 320, prescaler = 1. I will dig deeper in data sheet but can you tell if its possible to increase frequency by 1Hz in that range using arduino uno device?

  unsigned value = analogRead(A5);
  unsigned frequency = map(value, 0, 1023, 24750, 25250);
  unsigned TOP = F_CPU / (2UL * frequency);
  ICR1 = TOP;
  OCR1A = TOP / 2;
  OCR1B = TOP / 2;

can you tell if its possible to increase frequency by 1Hz in that range using arduino uno device?

No.

The frequency is determined by ICR1. Consider the math.

If you change ICR1 from 320 to 319 or 321, the frequency will change + or - by 25000/320 = 78Hz

flo412:
can you tell if its possible to increase frequency by 1Hz in that range using arduino uno device?

Sorry, but your entire range is covered by ICR1=317 to ICR1=323. In other words, your 500Hz range is covered in about 6 steps of about 78 Hz each.
There are frequency generator chips that can probably do much better