Reducing clock speed of the NANO Every (ATMEL4809)

Hi all,

For a project that runs on a battery I want to reduce the clockspeed of the Arduino Nano Every wich I am using to increase batterylife. For the nano V3 (and some other boards) this seems to work by adding 'CLKPR = 0x80;
CLKPR = 0x02;' to the void setup. However, since the Nano Every runs on the ATMEL 2809 this code doesn't work with the Every. I have been looking at the ATMEL 2809 datasheet for a while to find out a similair command to reduce the clockspeed of the Every board but unfortunately I couldn't find something that works. Possibly because of my lack of experience with clockspeed adjustments. Therefore my question is if anyone knows with what code I can reduce the clockspeed of the Every, similair to how I reduced it on the Nano V3 board?

Thanks in advance for any help!

The ATmega4809 data sheet has the information you require.

Changing the clock speed won't accomplish much, as slower clock speeds take more time to do computations.

Sleep modes are more effective at increasing battery life, but are the other chips on the Every board under your control?

Thanks a lot for your quick reply!

I guess I have to take some more looks at the data sheet. The code of my project is actually really simple so there isn't a lot of computing and a reduced clockspeed
therefor wouldn't harm the practical results of my project. With the 'CLKPR = 0x80; CLKPR = 0x02;' code I achieved a very usefull consumption reduction with the exact same project on a counterfeit pro micro board. Because of that I am looking for similar reduction with this Nano Every board. Adding sleep modes would have been my next step in my quest for improving batterylife but at the moment I am not very known yet with how to get that feature to work properly on the Every as well.

I must admit I am not sure about what you mean by the question if the other chips on the Every are under my control?

There are registers similar to CLKPR on the ATmega4809, with similar function. The CLKCTRL section of the data sheet gives the details.

The Every has a USB controller chip, which consumes power.

I strongly recommend this excellent tutorial on power saving and sleep modes. Most of the ideas apply to other members of the ATmega series.

Hi,

Example

CPU_CCP = CCP_IOREG_gc;							// write access for four CPU instructions
CLKCTRL_MCLKCTRLB = CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm;	// prescaler 2, enable prescaler

and you surely mean ATmega4809 :wink:

Use MCUdude's MegaCoreX and you can set the clock speed in the Arduino IDE Tools menu. The clock speed on the Nano Every is set via the fuses every time you upload a sketch, and uses the internal oscillator because there is no external crystal or oscillator on the board.

More precise would be to choose between internal 16 or 20MHz clock source by means of fuse setting. All the rest is adjustable by software. However, I don't think the TO wants to change the clock source. :wink:

_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);

There are numerous possibilities other than 2X:

    CLKCTRL_PDIV_2X_gc = (0x00<<1),  /* 2X */
    CLKCTRL_PDIV_4X_gc = (0x01<<1),  /* 4X */
    CLKCTRL_PDIV_8X_gc = (0x02<<1),  /* 8X */
    CLKCTRL_PDIV_16X_gc = (0x03<<1),  /* 16X */
    CLKCTRL_PDIV_32X_gc = (0x04<<1),  /* 32X */
    CLKCTRL_PDIV_64X_gc = (0x05<<1),  /* 64X */
    CLKCTRL_PDIV_6X_gc = (0x08<<1),  /* 6X */
    CLKCTRL_PDIV_10X_gc = (0x09<<1),  /* 10X */
    CLKCTRL_PDIV_12X_gc = (0x0A<<1),  /* 12X */
    CLKCTRL_PDIV_24X_gc = (0x0B<<1),  /* 24X */
    CLKCTRL_PDIV_48X_gc = (0x0C<<1),  /* 48X */

Goodmorning,

first of all thanks a lot for your reply! Indeed i meant the 4809! Don't know how that 2 got there hahaha.

I tried the example you gave but I either get the error 'does not name a type' or 'not declared in this scope' on the CPU_CCP & CLKCTRL_MCLKCTRLB.

Hi and thanks a lot for the helpfull reply,

Your solution seems to be accepted when compiling however I get the error: 'expected ')' before ':' token'. Making several changes didn't fix that problem. Maybe I am missing something here... This is my code at the moment.

_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);
CLKCTRL_PDIV_2X_gc = (0x00<<1),  /* 2X */  

int transistorPin = 9;
const int ldrPin = A0; 

void setup() {

pinMode(transistorPin, OUTPUT);
pinMode(ldrPin, INPUT);

}

void loop() {
int ldrStatus = analogRead(ldrPin);

if (ldrStatus <300) {
  
  digitalWrite(transistorPin, LOW);
  delay(500);
  digitalWrite(transistorPin, HIGH);
  delay(500);

}
else {
  digitalWrite(transistorPin, LOW);
}
}

Hi and thanks for the reply!

I'll be trying your solution later as well!

Hi,

executable code belongs in setup or loop.

// this ...
  CPU_CCP = CCP_IOREG_gc;             
  CLKCTRL_MCLKCTRLB = CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm;  
  /* ... or this here in setup
  _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);
  */

Both have the same effect.

You're not supposed to include the CLKCTRL_PDIV_2X_gc = (0x00<<1), /* 2X */ line - those are values that are already pre-defined for you; you just have to pick the one you want:

// with 16MHz oscillator, divide by 16 to get a 1MHz CPU clock:
  _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm);

I gave this a try and indeed, this did the trick. Thankyou all so much for the help! Really appreciate it!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.