Yo también lo haría con solenoides con el positivo a común a todas y activadas independientemente cada una con transistores a emisor común.
El positivo común lo alimentaría a través de un mosfet comandado por el pwm del micro. Así podrías no solo tocar las notas sino además elegir la fuerza con la que el solenoide va a golpear cada tecla.
La secuencia sería:
- elijo la fuerza de la nota y la traduzco a un pwm con dutty positivo más amplio. A mayor dutty positivo más fuerte golpeará el solenoide.
- ahora activo el solenoide mediante su transistor de gnd y listo.
Siguiente nota.
Además podrías incluso hacer acordes por que puedes activar varios solenoides a la vez.
Eso en cuanto a la parte actuadora.
Respecto a la parte orquestadora pues te haces una función a la que le envías tres argumentos por ejemplo:
tocar ( nota,duración,fuerza) ;
La nota sería : c,d,e,f,g,a,b para (do, re, mi, fa, sol, la, si)
C#, d#, f#,g#,a#. ( para los sostenidos , teclas negras del piano)
La duración expresada en tiempos de compás. ( duración de las notas musicales)
Luego otra que sea:
Acorde(nota1,nota2,nota3,duración,fuerza); // tocar un acorde.
Luego la composición (secuencia de notas) la declaras en una tabla que contenga los tres argumentos (nota,duración,fuerza). Para la melodía
Para los acordes otra tabla con lo mismo.
Te creas una variable llamada tempo donde elijas la velocidad en BPM (beats por minuto) será tu base de tiempo y por la que se guiará la función tocar y acorde para aplicarles las duraciones a las notas en ms o segundos.
Una iteracción for(;
; será quien vaya leyendo las tablas y enviado a las funciones tocar() y acorde()
Un saludo.