Go Down

Topic: Active vs. passive buzzer? Light/sound/display project (Read 9112 times) previous topic - next topic

sulla

I have a project that has (so far) three different elements which I need to choreograph.  It is meant to look like it is reading random electromagnetic fields.  This device is basically a toy and does nothing useful.

It will cycle randomly through 5 LEDs, push a voltmeter needle back in forth with the pulsing of the LEDs, and now I need to work in a buzzer that increases and decreases in volume with the random fluctuations of the lights and the needle.

I'll post the code after work tonight. (Can't put the environment on my work PC.)

Right now, I need a crash course on piezo's.  Active, passive, I don't really know anything about buzzers.  Plus there is not a lot of room to mount it in my device.  Anyone have any suggestions for where I can start learning about these things?

Here is a link to a video of the lights and needle:
http://s699.photobucket.com/user/boozee2/media/DSCN5172_zps5274d251.mp4.html



DVDdoug

Quote
Right now, I need a crash course on piezo's.  Active, passive, I don't really know anything about buzzers. 
A passive device is like a speaker...  You feed-in a signal and the signal gets converted to sound.   And active buzzer just needs power and it generates it's own sound.

If you want to control the volume/pitch, a passive device is the way to go.   You can't directly control volume of the Arduino's PWM output but changing the PWM value will affect the volume and the "character" of the tone together, and that will probably work in your application.

I've never used the Arduion to make sound, but the basic PWM output will sound the same at 90% as 10% (the signal is just inverted).   The loudest sound should be at 50% (127), although since the piezo is better at reproducing higher frequencies, something between 0 an 50% (with more harmonics) might end-up being louder.

sulla

Thanks a bunch, that has helped a lot.

I did a little bit or surfing and found this.  Is it kind of what you are talking about?  I am a little leery about the first bullet point.


  • No oscillation source,need  square wave(frequency 2K-5K ) to drive



  • Audino 9012 drive;



  • Work  Voltage:3.3-5V



  • Set bolt hole, easy to assemble



  • PCB Dimension:3.3cm*1.3cm



  • Pin definition



  • Vcc : 3.3-5v



  • GND : The Ground



  • I/O : I/O Interface of SCM







sulla

Here's the code (sorry if it's a little messy.)


Code: [Select]
/*
  LED piezo and meter display.
 
  By Luke Thomas
*/

#define LED_PIN 13        //LED in on pin 13
#define DELAY_AMOUNT_MIN 20  //500m == 0.5s
#define DELAY_AMOUNT_MAX 100  //500m == 0.5s
#define BETWEEN_CYCLE_DELAY_MIN 200
#define BETWEEN_CYCLE_DELAY_MAX 800
#define LONG_DELAY_COUNT_MIN 5
#define LONG_DELAY_COUNT_MAX 10

#define NUM_LEDS 5
#define LED_1 6
#define LED_2 5
#define LED_3 4
#define LED_4 3
#define LED_5 2

#define VOLT_METER_PIN 9
#define VOLT_METER_MAX_VAL (255/45)



int led_global = LED_PIN;
int leds[NUM_LEDS] = {LED_1, LED_2, LED_3, LED_4, LED_5};
int globalCycleCount = 0;
int globalLongDelayCount = 0;
int voltMeterLookup[] = {1, 2, 3, 4, 6};

// the setup routine runs once when you press reset:
void setup() {               
 
  //Local variables
  int ct = 0;
 
  // initialize the digital pin as an output.
  pinMode(led_global, OUTPUT); 
  pinMode(VOLT_METER_PIN, OUTPUT); 
 
  for(ct = 0; ct < NUM_LEDS; ct++){
    pinMode(leds[ct], OUTPUT);
  }
 
  //Intialize global variables
  globalCycleCount = 0;
  globalLongDelayCount = 0;
 
}

// the loop routine runs over and over again forever:
void loop() {

  //Local variables
  int ct = 0;
  int randNumLedVal = rand() % NUM_LEDS + 1;
  int tempDelayVal = rand() % (DELAY_AMOUNT_MAX - DELAY_AMOUNT_MIN) + DELAY_AMOUNT_MIN;
  int topDelayVal = 3 * randNumLedVal * tempDelayVal;
  int betweenCyleDelayVal = rand() % (BETWEEN_CYCLE_DELAY_MAX - BETWEEN_CYCLE_DELAY_MIN) + BETWEEN_CYCLE_DELAY_MIN;
 
  int voltMeterIncrVal = (VOLT_METER_MAX_VAL / (NUM_LEDS));
 
  /*
  digitalWrite(led_global, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(DELAY_AMOUNT);               // wait for DELAY_AMOUNT
  digitalWrite(led_global, LOW);    // turn the LED off by making the voltage LOW
  delay(DELAY_AMOUNT);               // wait for DELAY_AMOUNT
  */
 
  digitalWrite(led_global, HIGH);
 
  //Run the LEDs up - from the low to high LEDs, with a delay between each
  for(ct = 0; ct < randNumLedVal; ct++){
   
    analogWrite(VOLT_METER_PIN, voltMeterLookup[ct]);
   
    digitalWrite(leds[ct], HIGH);   // turn the LED on (HIGH is the voltage level)
   
    delay(tempDelayVal);               // wait for DELAY_AMOUNT
  }
   
  //DEBUG - toggle the onboard LED for debug purposes.
  digitalWrite(led_global, LOW);
  //Delay at the top of the LEDs for a bit
  delay(topDelayVal);
 
  //Run the LEDs back down - from the high to low LEDs, with a delay between each
  for(ct = randNumLedVal-1; ct >= 0; ct--){
   
    analogWrite(VOLT_METER_PIN, voltMeterLookup[ct]);
   
    digitalWrite(leds[ct], LOW);    // turn the LED off by making the voltage LOW
   
    delay(tempDelayVal);               // wait for DELAY_AMOUNT
  }

  //Reset the volt meter to no output...
  analogWrite(VOLT_METER_PIN, 0);

  //Increment the global cycle counter
  globalCycleCount++;
 
  //Check if a 'long' delay should be ran
  if(globalCycleCount >= globalLongDelayCount){
   
    //If there should be one here, reset the global cycle counter and determine a new cycle wait delay
    globalCycleCount = 0;
    globalLongDelayCount = rand()%(LONG_DELAY_COUNT_MAX - LONG_DELAY_COUNT_MIN) + LONG_DELAY_COUNT_MIN;
   
    //Delay 5 times the previously determined random delay
    //TODO - make this random?
    delay(5*betweenCyleDelayVal);
   
  //If it isn't a lond delay, just delay the normal amount
  } else {
    //Wait for a bit between cycles
    delay(betweenCyleDelayVal);   
  }
 
}


Go Up