How to do a frequency multiplier?

Hi all,

I'd like to fulfill a frequency multiplier, which will generate 6*1.023M Hz signal, by Arduino Uno. How can I do it? Please give me some hints. Thanks a lot!

You can, of course, generate frequencies of up to 8MHz directly or have you been given an assignment which requires a specific solution, say designing a PLL frequency multiplier ?

Hi,
Welcome to the Forum.

Do have a 1.023MHz signal and want the Arduino to multiply it by 6 to 6.138MHz?

Or you want the Arduino to generate a 6.138MHz signal?

What is the application?

Will the 1.023MHz change in frequency?

What about its amplitude?

Thanks.. Tom... :slight_smile:

6v6gt:
You can, of course, generate frequencies of up to 8MHz directly or have you been given an assignment which requires a specific solution, say designing a PLL frequency multiplier ?

Thanks for respond! I'd like to generate 6.138MHz signal directly. How can I use timer to do it?

TomGeorge:
Hi,
Welcome to the Forum.

Do have a 1.023MHz signal and want the Arduino to multiply it by 6 to 6.138MHz?

Or you want the Arduino to generate a 6.138MHz signal?

What is the application?

Will the 1.023MHz change in frequency?

What about its amplitude?

Thanks.. Tom... :slight_smile:

Thanks Tom! I have a 1.023MHz signal but I'd like to generate 6.138MHz directly by Arduino UNO.
It's for external frequency of another system. My goal is:
Generate a 6.138MHz, square wave with duty cycle 50%, 2Vpp to output for usage.

Hi,
Try DDS board with Arduino.

google arduino DDS

Tom... :slight_smile:

TomGeorge:
Hi,
Try DDS board with Arduino.

google arduino DDS

Tom... :slight_smile:

TomGeorge:
Hi,
Try DDS board with Arduino.

google arduino DDS

Tom... :slight_smile:

Hi Tom,

I try to use timer:

//set timer0 interrupt at 6MHz
TCCR0A = 0;// set entire TCCR0A register to 0
TCCR0B = 0;// same for TCCR0B
TCNT0 = 0;//initialize counter value to 0
// set compare match register for 2khz increments
OCR0A = 2;// = (1610^6) / (610^6*1) - 1 (must be <256)
// turn on CTC mode
TCCR0A |= (1 << WGM01);
// Set CS01 and CS00 bits for 1 prescaler
TCCR0B |= (1 << CS00);
// enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);

ISR(TIMER0_COMPA_vect){//timer0 interrupt 6MHz toggles pin 8
//generates pulse wave of frequency 6MHz/2 = 3MHz (takes two cycles for full wave- toggle high then toggle low)
if (toggle0){
digitalWrite(8,HIGH);
toggle0 = 0;
}
else{
digitalWrite(8,LOW);
toggle0 = 1;
}
}

The output isn't the desired frequency but about 56kHz. I wonder why and any suggestion? Thanks a lot.

Use the 16 bit timer 1 on the Uno and configure it to use fast PWM (WGM mode 14 ) to directly toggle pin OC1A (pin 9) and set the prescaler to 1.
You can not use an interrupt to toggle a pin, especially not using digitalWrite() at the speed you require.

6v6gt:
Use the 16 bit timer 1 on the Uno and configure it to use fast PWM (WGM mode 14 ) to directly toggle pin OC1A (pin 9) and set the prescaler to 1.
You can not use an interrupt to toggle a pin, especially not using digitalWrite() at the speed you require.

Hi,
Thanks for advice. Could you please tell more detail about it for coding.
I've modified the code as the following:

void setup(){
//set pins as outputs
pinMode(9, OUTPUT);

//set timer1 interrupt at 6MHz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 2;// = (16M) / (1*6M) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM14);
// Set CS12 and CS10 bits for 1 prescaler
TCCR1B |= (1 << CS11); // (1 << CS12) |
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);

//generates pulse wave of frequency 6MHz/2 = 3MHz (takes two cycles for full wave- toggle high then toggle low)
if (toggle1){
digitalWrite(9,HIGH);
toggle1 = 0;
}
else{
digitalWrite(9,LOW);
toggle1 = 1;
}
}

But the error shows that " 'WGM14' was not declared in this scope."
And what' the meaning of: directly toggle pin OC1A (pin 9)?

Thanks a lot.

  // OC1A = D9
  // OC1B = D10

  //set timer1 toggle OC1A at xHz
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  ICR1 = 2  ;   //    = 16/3 MHz
  OCR1A = 1 ; // 50% of ICR1 for a 50% duty cycle

  TCCR1A |= ( 1 << COM1A1 ) | (1 << WGM11) ;

  // wg mode 14
  TCCR1B |= (1 << WGM12) | (1 << WGM13);
  // prescaler  
  TCCR1B |= (1 << CS10)  ;

Direct toggle in this context means that the timer sets the pin directly. There is no interrupt service routine containing code to set it. The disadvantage is that you have to use the specified pin which is assigned to the timer, in this case D9 (OC1A).

At these high frequencies (high relative to the clock speed) the resolution is low, so you may find that you cannot set exactly the frequency you want.

6v6gt:
ICR1 = 2 ; // = 16/3 MHz
OCR1A = 1 ; // 50% of ICR1 for a 50% duty cycle

Thanks! With the code above, I can generate about 16MHz/3= 5.33MHz signal with duty cycle 65% .

Is it possible that I can generate exact 6MHz?

Really appreciate your respond.

As I said, the resolution is not good at high frequencies, and that is because you have to work in whole numbers of clock periods. With a 16MHz crystal, the next higher frequency is 8 MHz and the next lower is 4MHz. The same applies to the duty cycle in that again you are working with whole numbers of clock periods.

Changing the crystal (resonator) to 12 MHz could give you 6MHz @ 50% duty cycle, but that is a drastic solution because you'd probably have to recompile the boot loader and change the boards.txt file and expect other timing related problems.

Why not just buy a 6MHz crystal and put it in a simple Colpitts oscillator circuit?

Any frequency derived from an arduino is unlikely to be accurate, as they generally use cheap ceramic resonators as a reference -

+/- 2%?

Allan.

allanhurst:
Why not just buy a 6MHz crystal and put it in a simple Colpitts oscillator circuit?

Any frequency derived from an arduino is unlikely to be accurate, as they generally use cheap ceramic resonators as a reference -

+/- 2%?

Allan.

Hi Allan,

I'd like to generate 6.138M, but seems like no available such crystal. Therefore, I thought I could generate it from divided the 16M. Thanks!

Hi,

GBCC1:
Hi Allan,

I'd like to generate 6.138M, but seems like no available such crystal. Therefore, I thought I could generate it from divided the 16M. Thanks!

See post #5

A DDS allows you to produce what you need, simply. if you need to adjust it, then you can.
The library has the examples that you can use, please look at it.

16,000,000 / 6,138,000 = 2.6067122841316389703486477680026

How are you going to get that fraction?

Can you please use code tags.
Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom... :slight_smile:

6.144 MHz crystals are freely availablle - that's within 0.1%.

Much closer than you'll get with an arduino with it's +/- 2% reference.

Allan

Simply you can not generate a 6.138MHz signal from a processor running at 16MHz. I am sorry that some "advice" lead you to think you could.

It is quite cheap to have crystals made to any frequency you want, even one off.

Simply you can not generate a 6.138MHz signal from a processor running at 16MHz. I am sorry that some "advice" lead you to think you could.

A standard integer - N synth chip would do it - just divide down from 16Mhz to a 1kHz reference (16000)

The use a vco output divided by 6138 to drive the phase detector.

Loads of people make them - TI, NXP, AD etc etc

I've used lots in the RF game.

You can either buy a vco or make one - the Colpitts topology is common - with a varicap to change frequency.

But if you want accuracy, don't use the arduino's oscilllator as a reference source. Buy a standard crystal to any accuracy you need.

Allan

A standard integer - N synth chip would do it - just divide down from 16Mhz to a 1kHz reference (16000)

Oh come off it, where is the processor in that? The Arduino has no part in that process and well you know it.

If you had a fast enough processor it could be done - most modern superfast ones have a PLL to generate a very fast internal clock from an external (eg 16MHz?) crystal...

Arduinos don't do that. (or does the due?)

So being pedantic, of course you're right - though you'd need a processor of some sort to load up the synth registers.

At least it's a viable solution to the OP's problem.

regards

Allan