Generating a Clock Signal That Can Vary

I am looking to generate a clock signal on a pin of 720KHz with a 50% duty cycle. I would also like to be able to vary the frequency (let's say +/- 200kHz) based on a variable that could either be altered by the program or a sensor. How would I program PWM on a pin to give me the correct clock speed? I need it to run in the background, but still check on the variable running in the main loop to see what value the clock speed should be set to.

I looked through a tutorial on using timers, but I could not understand the way they are setting parameters due to the lack of commenting on what each command was doing. http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Thanks!

Wow, that's fast. And you want to vary from 520kHZ to 920KHz? That's like AM Radio transmitter range. You might be better off setting a 555 timer to run at 720KHz and use a PWM created voltage level to alter the frequency. WilliamK has done the same over audio range. I had suggested modifying the voltage via external DAC to be more precise, use pulseIN() to monitor it and adjust as needed.

CrossRoads: setting a 555 timer to run at 720KHz and use a PWM created voltage level to alter the frequency.

That would be my approach. Maybe input the signal to a hardware counter to measure the actual frequency and then have a software servo control loop to adjust it to the precise requirement.

Thanks for the suggestions...

If this helps, I do not need a lot of precision for the application. Can the 16MHz ATmega328 not handle 720kHz?

Just so I'm clear ... we're talking about PFM (pulse [u]frequency[/u] modulation) not PWM (pulse [u]width[/u] modulation)?

N = 1; OCR = 10 gives a frequency of 727,273.

The next higher frequencies are... N = 1; OCR = 9 gives a frequency of 800,000. N = 1; OCR = 8 gives a frequency of 888,889. N = 1; OCR = 7 gives a frequency of 1,000,000.

The next lower frequencies are... N = 1; OCR = 11 gives a frequency of 666,667. N = 1; OCR = 12 gives a frequency of 615,385. N = 1; OCR = 13 gives a frequency of 571,429.

Does that suite your needs?

Yes, to be more precise, you could say I am trying to do pulse frequency modulation...basically being able to put out a varying clock signal that goes to another IC to vary its speed. From the numbers you give, it looks like the division has to happen in coarse increments, is that correct? I want to be able to set it to arbitrary frequencies like 780, 600, 550, 800, 810, etc.

buchacho:
basically being able to put out a varying clock signal that goes to another IC to vary its speed

Seems like a strange thing to do.

From the numbers you give, it looks like the division has to happen in coarse increments, is that correct?

From the constraints you’ve provided the answer is “yes”.

I want to be able to set it to arbitrary frequencies like 780, 600, 550, 800, 810, etc.

Then you have one practical choice… more hardware.

Voltage controlled oscillator! http://voltagecontrolledoscillator.net

Many ways to get there.

CrossRoads: Voltage controlled oscillator!

Cool idea. How would the Arduino control voltage to the VCO?

I am looking for a simple solution, like say I send serial data for the frequency value to the IC and then it sends out that clock signal at that rate at whatever input voltage I give it. Perhaps a pipe dream...

The alternative is I can use a pot, resistor and cap that sets the IC's internal clock signal, but I thought using digital control could open-up other possibilities.

You could output PWM and filter thru an RC network (lowpass filter) to make DC, but you onky get 256 levels, 0 to 255. Or use an external DAC and make as many levels as you have bits in your DAC - 8-12-14-16-20-24, etc.

A pre-built module example: http://www.sparkfun.com/products/8736

Or, take a look at this from gravitech! http://www.gravitech.us/i2c1kto68pro.html I2C 1KHz to 68MHz Programmable Oscillator! Read the datasheet at the website for determining the frequency http://site.gravitech.us/MicroResearch/I2C/I2C-OSC/LTC6904.pdf

CrossRoads: You could output PWM and filter thru an RC network (lowpass filter) to make DC, but you onky get 256 levels, 0 to 255.

To get more resolution, you could:

Build a 2 or 4 or whatever bit DAC with an R-2R network and combine this with the PWM. Or combine two 8-bit PWM outputs via a R-2R network. Or use the 16-bit Timer/counter.