Society of Robots - Robot Forum
Software => Software => Topic started by: silo_xtreme on June 26, 2009, 12:45:44 PM
-
Hey All,
How's everyone?
My electrical engineer put a SMT-2240-T piezo buzzer behind a BC817 (transistor I think). So, I'm not sure if I need to generate a 4KHz singal to turn it on, or if I need to just set a pin high.,
I'm not having luck with either.
What's the typical code for an ATMEGA for this type of application? We're using an ATXMEGA .
Mike
-
Usually you would just have to switch the pin high.
Here is some code to switch PORTD 7 high:
PORTD |= (1<<7);Before you would do that though you would need to declare that pin as an output like this:
DDRD |= _BV(PD7);
-
Hey Trumpkin,
That is what i orginally thougt, but here is what I found:
http://www.pui.com/audioProducts/MovieClips/TechNotes/Glossary.asp?articalID=1 (http://www.pui.com/audioProducts/MovieClips/TechNotes/Glossary.asp?articalID=1)
Since my buzzer is actually on PORTC Pin 6 -also as Pin 21 on an ATXMEGA128A1 my code is this:
// Make PC6 an output
PORTC.DIR = (1 << 6);
// Set that output to high
PORTC.OUT = (1 << 6);
and I also tried sending a 4Khz signal as well.
-
Could you post the datasheet of the buzzer?
-
of course!
http://www.projectsunlimited.com/audioproducts/movieclips/products/audioDetailPrint.asp?CATEGORY=2&PARTNUMBER=SMT-2240-TW-R&GUID={AD8833AE-80E1-4EB6-8150-FCEE9CFCB839} (http://www.projectsunlimited.com/audioproducts/movieclips/products/audioDetailPrint.asp?CATEGORY=2&PARTNUMBER=SMT-2240-TW-R&GUID={AD8833AE-80E1-4EB6-8150-FCEE9CFCB839})
which is also
http://parts.digikey.com/1/parts/479-buzzer-piezo-10v-22mm-4-0khz-smd-smt-2240-tw-r.html (http://parts.digikey.com/1/parts/479-buzzer-piezo-10v-22mm-4-0khz-smd-smt-2240-tw-r.html)
Hope this helps!
-
Try connecting a nine volt battery to the two terminals of the buzzer (directly).
-
Hmm ... kinda hard to do when it's SMT part on a PCB. ;)
-
find the traces and touch probes/wires?
-
find the traces and touch probes/wires?
yep, that's what I meant.
-
Ok All,
Thanks for the help so far. When I connect it to a 9V battery I hear something that is almost like static.
Definitely not the correct sound.
Does this imply I need to send in a 4KHZ signal - I'm a bit confused because that's a resonate frequency (output??)
-
The sound of static implies that this is a piezo transducer and not a piezo buzzer. Read a bit about them here http://www.kpsec.freeuk.com/components/other.htm#piezo (http://www.kpsec.freeuk.com/components/other.htm#piezo). So it looks like you need a square wave with a frequency of about 4khz, which is probably what you were doing before lol....
-
LOL. I'm working on it.
-
I think that's the problem. my signal is probably no square. :)
-
The sound of static implies that this is a piezo transducer and not a piezo buzzer. Read a bit about them here http://www.kpsec.freeuk.com/components/other.htm#piezo (http://www.kpsec.freeuk.com/components/other.htm#piezo). So it looks like you need a square wave with a frequency of about 4khz, which is probably what you were doing before lol....
You are right, it's listed as a piezo transducer on mouser: http://ca.mouser.com/Search/ProductDetail.aspx?qs=sGAEpiMZZMuNFJjvCI6tQgUWCBGptnRr%2f1ZaW3omx7A%3d (http://ca.mouser.com/Search/ProductDetail.aspx?qs=sGAEpiMZZMuNFJjvCI6tQgUWCBGptnRr%2f1ZaW3omx7A%3d)
-
Ok. So logic check me please.
Wouldn't this cause a 4000 Hz square wave?
unsigned int cycles = 30;
unsigned int freq = 4000;
PORTC.DIR |= 1<<6; //make PC6 an output
long i;
while (cycles > 0) {
PORTC.OUT |= 1<<6; // buzzer pin high
for(i=0;i<freq;i++);
PORTC.OUT &= !(1<<6); // buzzer pin low
for(i=0;i<freq;i++);
cycles--;
}
if yes, how would I control the duty cycle?
-
Ok. So logic check me please.
Wouldn't this cause a 4000 Hz square wave?
unsigned int cycles = 30;
unsigned int freq = 4000;
PORTC.DIR |= 1<<6; //make PC6 an output
long i;
while (cycles > 0) {
PORTC.OUT |= 1<<6; // buzzer pin high
for(i=0;i<freq;i++);
PORTC.OUT &= !(1<<6); // buzzer pin low
for(i=0;i<freq;i++);
cycles--;
}
if yes, how would I control the duty cycle?
I see several issues.
First, to drive the pin low, you need to use a binary not operator (~), not a logical not (!).
Try:
PORTC.OUT &= ~_BV(PC6)
Second, your delay loop is completely wrong ;)
You need to introduce a delay corresponding to the period and the duty cycle you want.
The period is 1/F, that's easy. A complete iteration (HIGH then LOW) must last 1/4000Hz = 250 microseconds.
The duty cycle of a square wave is 50% so you need to drive your pin HIGH for 250*0.5 = 125 microseconds and then drive your pin low for the same duration.
so basically your loop should look like
unsigned int cycles = 20000; //make noise for 20000 * 250 microseconds = 5 seconds
PORTC.DIR |= _BV(PC6); //make PC6 an output
while (cycles > 0) {
PORTC.OUT |= _BV(PC6); // buzzer pin high
//wait for 125 micro seconds
PORTC.OUT &= ~_BV(PC6); // buzzer pin low
//wait for 125 micro seconds
cycles--;
}
The way you introduce delay is up to you. You can use:
- a busy loop (like you did): it depends on the frequency of your MCU.
- a timer: take a look at this page for more information about timers: http://members.shaw.ca/climber/avrtimers.html (http://members.shaw.ca/climber/avrtimers.html)
Michel.
-
hmm... what compiler are you using? my compiler does not like the PC6 or _BV function.
Either way, when I just changed _BV( PC6) to (1<<6)
and used delay_us(125) from WinAVR util\delay.h
I didn't get this working. I'm still working on it and will report back.
-
hmm... what compiler are you using? my compiler does not like the PC6 or _BV function.
Either way, when I just changed _BV( PC6) to (1<<6)
and used delay_us(125) from WinAVR util\delay.h
I didn't get this working. I'm still working on it and will report back.
I'm using avr-gcc 4.3.2 and avr-libc 1.6.2
I dont know WinAVR, but I guess there is a initialization function. Did you call it?
Do you have access to an oscilloscope or a multimeter with frequency measure?