ATMega328PB low power/sleep

After lots of messing around, I finally got everything working with the ATMega328PB…working as an actual 328PB…so now I can use the additional GPI/O’s offered by it.

Im using a custom PCB and the “Elektor Uno R4” bootloader.

However Im having trouble getting sleep/low power functions working on it.

As far as I know, the 328PB and 328P are basically the same in this regard, so all existing sleep/low power functions that work on the 328P should work fine on the 328PB.

Im using Rocket Scream’s “low-power” library, and it works great on the 328P, I just need to figure out how to make it work on the 328PB.

When I try to compile it with the arduino IDE board set to “elektor uno R4” (as it needs to be), I get a compile error that says “error, please ensure the chosen MCU is either 168, 328P, 32U4, 2560, or 256RFR2”…obviously I would expect this, so I went into the LowPower.h and LowPower.cpp files and added what I thought was the proper stuff to make the compiler pass the “which processor is it” check.

However I still cant get it to acknowledge the Elektor Uno R4. I suspect Im not referring to the Elektor Uno R4 properly in the LowPower libraries. The regular 328PB Is referred to as “AVR_ATMega328P”. I have tried adding code in the LowPower libraries for “AVR_ATMega328PB” “ELEKTOR_UNO_R4”, “AVR_ATmega328pb”, etc. (different iterations of capital letters, etc).

But it still wont work. What file can I look at to see exactly what the Arduino IDE refers to the Elektor Uno R4 as? Im pretty sure if I can just get the NAME right, the compiler will see that things match with my additions to the LowPower.h/.cpp files, and things will be great…I just dont know what its called!

Thanks
Ben

LowPower.cpp (33.2 KB)

LowPower.h (2.85 KB)

Dear duramaxhd,

I am having the same issue. Did you find the solution?

Hey, I’m having this issue as well! I don’t suppose either of you found a solution did you?

Edit * in case any Duck Duck Go searches make their way here. I was really only interested in the powerDown function. So I went into the the LowPower.h file and just removed the #ifdefs. Then in the .cpp file I removed all the ifdefs and all the functions that I wasn’t using until I ended up with just

#if defined (__AVR__)
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#elif defined (__arm__)

#else
#error "Processor architecture is not supported."
#endif

#include "LowPower.h"

#define sleep_bod_disable() \
do { \
unsigned char tempreg; \
__asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \
"ori %[tempreg], %[bods_bodse]" "\n\t" \
"out %[mcucr], %[tempreg]" "\n\t" \
"andi %[tempreg], %[not_bodse]" "\n\t" \
"out %[mcucr], %[tempreg]" \
: [tempreg] "=&d" (tempreg) \
: [mcucr] "I" _SFR_IO_ADDR(MCUCR), \
[bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \
[not_bodse] "i" (~_BV(BODSE))); \
} while (0)

#define lowPowerBodOn(mode) \
do { \
set_sleep_mode(mode); \
cli(); \
sleep_enable(); \
sei(); \
sleep_cpu(); \
sleep_disable(); \
sei(); \
} while (0);

// Only Pico Power devices can change BOD settings through software
#define lowPowerBodOff(mode)\
do { \
set_sleep_mode(mode); \
cli(); \
sleep_enable(); \
sleep_bod_disable(); \
sei(); \
sleep_cpu(); \
sleep_disable(); \
sei(); \
} while (0);

void LowPowerClass::powerDown(period_t period, adc_t adc, bod_t bod)
{
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);

if (period != SLEEP_FOREVER)
{
wdt_enable(period);
WDTCSR |= (1 << WDIE);
}
if (bod == BOD_OFF)
{
#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega328PB__)
lowPowerBodOff(SLEEP_MODE_PWR_DOWN);
#else
lowPowerBodOn(SLEEP_MODE_PWR_DOWN);
#endif
}
else
{
lowPowerBodOn(SLEEP_MODE_PWR_DOWN);
}

if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
}

LowPowerClass LowPower;

And that worked!