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.
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.
No comments:
Post a Comment