atmega328PB sleep mode programming; help please

Hello,

I created a pcb, which I’ve mentioned on other threads. I initially built the project using a 328P and using rocketscream sleep lib, I got the current consumption down to 150uA. Now that I’ve used the 328PB, the lowest I can get the consumption during sleep mode is 5mA, using a fork of rocket screams lib for the PB. Which is a massive difference for a battery powered project.

I came across this AVR example and building the simple led circuit, which reduced the comsuption to about 25uA. So what I am trying to achieve is possible but I’m having to go down the actual programming route, rather than libs and I do not have a clue, I can not get it to work.

https://microchipdeveloper.com/8avr:low-power-example

This is my code, using the forked lib;

// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//#include <DHT.h>
//#include <LowPower.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "LowPower328PB.h"
//#include <LowPower328PB.h>

#define power2_h
#define __AVR_ATmega328PB__
//#define DHTPIN 2

//not all #defines used but here for documentation
#define CE_PIN   7
#define CSN_PIN 8
#define MOSI_PIN 11
#define MISO_PIN 12
#define SCK_PIN 13

// define device I2C address: 0x76 or 0x77 (0x77 is library default address)
#define BME280_I2C_ADDRESS  0x76

Adafruit_BME280  bme280;  // initialize Adafruit BME280 library

//added for cal adjustment
const float adjustment = -1;


const byte slaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
//#define DHTTYPE DHT22

struct data
{
  float temperature;
  float humidity;
} sentData;

char txNum = '0';

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 2000;
//DHT dht(DHTPIN, DHTTYPE);
unsigned long delayTime; //added last 12/08/19

void setup()
{
  Serial.begin(9600);
  Serial.println("SimpleTx Starting");
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate( RF24_250KBPS );
  radio.setChannel(124);
  radio.setRetries(3, 5); // delay, count
  radio.openWritingPipe(slaveAddress);
  //dht.begin();
    Wire.begin();
  //dht.begin();
  while(!Serial);    // time to get serial running
  Serial.println(F("BME280 test"));
  bme280.begin(BME280_I2C_ADDRESS);
//bme280.setTempCal(-1);
  delayTime = 5000; //added last 12/08/19
}

void loop()
{
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis)
  {
    sentData.temperature = bme280.readTemperature() + adjustment;
    sentData.humidity = bme280.readHumidity();
    send();
    prevMillis = millis();
  }

}

void send()
{
  bool rslt;
  rslt = radio.write( &sentData, sizeof(sentData) );
  if (rslt)
  {
    Serial.println("  Acknowledge received");
  }
  else
  {
    Serial.println("  Tx failed");
  }
  delay(50);

//works for A and B below
//Loop for 6 times (48 seconds between temprature transissions)
  for (int i = 0; i < 6; i++) 
  {

//A - From pro mini code - doesn't work here
//    LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
//                  SPI_OFF, USART0_OFF, TWI_OFF);

//B - works from LowerPower328PB lib - power not reduced much
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 

//C - lib
//  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, 
//                SPI_OFF, USART0_OFF, TWI_OFF);

  }
}

This is the example code, which I tried to integrate

/*
 * lowpower2.c
 */
 
//#include <avr/io.h>
 
#include <avr/io.h>
#include "avr/interrupt.h"
#include "avr/wdt.h"
#include "avr/sleep.h"
 
#include <avr/power.h>
#include <avr/interrupt.h>
//#include <util/delay.h>  //maybe use this for delay instead of count
 
void    optimize_power_consumption(void){
 
    /* Disable digital input buffer on ADC pins */
    DIDR0 = (1 << ADC5D) | (1 << ADC4D) | (1 << ADC3D) | (1 << ADC2D) | (1 << ADC1D) | (1 << ADC0D);
    DIDR0 |= 0xC0 ;   /*ADC7D and ADC6D are undefined in header file so set bits this way*/
 
    /* Disable digital input buffer on Analog comparator pins */
    DIDR1 |= (1 << AIN1D) | (1 << AIN0D);
    /* Disable Analog Comparator */
    ACSR |= (1 << ACD);
 
    /*Power shutdown to unused peripherals*/
    PRR0 = 0xDF;
    PRR1 = 0x3F;
    /*Unused pins set as input pull up*/
    DDRB &= 0xE0;
    DDRC &= 0xC9;
    DDRD &= 0x03;
    DDRE &=0xF3;
 
    PORTB |=~(0xE0);
    PORTC |=~(0xC9);
    PORTD |=~(0x03);
    PORTE |=~(0xf3);
 
    /*Watchdog Timer OFF*/
 
    /* Disable interrupts */
    cli();
    /* Reset watchdog timer */
    wdt_reset();
    /* Clear WDRF in MCUSR */
    MCUSR &= ~(1<<WDRF);
    /* Turn off WDT */
    WDTCSR = 0x00;
 
    /* Set sleep mode */
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); ///////////
 
}
 
/********************************************************************************
                                TMR 0 Initialization
********************************************************************************/
 void TMR0_init( void ){
 
    // enable timer overflow interrupt for both Timer0 and Timer1
    TIMSK0=(1<<TOIE0) ;
 
    // set timer0 counter initial value to 0
    TCNT0=0x00;
 
    // start timer0 with /1024 prescaler
    TCCR0B = (1<<CS02) | (1<<CS00);
 
    // enable interrupts
    sei(); 
 
}  
     uint8_t    count;
/* Timer 0 Interrupt */
 ISR(TIMER0_OVF_vect){
 
    count++;
    if(count==20){
        count=0;
        // Toogle LED
        PORTB=PORTB ^ 0x20;
    }
}
 
ISR (PCINT0_vect)
{
     if (!(PINB & (1<<PINB2))) // if PINB7 is low (Switch pressed)
    {
        PORTB |= (1<<PORTB5); // Turn ON LED
    }
    else
    {
        PORTB &= ~(1<<PORTB5); // Turn OFF LED
    } 
}
 
int main(void)
{
    TMR0_init();
 
    DDRB |= 1<<DDRB5;   // Direction of pin PB5 set as Output
    DDRB &= ~(1<<DDB2); //Set PORTB7 as input
 
    optimize_power_consumption();
 
    PCMSK0 |= (1<<PCINT2); //Enable Pin Change Interrupt 7
    PCICR |= (1<<PCIE0); //Enable the interrupt enable bit for PCINT
    sei();
 
    //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    //sleep_enable();
    //sleep_cpu();
 
    /* Replace with your application code */
    while (1) 
    {
        sleep_mode();
    }
}

Any help, advice or pointers. I’ll happily pay for some coding expertise :slight_smile:

This is what I was using for the 328P, which worked a treat.

//Loop for 6 times (48 seconds between temprature transissions)
  for (int i = 0; i < 6; i++) 
  {


    LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
                  SPI_OFF, USART0_OFF, TWI_OFF);