Hey guys ![]()
Prank Wars started early this year, so i tried to improve upon my old annoyatron.
main differences are: only one unified timer interrupt using WDT and WDT_ADLY_1000 and the possibility to put the thing into sleep mode e.g. you can set a time in hours minutes and seconds until the annoyatron becomes active. good for hiding.
my main concerns are :
- is there any way to improve the WDT timer accuracy without using ACLK
- is the code energy efficient? how much current does it eat, i don't have a scope and cannot check things like that
![:(]()
- how would one immitate a locust chirp ?
any feedback is welcome ![]()
#include "msp430g2231.h"
#define PIEZO BIT6
#define LED1 BIT0
#define TRUE 1
#define FALSE 0
unsigned short lfsr = 0xACE1u;
short hours = 0;
short minutes = 10;
short seconds = 0;
short sleeping = TRUE;
unsigned int getRnd (void);
void timer (void);
void initPWM (void);
unsigned i=0;
int LPMMode = 0;
void main(void)
{
BCSCTL3 |= LFXT1S_2; // Set VLO
WDTCTL = WDT_ADLY_1000; // Set WDT to timer mode at 1000ms, with VLO this is 2740ms
IE1 |= WDTIE; // Enable WDT+ interrupt
P1DIR |= PIEZO + LED1; // P1.2 PWM output/P1.6 constant output
P1OUT = 0;
unsigned int delay = 1;
while(TRUE)
{
if (sleeping) {
P1OUT ^= LED1;
} else {
P1OUT ^= LED1;
}
if (i>delay && !sleeping )
{
CCTL1 = OUTMOD_6; // Start P1.2 PWM output
// WDTCTL = WDT_ADLY_250; // Reset WDT+ timer to 250ms, with VLO source this is 685ms
LPMMode = 0;
_BIS_SR(LPM0_bits + GIE); // Go to sleep
CCTL1 = OUTMOD_0;
i=0;
delay = (getRnd() >> 7);
}
LPMMode = 3;
_BIS_SR(LPM3_bits + GIE);// Enter LPM3 w/ interrupt
}
}
// WDT+ ISR for time between beeps and reset for beep length
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer (void)
{
if (sleeping) {
LPMMode = 0;
i = 0; // keeps or counter from overflowing
// without having to put more stuff into the isr
seconds -= 3;
if ( seconds <= 0) { // count down timer until deployment
// we are compensating for the LARGELY inaccurate vlo
seconds = 60;
if (minutes--<= 0) {
minutes = 60;
if (hours-- <= 0) {
sleeping = seconds = minutes = hours = FALSE;
P1SEL |= PIEZO;
CCR0 = 42; // Set PWM parameters, CCR0 is PWM Period/2
CCR1 = 21; // Duty cycle
TACTL = TASSEL_2 + MC_3;
}
}
}
} else {
i++;
}
if(LPMMode == 3)
_BIC_SR_IRQ(LPM3_bits);
else if(LPMMode == 0)
_BIC_SR_IRQ(LPM0_bits);
}
unsigned int getRnd ()
{
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
return lfsr;
}
thanks,
lastaid
