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.