Sign in to follow this  
Followers 0
lastaid

Annoy A Tron 2.0

7 posts in this topic

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

 

main.c

bluehash likes this

Share this post


Link to post
Share on other sites

And yet again, i had to rework it a little.

Features now include :

 

  • Adjustable delay before device becomes armed
  • LED indicator that the device has power and has entered sleep mode
  • The seed for the PRNG are sourced from a a floating pin, 
  • Its a state machine :smile:

As with the last post, i'd really welcome some ideas especially concerning accuracy of the clock and power saving. But i think it might run a while on a cr2032 coincell.

#include "msp430g2231.h"

#define PIEZO BIT6
#define LED1 BIT0

#define TRUE 1
#define FALSE 0

#define STATE_SLEEPING 1
#define STATE_NOTIFY 2
#define STATE_ARMED 3
#define STATE_ANNOYING 4

unsigned short lfsr = 0xACE1u;

short hours = 0;
short minutes = 10;
short seconds = 0;

short state = 0;


unsigned int getRnd (void);
void timer (void);
void initPWM (void);
short getRandom(void);

unsigned i=0;
int LPMMode = 0;
void main(void)
{
	state = STATE_NOTIFY;
	BCSCTL3 |= LFXT1S_2;                  // Set VLO

	WDTCTL = WDT_ADLY_250;                // Set WDT to timer mode at 250ms, with VLO this is 2740 / 4ms
	IE1 |= WDTIE;                        // Enable WDT+ interrupt

	P1DIR |= PIEZO + LED1;                     // P1.2 PWM output/P1.6 constant output
	P1OUT = 0;

	lfsr = getRandom(); // initiate lfsr randomly

	unsigned int delay = 1;
	while(TRUE)
	{
		switch( state ) {
			case STATE_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) {
							state = STATE_ARMED; // time has run out, lets go to armed
							P1SEL |= PIEZO;
							CCR0 = 42;                           // Set PWM parameters, CCR0 is PWM Period/2
							CCR1 = 21;                           // Duty cycle
							TACTL = TASSEL_2 + MC_3;
						}
					}
				}
				break;
			case STATE_NOTIFY :
				P1OUT ^= LED1;
				if (i++ >= 5) {
					state = STATE_SLEEPING;
					P1OUT &= ~LED1;
					i = 0;
					WDTCTL = WDT_ADLY_1000;                // Set WDT to timer mode at 1000ms, with VLO this is 2740ms
				}
				break;
			case STATE_ARMED :
				if ( i++ >= delay ) state = STATE_ANNOYING;
				break;
			case STATE_ANNOYING :
				state = STATE_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);

				break;
		}
		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(LPMMode == 3)
		_BIC_SR_IRQ(LPM3_bits);
	else if(LPMMode == 0)
		_BIC_SR_IRQ(LPM0_bits);
}

unsigned int getRnd (void)
{
	lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
	return lfsr;
}

short getRandom(void){
	ADC10CTL1 |= INCH_5;
	ADC10CTL0 |= SREF_1 + ADC10SHT_1 + REFON + ADC10ON;
	ADC10CTL0 |= ENC + ADC10SC;
	while(ADC10CTL1 & ADC10BUSY);
	return ADC10MEM;
}

considering flash size, the 2231 is providing quite a lot of room for improvement.

Text: 724 bytes Data: 4 bytes.

you guys have fun,

 

lastaid

main.c

Share this post


Link to post
Share on other sites

Hey :),

 

Ok, i am currently building 2 kinds of annoyatrons, one being very small an having a high annoy frequency ( delay between beeps) and the other one a huge annoyatron that rarely beebs but is insanly loud and has oversized batteries because i was afraid that a coincell might not provide enough juice and the mcu would brownout.

 

the big version can be attached to anything metal thanks to a harddrive donored magnet. the small one will fit in a matchbox so it can be hidden in plain sight.

 

http://youtu.be/90sXqgu-0XA here is a video of the breadboard circuit in action, the beep is somewhere around 0:53 and might not be audible on some speakers.

 

still wondering how much power this circuit really draws.

 

-lastaid

post-161-0-00766100-1377259110_thumb.jpg

post-161-0-08966800-1377259176_thumb.jpg

post-161-0-62731600-1377259207_thumb.jpg

abecedarian, GeekDoc and bluehash like this

Share this post


Link to post
Share on other sites

I might need to completly rework this thing. It seems like a problem you might only confronted with in warfare, but if a friend finds this annoyatron and deploys it in your flat, which is way messier due to electronic projects and part bins lying around, you're fucked.

 

i am currently thinking about making an enclosure that is conductive, uses a pin with cap touch capabilities to check if the device was found and then writes a certain value to flash which disables the annoyatron even if it is restartet. that way only someone with a programmer could re-use it.

 

this on the other hand might interfere with the low power idea, but i don't have any idea how much energy touch i/o actually eats.

 

any suggestions?

 

lastaid

GeekDoc likes this

Share this post


Link to post
Share on other sites

I might need to completly rework this thing. It seems like a problem you might only confronted with in warfare, but if a friend finds this annoyatron and deploys it in your flat, which is way messier due to electronic projects and part bins lying around, you're f-ed.

 

As in any fight, you don't want to lose control of your weapon!  Good idea on the failsafe.  I hope it works.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0