Jump to content
43oh

MSP430 Annoyatron


Recommended Posts

this is beautiful :) and merciless :D

 

nice thing is without the crystal you can build tons of those with just an mcu [ 25c @1k ], 2 coin cells and one piezo. i wonder how much power it draws. on off switch could be a piece of paper between the coin cells paired with a prng starting var that maximizes the first interval.

 

i might try to build one deadbug style this weekend as small as possible :)

 

thanks for sharing,

 

lastaid

:P that's one of the main reasons why I want this. Combining the low price with a more basic piezo (not the Radioshack one) then I can just grab parts from my scrap bin and I assume those piezo speakers would be cheaper than the buzzer anyways. I need to try to get the other thing going to compile the other code.

Link to post
Share on other sites
  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

hey brian   i just played with your source a little. i really like the annoyatron, wanted to plant one on a friend for quite some time. i made a little change which would make it completly imposs

hi again,   fixed my code ^^   brian: do you use piezo that automaticly generates a sound? because your code just turn port 1.6 on, then off without any PWM   second: as the code uses timerA, ca

I'm not really sure how a piezo works, but i think you just power it and it generates sound, so no PWM is needed.   I also made a twist to the annoyatron on https://github.com/sergiocampama/Launch .

 

    #include "msp430g2001.h"

   #define PIEZO BIT6

   unsigned short lfsr = 0xACE1u;
   unsigned period = 0;         
   unsigned int getRnd (void);

   int i=0;
   void main(void)
   {
     WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
     P1DIR |= PIEZO;                            // P1.6 output
     BCSCTL3 |= LFXT1S_2;						// Set VLO
     CCTL0 = CCIE;                             // CCR0 interrupt enabled
     CCR0 = 12000;
     TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
     P1OUT = 0x00;
     unsigned int delay = 10;
     while(1)
     {
       if (i>delay)
       {
         P1OUT ^= PIEZO;                            // Toggle P1.6
         CCR1 = 800;			// Set 800 cycles to reset counter 12000 = 1sec length
         CCTL1 = CCIE;			// Enable CCR1 interrupt
         _BIS_SR(LPM3_bits + GIE);		//Go to sleep
         P1OUT ^= PIEZO;
         i=0;

         delay = getRnd() >> 7;
       }
       _BIS_SR(LPM3_bits + GIE);
                        // Enter LPM3 w/ interrupt
     }
   }

   // Timer A0 interrupt service routine for time between beeps
   #pragma vector=TIMERA0_VECTOR
   __interrupt void Timer_A (void)
   {
   i++;
   _BIC_SR_IRQ(LPM3_bits);
   }
   // Timer A1 ISR for beep length
   #pragma vector=TIMERA1_VECTOR
   __interrupt void Timer_B (void)
   {
   CCTL1 &= CCIE;
   _BIC_SR_IRQ(LPM3_bits);
   }

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

 

This is in CCS btw.

 

I edited this code so it would work with a g2553, getting it to work successfully while on the Launchpad. When I breadboard it with just 2 AA batteries, the MCU and a buzzer and it doesn't work.

 

I am stumped as to what I am doing wrong. Is there any reason why it'd work while on the launchpad but not by itself?

Link to post
Share on other sites
I am stumped as to what I am doing wrong. Is there any reason why it'd work while on the launchpad but not by itself?

 

Did you tie the reset pin to V+? I had forgotten to do that in mine too. Doh!

 

I edited the code again and still uses the 2001. This time, PWM driver output is on P1.0(uses ACLK for 12KHz) and constant beep output is on P1.6. I have another version that uses the WDT+ for polling and SMCLK for the PWM giving whatever frequencies you want but it isn't ready.

 

        #include "msp430g2001.h"

       #define PIEZO BIT6
       #define PWM BIT0

       unsigned short lfsr = 0xACE1u;
       unsigned period = 0;         
       unsigned int getRnd (void);

       int i=0;
       void main(void)
       {
         WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
         P1DIR |= PIEZO + PWM;                            // P1.6 output and P1.0 PWM
         BCSCTL3 |= LFXT1S_2;                  // Set VLO
         CCTL0 = CCIE;                             // CCR0 interrupt enabled
         CCR0 = 12000;
         TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
         P1OUT = 0x00;
         unsigned int delay = 10;
         while(1)
         {
           if (i>delay)
           {
             P1OUT ^= PIEZO;                            // Toggle P1.6
             P1SEL ^= PWM;			// Toggle P1.0 to ACLK 12kHz
             CCR1 = 1200;         // Set 800 cycles to reset counter 12000 = 1sec length
             CCTL1 = CCIE;         // Enable CCR1 interrupt
             _BIS_SR(LPM3_bits + GIE);      //Go to sleep
             P1OUT ^= PIEZO;
             P1SEL ^= PWM;			// Toggle off P1.0
             i=0;

             delay = getRnd() >> 7;
           }
           _BIS_SR(LPM3_bits + GIE);
                            // Enter LPM3 w/ interrupt
         }
       }

       // Timer A0 interrupt service routine for time between beeps
       #pragma vector=TIMERA0_VECTOR
       __interrupt void Timer_A (void)
       {
       i++;
       _BIC_SR_IRQ(LPM3_bits);
       }
       // Timer A1 ISR for beep length
       #pragma vector=TIMERA1_VECTOR
       __interrupt void Timer_B (void)
       {
       CCTL1 &= CCIE;
       _BIC_SR_IRQ(LPM3_bits);
       }

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

 

:P that's one of the main reasons why I want this. Combining the low price with a more basic piezo (not the Radioshack one) then I can just grab parts from my scrap bin and I assume those piezo speakers would be cheaper than the buzzer anyways. I need to try to get the other thing going to compile the other code.

 

The output you want is now on P1.0. P1.6 for buzzers.

Link to post
Share on other sites

This one has both outputs as well, but uses SMCLK for PWM output(doesn't sleep as well during beep but allows custom frequencies) but makes up for it by only waking up every ~2.7 seconds to see if it's time to beep. Uses WDT+ for interval timer so its limited to either 45ms or 685ms beeps (WDT_ADLY_16 and WDT_ADLY_250 respectively).

 

P1.2 for PWM, P1.6 for buzzer. Currently set to 12kHz but this can be changed via CCR0 and CCR1 values.

 

    #include "msp430g2001.h"

   #define PIEZO BIT6
   #define PWM BIT2

   unsigned short lfsr = 0xACE1u;
   unsigned period = 0;         
   unsigned int getRnd (void);

   int i=0, 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 + PWM;                     // P1.2 PWM output/P1.6 constant output
     P1OUT = 0;
     P1SEL |= PWM;

     CCR0 = 42;									// Set PWM parameters, CCR0 is PWM Period/2
     CCR1 = 21;									// Duty cycle
     TACTL = TASSEL_2 + MC_3;                  // SMCLK, up/dn mode

     unsigned int delay = 1;
     while(1)
     {
       if (i>delay)
       {
         P1OUT ^= PIEZO;       // Toggle P1.6 steady output
         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
         P1OUT ^= PIEZO;
         CCTL1 = OUTMOD_0;
         WDTCTL = WDT_ADLY_1000;

         i=0;
         delay = (getRnd() >> 7)/3;
       }
       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)
   {
   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);   
     ++period;
     return lfsr;
   }   

Link to post
Share on other sites

I have a suggestion, Switch out the 2001 with a 2131 and use the ADC to get random samples and temperature readings to change the timing, output noise, etc...

 

Consider making i and other globally used variables volatile.

 

Set all clocks to DAMNSLOW :thumbup: (My term for 1.5Khz clock speed. VLO / 8)

 

Also you could go into LPM4 and wait for a NMI that is caused by a RC circuit. That would reduce the need for the WDT or any clock at all.

Link to post
Share on other sites

This reminds me of an old project made from a couple of 555's and a tiny pizeo transducer. It made an almost inaudible, very high frequency chirp every two or three hours, depending on the R/C. It would run for a month or so from one 9v battery. Hidden somewhere in an office it would be nearly impossible to located. :mrgreen:

Link to post
Share on other sites
The wake-up by RC circuit looks very interesting! But is it really more energy efficient than LPM3? I'm always amazed at how little power the MSP draws in the LPMs, wouldn't charging a cap require more energy?

 

Cheers

TomKraut

 

Good question, the difference between LPM3 and LPM4 is estremely minimal.

 

It looks like we've got some pretty long runtime as is!

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...