Testing PWM with a speaker

Dependencies:   mbed

Committer:
ffxx68
Date:
Fri Feb 18 11:29:26 2022 +0000
Revision:
2:ad1ac14ce44a
Parent:
1:aa7cd19c6a4f
Publishing on the new MBed GIT

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bcostm 0:b82c05c12d48 1 #include "mbed.h"
bcostm 0:b82c05c12d48 2
bcostm 0:b82c05c12d48 3 DigitalOut my_led(LED1);
bcostm 0:b82c05c12d48 4 InterruptIn my_button(USER_BUTTON);
ffxx68 2:ad1ac14ce44a 5 PwmOut my_speaker(PA_0); // Speaker output PWM2/1
ffxx68 2:ad1ac14ce44a 6 Ticker led_flash;
ffxx68 1:aa7cd19c6a4f 7
ffxx68 1:aa7cd19c6a4f 8 // Configuration for sinewave
ffxx68 1:aa7cd19c6a4f 9 #define PI (3.141592653589793238462)
ffxx68 1:aa7cd19c6a4f 10 #define AMPLITUDE (1.0) // x * 3.3V
ffxx68 1:aa7cd19c6a4f 11 #define PHASE (PI * 1) // 2*pi is one period
ffxx68 2:ad1ac14ce44a 12 //#define RANGE (4096/2) // for a 12 bits DAC
ffxx68 2:ad1ac14ce44a 13 //#define OFFSET (4096/2) // for a 12 bits DAC
ffxx68 2:ad1ac14ce44a 14 #define RANGE (10) // for 0-20 range
ffxx68 2:ad1ac14ce44a 15 #define OFFSET (10) // for 0-20 range
ffxx68 2:ad1ac14ce44a 16 #define BUFFER_SIZE (50)
ffxx68 2:ad1ac14ce44a 17 int buffer[BUFFER_SIZE];
ffxx68 2:ad1ac14ce44a 18 int mode = 0;
ffxx68 1:aa7cd19c6a4f 19
ffxx68 2:ad1ac14ce44a 20 // Fill sinewave buffer
ffxx68 1:aa7cd19c6a4f 21 void calculate_sinewave(void){
ffxx68 1:aa7cd19c6a4f 22 for (int i = 0; i < BUFFER_SIZE; i++) {
ffxx68 2:ad1ac14ce44a 23 float rads = PI * i * 360 / BUFFER_SIZE / 180.0; // Convert degree in radian
ffxx68 2:ad1ac14ce44a 24 buffer[i] = OFFSET + AMPLITUDE * RANGE * cos(rads + PHASE);
ffxx68 2:ad1ac14ce44a 25 // printf ("%d\n", buffer[i]);
ffxx68 1:aa7cd19c6a4f 26 }
ffxx68 1:aa7cd19c6a4f 27 }
bcostm 0:b82c05c12d48 28
bcostm 0:b82c05c12d48 29 void pressed() {
ffxx68 2:ad1ac14ce44a 30
ffxx68 2:ad1ac14ce44a 31 my_led = !my_led;
ffxx68 2:ad1ac14ce44a 32
ffxx68 1:aa7cd19c6a4f 33 // change mode
ffxx68 2:ad1ac14ce44a 34 if (mode < 2) mode++;
ffxx68 2:ad1ac14ce44a 35 else mode = 0;
ffxx68 2:ad1ac14ce44a 36
ffxx68 2:ad1ac14ce44a 37 if (!mode) {
ffxx68 2:ad1ac14ce44a 38 printf ("mute\n");
ffxx68 2:ad1ac14ce44a 39 my_speaker=0.0; // turn off PWM
ffxx68 2:ad1ac14ce44a 40 }
ffxx68 2:ad1ac14ce44a 41 else if (mode == 1){
ffxx68 2:ad1ac14ce44a 42 printf ("square wave\n");
ffxx68 2:ad1ac14ce44a 43 my_speaker.period_ms(2); // Frequency 500 Hz
ffxx68 2:ad1ac14ce44a 44 my_speaker.write(0.5); // Duty Cycle to 50% (max volume)
ffxx68 2:ad1ac14ce44a 45 } else if (mode == 2){
ffxx68 2:ad1ac14ce44a 46 printf ("sine wave\n");
ffxx68 2:ad1ac14ce44a 47 my_speaker.period_us(20); // PWM frequency 50Khz
ffxx68 2:ad1ac14ce44a 48 my_speaker.write(0); // swith off initially
ffxx68 2:ad1ac14ce44a 49 }
bcostm 0:b82c05c12d48 50 }
bcostm 0:b82c05c12d48 51
bcostm 0:b82c05c12d48 52 int main()
bcostm 0:b82c05c12d48 53 {
ffxx68 2:ad1ac14ce44a 54 int i;
ffxx68 2:ad1ac14ce44a 55
ffxx68 1:aa7cd19c6a4f 56 my_speaker.period_ms(5); // PWM initial frequency: 200Hz
ffxx68 2:ad1ac14ce44a 57 my_speaker.write(0); // Set duty to null, initially (mute)
ffxx68 2:ad1ac14ce44a 58 my_led = 1; // set mode 1
ffxx68 1:aa7cd19c6a4f 59 my_button.fall(&pressed); // Set button action
ffxx68 1:aa7cd19c6a4f 60 calculate_sinewave(); // Fill in the sinewave buffer
ffxx68 2:ad1ac14ce44a 61
ffxx68 2:ad1ac14ce44a 62 printf ("PWM speaker driver example\n");
ffxx68 2:ad1ac14ce44a 63
ffxx68 2:ad1ac14ce44a 64 // intro beeps
ffxx68 2:ad1ac14ce44a 65 for (i=0; i<3; i++) {
ffxx68 2:ad1ac14ce44a 66 my_speaker.period_ms(2); // 500Hz
ffxx68 2:ad1ac14ce44a 67 my_speaker.write(0.25); //25% duty cycle - mid range volume
ffxx68 2:ad1ac14ce44a 68 wait(.02);
ffxx68 2:ad1ac14ce44a 69 my_speaker=0.0; // turn off audio
ffxx68 2:ad1ac14ce44a 70 wait(0.5);
ffxx68 2:ad1ac14ce44a 71 }
bcostm 0:b82c05c12d48 72
ffxx68 1:aa7cd19c6a4f 73 while(1) {
ffxx68 2:ad1ac14ce44a 74 if (mode == 2) {
ffxx68 2:ad1ac14ce44a 75 // play one cycle of a sinewave
ffxx68 2:ad1ac14ce44a 76 for (int i = 0; i < BUFFER_SIZE; i++) {
ffxx68 2:ad1ac14ce44a 77 my_speaker.pulsewidth_us ( buffer[i] ); // sweep duty with waveform
ffxx68 2:ad1ac14ce44a 78 wait_us(2); // waveform period: BUFFER_SIZE*delay
ffxx68 2:ad1ac14ce44a 79 }
ffxx68 1:aa7cd19c6a4f 80 }
ffxx68 2:ad1ac14ce44a 81 else if (mode == 1) {
ffxx68 2:ad1ac14ce44a 82 // square wave - nop
ffxx68 2:ad1ac14ce44a 83 wait(0.2);
ffxx68 1:aa7cd19c6a4f 84 }
bcostm 0:b82c05c12d48 85 }
bcostm 0:b82c05c12d48 86 }