Jump to content
Sign in to follow this  
mattanonymous

Help reducing power consumption please :)

Recommended Posts

Hi all,

 

I'm working on a very simple project that uses the RTC library to set an alarm. I'd like the board to last at least 1 year on a single charge from a 1500mAh li-ion battery and I don't think the MSP430G2553 I'm using should have any problem meeting this requirement. However, the battery is depleting within a couple of days and my multimeter is showing ~40mA being drawn by the board. Since I don't need the time to be super accurate, I'm using VLO as my clock source to save on power (at least I think I am). Since I'm just mocking this up, there is no buzzer yet. I'm just using the onboard LED instead.

 

The code is below and below that is an explanation of the purpose of the project in case you'd like some context.

 

#include  
#include  "RTC.h"

#define ALARM_INTERVAL 0x04 // in hours / how often the alarm will sound the buzzer
#define BUZZER_KILL_TIMER_START 600 // 10minutes in seconds / number of seconds we'll allow the buzzer to remain buzzing before we stop it
#define START_HOUR 0x11 // the hour to initially trigger the alarm if the nebulizer hasn't be used today
#define LATEST_ALARM_HOUR 0x20 // the latest we'll worry about setting alarms
int buzzerTimer = -1;
char nextAlarm12Hr = START_HOUR;
char nextAlarm24Hr = START_HOUR;

inline void setNextAlarm() {
char crntHr = get24Hour();
if ( crntHr <= LATEST_ALARM_HOUR ) {
	nextAlarm12Hr = (crntHr + ALARM_INTERVAL) % 0x12;
	nextAlarm24Hr = (crntHr + ALARM_INTERVAL) % 0x24;
} else {
	// NOTE: this will need to change if START_HOUR is not in the am
	nextAlarm12Hr = START_HOUR;
	nextAlarm24Hr = START_HOUR;
}
}

inline void turnBuzzerOn() {
// TODO: turn buzzer on
P1OUT |= BIT0;
buzzerTimer = BUZZER_KILL_TIMER_START;
}

inline void turnBuzzerOff() {
// TODO: turn buzzer off
P1OUT &= ~BIT0;
buzzerTimer = -1;
}

// Timer0 A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
// tick the RTC one second forward
incrementSeconds();

if ( buzzerTimer > 0 ) {
	// if the buzzer is currently buzzing
	buzzerTimer -= 1; // subtract a second from the buzzerTimer
	// TODO: toggle buzzer pin to create beeping effect
} else if ( buzzerTimer == 0 ) {
	// buzzerTimer has run out, we need to turn it off
	turnBuzzerOff();
	// we'll set it for a time in the near future;
	// TODO: set for time in future
} else if ( TI_hour == nextAlarm12Hr ) {
	// if we're potentially at the correct hour (ex 7am / 7pm)
	if ( nextAlarm24Hr == get24Hour() ) {
		// if we're at the exact hour
		turnBuzzerOn();
	}
}
}

// ON button pressed interrupt service routine
#pragma vector=PORT1_VECTOR   
__interrupt void Port_1(void)
{
 P1IFG &= ~BIT3; // P1.3 interrupt flag cleared

 if ( buzzerTimer >= 0 ) { // only worry about doing something if the buzzer is sounding
   turnBuzzerOff();
   setNextAlarm();
 }
}

void main ( void )
{
 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
 setTime(0x10,0x59,0x50,0);					// initialize time
 TACCR0 = 32768-1;
 TACTL = TASSEL_1+MC_1;                    // ACLK, upmode
 TACCTL0 |= CCIE;                          // enable TA0CCRO interrupt

 // set up led blink on 1.0
 // set up interrupt for ON button press via P1.3
 P1DIR |= BIT0; // Set P1.0 to output and P1.3 to input direction
 P1OUT &= ~BIT0; // set P1.0 to Off
 P1REN |= BIT3; // enable internal pull-up resistor
 P1IFG &= ~BIT3; // P1.3 interrupt flag cleared
 P1IE |= BIT3; // P1.3 interrupt enabled

 // turn off unused ports
 P2DIR = 0xFF;
 P2OUT = 0x00;
 P3DIR = 0xFF;
 P3OUT = 0x00;

 __bis_SR_register(GIE); // Enable all interrupts

 turnBuzzerOff(); //initialize buzzer state
}

 

Details on the project:

This is an alarm that buzzes every 4 hours (starting at 11am at the latest) and shut off whenever the button is pressed. It is for my grandmother who is having trouble remembering to use her nebulizer. I'm definitely a newb and am trying to learn what I can as I go along.

 

Thanks,

Matt

Share this post


Link to post
Share on other sites

Hmm, the end of your main() function doesn't enter any sleep modes, it just exits (which I think causes the program to reset), so your app just continuously initializes itself without ever giving the processor a chance to sleep or whatnot.

 

At the end you should probably do:

while(1) {
 LPM3;
}

so that the timer remains running while everything else is asleep.

Share this post


Link to post
Share on other sites

Thanks for the quick replies!

 

For some reason, my "__bis_SR_register(LPM3_bits);" line didn't get pasted into the original code, but it was in the program when I got the 40mA number. It may have dropped a couple of milliamps, but it seems like something still isn't right.

 

This is what my main function looks like now:

 

void main ( void )
{
 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
 setTime(0x10,0x59,0x50,0);					// initialize time
 TACCR0 = 32768-1;
 TACTL = TASSEL_1+MC_1;                    // ACLK, upmode
 TACCTL0 |= CCIE;                          // enable TA0CCRO interrupt

 // set up led blink on 1.0
 // set up interrupt for ON button press via P1.3
 P1DIR |= BIT0; // Set P1.0 to output and P1.3 to input direction
 P1OUT &= ~BIT0; // set P1.0 to Off
 P1REN |= BIT3; // enable internal pull-up resistor
 P1IFG &= ~BIT3; // P1.3 interrupt flag cleared
 P1IE |= BIT3; // P1.3 interrupt enabled

 // turn off all unused ports
 P2DIR = 0xFF;
 P2OUT = 0x00;
 P3DIR = 0xFF;
 P3OUT = 0x00;

 turnBuzzerOff(); //initialize buzzer state
 __bis_SR_register(GIE + LPM3_bits); // Enable all interrupts and go into LPM3

 while(1);
}

 

Thanks again,

Matt

Share this post


Link to post
Share on other sites

That is bizarre, 40mA is a lot for that chip even when it's in fully active mode (I don't think it draws that much even if you have it in a busy-wait loop nonstop at full 16MHz active mode). What else is in the circuit?

 

Also where are you measuring the 40mA -- at the Vcc jumper between the EMULATION and main portion of the launchpad board, or from the USB port? The emulation layer would use a fair amount of power keeping its chips & LED functioning which could account for that although I'm not really sure. And if the Vcc jumper is still installed but you're powering it from an external battery, the emulation layer (SBW programmer/UART) chips up top might still be receiving power back through that jumper... removing it should tell you.

Share this post


Link to post
Share on other sites

Bingo! That was it. I had to remove all of the jumpers from J3. Now it's idling around 25uA like it should be. I guess I missed this info in the 'MSP-EXP430G2 LaunchPad Experimenter Board User's Guide'. The jumpers and dotted line between EMULATION and MSP-EXP430G2 make sense, now.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...