Testing PWM with a speaker

Dependencies:   mbed

main.cpp

Committer:
ffxx68
Date:
2022-02-18
Revision:
2:ad1ac14ce44a
Parent:
1:aa7cd19c6a4f

File content as of revision 2:ad1ac14ce44a:

#include "mbed.h"

DigitalOut  my_led(LED1);
InterruptIn my_button(USER_BUTTON);
PwmOut      my_speaker(PA_0); // Speaker output PWM2/1
Ticker      led_flash;

// Configuration for sinewave
#define PI        (3.141592653589793238462)
#define AMPLITUDE (1.0)    // x * 3.3V
#define PHASE     (PI * 1) // 2*pi is one period
//#define RANGE     (4096/2) // for a 12 bits DAC
//#define OFFSET    (4096/2) // for a 12 bits DAC
#define RANGE     (10) // for 0-20 range
#define OFFSET    (10) // for 0-20 range
#define BUFFER_SIZE (50)
int    buffer[BUFFER_SIZE];
int    mode = 0;

// Fill sinewave buffer
void calculate_sinewave(void){
  for (int i = 0; i < BUFFER_SIZE; i++) {
     float rads = PI * i * 360 / BUFFER_SIZE / 180.0; // Convert degree in radian
     buffer[i] = OFFSET + AMPLITUDE * RANGE * cos(rads + PHASE);
     // printf ("%d\n", buffer[i]);
  }
}

void pressed() {

    my_led = !my_led;
    
    // change mode
    if (mode < 2) mode++;
    else mode = 0;
    
    if (!mode) {
        printf ("mute\n");
        my_speaker=0.0; // turn off PWM
    }
    else if (mode == 1){
        printf ("square wave\n");
        my_speaker.period_ms(2); // Frequency 500 Hz
        my_speaker.write(0.5); // Duty Cycle to 50% (max volume)
    } else if (mode == 2){
        printf ("sine wave\n");
        my_speaker.period_us(20); // PWM frequency 50Khz
        my_speaker.write(0); // swith off initially
    } 
}

int main()
{
    int i;
    
    my_speaker.period_ms(5); // PWM initial frequency: 200Hz 
    my_speaker.write(0); // Set duty to null, initially (mute)
    my_led = 1; // set mode 1
    my_button.fall(&pressed); // Set button action
    calculate_sinewave(); // Fill in the sinewave buffer

    printf ("PWM speaker driver example\n");
    
    // intro beeps
    for (i=0; i<3; i++) {
        my_speaker.period_ms(2); // 500Hz
        my_speaker.write(0.25); //25% duty cycle - mid range volume
        wait(.02);
        my_speaker=0.0; // turn off audio
        wait(0.5);
    }
    
    while(1) {
        if (mode == 2) {
            // play one cycle of a sinewave
            for (int i = 0; i < BUFFER_SIZE; i++) {
                my_speaker.pulsewidth_us ( buffer[i] ); // sweep duty with waveform
                wait_us(2); // waveform period: BUFFER_SIZE*delay
            }
        }
        else if (mode == 1) {
            // square wave - nop
            wait(0.2);
        }
    }
}