I want to run an arduino board at a slower - but more accurate - clock speed. What (if anything) needs to be changed in the arduino code/libraries in order to achieve this? Normally the boards I use run at 16MHz, but I wish to derive a 10MHz clock from a GPS timing module and run the ATMEL processor off the 10MHz timing clock.

  • What kind of timing facilities do you need? Would millis() be enough? Would you need micros() or delay() as well? millis() could be easily reimplemented on top of Timer 1, if you can spare it for this use. Depending on your needs, you could also have single-cycle timing resolution by taping directly on the hardware timers. – Edgar Bonet Nov 5 '17 at 11:22

You have to change F_CPU only - You can add new board into the boards.txt with correct clock speed. EDIT: Aparently millis counter will be drifting much more then expected due to "rounding" errors.

The bootloader on the other side needs to be recompiled with correct F_CPU and reflashed, if you want it working at the same baud rate (plus it's possible to change fuses to use external clock source instead of crystal). Otherwise you have to try reduced speed (also configured in board config).

You can use MCUdude/MiniCore as inspiration. It supports many clock speeds (but 10MHz doesn't)

| improve this answer | |
  • Note that all the timing functions will be off, as the implementation of millis() relies on some arithmetic that does not work well for arbitrary clock speeds. See this comment in the source: “for the clock speeds we care about - 8 and 16 MHz - this doesn't lose precision.” Since the OP seems to care about accuracy, this could be a deal breaker. – Edgar Bonet Nov 5 '17 at 10:12
  • Looking at that source code, it turns out that, with F_CPU set at 10 MHz, millis() will assume a frequency of 512/51 ≈ 10.039 MHz. It will then run about 3900 ppm slow, which is a huge error: more than 5 min/day. – Edgar Bonet Nov 5 '17 at 10:26
  • @EdgarBonet I'm not sure about this, but ISR handler is adding 1ms and 638us every interrupt instead of 1ms and 638.4us (those values are counted from F_CPU). Somehow it gives me about 21.1s every day: (1 - (1/0.0016384)*0.001638) * 24* 3600. But maybe I'm calculating this completely wrong. – KIIV Nov 5 '17 at 11:24
  • Okay, I've missed that bitshift... Well, then it will be much worst (337.5s) – KIIV Nov 5 '17 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.