2013-06-28 3 views
0

Я создал sketch, который использует сторожевой таймер, который запускается каждые восемь секунд. Я использовал счетчик, чтобы подождать 64 секунды (около минуты).Передача XBee и сторожевого таймера не работает

Кроме того, я использовал режим спящего режима на XBee. Связь XBee вместе с синхронной спящей работает правильно. Если я добавлю watchdog timer, он перестанет работать. Перезагружена ли программа из последней строки, выполняемой до прерывания сторожевого таймера?

#include <avr/sleep.h> 
#include <avr/power.h> 
#include <avr/wdt.h> 
#include <XBee.h> 

XBeeAddress64 coordAddr = XBeeAddress64(0x0013a200, 0x4090c5a6); 
uint8_t xbeePayload[] = "Hello"; 
XBee xbee = XBee(); 

ZBTxRequest zbTx = ZBTxRequest(); 
ZBTxStatusResponse txStatus = ZBTxStatusResponse(); 

int XBee_pin = 9;   // This pin wakes up the XBee and puts it to sleep. 
int counter = 0; 

void sendData() { 
    zbTx.setAddress64(coordAddr); 
    zbTx.setAddress16(0xFFFE); 
    zbTx.setPayload(xbeePayload); 
    zbTx.setPayloadLength(sizeof(xbeePayload)); 
    xbee.send(zbTx); 
} 

ISR(WDT_vect) 
{ 
    counter++; 
} 

void enterSleep(void) 
{ 
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
    sleep_enable(); 

    /* Now enter sleep mode. */ 
    sleep_mode(); 

    /* The program will continue from here after the WDT timeout */ 
    sleep_disable(); /* First thing to do is disable sleep. */ 

    /* Re-enable the peripherals. */ 
    power_all_enable(); 
} 

void setup() 
{ 
    // To reduce power, setup all pins as inputs with without any pullups 
    /*for(int x = 1 ; x < 18 ; x++){ 
      pinMode(x, INPUT); 
      digitalWrite(x, LOW); 
    }*/ 

    pinMode(XBee_pin, OUTPUT); 
    digitalWrite(XBee_pin, HIGH); 
    xbee.begin(9600); 
    delay(5000); 

    /*** Setup the WDT ***/ 

    /* Clear the reset flag. */ 
    MCUSR &= ~(1 << WDRF); 

    /* In order to change WDE or the prescaler, we need to 
    * set WDCE (this will allow updates for 4 clock cycles). 
    */ 
    WDTCSR |= (1 << WDCE) | (1 << WDE); 

    /* Set new watchdog timeout prescaler value */ 
    WDTCSR = 1 << WDP0 | 1 << WDP3; /* 8.0 seconds */ 

    /* Enable the WD interrupt (note no reset). */ 
    WDTCSR |= _BV(WDIE); 

    //Serial.println("Initialisation complete."); 
    //delay(100); //Allow for serial print to complete. 

    ADCSRA &= ~(1 << ADEN); //Disable ADC 
    ACSR = (1 << ACD); //Disable Analog Comparator 
    DIDR0 = 0x3E; //Disable digital input buffers on ADC1-ADC5 pins 
    DIDR1 = (1 << AIN1D)|(1 << AIN0D); //Disable digital input buffer on AIN1/0 

    power_twi_disable(); 
    power_spi_disable(); 
    power_usart0_disable(); 
    //power_timer0_disable(); //Needed for delay_ms 
    power_timer1_disable(); 
    power_timer2_disable(); 
} 

void loop() 
{ 
    if(counter == 8) 
    { 
     counter = 0; 
     pinMode(XBee_pin, OUTPUT); 
     digitalWrite(XBee_pin, LOW); 
     delay(5000); 
     sendData(); 
     delay(2000); 
     pinMode(XBee_pin, INPUT); 
     digitalWrite(XBee_pin, HIGH); 

     /* Re-enter sleep mode. */ 
     enterSleep(); 
    } 
} 

ответ

0

enterSleep() должен находиться вне оператора if. Ваша текущая реализация вращается в loop(), ждет 8 тайм-аутов сторожевого таймера, выполняет код один раз, спит, просыпается и делает тот же самый оборот. Код должен выглядеть так, как я полагаю.

void loop() 
{ 
    if(counter == 8) 
    { 
    counter = 0; 
    pinMode(XBee_pin, OUTPUT); 
    digitalWrite(XBee_pin, LOW); 
    delay(5000);  
    sendData(); 
    delay(2000); 
    pinMode(XBee_pin, INPUT);  
    digitalWrite(XBee_pin, HIGH); 
    } 
    /* Re-enter sleep mode. */ 
    enterSleep(); 
} 

Кроме того, имейте в виду, что сторожевой таймер по-прежнему работает во время задержек. Это может вызвать еще раз во время, если заявление, вы должны выдать wdt_reset() в нескольких местах, таких как:

void loop() 
{ 
    if(counter == 8) 
    { 
    counter = 0; 
    pinMode(XBee_pin, OUTPUT); 
    digitalWrite(XBee_pin, LOW); 
    delay(5000); 
    wdt_reset(); 
    sendData(); 
    wdt_reset(); 
    delay(2000); 
    pinMode(XBee_pin, INPUT);  
    digitalWrite(XBee_pin, HIGH); 
    } 
    /* Re-enter sleep mode. */ 
    enterSleep(); 
} 
+0

Я не уверен, что это собирается занять менее 8 секунд ... Я думаю, что это должно быть лучше временно отключить сторожевой таймер ... что вы мне предлагаете? – kip

+0

Трансмиссия теперь работает. Это эскиз: http://pastebin.com/tFt2vJRm Он использует некоторые варианты энергосбережения, спящий режим для выводов xBee и режим power_done. Проблема в том, что мне нужно дождаться действительно долгого времени (около 10 секунд), прежде чем я могу отправить пакет. Где я ошибаюсь? – kip

+0

Какой модуль xBee вы используете? Я хочу посмотреть, могу ли я создать что-то, что будет использовать прерывание + сторожевой таймер (таймер безопасности), чтобы вы могли спать микро в ожидании появления xBee. – James