007 – ESP32 MicroPython: How to make some sound with MicroPython

In this article, we will be exploring the use of Pulse Width Modulation or PWM in producing a sound using MicroPython.

Bill of Materials:

  1. ESP32 Development board.
  2. A buzzer module or a speaker.
  3. Some connecting wires.

Circuit Diagram:


Video Demonstration:

If you found this tutorial as helpful, please consider supporting me by Subscribing to my Youtube channel: Click this to Subscribe to TechToTinker

Source Code:


Example 1, Single Note:

# How to make some sound with MicroPython
# Author: George Bantique,
#         TechToTinker Youtube channel
#         www.techtotinker.com
# Date: September 18, 2020

# Import the machine module for GPIO and PWM
import machine
# Import the time module to add some delays
import time

# Create a regular GPIO object from pin 23
p23 = machine.Pin(23, machine.Pin.OUT)

# Create a new object and attach the pwm driver
buzzer = machine.PWM(p23)

# Set a pwm frequency
buzzer.freq(1047)
# Set the pwm duty value
# this serves as volume control
# Max volume is a duty value of 512
buzzer.duty(50)
# Let the sound ring for a certain duration
time.sleep(1)
# Turn off the pulse by setting the duty to 0
buzzer.duty(0)
# And disconnect the pwm driver to the GPIO pin
buzzer.deinit()

Example 2, Mario Melody:

# How to make some sound with MicroPython
# Author: George Bantique,
#         TechToTinker Youtube channel
#         www.techtotinker.com
# Date: September 18, 2020
from machine import Pin
from machine import PWM
from time import sleep_ms

class GORILLACELL_BUZZER: 
    def __init__(self, sig_pin):
        self.pwm = PWM(Pin(sig_pin),duty_u16=0)      
        
    def play(self, melodies, wait, duty=32767):
        for note in melodies:
            if note != 0:
                self.pwm.freq(note)
            self.pwm.duty_u16(duty)
            sleep_ms(wait)
        # Disable the pulse, setting the duty to 0
        self.pwm.duty_u16(0)
        # Disconnect the pwm driver
        #self.pwm.deinit() # remove to play the next melodies
        
    def tone(self, notes, wait, duty=32767):
        self.pwm.freq(notes)
        self.pwm.duty_u16(duty)
        sleep_ms(wait)
        self.pwm.duty_u16(0)

# Notes and its equivalent frequency
           # Octave 0 ********************
B0  = 31   # B
           # Octave 1 ********************
C1  = 33   # C
CS1 = 35   # C#/Db
D1  = 37   # D
DS1 = 39   # D#/Eb
E1  = 41   # E
F1  = 44   # F
FS1 = 46   # F#/Gb
G1  = 49   # G
GS1 = 52   # G#/Ab
A1  = 55   # A
AS1 = 58   # A#/Bb
B1  = 62   # B
           # Octave 2 ********************
C2  = 65   # C
CS2 = 69   # C#/Db
D2  = 73   # D
DS2 = 78   # D#/Eb
E2  = 82   # E
F2  = 87   # F
FS2 = 93   # F#/Gb
G2  = 98   # G
GS2 = 104  # G#/Ab
A2  = 110  # A
AS2 = 117  # A#/Bb
B2  = 123  # B
           # Octave 3 ********************
C3  = 131  # C
CS3 = 139  # C#/Db
D3  = 147  # D
DS3 = 156  # D#/Eb
E3  = 165  # E
F3  = 175  # F
FS3 = 185  # F#/Gb
G3  = 196  # G
GS3 = 208  # G#/Ab
A3  = 220  # A
AS3 = 233  # A#/Bb
B3  = 247  # B
           # Octave 4 ********************
C4  = 262  # C
CS4 = 277  # C#/Db
D4  = 294  # D
DS4 = 311  # D#/Eb
E4  = 330  # E
F4  = 349  # F
FS4 = 370  # F#/Gb
G4  = 392  # G
GS4 = 415  # G#/Ab
A4  = 440  # A
AS4 = 466  # A#/Bb
B4  = 494  # B
           # Octave 5 ********************
C5  = 523  # C
CS5 = 554  # C#/Db
D5  = 587  # D
DS5 = 622  # D#/Eb
E5  = 659  # E
F5  = 698  # F
FS5 = 740  # F#/Gb
G5  = 784  # G
GS5 = 831  # G#/Ab
A5  = 880  # A
AS5 = 932  # A#/Bb
B5  = 988  # B
           # Octave 6 ********************
C6  = 1047 # C
CS6 = 1109 # C#/Db
D6  = 1175 # D
DS6 = 1245 # D#/Eb
E6  = 1319 # E
F6  = 1397 # F
FS6 = 1480 # F#/Gb
G6  = 1568 # G
GS6 = 1661 # G#/Ab
A6  = 1760 # A
AS6 = 1865 # A#/Bb
B6  = 1976 # B
           # Octave 7 ********************
C7  = 2093 # C
CS7 = 2217 # C#/Db
D7  = 2349 # D
DS7 = 2489 # D#/Eb
E7  = 2637 # E
F7  = 2794 # F
FS7 = 2960 # F#/Gb
G7  = 3136 # G
GS7 = 3322 # G#/Ab
A7  = 3520 # A
AS7 = 3729 # A#/Bb
B7  = 3951 # B
           # Octave 8 ********************
C8  = 4186 # C
CS8 = 4435 # C#/Db
D8  = 4699 # D
DS8 = 4978 # D#/Eb



# This is the list of notes for mario theme
# 0 denotes rest notes
mario = [
     E7, E7,  0, E7,  0, C7, E7,  0,
     G7,  0,  0,  0, G6,  0,  0,  0,
     C7,  0,  0, G6,  0,  0, E6,  0,
      0, A6,  0, B6,  0,AS6, A6,  0,
     G6, E7,  0, G7, A7,  0, F7, G7,
      0, E7,  0, C7, D7, B6,  0,  0,
     C7,  0,  0, G6,  0,  0, E6,  0,
      0, A6,  0, B6,  0,AS6, A6,  0,
     G6, E7,  0, G7, A7,  0, F7, G7,
      0, E7,  0, C7, D7, B6,  0,  0,
    ]

# This is the list of notes for jingle bells
jingle = [
    E7, E7, E7, 0,
    E7, E7, E7, 0,
    E7, G7, C7, D7, E7, 0,
    F7, F7, F7, F7, F7, E7, E7, E7, E7, D7, D7, E7, D7, 0, G7, 0,
    E7, E7, E7, 0,
    E7, E7, E7, 0,
    E7, G7, C7, D7, E7, 0,
    F7, F7, F7, F7, F7, E7, E7, E7, G7, G7, F7, D7, C7, 0 
    ]

# This is the list of notes for Twinkle, Twinkle Little Star
twinkle = [
    C6, C6, G6, G6, A6, A6, G6, 0,
    F6, F6, E6, E6, D6, D6, C6, 0,
    G6, G6, F6, F6, E6, E6, D6, 0,
    G6, G6, F6, F6, E6, E6, D6, 0,
    C6, C6, G6, G6, A6, A6, G6, 0,
    F6, F6, E6, E6, D6, D6, C6, 0,
    ]


buzzer = GORILLACELL_BUZZER(10)

print("Playing mario.")
buzzer.play(mario, 150, 32767)
sleep_ms(1000)

print("Playing jingle bells.")
buzzer.play(jingle, 250, 32767)
sleep_ms(1000)

print("Playing twinkle, twinkle little star.")
buzzer.play(twinkle, 600, 32767)

Example 3, More Melodies:

# How to make some sound with MicroPython
# Author: George Bantique,
#         TechToTinker Youtube channel
#	  www.techtotinker.com
# Date: September 18, 2020

# This is the list of notes for jingle bells
jingle = [
    E7, E7, E7, 0,
    E7, E7, E7, 0,
    E7, G7, C7, D7, E7, 0,
    F7, F7, F7, F7, F7, E7, E7, E7, E7, D7, D7, E7, D7, 0, G7, 0,
    E7, E7, E7, 0,
    E7, E7, E7, 0,
    E7, G7, C7, D7, E7, 0,
    F7, F7, F7, F7, F7, E7, E7, E7, G7, G7, F7, D7, C7, 0 
]

def play_jingle():
    play(p23, jingle, 0.25, 512)

# This is the list of notes for Twinkle, Twinkle Little Star
twinkle = [
    C6, C6, G6, G6, A6, A6, G6, 0,
    F6, F6, E6, E6, D6, D6, C6, 0,
    G6, G6, F6, F6, E6, E6, D6, 0,
    G6, G6, F6, F6, E6, E6, D6, 0,
    C6, C6, G6, G6, A6, A6, G6, 0,
    F6, F6, E6, E6, D6, D6, C6, 0,
]

def play_twinkle():
    play(p23, twinkle, 0.6, 50)

7 thoughts on “007 – ESP32 MicroPython: How to make some sound with MicroPython

  1. Hello George, I'm thankful to you for this Micropython tutorials. I have NodeMCU ESP8266 Dev. Board & I have connected GPIO pin 4 for the same code(changed p23 to p4 at all places in your code) but it is not giving me the same sound output as shown in your YouTube video. The first code is working perfectly fine but the other one doesn't. Can you please tell me what is the issue behind the stuff? or if possible help me by sharing new codes of mario melody, twinkle & jingle, compatible to NodeMCU ESP8266 Board.

  2. @Pranav Khatale, can you try again with the following?

    # How to make some sound with MicroPython
    # Example 2: Make a mario sound
    # Author: George Bantique,
    # TechToTinker Youtube channel
    # techtotinker.blogspot.com
    # Date: September 18, 2020

    import machine
    import time

    p4 = machine.Pin(4, machine.Pin.OUT)

    # These are the notes with equivalent frequency
    # https://www.blackghostaudio.com/blog/basic-music-theory-for-beginners
    B0 = 31
    C1 = 33
    CS1 = 35
    D1 = 37
    DS1 = 39
    E1 = 41
    F1 = 44
    FS1 = 46
    G1 = 49
    GS1 = 52
    A1 = 55
    AS1 = 58
    B1 = 62
    C2 = 65
    CS2 = 69
    D2 = 73
    DS2 = 78
    E2 = 82
    F2 = 87
    FS2 = 93
    G2 = 98
    GS2 = 104
    A2 = 110
    AS2 = 117
    B2 = 123
    C3 = 131
    CS3 = 139
    D3 = 147
    DS3 = 156
    E3 = 165
    F3 = 175
    FS3 = 185
    G3 = 196
    GS3 = 208
    A3 = 220
    AS3 = 233
    B3 = 247
    C4 = 262
    CS4 = 277
    D4 = 294
    DS4 = 311
    E4 = 330
    F4 = 349
    FS4 = 370
    G4 = 392
    GS4 = 415
    A4 = 440
    AS4 = 466
    B4 = 494
    C5 = 523
    CS5 = 554
    D5 = 587
    DS5 = 622
    E5 = 659
    F5 = 698
    FS5 = 740
    G5 = 784
    GS5 = 831
    A5 = 880
    AS5 = 932
    B5 = 988
    C6 = 1047
    CS6 = 1109
    D6 = 1175
    DS6 = 1245
    E6 = 1319
    F6 = 1397
    FS6 = 1480
    G6 = 1568
    GS6 = 1661
    A6 = 1760
    AS6 = 1865
    B6 = 1976
    C7 = 2093
    CS7 = 2217
    D7 = 2349
    DS7 = 2489
    E7 = 2637
    F7 = 2794
    FS7 = 2960
    G7 = 3136
    GS7 = 3322
    A7 = 3520
    AS7 = 3729
    B7 = 3951
    C8 = 4186
    CS8 = 4435
    D8 = 4699
    DS8 = 4978

    # Function play is use to play sound from a list of notes
    def play(pin, melodies, delays, duty):
    # Create the pwm object
    pwm = machine.PWM(pin)
    # Loop through the whole list
    for note in melodies:
    pwm.freq(note)
    pwm.duty(duty)
    time.sleep(delays)
    # Disable the pulse, setting the duty to 0
    pwm.duty(0)
    # Disconnect the pwm driver
    pwm.deinit()

    # This is the list of notes for mario theme
    # 0 denotes rest notes
    mario = [
    E7, E7, 0, E7, 0, C7, E7, 0,
    G7, 0, 0, 0, G6, 0, 0, 0,
    C7, 0, 0, G6, 0, 0, E6, 0,
    0, A6, 0, B6, 0,AS6, A6, 0,
    G6, E7, 0, G7, A7, 0, F7, G7,
    0, E7, 0, C7, D7, B6, 0, 0,
    C7, 0, 0, G6, 0, 0, E6, 0,
    0, A6, 0, B6, 0,AS6, A6, 0,
    G6, E7, 0, G7, A7, 0, F7, G7,
    0, E7, 0, C7, D7, B6, 0, 0,
    ]

    # Function to easily play the mario theme
    def play_mario():
    # Play the mario theme to GPIO 23
    # with 150ms note interval
    # with a low volume
    play(p4, mario, 0.15, 50)

  3. hi bro
    I've problem with do it.
    with simple code in python and simple connect buzzer to ESP32, nothing happening. it seems, duty not work!. after code: buzzer.duty(50), for test it, i want to see duty value with this code: pring(buzzer.duty()). it show 0.
    note: I'm working in Wokwi.com simulator

  4. thank you very much you tutorial is very useful .I enjoyed your tutorial Sir George. But I have I problem whzn i send a 0 freqency for exemple in the function play_mario i had this error message and the sound doesn’t play:
    Traceback (most recent call last):
    File “”, line 1, in
    File “”, line 139, in play_mario
    File “”, line 111, in play
    ValueError: freqency must be from 1Hz to 40MHz

    I use an ESP32 for this exemple with the same pin with you p23.

Leave a Reply

Your email address will not be published. Required fields are marked *