Testing PWM with a speaker

Dependencies:   mbed

Revision:
2:ad1ac14ce44a
Parent:
1:aa7cd19c6a4f
--- a/main.cpp	Thu Jan 08 15:22:35 2015 +0000
+++ b/main.cpp	Fri Feb 18 11:29:26 2022 +0000
@@ -2,50 +2,85 @@
 
 DigitalOut  my_led(LED1);
 InterruptIn my_button(USER_BUTTON);
-PwmOut      my_speaker(PB_3); // Speaker outut on PB 3
+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) // 12 bits DAC
-#define OFFSET    (4096/2) // 12 bits DAC
-#define BUFFER_SIZE (360)
-uint16_t    buffer[BUFFER_SIZE];
+//#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++) {
-     double rads = (PI * i)/180.0; // Convert degree in radian
-     buffer[i] = (uint16_t)(AMPLITUDE * (RANGE * (cos(rads + PHASE))) + OFFSET);
+     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
-    my_led = !my_led;
+    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
-    my_led = 1; // turn on led and action
+    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 (my_led) { 
-            // play a continuos square wave
-            my_speaker.period_ms(2); // Frequency 500Hz
-            my_speaker.write(0.5); // Duty to 50%
+        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 {
-            // play a sinewave
-            my_speaker.period_us(5); // PWM frequency: 200KHz
-            for (int i = 0; i < BUFFER_SIZE; i++) {
-                my_speaker.write( buffer[i] / (RANGE + OFFSET) ); // duty = sound amplitude
-                wait_us(50); // period: 360*50us -> 1350 Hz sinusoid
-            }
+        else if (mode == 1) {
+            // square wave - nop
+            wait(0.2);
         }
     }
 }