Skip to content
Snippets Groups Projects
Select Git revision
  • 994fdf6a58fedeaa00095bdcb844f942d85ce405
  • main default protected
2 results

solution.c

Blame
  • solution.c 2.63 KiB
    #include "pico/stdlib.h"
    #include "hardware/pwm.h"
    #include "hardware/clocks.h"
    
    #define BUZZER_PIN 18 // This is both the buzzer and audio jack (just in case you have anything to plug into it)
    
    #define BUTTON_1_PIN 20
    #define BUTTON_2_PIN 21
    #define BUTTON_3_PIN 22
    
    #define FREQ_1 261.6256f
    #define FREQ_2 293.6648f
    #define FREQ_3 329.6276f
    
    /**
     * A method for playing a note on the speaker.
     * @param frequency Frequency of the note in Hz.
    */
    void playNote(float frequency) {
    
        uint pwmSlice = pwm_gpio_to_slice_num(BUZZER_PIN);
    
        uint32_t wrap = clock_get_hz(clk_sys) / frequency;
        float clkdiv = 1.0f;
    
        while (wrap > 65535) {
            wrap = wrap / 2;
            clkdiv = clkdiv * 2;
        }
    
        // Setting the clkdiv and wrap
        pwm_set_clkdiv(pwmSlice, clkdiv);
        pwm_set_wrap(pwmSlice, wrap);
    
        // Setting the volume to maximum (having maximum oscillation)
        uint32_t dutyCycle = wrap / 2;
        pwm_set_chan_level(pwmSlice, PWM_CHAN_A, dutyCycle);
    
        pwm_set_enabled(pwmSlice, true);
    
    }
    
    /**
     * A method for silencing the speaker.
    */
    void playNothing() {
    
        uint pwmSlice = pwm_gpio_to_slice_num(BUZZER_PIN);
    
        pwm_set_enabled(pwmSlice, false);
    
    }
    
    /**
     * A method for handling GPIO events.
     * @param gpio GPIO Number.
     * @param event_mask Which events will cause an interrupt. See gpio_irq_level for details.
    */
    void handleEvent(uint gpio, uint32_t event_mask) {
    
        // Making keys play frequencies
        if (event_mask == GPIO_IRQ_EDGE_FALL) {
            if (gpio == BUTTON_1_PIN) {
                playNote(FREQ_1);
            }
            if (gpio == BUTTON_2_PIN) {
                playNote(FREQ_2);
            }
            if (gpio == BUTTON_3_PIN) {
                playNote(FREQ_3);
            }
        }
    
        // Making releasing a button make it silent
        if (event_mask == GPIO_IRQ_EDGE_RISE) {
            playNothing();
        }
    
    }
    
    int main() {
        stdio_init_all();
    
        // Setting up the buzzer
        gpio_set_function(BUZZER_PIN, GPIO_FUNC_PWM);
    
        // Linking the buttons to the event handler
        gpio_set_irq_enabled_with_callback(BUTTON_1_PIN, GPIO_IRQ_EDGE_FALL, true, &handleEvent);
        gpio_set_irq_enabled_with_callback(BUTTON_2_PIN, GPIO_IRQ_EDGE_FALL, true, &handleEvent);
        gpio_set_irq_enabled_with_callback(BUTTON_3_PIN, GPIO_IRQ_EDGE_FALL, true, &handleEvent);
    
        gpio_set_irq_enabled_with_callback(BUTTON_1_PIN, GPIO_IRQ_EDGE_RISE, true, &handleEvent);
        gpio_set_irq_enabled_with_callback(BUTTON_2_PIN, GPIO_IRQ_EDGE_RISE, true, &handleEvent);
        gpio_set_irq_enabled_with_callback(BUTTON_3_PIN, GPIO_IRQ_EDGE_RISE, true, &handleEvent);
    
        // Main Program Loop
        while (true) {
            tight_loop_contents();
        }
    
        return 0; // This will never be reached
    }