Best way to generate a clock signal with arduino mega

Hello,

I'd like to generate a clock signal with my mega to drive an external camera sensor. The signal is specified as over 10MHz, so 16MHz should work, but it may be possible to make the sensor work with 8MHz. As I'm just starting out, I don't have a very good understanding of the best way to do this.

What I've learned: seems that changing the "fuse" settings for the chip is one way to get a clock signal to a pin, I believe it's pin 52 on the mega. Another way seems to be to use a timer and put it on any pin, but I couldn't quite make sense of the code I've seen for this or how it works. I've also not seen it used for over 8MHz, don't know if 16 is possible.

Which of these approaches would be easier or better to implement? Is there a good clear example (step-by-step would help) of how to do it? Thanks for reading.

The pin is hard to get to on the chip. If you could get to it, you could output 16 MHz. Failing that you can use a timer to output 8 MHz (that's toggling the pin ever 62.5 nS which gives you 8 MHz). There was a recent thread with example code for doing that.

You might find this handy:

https://www.adafruit.com/products/2045

Under I2C control it can output a wide range of frequencies - 8KHz to 160MHz. It costs around $US 8.

Thanks for the response.

So the only way to get the 16MHz clock directly is to actually attach it to the processor pin? That sound rather difficult, but I did read that changing the fuse settings (just learned what those are and don’t understand completely yet) can allow you to output the clock on an actual pin.

I did see some of those threads, and I can try copying the code, but I don’t fully understand it. I think that uses pin registers. Again, not totally sure how those work yet, but I’m guessing they control the internal pin behavior via the chip itself independently of what is written in the IDE loop function, otherwise I’d need to write the switching code in there and clearly that would be the only thing the program does. I’ll try the copy-paste of that code if all else fails, just thought perhaps there might be a way to get easily to the internal clock, or at least a guide to help me understand the timer code.

Don’t want to go for the additional device, not only does it costs about as much as I paid for my mega, but consumes some serial communication pins which I think I’ll be running short on (several I2C devices to connect).

Also see: http://forum.arduino.cc/index.php?topic=180382.5

Again, not totally sure how those work yet, but I’m guessing they control the internal pin behavior via the chip itself independently of what is written in the IDE loop function, otherwise I’d need to write the switching code in there and clearly that would be the only thing the program does.

That’s right, it works regardless of what the code is doing.

Don’t want to go for the additional device, not only does it costs about as much as I paid for my mega …

You got your Mega for $8?

See http://www.gammon.com.au/forum/?id=11504&reply=15#reply15 for a new post I made with example code.

That sound rather difficult, but I did read that changing the fuse settings (just learned what those are and don't understand completely yet) can allow you to output the clock on an actual pin.

Yes it can, but that particular pin on the chip is not brought out to a pin on the board itself. As you can see the processor pins are very close together, so soldering on an appropriate wire would be fiddly. Personally I would stick with 8 MHz, or pay the $8 for the dedicated board. Another option would be to use an ATtiny85 (or similar), configure it to run at 16 MHz (or more) and set the CKOUT fuse - then it could provide your clock source. Those chips are selling on eBay for around $1.25.

Just as a test I configured my ATtiny85 as follows:

  • Low fuse: 0xA1
  • Flash: erased

Now it outputs 16.45 (or so) MHz on pin 3 of the chip. No programming required. Can't get much simpler than that.

I'd like to generate a clock signal with my mega to drive an external camera sensor

Although I am a bit skeptical about this. What camera sensor needs 10+ MHz to make it work?

[quote author=Nick Gammon link=msg=2293721 date=1435371175] See http://www.gammon.com.au/forum/?id=11504&reply=15#reply15 for a new post I made with example code. [/quote]

Appreciate it, I'll give it a try. Guess I'll try to learn more about registers and such.

[quote author=Nick Gammon link=msg=2293714 date=1435370486] Also see: http://forum.arduino.cc/index.php?topic=180382.5

That's right, it works regardless of what the code is doing.

You got your Mega for $8? [/quote]

One at least (ebay auction), another for ~10.

ATtiny85 sounds like a good idea, was just hoping to avoid external circuitry if the arduino can do it. Could probably get a quartz crystal just as easily too, without taking any arduino pins.

A[quote author=Nick Gammon link=msg=2293749 date=1435373525] Although I am a bit skeptical about this. What camera sensor needs 10+ MHz to make it work? [/quote]

The ov7670 camera sensor seems to specify at least a 10MHz signal on its XCLK pin to drive it. Someone got it working with 8MHz by doing extra work with the camera's registers, I'm just not sure I'm up to it.

anvoice:
ATtiny85 sounds like a good idea, was just hoping to avoid external circuitry if the arduino can do it. Could probably get a quartz crystal just as easily too, without taking any arduino pins.

Don’t you need more than just a crystal? Like a capacitor and some sort of driver? The Attiny is only a DIP-8 device. Pretty small.

[quote author=Nick Gammon link=msg=2293807 date=1435377762] Don't you need more than just a crystal? Like a capacitor and some sort of driver? The Attiny is only a DIP-8 device. Pretty small. [/quote]

Didn't know that. Then the Attiny is a good idea, just that I'm already adding so much extra circuitry (it's supposed to go on a robot with limited space) I was hoping to try to keep it down if I could.

I tried that code exactly as written in the arduino IDE, but got a bunch of compilation errors including that byte is not defined as a type and that what I'm guessing are register names are not defined. Is there something I should include there? A library, etc.?

This code?

#ifdef __AVR_ATmega2560__
  const byte CLOCKOUT = 11;  // Mega 2560
#else
  const byte CLOCKOUT = 9;   // Uno, Duemilanove, etc.
#endif

void setup ()
  {
  // set up 8 MHz timer on CLOCKOUT (OC1A)
  pinMode (CLOCKOUT, OUTPUT); 
  // set up Timer 1
  TCCR1A = bit (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12) | bit (CS10);   // CTC, no prescaling
  OCR1A =  0;       // output every cycle
  }  // end of setup

void loop ()
  {
  // whatever 
  }  // end of loop

That compiled for me under 1.0.6 of the IDE without any change.

There is some weird bug in recent versions of the IDE. Add this line to the very start of the sketch:

byte foo;

Not that I understand why, but that worked fine, compiled and oscilloscope shows about an 8 MHz waveform at the right pin. Thank you, I appreciate it.

I'll try to get the sensor working with the 8MHz, hopefully It'll suffice.

Not that I understand why, but that worked fine ...

The IDE tries to "help" you. Sometimes it fails. :)

I see, makes sense.

On a positive note, seems the sensor is reacting to the 8MHz clock. Hopefully I can get it to work, doesn't seem to be the most straightforward device.

Thanks for the help.