Home/Support/Support Forum/Irregular Serial communication between MC and XBee

Irregular Serial communication between MC and XBee

0 votes
I've been working on a small Home automation project involving XBee nodes.
One of the sensors will only detect if windows/doors (or whatever that has a door) is open or close. It's fairly simple to build with reed switches, but everything gets more complicated when you want to run it on batteries and well... you want the batteries to last.

To save battery, I've set the XBee to Pin sleep, controlled by a ATTiny84A at 8MHz(initially I used a ATTiny85 at 1MHz, but soon realised I needed more A/D pins to simulate serial communication).

Given that the door is not always opening and closing, specially on the vacation periods, I wanted to make sure that, when the XBee is awaken by the MC, I wait enough time so that it is able to pair with the controller(or router) before any information is sent. In order to control that timing, I decided to configure the XBee as a API End Node, and use a slightly modified version (I'll get to that) of the Software Serial library on the ATTiny84A to read the status coming from the XBee. I've also configured XBee with RTS and CTS flow control, once again, managed with the MC.

Concerning the slightly modified Software Serial Library. In order to save battery power (once again) I also put the MC to sleep and programmed it to detect pin voltages changes to wake it up. Unfortunately the Software Serial library was making use of just to many pin interrupts...

//
// Interrupt handling
//

/* static */
inline void SoftwareSerial_mod::handle_interrupt()
{
if (active_object)
{
active_object->recv();
}
}

#if defined(PCINT0_vect)
ISR(PCINT0_vect)
{
SoftwareSerial_mod::handle_interrupt();
}
#endif

#if defined(PCINT1_vect)
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
#endif

#if defined(PCINT2_vect)
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
#endif

#if defined(PCINT3_vect)
ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
#endif

and the ATTiny84A pin interrupts available to detect pin voltages changes are only 2 and were already set as possible ones to be used by software serial. So basically, I commented in the interrupt pin number that I wanted to use for awaking the MC.

//
// Interrupt handling
//

/* static */
inline void SoftwareSerial_mod::handle_interrupt()
{
if (active_object)
{
active_object->recv();
}
}

#if defined(PCINT0_vect)
ISR(PCINT0_vect)
{
SoftwareSerial_mod::handle_interrupt();
}
#endif

// COMMENTED code *******************************
/*#if defined(PCINT1_vect)
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
#endif*/
// **********************************************

#if defined(PCINT2_vect)
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
#endif

#if defined(PCINT3_vect)
ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
#endif

My problem is the following... most of the times, everything works fine, but there are few times, let's say 5% I get the following behaviour:

After awaking I don't get any serial communication indicating the Xbee status (although on my tests the “association” was blinking, thus, the modem was associated actually associated. Normally at this point I request the Xbee for it's status, but sometimes (still within those 5%) it doesn't work also.

I wonder if commenting in the pin interrupt in the Software Serial library ended up by messing it that bad. It seems, but I'm possibly wrong, that it uses one of the possibly available... and I left all remaining ones uncommented.

Maybe I need to change the MC with one that has already dedicated serial TX/RX pins, or maybe it's something else, like the timing to read the serial data sent by the XBee (normally I wait 50 ms after waking it up before reading Serial communication... but anyway, I'm sort of controlling the flow with RTS/CTS, so...).

Any new new idea would be greatly appreciated.

Thanks.
asked Aug 15, 2016 in Miscellaneous Hardware and Software by cvicente New to the Community (6 points)

Please log in or register to answer this question.

1 Answer

+1 vote
You need to wait for CTS to go to a low state before you can query the radio. This is one of the stations where AT mode may actually be better than API. Or it may be better to switch to the Programmable S2C modules. This way you can use the low power function but use a known lib file to control and long and when the XBee module stays asleep with its 2nd processor.
answered Aug 18, 2016 by mvut Veteran of the Digi Community (12,786 points)
Hi mvut,

Thanks for answering.

I'm already checking CTS, actually in a kind-of-risky, because, if it never goes "LOW", I'll end-up in a endless loop:

// Method which sends the AT command "AI" (Association Indication)
void requestModemStatus(byte frameID){

  //char command[2] = {'A', 'I'};
  boolean goodResponse = false;
  unsigned short answerSize = 0, iter = 0;
  byte aux;
  byte at_command[8] = {0x7E, 0x0, 0x04, 0x08, frameID, 0x41/*A*/, 0x49/*I*/};

  //digitalWrite(led_ok, HIGH);
  while(digitalRead(ctsPin == HIGH)){
    continue;
    delay(20);
  }
  for(unsigned short i = 0; i < 7; i++){

    mySerial.write(at_command[i]);
    if(i > 2){
      at_command[7] += at_command[i];
    }
  }
  mySerial.write(0xFF - (at_command[7] & 0xFF));
}

But up until now, I haven't seen it happen. I could use S2C (rather new to me these modules). I wonder how much power will this second processor will waste. Thanks for the pointer.
Thank you for the resources...
I'll investigate!
...