Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Buzz a piezo speaker?


  • Please log in to reply
6 replies to this topic

#1 James

James

    Advanced Member

  • Members
  • PipPipPip
  • 56 posts

Posted 18 September 2010 - 02:26 AM

I'm attempting to use a piezo speaker with the netduino. It seems like a simple enough task - here's my code:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using System.Threading;

namespace HelloNetduino
{
    class PiezoSpeaker
    {
        PWM pwm;
        Timer timer;

        public PiezoSpeaker(Cpu.Pin pin)
        {
            pwm = new PWM(pin);
        }

        /// <summary>
        /// Sends the given frequency to the piezo speaker for the parameter duration.
        /// </summary>
        /// <param name="duration">Duration of the output, in ms.</param>
        /// <param name="frequency">Frequency of the output in Hz.</param>
        public void FrequencyOut(int duration, int frequency)
        {
            if (timer != null)
                throw new Exception("The speaker is already in use.");

            // Start the PWM pin buzzing.  The input in Hz is the number of times the signal
            // should oscillate per second.  Given high and low values times should be equal,
            // divide the time in a second in half to account for off time, then divide the 
            // remainder by the frequency to get the PWM duration value.  Period = duration here.
            var period = (uint)(1000 / 2 / frequency);
            pwm.SetPulse(period, period);

            timer = new Timer(FrequencyOutTimerCallback, null, duration, 0);
        }

        /// <summary>
        /// Turns off the PWM pin used for the speaker and cleans up the timer.
        /// </summary>
        private void FrequencyOutTimerCallback(object state)
        {
            Debug.Print(DateTime.Now.ToString() + " tick.");
            pwm.SetDutyCycle(0);

            timer.Dispose();
            timer = null;
        }
    }
}

And to make it buzz at 3000 Hz for 1 second:

public static void Main()
        {
            PiezoSpeaker speaker = new PiezoSpeaker(Pins.GPIO_PIN_D5);

            Debug.Print(DateTime.Now.ToString() + " start.");
            speaker.FrequencyOut(1000, 3000);


            Thread.Sleep(10000);  // Sleep for 10 seconds so the program doesn't exit while the speaker is in use.
            Debug.Print(DateTime.Now.ToString() + " done.");
        }

Sadly, I get no result from the speaker. The speaker I have was made for use with a Parallax basic stamp. I assumed I could wire it up to the Netduino the same way it's wired up for a basic board - I'm running the + terminal to pin 5 on the Netduino and the - terminal to ground. Can anyone spot an error in my code or wiring?

#2 klotz

klotz

    Advanced Member

  • Members
  • PipPipPip
  • 60 posts

Posted 18 September 2010 - 04:02 AM

The problem is that when a pwm period and duration are the same the output is high. Period is the rising edge to rising edge time of the output wave form. While duration is the length of the high time of the period. So period should be 1/frequency and duration should be (duty_cycle * period) where duty cycle is some value < 1. Also if I remember correctly, period is in microseconds so:

Try

  var period = (uint)(1000000 / frequency); 
  pwm.SetPulse(period, period/2); 
 

I used the same buzzer and I just checked my code and the period is in microseconds like I remembered.

#3 Flores

Flores

    Advanced Member

  • Members
  • PipPipPip
  • 64 posts

Posted 18 September 2010 - 05:30 AM

Don't forget that the current you can draw from the netduino pin outs is not that high. Be sure to check that and use a driver in between if your device is able to draw more (milli) amps.

#4 James

James

    Advanced Member

  • Members
  • PipPipPip
  • 56 posts

Posted 19 September 2010 - 03:52 PM

Thanks Klotz - that worked!

#5 dm3281

dm3281

    Advanced Member

  • Members
  • PipPipPip
  • 31 posts

Posted 27 September 2010 - 03:42 PM

Hi -- can we see the completed code? Also, do you have a link to the piezo that you used?

#6 EC_dude

EC_dude

    New Member

  • Members
  • Pip
  • 5 posts

Posted 31 October 2010 - 05:52 AM

Hey

I am trying to do the same on my Netduino. May I know what the timer is used for ? When I try to just set the pulse using the SetPulse command with appropriate inputs, an unhandled exception pops up and the speaker just keeps producing a particular frequency.

static void play(int tone, int duration)
        {
            PWM speaker = new PWM(Pins.GPIO_PIN_D6);
            uint period = (uint)(tone);
            speaker.SetPulse(period, period/2);
            Thread.Sleep((int)(duration / 1000));
        }

Here is what i use to play the song. The above function is called from other which gives it the period(of the pulse) and the duration for which it is played..
Difficult I'll do it today, impossible it'll take a bit longer ...

#7 Mustang

Mustang

    Member

  • Members
  • PipPip
  • 26 posts
  • LocationDetroit, Michigan

Posted 21 November 2010 - 07:16 PM

EC, are you calling that function more than once? If you are, the code is trying to use the pin without first disposing it. That is the cause of your exception. Declare the PWM in global and use it from there.

Using your code, I was able to recreate the annoying European police sirens that I am using for an RC car project.

for (i = 0; i <= 5; i++)
               {
                   police(led1, led2, led3);
                   int timeToPlay = 500;
                   play(1654, 250);
                   Thread.Sleep(timeToPlay);
                   play(1543, 250);
                   Thread.Sleep(timeToPlay);
               }

static PWM speaker = new PWM(Pins.GPIO_PIN_D10);
            const int time = 250;
            static sbyte dirr = 1;
            static byte duty = 40;
            static int i = 0;

            static void play(int tone, int duration)
            {

                uint period = (uint)(tone);
                speaker.SetPulse(period, period / 2);
                Thread.Sleep((int)(duration / 1000));
            }





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.