Sunday, December 7, 2014

Project: Motion Sensing over wireless link using MSP430 and Anaren Booster Pack

In a previous post, problem of finding suitable programming environment for the Anaren Booster Pack has been discussed; we talked about how easy it was to program MSP430 using the Energia environment. In the newer versions of Energia 0101E0013 (09/05/2014), Anaren has included a library with some cool functions and couple of code examples for sensor-hub communication, control example, and simple wireless communication test example. Stay tuned to read a nice post about a simple modification to Anaren code to include acknowledgment mechanism. But for this post will cover a cool project that I was asked to do.

Requirements were simple: we have a TV connected to a security camera (camera always on). Turn TV ON whenever motion happens in a certain area. To safe power, TV had to be turned OFF when no motion is detected for a specified period.  


Remember in a previous post you have seen how to program a pair of TI MSP430 Microcontroller Units (MCU) to communicate motion detection event coming from Passive Infra Red (PIR) sensor. Well, this is just what we are going to do in this cool project. One end, where motion is to be detected, will have a PIR sensor connected to MSP430 MCU plus Anaren Booster Pack RF module in order to communicate motion detection event to the other end. On the TV/Security camera end we have to turn the TV ON when receiving a signal on the RF module. While first thing comes into your mind is a RELAY to turn TV ON, remember that now days all TV’s need to be turned on using an IR remote even if the power source is on!! To satisfy your curiosity, yes we will have a post about using a relay to turn TV. In that project, my contribution was only the part of turning TV on using Infra Red (IR) signal coming from IR LED connected to the MCU after the relay turns power source on; stay tuned to see how to get MCU acting like a remote!! This post will only deal with the end composed of MSP430 LaunchPad, PIR sensor and the Anaren Booster Pack. 





Figure 1 TI MSP430 LuanchPad, Anaren Booster Pack inside the enclosure

 First thing is to decide program structure, next we can talk about the choosing enclosure, mounting, and power supply. As mentioned above, code examples published by Anaren included a sensor-hub example code; this is exactly what we need. The sensor will send data and hub will receive data; we can choose to have the hub acknowledging sensor’s packets but this project did not go this direction, we will talk more about using an acknowledgment in the end of this post. Since one requirement is to count no motion period, we have to use timers. Since MSP430 is busy with counting (timer), we can not afford to have the MCU waiting on a positive edge from PIR (when it detects motion); interrupts will be the best choice to alarm for a positive edge. Next, we get to choose the pin on MCU to connect to PIR output. Note that some pins do not have interrupt enabled, and some pins are used by the Anaren Booster Pack. This leaves us with very limited choice, either pin 1_3 or pin 2_3. In our code we choose pin 1.3 which is defined as PUSH2 in Energia, it happens to be connected to a push button on TI LaunchPad. Next, lets us choose the timer; note that we need to measure periods in order of minutes when counting no motion period. This means the timer should drive its clock from a low frequency oscillator; MSP430 has many choices for oscillator. MSP430 runs its system clock of 1.1MHz oscillator, but the best thing with MSP430 is you can run multiple oscillators same time.  You can have a 1.1Mhz oscillator as the source of the system clock and anther low frequency oscillator for peripherals.For a low frequency , the VLO oscillator is one choice, it runs somewhere around 12KHz, and the second choice would be to attach an external crystal, the one supplied with TI Launchpad provide 32KHz clock. VLO was the choice for this setup, and this allows a timer as long as 40seconds.  If you allow the timer to overflow certain number of times you can get the time period you like; allowing the timer to overflow 15 times will allow periods of10 minutes. Well, this is it about the program structure. Below is code:

#include <SPI.h>
#include <AIR430BoostFCC.h>
// -----------------------------------------------------------------------------
/**
 *  Defines, enumerations, and structure definitions
 */
#define ADDRESS_LOCAL    0x02
#define ADDRESS_REMOTE   0x01
#define PIR_Settling_Time 20000 //Allow PIR learn its environment up to 40sec (datasheet)
#define CC110L_Settling_Time 5000//Startup time between MSP430 and CC110L
 /**
 *  sPacket - packet format.
 */
struct sPacket
{
  uint8_t from;           // Local node address that message originated from
  uint8_t message[1];    // Local node message
};

// -----------------------------------------------------------------------------
/**
 *  Global data
 */
 struct sPacket txPacket;
volatile boolean Lockhigh=true;
volatile unsigned char counter = 0;
 // -----------------------------------------------------------------------------
// Main example

void setup()
{
     //Allow setup time for PIR and CC110L
     if (PIR_Settling_Time>CC110L_Settling_Time){
      delay(PIR_Settling_Time);}
       else{delay(CC110L_Settling_Time);}
  /**
   * 
   *  Note: Set radio first to ensure that GDO2 line isn't being driven by the
   *  MCU as it is an output from the radio.
   */
    Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX);

  txPacket.from = ADDRESS_LOCAL;
  memset(txPacket.message, 0, sizeof(txPacket.message));

   WDTCTL = WDTPW + WDTHOLD;      // stop WDT
  
   pinMode(PUSH2,INPUT);//P1.3 is PIR input
   attachInterrupt (PUSH2, Port_1, CHANGE);//activate interrupt on pin P1_3
   P1DIR = BIT0; // set P1.0 as output (RED LED on LaunchPad)
   P1OUT =~BIT0;// Turn OFF RED LED
     
   BCSCTL1 = CALBC1_1MHZ;    // Set DCO to calibrated 1 MHz.
   DCOCTL = CALDCO_1MHZ;
   BCSCTL3 =LFXT1S_2;   //Set VLO
   TACCR0 = 60000 - 1;    // A period of 60,000 cycles (~40sec@VLO)
   TACCTL0 = CCIE;        // Enable interrupts for CCR0.
   TACTL = TASSEL_1 + ID_3 + MC_1 + TACLR;  // ACKL, div 8, up mode,clear timer
 
}

void loop()
{
 
}

//// Timer A interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A()
{
       if(counter == 10 & !Lockhigh ) {// this is when the PIR indicate no motion for 10min
        counter = 0;
        txPacket.message[1] = 'O';
        Radio.transmit(ADDRESS_REMOTE, (unsigned char*)&txPacket, sizeof(txPacket));
        P1OUT =~BIT0; // RED LED OFF
        Lockhigh=true;
       }
        else {// this is when PIR indicate motion or while no motion w/time <Total Wait Time
         counter++;
            
      }
}
  
// Port 1 interrupt service routine
//__interrupt void Port_1()
void Port_1(void)
{
 
   if (digitalRead(P1_3) && Lockhigh){
   P1OUT = BIT0; // Trun on RED LED in case of motion being detected
   txPacket.message[1] = 'A';//
   Radio.transmit(ADDRESS_REMOTE, (unsigned char*)&txPacket, sizeof(txPacket));
   Lockhigh=!Lockhigh;//Toggel Lock (indicate no motion period /end of no motion period)
   }
    else {counter=0;}//any other signal from PIR rests timer
 }


Next, we will talk about the final product including hardware, enclosure, mounting and power source. Note that Anaren Booster Pack can be a stand alone; you can mount the TI MSP430G2553 onto the board and connect led, push button and power supply with some capacitors, please see Figure 2 below from Anaren manual. In this project, soldering surface mount components was not possible; the final product used LuanchPad to hold the MCU and Anaren Booster Pack as shown in figure 1 above. Since PIR sensor has to sticking outside the mount, you need to choose a mount with flat surface on one side. Drill through the flat surface a hole such you can mount the PIR sensor with its lens outside as shown in figure 3. Note in this figure; the power source is sticking to the side of the enclosure; a simple phone charger with USB output has been used.
 
Figure 2 Picture courtesy of Anaren
Figure 3 Enclosure with PIR sensor sticking out of it


Trouble shooting:
Possible problems that you may face are as follow
1-      Failed communication between the unit holding the sensor and unit responsible for turning TV ON. If this happens you will note indicator led, shown in figure one above, tuned ON while the TV is OFF or visa versa. Just rest the unit by unplugging the power from the unit with PIR and make sure the TV is turn off .Then plug power to the MCU connected to PIR, make sure to allow some period of no motion while the PIR learns the environment.
2-       Wires are loose; this may happen and it will cause the unit to not function correctly. Refer to figure 1 for correct connection and secure the wire to pins.
3-      Infra Red LED on the unit responsible for turning TV ON may get out of focus with the Infra Red detector on the TV. Just make sure the Infra Red LED on the MCU is in front of the Infra Red detector on the TV.
4-      If MCU goes bad then they can be replaced and programmed via the LaunchPad using the code provided.


Please stay tuned to read a nice post about a simple modification to Anaren sample code to include acknowledgment mechanism.


No comments:

Post a Comment