Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
11 years, 9 months ago.
How do I control two different loudspeakers with two separate pwm ports?
I'm trying to get one speaker to play the melody of a song and another speaker to play the bass of a song. I've managed to get the melody itself to work well but when I add in another loudspeaker I encounter a couple of problems.
The first one is; when using my function to play a note I need to use a wait for the duration of the note. I don't know how to make the program do something else while it is also waiting, ie, I can't make the melody speaker play a tune over the top of a single bass note due to the program waiting for the bass note to finish.
This means I am unable to set a duration for one speaker in the function so I have to jiggle the durations around, leaving the bass on (setting the frequency to a note) then leaving it while I play the melody until I need to change the bass note or turn the bass off.
While doing this, I encountered the second problem. I believe it's do with how pwm actually works. If I have something like this:
#include "mbed.h" PwmOut loudspeaker1(p21); PwmOut loudspeaker2(p22); int main(){ loudspeaker1.period(1/523.25); //note c loudspeaker1 = 0.5; wait(2); loudspeaker1.period(1/587.33); //note d loudspeaker1=0.5; loudspeaker2.period(1/329.63); //low note e loudspeaker2 = 0.5; wait(2); loudspeaker1 = 0; loudspeaker2 = 0; }
This should make loudspeaker1 a note c for 2 seconds then it should change to a note d while the loudspeaker2 goes to a low note e. This doesn't happen, instead loudspeaker1 is forced to go to a low note e at the same time loudspeaker2 goes to a low note e. They should then turn off after 2 seconds, which they do.
Why does this happen and how can I fix it?
Any help would be much appreciated, thanks.
2 Answers
11 years, 9 months ago.
Unfortunately all Pwm channels are linked to the same period so you cant do what you want to do.
if you want to use 1 channel asynchronously you will have to use a Timer, (interrupts could also work) something like this:
float channel1[5][2] = {{2, 1/523.25}, {/*add more notes n delays*/}}; Timer timer1; int main(){ timer1.start(); int note1 = 0; loudspeaker1.period(channel1[note1][1]); //note d loudspeaker1 = 0.5; while(1){ if(timer1.read() > channel1[note1][0]){ timer1.reset(); note1++; loudspeaker1.period(channel1[note1][1]); //note c } } }
Its just an example, I haven't ran or tested, and you need more variables to check how many notes there are ect, but hopefully you can get some ideas from it.
11 years, 9 months ago.
In this PWM course is an example how to play a melody: http://mbed.org/media/uploads/robt/mbed_course_notes_-_pulse_width_modulation.pdf