Project

General

Profile

Resolved: Conflict between interrupts to wake from sleep and RF12

Added by Davebmiller almost 5 years ago

I’m building a timer that broadcasts when the clock is started, and I need it to run on batteries for an extended period. I can get the JeeNode to sleep and wake when an interrupt is activated, but I can’t get the interrupt wake to work with the radio - so I’m stuck without sleeping.

/*************************************************** 
Jeenode seven segment timer with broadcast

based on code from JeeLabs (JeeNode) and Adafruit (LED Backpack)


****************************************************/


#include 

//JeeLabs libraries
#include 
#include 
#include 
ISR(WDT_vect) {   Sleepy::watchdogEvent(); } //internal watchdog timer

//adafruit LEDBackpack
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_7segment matrix = Adafruit_7segment();

//global variables
static int pushButton = 4; // JeeNode DIO1 = Arduino DIO 4
static int duration = 10; //timer run in seconds
int count = 0; //storage for how many seconds remaining
long previousMillis = 0;        // will store last time the display is updated
byte xmit = 99; //dummy variable to transmit
int nodeID = 10;
int groupID = 100;

//interlocks
boolean isClosed = false;
boolean isOpen = true;

void setup() {
  Serial.begin(57600);
  Serial.println("7 Segment Backpack timer");
  matrix.begin(0x70); //initialize screen

  //RF12 radio setup
  Sleepy::loseSomeTime(32);
  rf12_initialize(nodeID, RF12_915MHZ, groupID); //(nodeID, freq band, groupID)
  rf12_sleep(RF12_SLEEP);
  // wait another second for the power supply to settle
  Sleepy::loseSomeTime(1000);

  pinMode(pushButton,INPUT);
  bitSet(PCMSK2,pushButton); //handler for interrupt
  bitSet(PCICR, PCIE2); //handler for interrupt
//  attachInterrupt(pushButton, wakeButton, RISING); //didn't work  - doesn't seem necessary with the PCIR and PCMSK lines

}

void loop() {
//  //button listener - latching to solve the problem if sleep and interrupt doesn't work
//  if(digitalRead(pushButton)==1){
//    count = duration; //reset the count
//    isClosed = true;
////    broadcast();
//    Serial.println("button");
//  }
//  else{
//    isOpen = true;
//  }
//  
//  if (isOpen == true && isClosed==true){
//    broadcast();
//    isClosed = false;
//    isOpen = false;
//  }


  unsigned long currentMillis = millis();

  //update the display if count is >0
  if(count >= 0){  
      updateDisplay(count); //update the display with current count
    }
  else {
    matrix.clear();
    matrix.writeDisplay(); //turn off display (not sure if it uses much power in this state)
    Serial.println("going to sleep");
    //Sleepy::loseSomeTime(10000);
    Sleepy::powerDown();
  }

  if(currentMillis - previousMillis > 1000) {
    // save the last update time
    previousMillis = currentMillis;   
    count--; //decrement the count ... ah ah ah
  }
}

//wakeup with the interrupt
ISR(PCINT2_vect) { 
  wakeButton(); 
}

void wakeButton(){
    //button listener
    count = duration; //reset the count
    Serial.println("button");
    broadcast();
}

//display on 7-segment LED panel
void updateDisplay(uint16_t counter){
  matrix.setBrightness(10); //full on
  matrix.writeDigitNum(1, (counter / 60) % 10); //minutes
  matrix.writeDigitRaw(2,0x2); //draw the colon
  matrix.writeDigitNum(3, (counter / 10) % 6); //tens seconds
  matrix.writeDigitNum(4, counter % 10); //ones seconds
  matrix.writeDisplay();
}

// broadcast nodeID via RF12
void broadcast(){
  rf12_sleep(RF12_WAKEUP); //turn on radio
  rf12_sendNow(0, &xmit, 1); //transmit packet
  rf12_sendWait(1);
  rf12_sleep(RF12_SLEEP); //turn off radio
}

Replies (3)

RE: Conflict between interrupts to wake from sleep and RF12 - Added by JohnO almost 5 years ago

Eekh, what a big ask. I think printing inside your interrupt routine is a problem, maybe flash an LED or set a flag and test it outside of the interrupt routine. As you know INT0 is used by the radio but INT1 is on all the IRQ pins on each JeeNode port. To use DIO4 you may want to take a look at pin change interrupts. I believe the millis counter stops when the Jeenode goes to sleep loosing track of time for you. You could try sleeping for 1 - 8 seconds and then waking up to increment your perception of time. If you keep your interrupt routine slim you won’t use much battery.

RE: Conflict between interrupts to wake from sleep and RF12 - Added by Davebmiller almost 5 years ago

Problem solved!

  1. reassigning the wake-up button interrupt to not conflict with the radio
  2. not calling broadcast() from in the ISR —nesting interrupts crashes the processor.

working code attached

RE: Conflict between interrupts to wake from sleep and RF12 - Added by JohnO almost 5 years ago

Nice one, interrupts are amazing things. Thanks for posting your working code.

    (1-3/3)