In diesem Beitrag möchte ich dir jetzt zeigen, wie du Töne und sogar ganze Lieder mit einem Piezo Buzzer am ESP32 mit MicroPython erzeugen kannst.
Im Beitrag MicroPython mit ESP32: Helligkeitsregelung von LEDs mit PWM hatte ich dir bereits gezeigt, wie du PWM Signale erstellen kannst, um die Helligkeit einer LED zu regeln. Für das Erzeugen eines Tones benötigen wir ebenfalls ein PWM Signal, in diesem Fall regeln wir damit die Frequenz des Tones.
Auf meinem Blog hatte ich dir bereits einen ähnlichen Beitrag in der Vergangenheit zu diesem Thema unter Programmieren mit MicroPython #5: Piezo Buzzer am ESP32 betreiben veröffentlicht, hier möchte ich jedoch passend zum Rich Shield von Open Smart speziell auf dieses eingehen.
Inhaltsverzeichnis
- Schaltung – Piezo Buzzer am ESP32 D1 R32
- Schaltung ohne Rich Shield von Open Smart
- Erzeugen eines Tones am Piezo Buzzer mit MicroPython
- Regeln der Frequenz mit dem Drehpotentiometer
- Ein Lied auf dem Piezo Buzzer abspielen
- Ausblick
Schaltung – Piezo Buzzer am ESP32 D1 R32
Für diese Beitragsreihe verwende ich wie bereits erwähnt das Rich Shield von Open Smart. Auf diesem ist ein Piezo Buzzer verbaut, welcher wie folgt, mit dem Mikrocontroller verbunden ist:
Bauteil | ESP32 D1 R32 | Arduino UNO R3 |
---|---|---|
Piezo Buzzer | IO25 | D4 |
Schaltung ohne Rich Shield von Open Smart
Wenn du das genannte Shield nicht hast, dann kannst du dir recht einfach diese kleine Schaltung selber nachbauen.
- einen ESP32 D1 R32*
- einen Piezo Buzzer*
- ein 170 Pin Breadboard*
- zwei Breadboardkabel*, männlich-männlich
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Erzeugen eines Tones am Piezo Buzzer mit MicroPython
Der kleine Piezo Buzzer nutzt die Spannung vom GPIO und somit benötigst du keine zusätzliche Stromquelle. Das macht die Schaltung einfach, jedoch ist dieser dadurch auch nicht besonders laut.
Für kleine Spielereien am Mikrocontroller sind diese jedoch ideal!
from machine import Pin, PWM # Importiere die notwendigen Module Pin und PWM aus der machine-Bibliothek import time # Importiere das time-Modul für Zeitsteuerungsfunktionen # Initialisiere den Piezo Buzzer auf Pin 25 mit einer Frequenz von 440 Hz und einem Duty Cycle von 50% (512 von 1024) beeper = PWM(Pin(25), freq=440, duty=512) # Lasse den Ton für 0,5 Sekunden erklingen time.sleep(0.5) # Deinitialisiere den PWM-Kanal, um den Ton zu stoppen beeper.deinit()
Erklärung der einzelnen Codezeilen:
from machine import Pin, PWM
:- Diese Zeile importiert die
Pin
undPWM
Klassen aus demmachine
Modul.Pin
wird verwendet, um die GPIO-Pins zu konfigurieren, undPWM
wird verwendet, um PWM-Signale zu erzeugen.
- Diese Zeile importiert die
import time
:- Das
time
Modul wird importiert, um Verzögerungen einzufügen.
- Das
beeper = PWM(Pin(25), freq=440, duty=512)
:Pin(25)
: Initialisiert den GPIO-Pin 25 als PWM-Ausgang.freq=440
: Setzt die PWM-Frequenz auf 440 Hz, was der Frequenz des Tons A entspricht (auch bekannt als der Kammerton A).duty=512
: Setzt den Duty Cycle auf 512, was 50 % der maximalen Duty Cycle (0 …1023) entspricht. Dies bedeutet, dass das Signal gleichmäßig zwischen an und aus wechselt.
time.sleep(0.5)
:- Wartet 0,5 Sekunden, während der Piezo Buzzer den Ton mit der eingestellten Frequenz und Duty Cycle ausgibt.
beeper.deinit()
:- Deinitialisiert den PWM-Kanal, wodurch der Ton gestoppt wird. Der PWM-Ausgang wird deaktiviert und der GPIO-Pin wird in seinen ursprünglichen Zustand zurückversetzt.
Dieser einfache Code erzeugt einen Ton mit einer Frequenz von 440 Hz (A4) für eine halbe Sekunde über einen Piezo Buzzer, der an GPIO-Pin 25 des ESP32 angeschlossen ist.
Regeln der Frequenz mit dem Drehpotentiometer
Im Beitrag MicroPython mit ESP32: Einführung in analoge Sensoren habe ich dir erläutert wie du einen Drehpotentiometer auslesen kannst, mit diesem analogen Bauteil kannst du auch die Frequenz anpassen.
In dem Code habe ich eine zusätzliche Funktion implementiert welche den Wertebereich des analogen Sensors (Drehpotentiometer) auf einen Frequenzbereich mappt.
# Funktion zum Mappen der analogen Werte des Drehpotentiometers (0..1023) # auf eine Frequenz von 200 Hz bis 1500 Hz def map_value(x, in_min=0, in_max=1023, out_min=200, out_max=1500): return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min
Wenn du die Frequenz erhöhen möchtest dann kannst du die Parameter out_min & out_max entweder in der Funktion anpassen oder du gibst diese als namedparameter beim aurufen der Funktion mit.
# Module zum Zugriff auf die GPIOs from machine import Pin, ADC, PWM # Modul zum Zugriff auf Funktionen # wie zum einlegen einer Pause im Code from time import sleep # ADC12 am GPIO2, als Eingang adc_pin = Pin(2, mode=Pin.IN) # Initialisieren eines ADC Objektes # (analog digital converter) adc = ADC(adc_pin) # Auflösung auf 0..1023 (10bit) adc.atten(ADC.ATTN_11DB) adc.width(ADC.WIDTH_10BIT) # Initialisiere den Piezo Buzzer auf Pin 25 # mit einer Frequenz von 440 Hz und einem Duty Cycle von 50% (512 von 1024) beeper = PWM(Pin(25), freq=440, duty=512) # Funktion zum Mappen der analogen Werte des Drehpotentiometers (0..1023) # auf eine Frequenz von 200 Hz bis 1500 Hz def map_value(x, in_min=0, in_max=1023, out_min=200, out_max=1500): return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min try: # Starten der Endlosschleife while True: analogValue = adc.read() frequenz = map_value(analogValue) beeper.freq(frequenz) print("analogValue:", analogValue) print("frequenz:", frequenz) sleep(0.25) except KeyboardInterrupt: # Deinitialisiere den PWM-Kanal, um den Ton zu stoppen beeper.deinit()
Hier nun das komplette Programm zum steuern der Frequenz mit einem Drehpotentiometer. Natürlich kannst du auch einen Fotowiderstand verwenden welcher ähnlich funktioniert.
Ein Lied auf dem Piezo Buzzer abspielen
Ein Lied ist quasi lediglich eine Aneinanderreihung von Tönen, welche in einer bestimmten Frequenz und Dauer abgespielt werden. Natürlich kannst du über den Piezo Buzzer über diese technische Lösung keine umfangreichen MP3-Dateien abspielen, jedoch kleine Lieder im Klassischen 8Bit Style sind easy möglich.
Bei nachfolgenden Liedern habe ich mich aus dem GitHub Repository robsoncouto/arduino-songs bedient welche eigentlich für den Arduino gedacht sind, jedoch ist der Code so einfach, das man diesen mit wenig aufwand zu MicroPython konvertieren kann.
from machine import Pin, PWM from time import sleep import urandom # Definition der Notenfrequenzen NOTE_B0 = 31 NOTE_C1 = 33 NOTE_CS1 = 35 NOTE_D1 = 37 NOTE_DS1 = 39 NOTE_E1 = 41 NOTE_F1 = 44 NOTE_FS1 = 46 NOTE_G1 = 49 NOTE_GS1 = 52 NOTE_A1 = 55 NOTE_AS1 = 58 NOTE_B1 = 62 NOTE_C2 = 65 NOTE_CS2 = 69 NOTE_D2 = 73 NOTE_DS2 = 78 NOTE_E2 = 82 NOTE_F2 = 87 NOTE_FS2 = 93 NOTE_G2 = 98 NOTE_GS2 = 104 NOTE_A2 = 110 NOTE_AS2 = 117 NOTE_B2 = 123 NOTE_C3 = 131 NOTE_CS3 = 139 NOTE_D3 = 147 NOTE_DS3 = 156 NOTE_E3 = 165 NOTE_F3 = 175 NOTE_FS3 = 185 NOTE_G3 = 196 NOTE_GS3 = 208 NOTE_A3 = 220 NOTE_AS3 = 233 NOTE_B3 = 247 NOTE_C4 = 262 NOTE_CS4 = 277 NOTE_D4 = 294 NOTE_DS4 = 311 NOTE_E4 = 330 NOTE_F4 = 349 NOTE_FS4 = 370 NOTE_G4 = 392 NOTE_GS4 = 415 NOTE_A4 = 440 NOTE_AS4 = 466 NOTE_B4 = 494 NOTE_C5 = 523 NOTE_CS5 = 554 NOTE_D5 = 587 NOTE_DS5 = 622 NOTE_E5 = 659 NOTE_F5 = 698 NOTE_FS5 = 740 NOTE_G5 = 784 NOTE_GS5 = 831 NOTE_A5 = 880 NOTE_AS5 = 932 NOTE_B5 = 988 NOTE_C6 = 1047 NOTE_CS6 = 1109 NOTE_D6 = 1175 NOTE_DS6 = 1245 NOTE_E6 = 1319 NOTE_F6 = 1397 NOTE_FS6 = 1480 NOTE_G6 = 1568 NOTE_GS6 = 1661 NOTE_A6 = 1760 NOTE_AS6 = 1865 NOTE_B6 = 1976 NOTE_C7 = 2093 NOTE_CS7 = 2217 NOTE_D7 = 2349 NOTE_DS7 = 2489 NOTE_E7 = 2637 NOTE_F7 = 2794 NOTE_FS7 = 2960 NOTE_G7 = 3136 NOTE_GS7 = 3322 NOTE_A7 = 3520 NOTE_AS7 = 3729 NOTE_B7 = 3951 NOTE_C8 = 4186 NOTE_CS8 = 4435 NOTE_D8 = 4699 NOTE_DS8 = 4978 REST = 0 # Ändere dies, um das Lied langsamer oder schneller zu machen tempo = 100 # Ändere dies auf den Pin, den du verwenden möchtest buzzer_pin = 25 buzzer = PWM(Pin(buzzer_pin)) # Noten der Melodie gefolgt von der Dauer melody = [ NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4 , 4, REST, 8, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4, 8, REST, 16, NOTE_B4, 16, NOTE_C5, 16, NOTE_D5, 16, NOTE_E5, -8, NOTE_G4, 16, NOTE_F5, 16, NOTE_E5, 16, NOTE_D5, -8, NOTE_F4, 16, NOTE_E5, 16, NOTE_D5, 16, NOTE_C5, -8, NOTE_E4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_E5, 16, NOTE_E6, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4, 8, REST, 16, NOTE_B4, 16, NOTE_C5, 16, NOTE_D5, 16, NOTE_E5, -8, NOTE_G4, 16, NOTE_F5, 16, NOTE_E5, 16, NOTE_D5, -8, NOTE_F4, 16, NOTE_E5, 16, NOTE_D5, 16, NOTE_C5, -8, NOTE_E4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_E5, 16, NOTE_E6, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4, 8, REST, 16, NOTE_C5, 16, NOTE_C5, 16, NOTE_C5, 16, NOTE_C5 , 4, NOTE_F5, -16, NOTE_E5, 32, NOTE_E5, 8, NOTE_D5, 8, NOTE_AS5, -16, NOTE_A5, 32, NOTE_A5, 16, NOTE_G5, 16, NOTE_F5, 16, NOTE_E5, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_AS4, 8, NOTE_A4, 8, NOTE_A4, 32, NOTE_G4, 32, NOTE_A4, 32, NOTE_B4, 32, NOTE_C5 , 4, NOTE_D5, 16, NOTE_DS5, 16, NOTE_E5, -8, NOTE_E5, 16, NOTE_F5, 16, NOTE_A4, 16, NOTE_C5 , 4, NOTE_D5, -16, NOTE_B4, 32, NOTE_C5, 32, NOTE_G5, 32, NOTE_G4, 32, NOTE_G5, 32, NOTE_A4, 32, NOTE_G5, 32, NOTE_B4, 32, NOTE_G5, 32, NOTE_C5, 32, NOTE_G5, 32, NOTE_D5, 32, NOTE_G5, 32, NOTE_E5, 32, NOTE_G5, 32, NOTE_C6, 32, NOTE_B5, 32, NOTE_A5, 32, NOTE_G5, 32, NOTE_F5, 32, NOTE_E5, 32, NOTE_D5, 32, NOTE_G5, 32, NOTE_F5, 32, NOTE_D5, 32, NOTE_C5, 32, NOTE_G5, 32, NOTE_G4, 32, NOTE_G5, 32, NOTE_A4, 32, NOTE_G5, 32, NOTE_B4, 32, NOTE_G5, 32, NOTE_C5, 32, NOTE_G5, 32, NOTE_D5, 32, NOTE_G5, 32, NOTE_E5, 32, NOTE_G5, 32, NOTE_C6, 32, NOTE_B5, 32, NOTE_A5, 32, NOTE_G5, 32, NOTE_F5, 32, NOTE_E5, 32, NOTE_D5, 32, NOTE_G5, 32, NOTE_F5, 32, NOTE_D5, 32, NOTE_E5, 32, NOTE_F5, 32, NOTE_E5, 32, NOTE_DS5, 32, NOTE_E5, 32, NOTE_B4, 32, NOTE_E5, 32, NOTE_DS5, 32, NOTE_E5, 32, NOTE_B4, 32, NOTE_E5, 32, NOTE_DS5, 32, NOTE_E5, -8, NOTE_B4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, -8, NOTE_B4, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4, 8, REST, 16, NOTE_B4, 16, NOTE_C5, 16, NOTE_D5, 16, NOTE_E5, -8, NOTE_G4, 16, NOTE_F5, 16, NOTE_E5, 16, NOTE_D5, -8, NOTE_F4, 16, NOTE_E5, 16, NOTE_D5, 16, NOTE_C5, -8, NOTE_E4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_E5, 16, NOTE_E6, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_D5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, 8, REST, 16, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, 8, REST, 16, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4, 8, REST, 16, REST, 16, REST, 8, NOTE_CS5 , -4, NOTE_D5 , 4, NOTE_E5, 16, NOTE_F5, 16, NOTE_F5 , 4, NOTE_F5, 8, NOTE_E5 , -4, NOTE_D5 , 4, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4 , 4, NOTE_A4, 8, NOTE_A4, 8, NOTE_C5, 8, NOTE_B4, 8, NOTE_A4 , -4, NOTE_CS5 , -4, NOTE_D5 , 4, NOTE_E5, 16, NOTE_F5, 16, NOTE_F5 , 4, NOTE_F5, 8, NOTE_F5 , -4, NOTE_DS5 , 4, NOTE_D5, 16, NOTE_C5, 16, NOTE_AS4 , 4, NOTE_A4, 8, NOTE_GS4 , 4, NOTE_G4, 8, NOTE_A4 , -4, NOTE_B4 , 4, REST, 8, NOTE_A3, -32, NOTE_C4, -32, NOTE_E4, -32, NOTE_A4, -32, NOTE_C5, -32, NOTE_E5, -32, NOTE_D5, -32, NOTE_C5, -32, NOTE_B4, -32, NOTE_A4, -32, NOTE_C5, -32, NOTE_E5, -32, NOTE_A5, -32, NOTE_C6, -32, NOTE_E6, -32, NOTE_D6, -32, NOTE_C6, -32, NOTE_B5, -32, NOTE_A4, -32, NOTE_C5, -32, NOTE_E5, -32, NOTE_A5, -32, NOTE_C6, -32, NOTE_E6, -32, NOTE_D6, -32, NOTE_C6, -32, NOTE_B5, -32, NOTE_AS5, -32, NOTE_A5, -32, NOTE_GS5, -32, NOTE_G5, -32, NOTE_FS5, -32, NOTE_F5, -32, NOTE_E5, -32, NOTE_DS5, -32, NOTE_D5, -32, NOTE_CS5, -32, NOTE_C5, -32, NOTE_B4, -32, NOTE_AS4, -32, NOTE_A4, -32, NOTE_GS4, -32, NOTE_G4, -32, NOTE_FS4, -32, NOTE_F4, -32, NOTE_E4, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4, -8, REST, -8, REST, -8, NOTE_G4, 16, NOTE_F5, 16, NOTE_E5, 16, NOTE_D5 , 4, REST, 8, REST, -8, NOTE_E4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_E5, 8, NOTE_E5, 8, NOTE_E6, -8, NOTE_DS5, 16, NOTE_E5, 16, REST, 16, REST, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_GS4, 16, NOTE_B4, 16, NOTE_C5, 8, REST, 16, NOTE_E4, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_DS5, 16, NOTE_E5, 16, NOTE_B4, 16, NOTE_D5, 16, NOTE_C5, 16, NOTE_A4, -8, NOTE_C4, 16, NOTE_E4, 16, NOTE_A4, 16, NOTE_B4, -8, NOTE_E4, 16, NOTE_C5, 16, NOTE_B4, 16, NOTE_A4 , -4 ] # Anzahl der Noten berechnen notes = len(melody) // 2 # Dauer einer ganzen Note in ms berechnen wholenote = (60000 * 4) / tempo led1 = Pin(17, Pin.OUT) led2 = Pin(16, Pin.OUT) led3 = Pin(27, Pin.OUT) led4 = Pin(14, Pin.OUT) leds = [led1, led2, led3, led4] lastRandomNumber = -1 # Funktion zum Abspielen eines Tons def play_tone(pwm, freq, duration): pwm.freq(freq) pwm.duty(512) sleep(duration / 1000) pwm.duty(0) sleep(duration / 1000 * 0.1) # Setup und Melodie abspielen for i in range(0, len(melody), 2): note = melody[i] duration = melody[i + 1] randomNumber = -1 while (lastRandomNumber == randomNumber): randomNumber = urandom.randint(0, 3) lastRandomNumber = randomNumber led = leds[randomNumber] led.on() if duration > 0: note_duration = wholenote / duration else: note_duration = (wholenote / abs(duration)) * 1.5 if note == REST: sleep(note_duration / 1000) else: play_tone(buzzer, note, note_duration * 0.9) led.off() buzzer.deinit()
Ausblick
Im nächsten Beitrag werde ich dir zeigen, wie du mit einer Infrarot Fernbedienung die LEDs und den Piezo Buzzer bedienen kannst.