Shop OBEX P1 Docs P2 Docs Learn Events
Piezo speaker question — Parallax Forums

Piezo speaker question

Greg LaPollaGreg LaPolla Posts: 323
edited 2009-07-15 06:34 in Propeller 1
I am using a piezo speaker and I can't seem to get it loud enough to hear it from inside a project box.

here is the code and the diagram is attached



CON

  _clkmode = xtal1 + pll16x                                                     ' set clock mode
  _xinfreq = 5_000_000                                                          ' set external crystal freq
  
                           

OBJ
 
PUB Main
  warn
PRI warn
  ctra[noparse][[/noparse]30..26] := %00100
  ctra[noparse][[/noparse]8..0] := 27
  frqa := 224_734

  repeat 3
    repeat 30
      !dira[noparse][[/noparse]27]
      waitcnt(clkfreq/30 + cnt)
    waitcnt(clkfreq + cnt)

PRI alarm

  ctra[noparse][[/noparse]30..26] := %00100
  ctra[noparse][[/noparse]8..0] := 27
  frqa := 224_734
  repeat 5
    !dira[noparse][[/noparse]27]
    waitcnt(clkfreq + cnt)
  




Am I asking to much from the piezo ?


Greg
612 x 792 - 5K

Comments

  • LeonLeon Posts: 7,620
    edited 2009-07-12 20:41
    Is it a plain piezo element or a piezo unit with a built-in driver? The schematic doesn't look right, anyway. The 1k resistor is shorted.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
    Suzuki SV1000S motorcycle
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-12 20:54
    It's the piezo that parallax sell. Your right about the resistor it should be between the piezo pins.
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-12 20:58
    @Leon good catch. I moved the resistor across the piezo pins and now it is so much louder. Sometime it just takes another set of eyes!


    Thanks


    Greg
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2009-07-12 21:13
    You need to catch the resonant frequency for best results on a piezo.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-07-13 20:49
    Greg LaPolla,

    In addition to finding a resonant frequency of the piezo (<- there can be more than one that will work), you can also increase the volume by driving the piezo element differentially rather than single ended. See this thread... although it was written for a BS2, it will still apply here.
    http://forums.parallax.com/showthread.php?p=464410



    If you can't provide a solution in software by sacrificing two pins that you can drive 180 Deg out of phase
    to supply a piezo, then the below circuit may be of some use to you. It is basically a two transistor inverter
    designed to be able to handle a floating input. Note for use from a Propeller pin, substitute the 4.7K resistors with 3.3K resistors.
    http://forums.parallax.com/attachment.php?attachmentid=36227

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 7/15/2009 6:00:07 AM GMT
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-14 01:01
    @Beau,

    I read through several spec sheets for various piezo's. One of them suggested placing a 1k resistor across the pins, (Resistor to do charging and discharging to a piezoelectric element - Value of about 1kΩ is good efficiency).
    Does that achieve sorta what you were referring to? It did get significantly louder once I did that (Correctly as Leon noted).



    Greg
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-14 01:12
    I have driven piezos differentially using 2 I/O and that makes a big difference to the volume for a few reasons. Alternatively I have also connected the piezo from collector to ground and used an inductor + some series resistance in the collector to VCC to provide that punch. The resistor across the piezo is the most basic way to drive it but then you don't need that transistor there for that do you?

    *Peter*

    P.S. I read your original post and you mentioned that you had the piezo inside the box. Bear in mind that this will muffle the sound a lot unless you mount the piezo against the inside of the box with a small hole of around 1 to 5mm for the sound. This is how it is done in all commercial projects, the hole may be very small but it makes a difference.

    Post Edited (Peter Jakacki) : 7/14/2009 1:36:09 AM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-07-14 03:32
    Greg LaPolla,

    The circuit that you provided will only drive the piezo in a single ended mode, and using a 1K bias resistor works fine for this. If you do however find that you need even more volume, the differential drive approach that I provided a link to can help. Even if you have one I/O pin there is an inverter that will work perfectly with the piezo that I also provided a link to that will drive the piezo element differentially.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-14 04:40
    @Beau

    Is there an inverter specifically that you would recommend or is it best to just build one as you have diagrammed.


    Greg
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-07-14 05:40
    Greg LaPolla,

    I have always just built one in this situation... A CMOS inverter would probably work just fine. The unique property of the inverter that I posted is that it can accept a floating or hi-Z input.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-14 23:36
    @Beau,

    I don't have any 2n3906 transistors, I only have 2n3904's. I thought I would attack the 2 pin method. I have been going over the Counter Modules and Circuit applications lab in the PE kit. I can't seem to find anything that would help. I understand the methodology, but I can seem to wrap my head around it completely.

    Would you just alternate the pins back and forth between input and output ? using the code I originally posted using ctra and frqa I am not sure it will work. Do those counters get reset when you change the pin direction?


    Greg
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 03:14
    Greg, if you use the counters you have a mode whereby you can nominate another pin as the complement so you don't have to worry about switching the I/O and direction. Try this on the "Synth" object that CHip and Beau did.

    PUB Synth(CTR_AB, Pin, Freq) | s, d, ctr, frq
    
      Freq := Freq #> 0 <# 128_000_000     'limit frequency range
      
      if Freq < 500_000                    'if 0 to 499_999 Hz,
        ctr := constant(%00100 << 26)      '..set NCO mode                                            change this to 00101 for differential
        s := 1                             '..shift = 1
      else                                 'if 500_000 to 128_000_000 Hz,
        ctr := constant(%00010 << 26)      '..set PLL mode                                             change this to 00011 for differential
        d := >|((Freq - 1) / 1_000_000)    'determine PLLDIV
        s := 4 - d                         'determine shift
        ctr |= d << 23                     'set PLLDIV
        
      frq := fraction(Freq, CLKFREQ, s)    'Compute FRQA/FRQB value
      ctr |= Pin                           'set PINA to complete CTRA/CTRB value
      ctr |= ++Pin<<9                                                                                             add this line to select the differential pin (assuming here that you are using next pin up)
    
      if CTR_AB == "A"
         CTRA := ctr                        'set CTRA
         FRQA := frq                        'set FRQA                   
         DIRA[noparse][[/noparse]Pin]~~                        'make pin output                                                change to       DIRA{Pin..Pin+1]~~     
         
      if CTR_AB == "B"
         CTRB := ctr                        'set CTRB
         FRQB := frq                        'set FRQB                   
         DIRA[noparse][[/noparse]Pin]~~                        'make pin output                                               change to       DIRA{Pin..Pin+1]~~     
    
    



    *Peter*
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 03:59
    @peter


    Thanks for the info. I am trying to get your example to work but It hangs here:

    frq := fraction(Freq, CLKFREQ, s) 'Compute FRQA/FRQB value

    What should that do ? I assume fraction is something you wrote.

    I modified my code like this:

    PUB warn
      ctra[noparse][[/noparse]30..26] := %00101
      ctra[noparse][[/noparse]8..0] := 18
      ctrb[noparse][[/noparse]8..0] := 19
      frqa := 224_734
    
      repeat 3
        repeat 30
          !dira[noparse][[/noparse]18..19]
          waitcnt(clkfreq/30 + cnt)
        waitcnt(clkfreq + cnt)
    
    
    



    this works but doesn't seem any louder so I assume my code is not correct.


    Greg
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-07-15 04:06
    Greg,

    You need to set the destination field of CTRA to 19, not the source field of CTRB. The latter doesn't do anything, since you're not using CTRB.

    -Phil
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 04:15
    OK maybe I am totally missing the concept here, based on what Beau said to push both sides beyond the center it can be done using 2 pins.

    My line of thinking is to drive pins high and low and alternate input and output respectfully on the 2 pins.

    Changing ctra to differential mode I understand, but what about the second pin ?


    Greg
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 04:34
    In my example I have left the parameters Synth(CTR_AB, Pin, Freq) as they are but simply made the extra pin as +1 so therefore if you specify pin 10 for your piezo then pin 11 will be the complement of pin 10 automatically.
    Basically all that happens is that one pin will be at 3.3V while the other will be at 0V, then it alternates (AC) so that it becomes 0V while the other will be at 3.3V. The piezo will with only two pins see a strong AC signal imposed across it which is ideal for this type of element as it is mostly capacitive in nature. Leaving a DC voltage on the piezo will have no effect at all or draw any current, it needs to be AC (in respect to the piezo).

    3.3V
    PIEZO
    0V
    0V
    PIEZO
    3.3V
    3.3V
    PIEZO
    0V


    If you want to specify a completely different complementary pin then you should add an extra parameter to the function and change the bits that write to the counter and direction register.


    *Peter*
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 04:38
    I just read Phil's post and I see you are getting confused with CTRA and CTRB. They are completely separate counters with the only thing in common being that they are accessed by the one cog. The destination field starts at bit 9 vs bit 0 for the source field in a 32-bit word. This is standard Propeller assembly convention for 9-bit source and destination fields and the counters are setup the same way.

    *Peter*
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 04:55
    @Peter,

    I have tried your code and I can't seem to make it work.

    Here is what I have done:

    
    count = "A"
    
    Synth(count,18,224_734)
    
    PUB Synth(CTR_AB, Pin, Freq) | s, d, ctr, frq
    
      Freq := Freq #> 0 <# 128_000_000     'limit frequency range
      
      if Freq < 500_000                    'if 0 to 499_999 Hz,
        ctr := constant(%00101 << 26)      '..set NCO mode                         change this to 00101 for differential
        s := 1                             '..shift = 1
      else                                 'if 500_000 to 128_000_000 Hz,          
        ctr := constant(%00011 << 26)      '..set PLL mode                         change this to 00011 for differential
        d := >|((Freq - 1) / 1_000_000)    'determine PLLDIV
        s := 4 - d                         'determine shift
        ctr |= d << 23                     'set PLLDIV
        
      'frq := fraction(Freq, CLKFREQ, s)    'Compute FRQA/FRQB value
      frq := Freq
      ctr |= Pin                           'set PINA to complete CTRA/CTRB value
      ctr |= ++Pin<<9                      ' add this line to select the differential pin (assuming here that you are using next pin up)
                                                                                   
      if CTR_AB == "A"
         CTRA := ctr                        'set CTRA
         FRQA := frq                        'set FRQA                   
         DIRA[noparse][[/noparse]Pin..Pin+1]~~                        'make pin output   change to       DIRA{Pin..Pin+1]~~     
         
      if CTR_AB == "B"
         CTRB := ctr                        'set CTRB
         FRQB := frq                        'set FRQB                   
         DIRA[noparse][[/noparse]Pin..Pin+1]~~                        'make pin output   change to       DIRA{Pin..Pin+1]~~
    
    



    I can seem to get anything out of the peizo with this. I even tried a repeat calling synth.


    Greg
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 05:03
    What is that frequency you are running it at. Even bat ears won't pick that up!

    Try 1500 for starters


    *Peter*
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-07-15 05:04
    Greg,

    You need to add a repeat to your main code to keep the cog alive. Your program is dying right after the call to synth since Spin is doing an automatic cogstop. Repeatedly calling synth is only going to make it keep reinitializing.

    -Phil
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 05:11
    Yes Phil, and that too but it looked like he had clipped the listing as there was no pub method defined there.

    Posters, if you are going to post code then post the exact code otherwise we have no idea what really is going on.

    *Peter*
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 05:11
    @Peter

    that is c8. It plays fine with my code.

    I changed it to 84_181 which is G6 still no go.


    @Phil

    I did use a repeat as I stated at the bottom neither worked.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 05:14
    Sorry Greg, but aren't you using the Synth object which expects frequency in Hertz, not in timing cycles?

    *Peter*
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 05:17
    ok, I made a change to it because some code was missing. I thought the change I made would work. What does the fraction method do? that was missing.


    Greg
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2009-07-15 05:25
    I think that fraction part is only working out what to load the counters with to get that frequency. If you notice the code checks the frequency to see if it is less than 500,000Hz so it uses 0 and 499_999 as the underscore is simply for readability and nothing else.

    *Peter*
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-07-15 06:08
    Greg,

    You said you "even tried a repeat calling synth", which is different from what I suggested: namely, a naked repeat at the end of your main method, which serves to keep the cog alive. As I explained before, calling synth in a repeat loop just keeps reinitializing the counters, rather than letting them produce any sound.

    -Phil
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-07-15 06:22
    Here is a modified FreqSynth object that will create a differential signal.


    For your application, you might try something like this to generate a 3kHz signal...

    Freq.Synth("A",PinA,PinB, 3000)

    Where PinA and PinB would be your output pins connecting to the piezo.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 06:25
    OK, I read the prop manual again and I had one of those ah hah moments.

    here is the final working copy

    
    CON
    
      _clkmode = xtal1 + pll16x                                                     ' set clock mode
      _xinfreq = 5_000_000                                                          ' set external crystal freq
     
    PUB Main
      warn
      alarm
      
    PRI warn
      ctra[noparse][[/noparse]30..26] := %00101
      ctra[noparse][[/noparse]5..0] := 18
      ctra[noparse][[/noparse]14..9] := 19
      frqa := 224_734
    
      repeat 1
        repeat 30
          !dira[noparse][[/noparse]18..19]
          waitcnt(clkfreq/30 + cnt)
        waitcnt(clkfreq + cnt)
    
    PRI alarm
    
      ctra[noparse][[/noparse]30..26] := %00101
      ctra[noparse][[/noparse]5..0] := 18
      ctra[noparse][[/noparse]14..9] := 19
      frqa := 224_734
      repeat 5
        !dira[noparse][[/noparse]18..19]
        waitcnt(clkfreq + cnt)
    
    



    After running this I about blew my ear drums out. It will definitely be able to be heard outside the project box.

    Thanks to Phil & Peter especially for being on the board late at night! You guys were a great help.
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2009-07-15 06:34
    @Beau

    Thanks for the code. I was just re-reading the ctra section in the prop manual. What was confusing me was the BPIN reference for diff mode. I was looking at the ctra register map and discovered that bpin was 9 - 14. Once I realized that I found the error of my ways.


    Greg
Sign In or Register to comment.