MCUdude / MightyCore

Arduino hardware package for ATmega1284, ATmega644, ATmega324, ATmega324PB, ATmega164, ATmega32, ATmega16 and ATmega8535
Other
637 stars 181 forks source link

Power_down mode consume 0.2ma #259

Closed garudaonekh closed 1 year ago

garudaonekh commented 1 year ago

Hi, My chip is Atmega16a.

I set sleep mode to SLEEP_POWER_DOWN, but the consumption is still at 0.2ma, which is too high for battery powered device. Any suggestion to reduce it to microamps?

const int ledpin=13;
const int sleepkey=20;
const int wakeupPIN=2;

volatile bool once = true;
volatile int i =0;

void setup() {

pinMode(wakeupPIN,INPUT_PULLUP);

Serial.begin(9600);
pinMode(ledpin,OUTPUT);
pinMode(sleepkey,INPUT_PULLUP);

attachInterrupt(digitalPinToInterrupt(wakeupPIN), wake, FALLING);
digitalWrite(ledpin,HIGH);
}

void loop() {

digitalWrite(ledpin,LOW);

if(true){//(digitalRead(sleepkey)==LOW) && once == true){

Serial.println(" Sleep "); 
delay(500);
once = false;
//disablePower(POWER_ALL);
sleepMode(SLEEP_POWER_DOWN);///0.2 ma=SLEEP_POWER_DOWN);
sleep();
}

}

void wake() {

Serial.println("Wakeup");
i++;
Serial.println(i);
once = true;
digitalWrite(ledpin,HIGH);
//noSleep();
}
MCUdude commented 1 year ago

There are some info here: https://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html

If you're looking for tutorials, the Atmega8 is very similar to the ATmega16, so low-power code written for ATmega8 should work on the ATmega16. The ATmega8 is more popular among the Arduino folks, so chances are you're able to find something useful.

A better place for help than here is to use the Arduino forum. This repo is mainly for reporting MightyCore-related bugs and issues.

garudaonekh commented 1 year ago

THanks, The following code reduce the power to less than 0.1ua but when I format it to Arduino, its deep sleep not working as its original code(0.2ma while sleeping). Sorry, I never convert avr to arduino.

#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main(void)
{
   DDRC |= (1 << PC2) | (1 << PC1);     // leds for testing

   DDRD &= ~(1 << PD2);    // INT0: input...
   PORTD |= (1 << PD2);    // ...with pullup.

   // level interrupt INT0 (low level)
   MCUCR &= ~((1 << ISC01) | (1 << ISC00));

   // infinite main loop
   while (1)
   {
      // trigger leds for testing
      PORTC ^= (1 << PC1);
      _delay_ms(500);
      PORTC ^= (1 << PC1);

      // enable external interrupt
      GICR |= (1 << INT0);

      // set sleep mode
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);

      // sleep_mode() has a possible race condition
      sleep_enable();
      sei();
      sleep_cpu();
      sleep_disable();

      // waking up...
      // disable external interrupt here, in case the external low pulse is too long
      GICR &= ~(1 << INT0);

      // disable all interrupts
      cli();
   }
}

ISR(INT0_vect)
{
   // ISR might be empty, but is necessary nonetheless
   PORTC ^= (1 << PC2);    // debugging
}

My converted code:

#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>

void setup()
{
   DDRC |= (1 << PC2) | (1 << PC1);     // leds for testing

   DDRD &= ~(1 << PD2);    // INT0: input...
   PORTD |= (1 << PD2);    // ...with pullup.

   // level interrupt INT0 (low level)
   MCUCR &= ~((1 << ISC01) | (1 << ISC00));

   // infinite main loop

}
void loop(){
      // trigger leds for testing
      PORTC ^= (1 << PC1);
      _delay_ms(500);
      PORTC ^= (1 << PC1);

      // enable external interrupt
      GICR |= (1 << INT0);

      // set sleep mode
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);

      // sleep_mode() has a possible race condition
      sleep_enable();
      sei();
      sleep_cpu();
      sleep_disable();

      // waking up...
      // disable external interrupt here, in case the external low pulse is too long
      GICR &= ~(1 << INT0);

      // disable all interrupts
      cli();
}

ISR(INT0_vect)
{
   // ISR might be empty, but is necessary nonetheless
   PORTC ^= (1 << PC2);    // debugging
}
garudaonekh commented 1 year ago

Ok, Adding disable adc code to setup() do the tricks,(Now it's 0.2ua).

 // infinite main loop
  ADCSRA &= ~_BV(ADEN);  // disable ADC