Question about "differential drive" and piezo buzzer

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
computurwizard
 
Posts: 7
Joined: Sat Jun 23, 2012 11:18 am

Question about "differential drive" and piezo buzzer

Post by computurwizard »

Under the description for the piezo buzzer, it says "For extra loudness, you can connect both pins to a microcontroller and swap which pin is high or low ('differential drive') for double the volume. "

Does that mean something like this would work?

TIA! :D

EDIT - Piezo can be found here: http://www.adafruit.com/products/160

Code: Select all

/*
Test of tone() using a simple piezo with a differential drive circuit
 */
 
const int piezopin1 = 7;
const int piezopin2 = 8;

// the setup routine runs once when you press reset:
void setup() {                
  pinMode(piezopin1, OUTPUT);
  pinMode(piezopin2, OUTPUT);  
}

// the loop routine runs over and over again forever:
void loop() {
  tone(piezopin1, 2200);
  digitalWrite(piezopin2, LOW);
  delay(100);
  noTone(piezopin1);
  delay(100);
  // Now swap pins
  tone(piezopin2, 2200);
  digitalWrite(piezopin1, LOW);
  delay(100);
  noTone(piezopin2);
  delay(100);
}

mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am

Re: Question about "differential drive" and piezo buzzer

Post by mtbf0 »

don't think that would work. the approach would involve connecting the two leads of the piezo buzzer to the two output compare pins of one of the arduino timers, setting one pin high and the other low then having them both toggle when the timer overflows. this is kind of a low level approach and not very arduinish. i think you can have a look at the code for the icetube kit for an example. as long as you don't use timer0 you can use this method on an arduino. it does require the use of two pwm pins, either 9 & 10 or 3 & 11.

User avatar
adafruit_support_mike
 
Posts: 67339
Joined: Thu Feb 11, 2010 2:51 pm

Re: Question about "differential drive" and piezo buzzer

Post by adafruit_support_mike »

Differential drive does mean "left-high-right-low / left-low-right-high". The idea is that you get twice the effective voltage swing.

If your output voltage is 5v, you start with the left pin at 5v and the right one at 0v. Then you go to the left pin being 0v and the right pin being 5v. For the first step, the left pin is 5v higher than the right pin. For the second, it's 5v lower. It's electrically equivalent to keeping the right pin at 0v and having the left pin swing from 5v to -5v.. a total swing of 10v.

Rather than hooking the piezo to the timer, you can bit-bang your tones with the delayMicroseconds() command:

Code: Select all

void diffDriveTone (period, duration) {
    char phase = 0;
    int i;
    
    for (i=0 ; i < duration ; i+=period) {
        digitalWrite( leftPin, phase & 1 );
        phase++;
        digitalWrite( rightPin, phase & 1 );
        delayMicroseconds( period );
    }
}

diffDriveTone( 2272, 1000000 );    // play 1sec of 440Hz A

I can't make any promises about the musicality of it, but that's the general idea.

mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am

Re: Question about "differential drive" and piezo buzzer

Post by mtbf0 »

using a timer allows for a non-blocking version. this one gives a tone near 500Hz using d5 and d6.

Code: Select all

void start_buzzer (void) {
  DDRD |=  0x60;      // make sure pins 5 and 6 are outputs
  PORTD  = (PORTD & ~0x60) | 0x40;  // pin 6 high, pin 5 low
  TCCR0A  = (TCCR0A & 0x0f) | 0x50;  // pins 5 & 6 toggle on compare match
}

void stop_buzzer (void) {
  TCCR0A &= 0x0f;  // stop toggle on compare match
}
yes, you must use pins 5 and 6. no, you can't change the frequency of the tone. this is the dead simplest approach, since it uses timer0 which is already running on an arduino. versions using timer1 or timer2 could offer a variable frequency.

EDIT: won't work on a mega or leonardo or anything not based on an atmegax8.

code is untested. gotta go to work.

User avatar
adafruit_support_mike
 
Posts: 67339
Joined: Thu Feb 11, 2010 2:51 pm

Re: Question about "differential drive" and piezo buzzer

Post by adafruit_support_mike »

Ooh.. nice code.

BTW - more recent versions of the Arduino library (since Arduino 0018) have made delayMicroseconds() nonblocking:

http://arduino.cc/en/Reference/DelayMicroseconds

mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am

Re: Question about "differential drive" and piezo buzzer

Post by mtbf0 »

or, how about this in case you want a little control of the volume...

Code: Select all

#define LO 0
#define HI 1

void start_buzzer (int volume) {
  DDRD |=  0x60;                       // make sure pins 5 and 6 are outputs
  PORTD  = (PORTD & ~0x60) | 0x40;     // pin 6 high, pin 5 low
  if (volume == HI)
    TCCR0A  = (TCCR0A & 0x0f) | 0x50;  // pins 5 & 6 toggle on compare match
  else
    TCCR0A  = (TCCR0A & 0x0f) | 0x10;  // pin 6 toggles on compare match
}

void stop_buzzer (void) {
  TCCR0A &= 0x0f;                      // stop toggle on compare match
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”