En los tiempos que corren estamos acostumbrados a vivir rodeados de tecnología, hoy en día cualquier movil supera en millones de operaciones por segundo al primer ordenador que tuve, hasta un PIC puede funcionar a mas velocidad que un 80286, pero hubo un tiempo en que un teléfono movil no estába al alcance de cualquiera, y en esa época no existían aparatos capaces de brindarnos la experiencia multimedia que hoy damos por sentado de que es así. Y estamos hablando de poco menos de 20 años atras, en esa epoca por lo menos los PC normales, no disponían de una placa de sonido y cualquier juego ejecutaba a duras penas un, a veces, desesperante pitido a modo de música.
Bueno, es por eso que en un arrebato de nostalgia se me ocurrió que podría emular esas "dulces" melodías con un PIC y es por eso que ahora tu estás leyendo esto. Inmediatamente despues me acordé de algo muy importante y es que no tengo ni la mas remota idea de música. Entonces decidí comenzar por el lugar mas obvio, o sea por el principio, fue cuando deduje que para que haya música primero tiene que haber sonido, entonces lo primero que hay que hacer es que el PIC emita algo de sonido controlado, ya habrá tiempo de generar notas musicales.
Primero hay que tener un concepto aunque sea básico de lo que el sonido es, en principio el sonido es un golpe en un medio, en nuestro caso el aire y, dependiendo de la frecuencia de ese "golpe", el sonido producido será mas agudo o mas grave; El oido humano puede percibir sonidos con una frecuencia que está comprendida entre los 20Hz y los 20KHz, en otras palabras que una persona puede escuchar frecuencias de esos golpes desde unas 20 veces por segundo hasta unas 20 mil aproximadamente. Entonces aquí ya tenemos un dato: para generar el sonido con el PIC debemos conectar un altavoz a una salida del microcontrolador y hacer alternar su estado de alto a bajo a una frecuencia determinada. Cuanto mas rápido se varíe el estado mas agudo será el sonido y viceversa.
Para obtener la duración del periodo (estado alto o bajo) para una frecuencia f solo hace falta usar la siguiente formula:
tP = 1
fPara generar un sonido dentro de los margenes perceptibles, digamos de unos 650Hz realizaremos la siguiente operación:
tP = 1
650= 0,0015385 El resultado obtenido es el tiempo, en segundos, que debe tardar cada periodo para producir un sonido de 650Hz. En este caso es 1538uS que es la medida que nosotros necesitamos para operar con el PIC, recuerda que un PIC con un cristal corriendo a 4 MHz realiza una operacion cada 1uS.
Cada 1538uS o, lo que es lo mismo, cada 1,538mS se debe producir un cambio de estado del la salida del microcontrolador para producir un sonido a 650Hz, entonces lo que necesitamos ahora es dividir ese valor en 2, una mitad para el estado alto y la otra mitad en estado bajo.
Con todo esto tenemos que: 1538 / 2 = 769, si traducimos esta teoría en lenguaje C quedaría de esta forma:
#include <16f876a.h> // Tipo de microcontrolador #use delay(clock=4000000) // Delay con xtal de 4MHz #use fast_io(all) // I/O todas rápidas, de esta forma cuando se // escribe en los puertos, no se configura el tris // acelerando el proceso. #fuses HS // FUSES cristal HS >=4MHz #FUSES NOPUT // No power up Timer, no espera a estabilizar la tension #FUSES NOBROWNOUT // No Brown out reset, no se resetea si cae la tension #define Speaker PIN_B0 // Altavoz conectado a RB0 void main(){ set_tris_b(2); // RB<7:2> Salida RB1 entrada (Pulsador) RB0 Salida (Speaker) do{ // Bucle infinito while(input(PIN_B1)){ // Mientras se presione el // interruptor conectado a RB1. output_high(Speaker); // Altavoz encendido delay_us(769); // espera 769 uS output_low(Speaker); // Altavoz apagado delay_us(769); // espera 769 uS } }while(true); }
Este ejemplo lo único que hace es emitir un sonido, ni agudo, ni grave, cuando se activa el pulsador conectado a RB1.
Nuestro PIC acaba de emitir su primer sonido!
Ahora podremos crear una funcion que emita un sonido con la frecuencia y duracion deseados.
El siguiente ejemplo hace sonar una sirena cuando se pulsa un interruptor en RB1.
///////////////////////////////////////////////////////////////////////////// // // // PICSirena 1.00 // // (c) 2010 Gerardo Ariel Ramírez. // // // ///////////////////////////////////////////////////////////////////////////// // // // uControlador: PIC16F876A Lenguaje: CCS C // // Xtal: 4MHz // // // ///////////////////////////////////////////////////////////////////////////// #include <16f876a.h> // Tipo de microcontrolador #use delay(clock=4000000) // Delay con xtal de 4MHz #use fast_io(all) // I/O todas rápidas, de esta forma cuando se // escribe en los puertos, no se configura el tris // acelerando el proceso. #FUSES HS // FUSES cristal HS >=4MHz #FUSES NOPUT // No power up Timer, no espera a estabilizar la tension #FUSES NOBROWNOUT // No Brown out reset, no se resetea si cae la tension #define Speaker PIN_B0 // Altavoz conectado a RB0 void Sound(int16 frecuencia, int16 duracion); void main(){ int t; set_tris_b(2); while(true){ //Bucle infinito if (input(PIN_B1)){ // Si se activa el pulsador for (t=0;t<30;t++) // Bucle ascendente incrementando la sound(((int16)t*15)+1600,20); // frecuencia del sonido for (t=30;t>0;t--) // Bucle decrementando sound(((int16)t*15)+1600,20); // la frecuencia del sonido } } } void Sound(int16 frecuencia, int16 duracion){ int16 mS_Transcurridos=0; int16 CiclosL=0; int16 uS; int32 tmp; if (frecuencia>=20&&frecuencia<=20000){ //si la frecuancia se encuentra entre // los margenes de 20Hz y 20 KHz se ejecuta tmp=100000; // de los contrario no. tmp/=frecuencia; // convierte los Hz a microsegundos para la pausa tmp*=5; uS=tmp; do{ output_high(Speaker); // Genera la frecuancia deseada delay_us(uS); // con los retardos mientras CiclosL+=(uS); // aumenta el contador de ciclos transcurridos output_low(Speaker); // en dos partes para repartir el delay_us(uS); // trabajo entre estado alto y bajo. CiclosL+=(uS); // CiclosL+=25; // Compensador. while(CiclosL>999){ // Se queda en el bucle mientras CiclosL sea // menor a 1000 (1 mS) CiclosL-=1000; // Le resta 1000 a CiclosL mS_Transcurridos++; // y le suma 1 a mS_Transcurridos. CiclosL+=25; // Compensador. } }while (duracion>mS_Transcurridos);// Repite el bucle hasta que haya pasado el // tiempo indicado. } }
Desde este link te puedes bajar el proyecto y el hex.
Bueno, hasta aquí hemos llegado, ahora resta por hacer que el PIC reproduzca alguna nota musical e interprete alguna canción, pero eso lo veremos en Generar música con PIC.
Hola, Como podria generar un sonido que vaya variando de frecuencia pero en el rango de los ultrasonicos (20K a 60KHz ). ¿Que speaker podria conectar y como?
ResponderEliminarSaludos desde Tigre, Buenos Aires, Argentina
Sólo debes generar la frecuencia deseada y, en lugar de un altavoz normal, utilizar un transductor ultrasónico.
ResponderEliminarSi tienes dudas sobre como generar las frecuencia, me avisas.
Saludos.
hola,
Eliminaruna pregunta como harias para generar sonidos como un laser disparando? es que he bajado sonidos en wav y lo he convertido en binario pero no se como usar esa informacion para generar sonidos,
me podrias ayudar?
gracias
De casualidad tienes el programa en asm, es que en c no entiendo nada.
ResponderEliminarMil gracias
Dame unos días, y lo posteo.
ResponderEliminarDe todas formas te cuento que en el programa IC-Prog, hay una opción que, cargando el HEX, te lo convierte a código Assembler. Es bastante genérico, sin nombres de variables, ni nada, pero para tener una idea y, si entiendes ASM, sirve bastante.
En realidad lo único que hace es "traducir" los opcodes a la sintaxis de ASM.
Saludos.
Hola
ResponderEliminarFijate amigo que en la escuela me dejaron un generador de tonos telefonico con un pic mi pregunta es k si con tu codigo guiandome pueda lograr que se genere un determinado tono con su respectiva frecuencia ej1472hz al momento de tocar un boton y lograr esto con los demas 9 tonos espero ke me puedas ayudar de antemano gracias saludos
ResponderEliminarBuenas, en la entrada http://picrobot.blogspot.com/2010/03/picmusic.html puedes observar que está la tabla con las frecuencias de cada nota musical. Si te fijas en FA# en la octava 5.
ResponderEliminarPuedes hacerlo modificando los valores para obtener las frecuencias deseadas, el inconveniente es que no podrías ejecutar 2 al mismo tiempo.
Saludos.
hola, tu proyecto esta muy interesante al igual que el de generar música con PIC, si podrías subir los archivos a otro servidor distinto a Megaupload. Te lo agradecería
ResponderEliminarHola, muy buena la pagina.
ResponderEliminarNecesitaria un programita para un PIC que generara 5 ó 6 tonos secuenciales, de una duración aproximada de entre 30 y 100 ms cada tono, que se activara este tren de tonos al poner un pin a masa y despues volviera a reposo. Desde ya muchas gracias.
amigo,buen día estoy empezando en esto, es factible que pueda utilizar un pic 18f84a? o en que afectaria, de antemano gracias por dedicar tu tiempo y compartir conocimientos
ResponderEliminarperdón es el "16f84a"
EliminarBuen día, por favor me podrías decir cuales son las frecuencias de los tonos de ambulancia? muchas gracias
ResponderEliminarHola les dejo los videos de unas melodias reproducidas con PIC
ResponderEliminarhttp://www.youtube.com/watch?v=jZexwvP0FUU
http://www.youtube.com/watch?v=I699YIQdYYc
Hola, tienes tutoriales para aprender a programar microcontroladores en C y que compilador me recomiendas. Saludos Excelente tu WEB
ResponderEliminarMaravilloso, muy util tu articulo! te felicito!
ResponderEliminarhola,
ResponderEliminaruna pregunta como harias para generar sonidos como un laser disparando? es que he bajado sonidos en wav y lo he convertido en binario pero no se como usar esa informacion para generar sonidos,
me podrias ayudar?
gracias
Hola, un tutorial muy interesante, he comenzado a aprender a programar y un proyecto que quisiera logra es usando un 12f675, generar sonidos usando un buscapolos que funcione con 12 volts. que se genere un sonido alto cuando se detecte un voltaje de 5 volts arriba y un tono bajo al detectar de .5 volts hacia tierra. cualquier ayuda seria de gran utilidad. gracias!
ResponderEliminarMuy bueno.... Te agradezco el esfuerzo por mantener este blog.
ResponderEliminarhola una pregunta para generar por ejemplo un tono corto un tono largo y dos tonos cortos mas como seria
ResponderEliminar