Per començar | Elements d'entrada | Programació CircuitPython | Recursos CITCEA | |
Elements no electrònics | Elements de sortida | Programació Arduino | ||
Projectes | Elements de control | Dades pràctiques | Inici |
En la placa Circuit Playground podem emprar la sortida A0 per generar sons de qualitat i reproduir-los a l'altaveu de la placa o en un altaveu extern.
Atès que només podem indicar valors enters de la freqüència, caldrà fer una aproximació. La taula següent indica els valors de freqüència per obtenir les notes de l'escala central del piano:
Nota | Freqüència teòrica (Hz) | Valor recomanat (Hz) | |||
do3 | C4 | 261,626 | 262 | ||
do#3 | re b3 | C#4 | Db4 | 277,183 | 277 |
re3 | D4 | 293,665 | 294 | ||
re#3 | mi b3 | D#4 | Eb4 | 311,127 | 311 |
mi3 | E4 | 329,628 | 330 | ||
fa3 | F4 | 349,228 | 349 | ||
fa#3 | sol b3 | F#4 | Gb4 | 369,994 | 370 |
sol3 | G4 | 391,995 | 392 | ||
sol#3 | la b3 | G#4 | Ab4 | 415,305 | 415 |
la3 | A4 | 440,000 | 440 | ||
la#3 | si b3 | A#4 | Bb4 | 466,164 | 466 |
si3 | B4 | 493,883 | 494 | ||
do4 | C5 | 523,251 | 523 |
Tenim dues maneres de generar sons. Per a tons senzills podem generar ones de la freqüència desitjada. L'altra opció és reproduir el so d'un fitxer WAV.
El programa següent mostra com crear un so d'una sola nota.
import audiocore import array import math import time import audioio import board import digitalio
Freq = 440 # Frequencia que volem fer sonar (La3) Mostreig = 8000 # 8000 mostres/segon, valor recomanat NumValors = Mostreig//Freq # Nombre de valors diferents per cicle # Creem una estructura array per guardar l'ona ona = array.array("H", [0] * NumValors) # La "H" indica que seran valors enters ocupant dos bytes cada un # Definint-ho aixi estalviem memoria # Aquest array s'omplira amb NumValors elements [0] # # Anem a calcular els valors for k in range(NumValors): ona[k] = int((1 + math.sin(2 * math.pi * k / NumValors)) * 32767) # La funcio sin dona valors entre -1 i 1 # Li sumem 1 per tenir un valor entre 0 i 2 # Multipliquem per 32768 per tenir un valor entre 0 i 65535 # # Anem a activar l'altaveu de la placa altaveu = digitalio.DigitalInOut(board.SPEAKER_ENABLE) altaveu.direction = digitalio.Direction.OUTPUT altaveu.value = True # Si posessim False l'altaveu estaria desactivat sons = audioio.AudioOut(board.SPEAKER) sinusoide = audiocore.RawSample(ona) sons.play(sinusoide, loop=True) # Fem sonar l'array repetidament time.sleep(1) # durant un segon sons.stop() # i el parem sons.deinit() # Alliberem l'objecte # per si hi ha un altre so posterior
Podem afegir un control de volum afegint un paràmetre en el càlcul de l'ona:
ona[k] = int((1 + math.sin(2 * math.pi * k / NumValors)) * 32767 * Vol)
on el paràmetre Vol ha d'estar entre 0 i 1.
En CircuitPython la biblioteca audio_lib.py ens permet fer sonar una nota determinada durant un temps concret i amb un volum que podem escollir. Per descarregar-la heu de picar amb el botó dret del ratolí. Aquí tenim un exemple en el que es fa sonar un Mi i un Sol durant mig segon cada un:
import audio_lib import board import digitalio import time import audioio
altaveu = digitalio.DigitalInOut(board.SPEAKER_ENABLE) altaveu.direction = digitalio.Direction.OUTPUT altaveu.value = True sons = audioio.AudioOut(board.SPEAKER) while True: sinusoide = audio_lib.nota(330, 1) # Mi # El segon parametre es el volum, entre 0 i 1 sons.play(sinusoide, loop=True) time.sleep(0.5) sinusoide = audio_lib.nota(392, 1) # Sol sons.play(sinusoide, loop=True) time.sleep(0.5) sons.stop() time.sleep(2)
Podríem connectar un altaveu extern o uns auriculars i desactivar l'altaveu de la placa. La connexió de l'altaveu la podem fer com mostra la fotografia segúent. El cable verd el conectaríem a la sortida A0 i el negre a la pota GND.
No és imprescindible que l'ona de so sigui sinusoïdal. En aquest exemple es compara com sona la mateixa nota segons si l'ona és sinusoïdal, triangular o quadrada. Podeu trobar l'explicació del programa a partir de la pàgina 74 del número 26 de la revista HackSpace magazine.
Una alternativa que pot ser útil en molts casos és reproduir un fitxer de so. Cal que el fitxer estigui gravat al disc CIRCUITPY en format wav monoaural (no estereofònic) amb una freqüència de mostreig més petita o igual de 22 kHz amb format 16 bit PCM.
Nota: El que s'explica en aquest apartat només funciona amb les darreres versions de CircuitPython. Si no teniu una versió recent cal que la instal·leu seguint les instruccions d'aquesta pàgina.
El programa següent reprodueix el fitxer de so ring.wav cada cop que es prem un dels dos polsadors de la placa.
import audiocore import audioio import board import digitalio
# Configura l'altaveu altaveu = digitalio.DigitalInOut(board.SPEAKER_ENABLE) altaveu.direction = digitalio.Direction.OUTPUT altaveu.value = True # Configura els dos polsadors polsadorA = digitalio.DigitalInOut(board.BUTTON_A) polsadorA.direction = digitalio.Direction.INPUT polsadorA.pull = digitalio.Pull.DOWN polsadorB = digitalio.DigitalInOut(board.BUTTON_B) polsadorB.direction = digitalio.Direction.INPUT polsadorB.pull = digitalio.Pull.DOWN
# Funcio per reproduir el fitxer de so def play_file(nom_fitxer): print("Inici del so") fitxer = open(nom_fitxer, "rb") with audiocore.WaveFile(fitxer) as wave: with audioio.AudioOut(board.A0) as audio: audio.play(wave) while audio.playing: pass print("Fi del so")
while True: if polsadorA.value: play_file("ring.wav") if polsadorB.value: play_file("ring.wav")
En aquest web, les fotografies marcades amb [AF] són del web d'Adafruit, les marcades amb [SF] del web d'Sparkfun i les marcades amb [AU] del web d'Arduino.
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.