The atmega gets stuck with a soft/hard modification

Hello all,

This is my first post. Amazing work done here! Congratulations!

I am developing a new board based on emonTX. It will be in sleep mode most part of the time to save energy because it is powered by a battery. For this, I am using “Sleepy::loseSomeTime();” function from JeeLib.h library in the loop. This works perfect.

The problem is when I implement an external interrupt and I want to send an RF message when it occurs. The software gets stuck at runtime and no clue what it is happening…

Here is a simple code of the Atmega168:

#include <JeeLib.h>  


// ------------------- RF setup  ----------------------

#define freq RF12_868MHZ 
const int nodeID = 1;  // emonTx RFM12B node ID
const int networkGroup = 7;  // emonTx RFM12B wireless network group 
unsigned long lastsendtime = 0;
unsigned long sendinterval = 2000; // milliseconds

// ----------------- Data setup  ---------------------   
                                           
typedef struct { 
   bool door_open : 1;
   int batery_level;    // in mV
} Tx_struct;            // data for RF comms
Tx_struct tx_data;

// ----------------- Interrupt setup  ---------------------  

ISR(WDT_vect) { Sleepy::watchdogEvent(); }      // Setup the watchdog
const byte interruptPin = 3;                    // INT1 --> digital pin 3 for interruption (hall sensor)
 


void setup() {
  
  delay(20);
  rf12_initialize(nodeID, freq, networkGroup);     // initialize RF
  rf12_sleep(RF12_SLEEP);

  attachInterrupt(digitalPinToInterrupt(interruptPin), interrupt_, RISING);       //door open interrupt
  
  Serial.begin(57600);                              // initialize Serial interface
  Serial.println();
  Serial.println("---------------------------------------");
  Serial.println("Nodo de detección de apertura de puerta");
  Serial.println("Nodo 1 en red 7 a 868Mhz");
  Serial.println("---------------------------------------");
  delay(100);
  
  tx_data.door_open = 1;
  tx_data.batery_level = 77;

}

void loop() {
  
 //Sleepy::powerDown();


   Sleepy::loseSomeTime(2000); 

   Serial.println(tx_data.door_open);
   Serial.flush();
}

void interrupt_()
{
  
  Serial.println("Sending data...");
  Serial.flush();
  
  send_rf_data();   //Send the data --> If I uncomment this, the software works perfect

}

void send_rf_data()
{
  rf12_sleep(RF12_WAKEUP);
  // if ready to send + exit route if it gets stuck 
  int i = 0; 
  while (!rf12_canSend() && i<10)
  { 
    rf12_recvDone(); 
    i++;
  }
  rf12_sendStart(2, &tx_data, sizeof tx_data);
  rf12_sendWait(2);
  rf12_sleep(RF12_SLEEP);
}  

Thank you in advance for your time!!

Regards!

David.

PD: I made a new post because I could not find something related with my problem.

You really should not be printing and sending data inside the interrupt service routine. Your ISR should set a flag, then the main loop should see the flag and do the printing and sending of data. Then, after allowing enough time for all the data to be sent (which might be some time after rf_send_data() returns), you can reset the flag and go back to sleep.

I can’t remember offhand which interrupts JeeLib uses, but I’d be checking to see if it goes to sleep before it’s completed the transmission, and getting tangled up that way.

Hello Robet,

Thank you for your quick reply. You are right, my code is not a good practice :sweat:
Now solved :wink:

Best regards,

David.