Clock speed for Nano Every

pert:
I was told the 16 MHz board definition for the Nano Every was an intentional choice for consistency with the classic Nano.

That would be fine except that the webpage in the Store shows the clock frequency as 20MHz, which is what led to the confusion while I was trying to modify the Adafruit_NeoPixel library to work with a 20MHz clock.

Yes, I agree this statement on the product page is misleading. It caused a similar confusion in another forum thread where someone was working to unnecessarily modify the Adafruit TFTLCD library for 20 MHz to port it to the Nano Every. That's why I asked the Arduino developer in charge of Arduino megaAVR Boards to clarify whether the 16 MHz board definition for the Nano Every was an error, or whether the product page information should be updated to be more clear.

I reported the issue on the product page here:

Hopefully it will be updated soon.

Playing around with boards.txt a bit, it is convenient to add a clock speed option to the menu in the IDE.

Not very experienced with modifying boards.txt, but using ATTinyCore as an example the following appears to work when added to the end of the section for the Nano Every:

menu.clock=Clock
nona4809.menu.clock.16internal=16MHz
nona4809.menu.clock.16internal.build.f_cpu=16000000L
nona4809.menu.clock.16internal.bootloader.OSCCFG=0x01
nona4809.menu.clock.20internal=20MHz
nona4809.menu.clock.20internal.build.f_cpu=20000000L
nona4809.menu.clock.20internal.bootloader.OSCCFG=0x02

Yeah, that's nice if you are going to want to switch clock speeds occasionally.

I think eventually what will happen is MCUdude will get their 3rd party hardware package for the megaAVR 0-series in a functional state with support for the Nano Every and anyone who wants to run their Nano Every will be able to just install that package via Boards Manager and not need to mess with editing Arduino megaAVR Boards:

Hi all.
Added the 20 MHZ code options to the boards.txt as per above comments. Everything works, compiles OK and sketches upload BUT, again, incompatibility with the servo library, even when using a different timer. I suspect the PWM frequency being off by the clock change?

What exactly do you mean by "incompatibility with the servo library"?

Hi, please refer to this post for the servo.h incompatibility
https://forum.arduino.cc/index.php?topic=628126.0

Have not tested any servos with the Nano Every, but I didn't think the Servo library cared about the PWM frequency, the timer is used to tell it when the next servo output needs to be changed, not to drive the actual servo output as a PWM signal.

GianNos:
Hi all.
Added the 20 MHZ code options to the boards.txt as per above comments. Everything works, compiles OK and sketches upload BUT, again, incompatibility with the servo library, even when using a different timer. I suspect the PWM frequency being off by the clock change?

What exactly are you having a problem with? Other than a warning message from the servo library, which I get regardless of whether the tone library is being used, I don't seem to have a problem driving a servo and using tone at the same time, once the default timer for the Servo library has been changed.

The compiler warning from Servo is as follows:

In file included from /home/pi/Arduino/libraries/Servo/src/Servo.h:73:0,
                 from /tmp/arduino_modified_sketch_20226/Sweep.ino:10:
/home/pi/Arduino/libraries/Servo/src/megaavr/ServoTimers.h:36:24: warning: '_timer' defined but not used [-Wunused-variable]
 static volatile TCB_t* _timer =
                        ^~~~~~

GianNos:
Hi, please refer to this post for the servo.h incompatibility
Arduino NANO EVERY and Servo and Tone issues - Nano Every - Arduino Forum

In that thread, the compilation error you were having was clearly explained to you and you reported you had fixed the problem. None of that had anything to do with the clock speed. So I'll ask again: What exactly do you mean by "incompatibility with the servo library"?

pert:
In that thread, the compilation error you were having was clearly explained to you and you reported you had fixed the problem. None of that had anything to do with the clock speed. So I'll ask again: What exactly do you mean by "incompatibility with the servo library"?

You are too quick in your attempt to school someone.

Rather than just posting and complaining you should try to check if the poster has a valid point by trying to replicate an issue, e.g. run a simple sketch to move a servo.

Had you have done so you would have discovered that when using the servo library with a 20 MHz clock rather than with a 16 MHz clock results in different positions for the same commands. For example a simple myservo.writeMicroseconds(1000); will not move the servo to your desired point. Fwiw the correct command for the 20 MHz clock would be very close to myservo.writeMicroseconds(1400); now.

I could explain why, or post the math for finding the correct shift but your tone makes me not want to make the effort.

1 Like

Ok, now that you have told us what the specific problem is, I can confirm that you are correct, and the different clock frequencies do give different positions for the servo, using both the servo.write and servo.writeMicroseconds commands.

Has nothing to do with the tone command, a sketch with only the servo commands will exhibit the behavior.

GianNos:
Rather than just posting and complaining you should try to check if the poster has a valid point by trying to replicate an issue, e.g. run a simple sketch to move a servo.

That would require that I own a Nano Every, which I don't.

It would also require me to spend time wiring up a servo. Why should I do all that when you're the one asking for help and you already know full well what the problem is? It's not too much to ask for the people asking for help to provide a description of their problem.

I'm not trying to "school" you (whatever that means). I was trying to help you.

It is a bug in the servo library. In the file Servo/src/megaavr/Servo.cpp, the calculation on line #6 is getting rounded off because of the integer math.

#define usToTicks(_us)    ((clockCyclesPerMicrosecond() / 16 * _us) / 4)                 // converts microseconds to tick

clockCyclesPerMicrosecond is 16 at 16MHz, 20 at 20MHz, but apparently the division by 16 is being rounded before the multiplication with _us, making the result the same regardless of the clock frequency.

Rearranging the equation fixes the problem, although you need to use a long instead of an integer because one of the calculations has _us = 20000.

#define usToTicks(_us)    (((int32_t)clockCyclesPerMicrosecond() * _us / 16) / 4 )                 // converts microseconds to tick

GianNos:
You are too quick in your attempt to school someone.

Rather than just posting and complaining you should try to check if the poster has a valid point by trying to replicate an issue, e.g. run a simple sketch to move a servo.

Had you have done so you would have discovered that when using the servo library with a 20 MHz clock rather than with a 16 MHz clock results in different positions for the same commands. For example a simple myservo.writeMicroseconds(1000); will not move the servo to your desired point. Fwiw the correct command for the 20 MHz clock would be very close to myservo.writeMicroseconds(1400); now.

I could explain why, or post the math for finding the correct shift but your tone makes me not want to make the effort.

The problem you are having is very obscure. You implied it had something to do with using Servo and tone together, which it does not, servo alone will produce the problem. It also requires that someone modify the boards.txt file to change the clock frequency, and then switch back and forth between the clock frequencies to make the problem obvious. There are very few people who actually have a Nano Every, and even fewer who have modified the boards.txt file to alter the frequency, and the code to easily switch between frequencies is something I came up with, so even fewer are using that.

This discussion goes away from the basic problem: The timing with 20 MHz seems not OK!!
I use a simple sketch to measure the micros() and the millis() timing. The behaviour is not OK.
I use the Saleae Logic Analyser for measurement of millis():
- With 50 ms it measures 63.45 ms
- with 100 ms it measures 125.9 ms
- ... and so on - always with a factor near 1.25x
Back calculation (20MHz/1.25x) gives 15,xx MHz.
I have changed the 2 lines in the "boards.txt" file and the compiler shows "-DF_CPU=20000000L" as expected. So I think it's not my mistake!

//========================================================
// Small sketch to check precision of micros()
//========================================================

long lTimer;  // Save the millis() for compare
bool bState;  // State of the Port (D2)

void setup() {

  pinMode(2,OUTPUT);  // This pin is used for Logic Analyser
  lTimer = millis();  // Initialise the time
}

void loop() {

  long lAct = millis();     // Collect the actual time
  if (lAct-lTimer > 200)    // If a limit is reached...
  {
    lTimer = lAct;          // Save the actual time for compare
    PinStatus state = bState ? HIGH : LOW;  // Hack for Every
    digitalWrite(2,state);  // Set the output to a new state
    bState = !bState;       //  ... and change it for next cycle
  }
}

To top the compleity of this thread, I get a warning - and I give up!.

RudolfAtRTC:
This discussion goes away from the basic problem: The timing with 20 MHz seems not OK!!
I use a simple sketch to measure the micros() and the millis() timing. The behaviour is not OK.
I use the Saleae Logic Analyser for measurement of millis():
- With 50 ms it measures 63.45 ms
- with 100 ms it measures 125.9 ms
- ... and so on - always with a factor near 1.25x
Back calculation (20MHz/1.25x) gives 15,xx MHz.
I have changed the 2 lines in the "boards.txt" file and the compiler shows "-DF_CPU=20000000L" as expected. So I think it's not my mistake!

Can you confirm that fuse2 is being written with 0x02 instead of 0x01? Set the IDE to verbose output during upload and it will show the fuses being written - File > Preferences > Show verbose output during - put a check mark in the box beside "upload".

I modified your code to blink the built-in LED in addition to pin 2, and set the time interval to 60 seconds, and I don't see any significant timing difference between 16MHz and 20MHz, a 25% error would certainly be obvious. I tested for both millis() and micros() with the same results.

Thank you - I am amazed and happy! This morning

  • with the same sketch
  • and the same analyser
    after I upload it with "Show verbose output during upload" it works!
    Yesterday I did a couple of uploads with varied timings, always with that bad result.
    Yes - now the fuse 2 is set to 0x02.
    Result: this forum is very helpful.
1 Like