Skip to content

Commit 980904d

Browse files
authored
#1 Include pwm/pico_tone example
2 parents eca13ac + 25e8dfa commit 980904d

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ App|Description
244244
[hello_pwm](pwm/hello_pwm) | Minimal example of driving PWM output on GPIOs.
245245
[led_fade](pwm/led_fade) | Fade an LED between low and high brightness. An interrupt handler updates the PWM slice's output level each time the counter wraps.
246246
[measure_duty_cycle](pwm/measure_duty_cycle) | Drives a PWM output at a range of duty cycles, and uses another PWM slice in input mode to measure the duty cycle.
247+
[pico_tone](pwm/pico_tone) | Play a christmas melody :notes::christmas_tree: by generating square waves with PWM and a Buzzer :speaker:.
247248

248249
### Reset
249250

pwm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ if (NOT PICO_NO_HARDWARE)
22
add_subdirectory(hello_pwm)
33
add_subdirectory(led_fade)
44
add_subdirectory(measure_duty_cycle)
5+
add_subdirectory(pico_tone)
56
endif ()

pwm/pico_tone/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
add_executable(pico_tone
2+
pico_tone.c
3+
)
4+
5+
# Add pico_stdlib library which aggregates commonly used features
6+
target_link_libraries(pico_tone pico_stdlib hardware_pwm)
7+
8+
# Create map/bin/hex/uf2 file in addition to ELF.
9+
pico_add_extra_outputs(pico_tone)
10+
11+
# add url via pico_set_program_url
12+
example_auto_set_url(pico_tone

pwm/pico_tone/pico_tone.c

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include "pico/stdlib.h"
8+
#include "hardware/pwm.h"
9+
10+
/** Example code to generate tones with Buzzer using PWM with pico-sdk.
11+
*
12+
* Every sound humans encounter consists of one or more frequencies, and the
13+
* way the ear interprets those sounds is called pitch.
14+
*
15+
* In order to produce a variety of pitches, a digital signal needs to convey
16+
* the frequency of sound it is trying to reproduce. The simplest approach is
17+
* to generate a 50% duty cycle pulse stream and set the frequency to the
18+
* desired pitch.
19+
*
20+
* References:
21+
* - https://www.hackster.io/106958/pwm-sound-synthesis-9596f0#overview
22+
*/
23+
#define BUZZER_PIN 3
24+
25+
// Notes' frequencies used for the melody in Hz.
26+
#define NOTE_C4 262
27+
#define NOTE_D4 294
28+
#define NOTE_E4 330
29+
#define NOTE_F4 349
30+
#define NOTE_G4 392
31+
#define NOTE_A4 440
32+
#define NOTE_B4 494
33+
#define NOTE_C5 523
34+
#define NOTE_D5 587
35+
#define NOTE_E5 659
36+
#define NOTE_F5 698
37+
38+
#define SPEED 400U // Speed of each note in ms
39+
#define SILENCE 10U // 10 ms of silence after each note
40+
41+
uint slice_num; // Variable to save the PWM slice number
42+
43+
void play_tone(uint gpio, uint16_t freq, float duration);
44+
45+
int main() {
46+
// Configure BUZZER_PIN as PWM
47+
gpio_set_function(BUZZER_PIN, GPIO_FUNC_PWM);
48+
// Update slice_num with the slice number of BUZZER_PIN
49+
slice_num = pwm_gpio_to_slice_num(BUZZER_PIN);
50+
// Get default configuration for PWM slice and initialize pwm
51+
pwm_config config = pwm_get_default_config();
52+
pwm_init(slice_num, &config, true);
53+
while (1) {
54+
/**
55+
* .:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:.
56+
* . .
57+
* . * Song: Noche de Paz (Silent Night) .
58+
* . /.\ Instrument: Buzzer .
59+
* . /..'\ Interpreter: Raspberry Pi Pico .
60+
* . /'.'\ _ .
61+
* . /.''.'\ _[ ]_ .
62+
* . /.'.'.\ Merry Christmas! (") .
63+
* . /'.''.'.\ Feliz Navidad! `__( : )--' .
64+
* . ^^^[_]^^^ ( : ) .
65+
* . ""`-...-'"" .
66+
* . .
67+
* .:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:.
68+
*/
69+
// 1
70+
play_tone(BUZZER_PIN, NOTE_G4, 1.5f);
71+
play_tone(BUZZER_PIN, NOTE_A4, .5f);
72+
play_tone(BUZZER_PIN, NOTE_G4, 1.f);
73+
74+
// 2
75+
play_tone(BUZZER_PIN, NOTE_E4, 3.f);
76+
77+
// 3
78+
play_tone(BUZZER_PIN, NOTE_G4, 1.5f);
79+
play_tone(BUZZER_PIN, NOTE_A4, .5f);
80+
play_tone(BUZZER_PIN, NOTE_G4, 1.f);
81+
82+
// 4
83+
play_tone(BUZZER_PIN, NOTE_E4, 3.f);
84+
85+
// 5
86+
play_tone(BUZZER_PIN, NOTE_D5, 2.f);
87+
play_tone(BUZZER_PIN, NOTE_D5, 1.f);
88+
89+
// 6
90+
play_tone(BUZZER_PIN, NOTE_B4, 3.f);
91+
92+
// 7
93+
play_tone(BUZZER_PIN, NOTE_C5, 2.f);
94+
play_tone(BUZZER_PIN, NOTE_C5, 1.f);
95+
96+
// 8
97+
play_tone(BUZZER_PIN, NOTE_G4, 3.f);
98+
99+
// 9
100+
play_tone(BUZZER_PIN, NOTE_A4, 2.f);
101+
play_tone(BUZZER_PIN, NOTE_A4, 1.f);
102+
103+
// 10
104+
play_tone(BUZZER_PIN, NOTE_C5, 1.5f);
105+
play_tone(BUZZER_PIN, NOTE_B4, .5f);
106+
play_tone(BUZZER_PIN, NOTE_A4, 1.f);
107+
108+
// 11
109+
play_tone(BUZZER_PIN, NOTE_G4, 1.5f);
110+
play_tone(BUZZER_PIN, NOTE_A4, .5f);
111+
play_tone(BUZZER_PIN, NOTE_G4, 1.f);
112+
113+
// 12
114+
play_tone(BUZZER_PIN, NOTE_E4, 3.f);
115+
116+
// 13
117+
play_tone(BUZZER_PIN, NOTE_A4, 2.f);
118+
play_tone(BUZZER_PIN, NOTE_A4, 1.f);
119+
120+
// 14
121+
play_tone(BUZZER_PIN, NOTE_C5, 1.5f);
122+
play_tone(BUZZER_PIN, NOTE_B4, .5f);
123+
play_tone(BUZZER_PIN, NOTE_A4, 1.f);
124+
125+
// 15
126+
play_tone(BUZZER_PIN, NOTE_G4, 1.5f);
127+
play_tone(BUZZER_PIN, NOTE_A4, .5f);
128+
play_tone(BUZZER_PIN, NOTE_G4, 1.f);
129+
130+
// 16
131+
play_tone(BUZZER_PIN, NOTE_E4, 3.f);
132+
133+
// 17
134+
play_tone(BUZZER_PIN, NOTE_D5, 2.f);
135+
play_tone(BUZZER_PIN, NOTE_D5, 1.f);
136+
137+
// 18
138+
play_tone(BUZZER_PIN, NOTE_F5, 1.5f);
139+
play_tone(BUZZER_PIN, NOTE_D5, .5f);
140+
play_tone(BUZZER_PIN, NOTE_B4, 1.f);
141+
142+
// 19
143+
play_tone(BUZZER_PIN, NOTE_C5, 3.f);
144+
145+
// 20
146+
play_tone(BUZZER_PIN, NOTE_E5, 3.f);
147+
148+
// 21
149+
play_tone(BUZZER_PIN, NOTE_C5, 1.5f);
150+
play_tone(BUZZER_PIN, NOTE_G4, .5f);
151+
play_tone(BUZZER_PIN, NOTE_E4, 1.f);
152+
153+
// 22
154+
play_tone(BUZZER_PIN, NOTE_G4, 1.5f);
155+
play_tone(BUZZER_PIN, NOTE_F4, .5f);
156+
play_tone(BUZZER_PIN, NOTE_D4, 1.f);
157+
158+
// 23 & 24
159+
play_tone(BUZZER_PIN, NOTE_C4, 5.f);
160+
// play_tone(BUZZER_PIN, <Silencio>, 2.f);
161+
// Fin
162+
}
163+
}
164+
165+
void play_tone(uint gpio, uint16_t freq, float duration) {
166+
// Calculate and configure new clock divider according to the frequency
167+
float clkdiv = (1.f / freq) * 2000.f;
168+
pwm_set_clkdiv(slice_num, clkdiv);
169+
// Configure duty to 50% ((2**16-1)/2)
170+
pwm_set_gpio_level(BUZZER_PIN, 32768U);
171+
sleep_ms((uint32_t) SPEED * duration);
172+
// Make silence after each note to distinguish them better.
173+
pwm_set_gpio_level(BUZZER_PIN, 0);
174+
sleep_ms(SILENCE);
175+
}

0 commit comments

Comments
 (0)