Using the Xbee to sleep Arduino

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

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.

"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.

Pin change interrupt?

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

CrossRoads:
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:

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.

Good to know!

Hi,

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

Thanku very much

jahnavi:
Hi,

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

Thanku very much

#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?

Kiwibird:
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: When sleeping helps - #34 by JChristensen - Microcontrollers - Arduino Forum

#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?

Kiwibird:
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.

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?

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