Go Down

Topic: Using the Xbee to sleep Arduino (Read 2509 times) previous topic - next topic

fnsnoop

I am having trouble figuring out a simple way to control the sleep mode of the Arduino from Xbee. I have my Xbee on a cyclic sleep cycle and I want to wake the Arduino when the xbee wakes.  I found an article about making the Arduino go to sleep on this website's playground section. It appears that an Arduino can only be awaken when the interrupt pin goes LOW.  This appears to be opposite of what pin 13 on the xbee does when it awakes.  Pin 13 on the XBee is asserted HIGH when it turns on and it goes LOW when it turns off.  Has anybody found a way to use an Xbee to control a sleeping Arduino?




Arduino can wake on date received on UART pins. Maybe look into that
Check out my site for DIY information: http://inventige.com

fnsnoop

I was looking at that but its only available for SLEEP_MODE_PWR_IDLE and not SLEEP_MODE_PWR_DOWN.  I am trying to go with the most energy savings possible.

CrossRoads

"Pin 13 on the XBee is asserted HIGH when it turns on and it goes LOW when it turns off. "
Can you add a transistor & use it as a simple inverter?
Interrupt pin with internal  pullup enabled. NPN transistor with base to XBee pin 13, collector to interrupt pin, emitter to gnd.
Collector pulled high by internal pullup, connects to GND when base goes high from Xbee.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Jack Christensen

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

CrossRoads

Not sure you can wake up from sleep with PCINT. Think you need to use one of the external INTs for that.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Jack Christensen


Not sure you can wake up from sleep with PCINT. Think you need to use one of the external INTs for that.


Yep, have a project that does exactly that. From the datasheet:

Quote
10.5 Power-down Mode
When the SM2...0 bits are written to 010, the SLEEP instruction makes the MCU enter Powerdown
mode. In this mode, the external Oscillator is stopped, while the external interrupts, the 2-
wire Serial Interface address watch, and the Watchdog continue operating (if enabled). Only an
External Reset, a Watchdog System Reset, a Watchdog Interrupt, a Brown-out Reset, a 2-wire
Serial Interface address match, an external level interrupt on INT0 or INT1, or a pin change
interrupt can wake up the MCU. This sleep mode basically halts all generated clocks, allowing
operation of asynchronous modules only.


INT0, INT1, and pin change interrupts will wake from any of the sleep modes.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

CrossRoads

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

jahnavi

Hi,

Can you please  send me an example code that uses pin interchange to wake up the arduino.

Thanku very much

Jack Christensen


Hi,

Can you please  send me an example code that uses pin interchange to wake up the arduino.

Thanku very much


Code: [Select]
#include <avr/sleep.h>

void setup(void)
{
}

void loop(void)
{
}

void goToSleep()
{
   byte adcsra, mcucr1, mcucr2;

   sleep_enable();
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   PCICR = _BV(PCIE1);            //enable pin change interrupts 8-14
   PCMSK1 = _BV(PCINT8) | _BV(PCINT11) | _BV(PCINT12) | _BV(PCINT13);    //enable PCINT8,11,12,13 (PC0,3,4,5)
   adcsra = ADCSRA;               //save the ADC Control and Status Register A
   ADCSRA = 0;                    //disable ADC
   cli();
   mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
   mcucr2 = mcucr1 & ~_BV(BODSE);
   MCUCR = mcucr1;                //timed sequence
   MCUCR = mcucr2;                //BODS stays active for 3 cycles, sleep instruction must be executed while it's active
   sei();                         //ensure interrupts enabled so we can wake up again
   sleep_cpu();                   //go to sleep
                                  //wake up here
   PCICR = 0x00;                  //disable pin change interrupts 8-14
   PCMSK1 = 0x00;
   sleep_disable();
   ADCSRA = adcsra;               //restore ADCSRA
}

ISR(PCINT1_vect)
{
   PCICR = 0x00;                  //disable pin change interrupts 8-14
   PCMSK1 = 0x00;
}
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Kiwibird




Code: [Select]
#include <avr/sleep.h>

void setup(void)
{
}

void loop(void)
{
}

void goToSleep()
{
   byte adcsra, mcucr1, mcucr2;

   sleep_enable();
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   PCICR = _BV(PCIE1);            //enable pin change interrupts 8-14
   PCMSK1 = _BV(PCINT8) | _BV(PCINT11) | _BV(PCINT12) | _BV(PCINT13);    //enable PCINT8,11,12,13 (PC0,3,4,5)
   adcsra = ADCSRA;               //save the ADC Control and Status Register A
   ADCSRA = 0;                    //disable ADC
   cli();
   mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
   mcucr2 = mcucr1 & ~_BV(BODSE);
   MCUCR = mcucr1;                //timed sequence
   MCUCR = mcucr2;                //BODS stays active for 3 cycles, sleep instruction must be executed while it's active
   sei();                         //ensure interrupts enabled so we can wake up again
   sleep_cpu();                   //go to sleep
                                  //wake up here
   PCICR = 0x00;                  //disable pin change interrupts 8-14
   PCMSK1 = 0x00;
   sleep_disable();
   ADCSRA = adcsra;               //restore ADCSRA
}

ISR(PCINT1_vect)
{
   PCICR = 0x00;                  //disable pin change interrupts 8-14
   PCMSK1 = 0x00;
}



Is this code work with Uno?

Jack Christensen

#11
May 31, 2013, 02:39 pm Last Edit: May 31, 2013, 02:41 pm by Jack Christensen Reason: 1

Is this code work with Uno?


Yes, but only modest power savings will be realized with an Uno due to the on-board support circuitry. See: http://forum.arduino.cc/index.php?topic=164146.msg1232507#msg1232507
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Kiwibird

#12
Jun 05, 2013, 05:35 pm Last Edit: Jun 05, 2013, 05:42 pm by Kiwibird Reason: 1

Yes, but only modest power savings will be realized with an Uno due to the on-board support circuitry. See: http://forum.arduino.cc/index.php?topic=164146.msg1232507#msg1232507


Code: [Select]
#include <avr/power.h>
#include <avr/sleep.h>


void setup(void)
{
 
 Serial.begin(9600);
}

void loop(void)
{
 while (Serial.available() > 0)
   {
        char ch;
     ch = Serial.read();
     Serial.print(ch);
     if (ch == '!')
       {
           
          Serial.print('!');
         
          delay(200);
       }
   }
   goToSleep();
}

void goToSleep()
{
   byte adcsra, mcucr1, mcucr2;

   sleep_enable();
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   PCICR = _BV(PCIE1);            //enable pin change interrupts 8-14
   PCMSK1 = _BV(PCINT8) | _BV(PCINT11) | _BV(PCINT12) | _BV(PCINT13);    //enable PCINT8,11,12,13 (PC0,3,4,5)
   adcsra = ADCSRA;               //save the ADC Control and Status Register A
   ADCSRA = 0;                    //disable ADC
   cli();
   mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
   mcucr2 = mcucr1 & ~_BV(BODSE);
   MCUCR = mcucr1;                //timed sequence
   MCUCR = mcucr2;                //BODS stays active for 3 cycles, sleep instruction must be executed while it's active
   sei();                         //ensure interrupts enabled so we can wake up again
   sleep_cpu();                   //go to sleep
                                  //wake up here
   PCICR = 0x00;                  //disable pin change interrupts 8-14
   PCMSK1 = 0x00;
   sleep_disable();
   ADCSRA = adcsra;               //restore ADCSRA
}

ISR(PCINT1_vect)
{
   PCICR = 0x00;                  //disable pin change interrupts 8-14
   PCMSK1 = 0x00;
}




on serial monitor:

!!
(but no massage)
try to use this code with xbee, but it didn't get any data. Where did I go wrong?

Jack Christensen


on serial monitor:

!!
(but no massage)


What message were you expecting? It would seem that "!" must have been received, which would cause "!!" to be output.

Quote

try to use this code with xbee, but it didn't get any data. Where did I go wrong?


Hard to say without seeing the code and schematics for both sending and receiving ends. What is the purpose of delay(200)? What is the purpose for going to sleep, and what will wake the MCU?

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Kiwibird

#14
Jun 06, 2013, 02:58 pm Last Edit: Jun 06, 2013, 03:06 pm by Kiwibird Reason: 1


Hard to say without seeing the code and schematics for both sending and receiving ends. What is the purpose of delay(200)? What is the purpose for going to sleep, and what will wake the MCU?



I'm sorry about my last post. I'm now manage to get the code to work with the xbee on the xbee shield.
Problem is I only know where to connect VCC, Dout, Din and ground. I'm looking for the way to put the whole thing on bread board.

can you please tell me a little bit more about the pin wake up code


Can you please give me some advice with pin of xbee that actually waking up the atmega328.  Where should that pin on xbee connect to the MCU pin.


Thank you so much
Kiwi

Go Up