Changing Mega to 3.3V 8MHz

I'm working on a concept design for something, and settled on the Mega as it has multiple hardware UARTs which are a great deal better than using software serial and I needed 3 of them. Initially I had one component at 3.3V (Everything else was 5V) and so had it through a TXB01XX level shifter and everything was good. I've now gotten to the point where the design has changed multiple times (As they do) and it's now looking like all the components either going to be native 3.3V or able to be used at 3.3V+ so I want to drop the Vcc down to 3.3V (Device is being powered by external regulator into 5V in pins) and subsequently I will need to drop the clock down to 8MHz to be within spec of the Atmega2560.
I know there are multiple ways to do this, but for all of them I often come across comments about millis() and baud rates not functioning correctly at a reduced clock rate, having to manually calculate the difference (i.e. you need to specify in the sketch that the UART is at 19200 when it's really 9600 because of the halving of clock speed). I also see posts that say that it's not necessary to do that so long as you compile it at the specified frequency.
I've already changed the board to use a 16MHz crystal instead of the default resonator as I required a more stable clock for one of the devices (My resonator was at the bottom end of it's allowable range) so I can easily change that to an 8MHz crystal as it's source. What else do I need to change (Software or hardware) to correctly run at 8MHz, without issues with timings or baud rate mismatches and so the sketch compiles and uploads correctly?

TL;DR: What is the correct way to lower Vcc and the clock rate to 3.3V 8MHz without causing issues with baud or timing?

Edit to add: It's running on batteries so the reduction in current would be a welcome extra benefit. It is not doing anything intensive that requires it be 16MHz instead of 8MHz, the Mega was selected so that software serial was not used

You need to make sure that the hardware definition has the correct build.f_cpu value and timing will be fine. The place where there is a timing issue is the bootloader, since that is not affected by the build.f_cpu property. You can use a bootloader that is compiled for 8 MHz or you can just change upload.speed to half the baud rate that the bootloader was intended to communicate at.

The easiest way to do all of this is to use MegaCore:

After selecting a MegaCore board you will find a new Tools > Clock menu where you can select "8 MHz external". That will correctly set build.f_cpu and also provide access to a bootloader compiled for 8 MHz. After that, connect an ISP programmer to your ATmega2560 and do Tools > Burn Bootloader. As a bonus, that will free up 7 kB of program memory due to the more modern bootloader used by MegaCore.

So all the people that have had baud or timing problems have just neglected to change the f_cpu value and that's it?
I didn't know of the MegaCore bootloaders, I'll grab them for some of my other projects that are closer to max (This one is <20%). Is there anything that's missing from those bootloaders? Or is the official one just big because of legacy code?

It might also be that some older versions of the Arduino core library didn't have code to account for other clock speeds but I don't think you'll find any significant timing issues. There may be some more subtle problems. For example, you can see from this website:
http://wormfood.net/avrbaudcalc.php?bitrate=300%2C600%2C1200%2C2400%2C4800%2C9600%2C14.4k%2C19.2k%2C28.8k%2C38.4k%2C57.6k%2C76.8k%2C115.2k%2C230.4k%2C250k%2C.5m%2C1m&clock=8%2C16&databits=8
that baud rate error is different depending on clock speed. It's not a case of lower clock speed meaning higher error but you will notice that in this case 8 MHz didn't fare well compared to 16 MHz.

I know that Optiboot (the bootloader used by MegaCore) doesn't program EEPROM via .eep files. I'm not sure whether the stk500v2 bootloader used on stock Megas does or not. I don't think that usage is even supported by the Arduino IDE so most Arduino users wouldn't miss it.

The version of Optiboot used by MegaCore actually has been modified to allow you to write to flash memory from the application at run time. That's something you can't do with the regular Mega bootloader. More info here:

Hmmm that link is really interesting and I've bookmarked it now. It's strange that certain bit rates are way out of spec, and others faster than it are within spec. I noticed that even at 16MHz that rates like 230.4K are out of spec, but 250K is in spec. Is it to do with the clock speed dividing at an uneven rate? i.e. at 230.4K and 16MHz the clock rate divides at 1 bit per 69.4444.... cycles, whereas at 250K it divides at an even bit per 64 cycles?

The atmega2560 used on the mega2560 is not rated for operation at 3.3v and 8mhz. See the datasheet. You need an atmega2560V. This also means that getting a suitable board is much harder, since boards with these pre-mounted are not readily available.

Yes, the issue of which baud rates give acceptable error rates is a function of whether the clock rate can be evenly divided to get the correct sampling speed for that baud rate. It is sort of explained in the datasheet.

DrAzzy:
The atmega2560 used on the mega2560 is not rated for operation at 3.3v and 8mhz. See the datasheet. You need an atmega2560V. This also means that getting a suitable board is much harder, since boards with these pre-mounted are not readily available.

Wow thanks for pointing that out. I've heard of people running it at 3.3V and the MCU with internal oscillator runs at 8MHz so I assumed it was on the atmega2560, I didn't realise there was a lower voltage variant.
Do you know if you can run the Arduino bootloader on the 2560V? It'd be nice to simplify to 3.3V, but if I have to run some translators it's not a big deal either.

Yeah, the only difference between V and not-V is speed grade - even same signature bytes.

Some/many boards may work at 3.3v and 8mhz, however, this is not guaranteed; they may be unstable, or not work over the full rated temperature range (just like how most 328p's work fine at room temp at 3.3v and 16MHz)

Not V parts need 4.5V to work correctly per the datasheet.
Design to the datasheet, especially if you want to make more than 1 of these systems.
https://www.digikey.com/product-detail/en/microchip-technology/ATMEGA2560V-8AU/ATMEGA2560V-8AU-ND/735456

Speed Grade:
– ATmega640V/ATmega1280V/ATmega1281V:
• 0 - 4MHz @ 1.8V - 5.5V,
0 - 8MHz @ 2.7V - 5.5V

– ATmega2560V/ATmega2561V:
• 0 - 2MHz @ 1.8V - 5.5V,
0 - 8MHz @ 2.7V - 5.5V

– ATmega640/ATmega1280/ATmega1281:
• 0 - 8MHz @ 2.7V - 5.5V,
0 - 16MHz @ 4.5V - 5.5V

– ATmega2560/ATmega2561: <<< Not V, as used on the Mega.
• 0 - 16MHz @ 4.5V - 5.5V

No 3.3V operation for the Mega's 2560 to be fully compliant for all operations - like Serial. Need a V part.

Can you use 2560s as a breakout board? I can put whatever processor/crystal you want on a system board:


Did you look at the "Arduino Due".
Almost the same as a Mega, but a (faster) 3.3volt processor.
Leo..

And limited IO current drive capability, something to consider depending on what you are connecting up.

CrossRoads:
No 3.3V operation for the Mega's 2560 to be fully compliant for all operations - like Serial. Need a V part.

Can you use 2560s as a breakout board? I can put whatever processor/crystal you want on a system board:

As I need several of these units, I was planning on making a custom PCB for all the components, so if it's the same signature and package and I can run the Arduino bootloader on it, I might give it a shot with a 2560V.

Wawa:
Did you look at the "Arduino Due".
Almost the same as a Mega, but a (faster) 3.3volt processor.
Leo..

I have, but having not used it as much as the Atmel 8 bit MCUs, I was hesitant to select it. The other reason for selecting an Atmel was the battery life in powerdown mode; I've made several designs based on the Mega2560 and Mega328 and have achieved very good battery life from them. When I had a brief look at the Due in low power modes, it looked like the power consumption was magnitudes higher.

If you are planning on making a custom PCB, this could be interesting for a really low power mode Sam3x in backup mode:

From Sam3x datasheet, page 2:

Low-power Modes(for Sam3x8e alone) :
̶ Sleep, Wait and Backup modes, down to 2.5 μA in Backup mode with RTC, RTT, and GPBR.

2.5 μA seems reasonnably low, does it ?

ard_newbie:
If you are planning on making a custom PCB, this could be interesting for a really low power mode Sam3x in backup mode:

From Sam3x datasheet, page 2:

Low-power Modes(for Sam3x8e alone) :
̶ Sleep, Wait and Backup modes, down to 2.5 μA in Backup mode with RTC, RTT, and GPBR.

2.5 μA seems reasonnably low, does it ?

2.5uA is perfect, however every article I've searched seems to indicate a lot of problems getting the Due into a low power state below around 30mA from memory. I don't know if every post and article I read is outdated, or perhaps they were doing something wrong, but I never saw any resolutions to getting into a suitably low power mode. None of the libraries that I looked at supported the Due, so I assumed that perhaps it was not a state that was supported.
I might have a proper look at it again in the future, but for now I'd prefer a personally tried and tested system (Not that the 2560V has been tried by me, but from what was said above it's almost identical).

IMO 2.5 μA in Backup mode with RTC, RTT, and GPBR is strictly for a Sam3x alone (don't count the voltage regulator and Leds).

Here is an example sketch to set the DUE in back up mode (beware : do not stop the software while in back up mode, or your board would become a brick for 5 minutes ! ):

/**********************************************************
             Backup mode with Alternate Way and Event
***********************************************************/

#define   SUPC_KEY                    (0xA5)
const uint32_t AL = 5;  // Alarm = AL * T

void setup() {

  Serial.begin(250000);
  printf("\n Last software update  : %s   %s\n", __DATE__, __TIME__);

  uint32_t status = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
  Serial.print("\nRSTTYP = 0b"); Serial.println(status, BIN);  // Should be 0b001 see page 232

  RTT->RTT_MR = RTT_MR_RTTRST
                | RTT_MR_RTPRES (0x8000);  // T = 1 second

  RTT->RTT_SR;

  RTT->RTT_AR = RTT_AR_ALMV(AL);

  SUPC->SUPC_WUMR |= SUPC_WUMR_RTTEN;

  Serial.println("\n\rHELLO ALL !!");
  Serial.print("\n GPBR[0] = "); Serial.println(GPBR->SYS_GPBR[0]);
  delay(1000);
}

void loop() {

  GPBR->SYS_GPBR[0] += 1;            // Increment one of the 8 General Purpose Backup Registers

  if (GPBR->SYS_GPBR[0] < 5) {

    Serial.print("Entering backup mode : Do NOT stop the software now  |:");

    Serial.end();                     // Exit from Serial

    //alternate way to enter backup mode
    SUPC->SUPC_CR = SUPC_CR_VROFF_STOP_VREG | SUPC_CR_KEY(SUPC_KEY);

  }

  Serial.println("Definitive Exit from backup mode");
  Serial.println("Now you can stop the software");
  Serial.println(GPBR->SYS_GPBR[0]);
  delay(5000);

}

ard_newbie:
IMO 2.5 μA in Backup mode with RTC, RTT, and GPBR is strictly for a Sam3x alone (don't count the voltage regulator and Leds).

Here is an example sketch to set the DUE in back up mode (beware : do not stop the software while in back up mode, or your board would become a brick for 5 minutes ! ):

Is that a sketch you've tried? If so what was the power draw you achieved in backup mode?
What do you mean by stop the software in backup mode? Do you mean if you power the device down?

Here are a couple of links I had referenced that reinforced my decision to stick with the 8 bit range:
Stating they are getting 12mA, and others saying that the Due is not for low power applications: Due for very low power applications? - Arduino Due - Arduino Forum
Stating low power is in hundreds of milliamps, others unable to get it into low power mode: Reducing SAM3X power consumption in WAIT or SLEEP mode? | UDOO Forum

That being said, if you've tried the above, and have got power down to <20uA then it's certainly something I will have a play with when I get some spare time.