Hi,
I have 2 boards both with XBee s2 and shield. One of them stays powered up the whole time (router) while other wakes up every so often (endpoint). Currently, I can POWER DOWN the AtMega328 chip using a watchdog timer, but this only gives me a maximum of 8 seconds power down time, before the watchdog counter wakes the chip up. So, for the future I plan to use a an external timer circuit to interrupt the ATMEGA processor on a pin.
Anyway before doing this I need to get the system working with the 8 second watchdog timer So I have the 2 arduinos with sheilds and XBees. The function of the 2 audrino boards:
The router just displays any data it received from the endpoint. That’s it. It’s on all the time.
The endpoint (arduino uno to be powered down) will:
Send some data
Sleep XBee
Powerdown chip (NOT sleep, power down, using watchdog timer) - will be powered down for 8 seconds
Wake XBee
Repeat
The procedure above crashes the endpoint and the XBee will just flash very fast for ever. If I remove the powerdown chip line of code, (so only XBee is slept), the system seems to work (after a connection has been established, it will continuously send data) which is seen by the router.
Please advise on how I can fix the problem! Has ANYBODY AN EXPERIENCE of doing this? To be honest I’m not even sure if XBee is being slept, but apparently pin 9 is the pin I need to write to to sleep the XBee. If possible can I power the XBee down any further?
Please help
Kiwi
Router:
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte; // a variable to read incoming serial data into
void setup() {
// initialize serial communication:
Serial.begin(9600);
Serial1.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// see if there's incoming serial data:
if (Serial1.available() > 0) {
// read the oldest byte in the serial buffer:
incomingByte = Serial1.read();
// if it's a capital H (ASCII 72), turn on the LED:
if (incomingByte == 'H') {
digitalWrite(ledPin, HIGH);
Serial.print('H');
}
// if it's an L (ASCII 76) turn off the LED:
if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
Serial.print('L');
}
}
}
Endpoint
#include <avr/sleep.h>
// This library contains functions to set various low-power
// states for the ATmega328
// This variable is made volatile because it is changed inside
// an interrupt function
volatile int sleep_count = 0; // Keep track of how many sleep
// cycles have been completed.
const int interval = 5; // Interval in minutes between waking
// and doing tasks.
const int sleep_total = (interval*60)/8; // Approximate number
// of sleep cycles needed before the interval defined above
// elapses. Not that this does integer math.
void setup(void) {
watchdogOn(); // Turn on the watch dog timer.
pinMode(13, OUTPUT);
Serial.begin(9600);
// The following saves some extra power by disabling some
// peripherals I am not using.
// Disable the ADC by setting the ADEN bit (bit 7) to zero.
ADCSRA = ADCSRA & B01111111;
// Disable the analog comparator by setting the ACD bit
// (bit 7) to one.
ACSR = B10000000;
// Disable digital input buffers on all analog input pins
// by setting bits 0-5 to one.
DIDR0 = DIDR0 | B00111111;
}
void loop(void) {
Serial.println("About to wake XBee");
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
Serial.println("XBee awake");
digitalWrite(13, HIGH); // turn the // wait for a second
Serial.println('H');
Serial.println("About to sleep XBee");
delay(2000);
pinMode(9, INPUT); // put pin in a high impedence state
digitalWrite(9, HIGH);
Serial.println("XBee powered down");
Serial.println("Board going asleep");
delay(2000);
// goToSleep();
// delay(2000);
Serial.println("Board awake");
delay(3000);
}
void goToSleep()
{
// The ATmega328 has five different sleep states.
// See the ATmega 328 datasheet for more information.
// SLEEP_MODE_IDLE -the least power savings
// SLEEP_MODE_ADC
// SLEEP_MODE_PWR_SAVE
// SLEEP_MODE_STANDBY
// SLEEP_MODE_PWR_DOWN -the most power savings
// I am using the deepest sleep mode from which a
// watchdog timer interrupt can wake the ATMega328
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.
sleep_enable(); // Enable sleep mode.
sleep_mode(); // Enter sleep mode.
// After waking from watchdog interrupt the code continues
// to execute from this point.
sleep_disable(); // Disable sleep mode after waking.
}
void watchdogOn() {
// Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
MCUSR = MCUSR & B11110111;
// Set the WDCE bit (bit 4) and the WDE bit (bit 3)
// of WDTCSR. The WDCE bit must be set in order to
// change WDE or the watchdog prescalers. Setting the
// WDCE bit will allow updtaes to the prescalers and
// WDE for 4 clock cycles then it will be reset by
// hardware.
WDTCSR = WDTCSR | B00011000;
// Set the watchdog timeout prescaler value to 1024 K
// which will yeild a time-out interval of about 8.0 s.
WDTCSR = B00100001;
// Enable the watchdog timer interupt.
WDTCSR = WDTCSR | B01000000;
MCUSR = MCUSR & B11110111;
}
ISR(WDT_vect)
{
sleep_count ++; // keep track of how many sleep cycles
// have been completed.
}