Copyright (c) 2005 Javier Martínez. Se otorga permiso para copiar, distribuir y/o modificar este documento bajo los términos de la Licencia de Documentación Libre de GNU, Versión 1.2 o cualquier otra versión posterior publicada por la Free Software Foundation; sin Secciones Invariantes ni Textos de Cubierta Delantera ni Textos de Cubierta Trasera.

Este es un proyecto divertido. Un reproductor de tonos musicales, el cual lee las partituras de una eeprom serie y las reproduce en un altavoz piezo-eléctrico. Util para ponerlo dentro de un adorno navideño y deleitarnos con cientos de canciones cortas.
Un RingTone es una partitura musical desarrollada por Nokia, es conocida también por tonos NokRing o RTTTL (RingTone Text Transfer Language). Una canción se escribre de ésta manera:
Simpsons:d=4,o=5,b=160:32p,c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g
Una descripción del formato RTTTL lo puedes encontrar en internet, un fichero de texto con las especificaciones está aqui (copia local). Para clarificar conceptos, intentaré explicar brevemente el formato RTTTL. El nombre de la canción va delante del primer caracter “:”. La siguiente sección (entre el primer “:” y el segundo “:”) es el campo de control; en éste campo se definen los parámetros por defecto de la canción:
“d=4” - Duración de la nota por defecto. Una “redonda”
tiene una duración de 1/1 (4 tiempos), y una “negra”
tiene una duración de ¼ (1 tiempo). En la sintáxis RTTTL la “blanca” tiene un valor de “1” y la “negra” tiene un valor de "4”. En la canción superior (Simpsons), salvo que se especifique, la duración de la nota es “4” (una "negra").

“o=5” - Octava por defecto. En música (al igual que en electrónica), una octava es el intervalo entre una nota respecto a otra que tiene la mitad (o el doble) de la frecuencia. El formato RTTTL es capaz de manejar las octavas 4, 5, 6, y 7. En la canción superior (Simpsons), salvo que se especifique, la octava por defecto es “5” (La = 880 Hz).
Scientific Pitch Notation, ISO 16:1975 standard
|
Natural |
C |
|
D |
|
E |
F |
|
G |
|
A |
|
B |
|
Sharp |
|
C# |
|
D# |
|
|
F# |
|
G# |
|
A# |
|
|
Latina |
Do |
|
Re |
|
Mi |
Fa |
|
Sol |
|
La |
|
Si |
|
Octava 4 |
261,6 |
277,2 |
293,7 |
311,1 |
329,6 |
349,2 |
370,0 |
392,0 |
415,3 |
440,0 |
466,2 |
493.9 |
|
Octava 5 |
523.3 |
554.4 |
587.3 |
622.3 |
659.3 |
698.5 |
740 |
784 |
830.6 |
880 |
932.3 |
987.8 |
|
Octava 6 |
1047 |
1109 |
1175 |
1245 |
1319 |
1397 |
1480 |
1568 |
1661 |
1760 |
1865 |
1976 |
|
Octava 7 |
2093 |
2217 |
2349 |
2489 |
2637 |
2794 |
2960 |
3136 |
3322 |
3520 |
3729 |
3951 |
“b=160” - Tempo por defecto. En música, el Tempo se mide en tiempos/minuto (en inglés “beats per minute”, y una “redonda” tiene 4 tiempos. En la canción superior (Simpsons), el Tempo es de 160 (= 2.666 tiempos por segundo) y una “redonda” dura 1,5 segundos. Los valores de Tempo disponibles en éste proyecto son: 25, 28, 31, 35, 40, 45, 50, 56, 63, 70, 80, 90, 100, 112, 125, 140, 160, 180, 200, 225, 250, 285, 320 and 355.
Cualquier caracter detrás de “:” hasta el final son las notas de la canción. En nuestra canción superior (Simpsons), (d=4,o=5,b=160) una nota como ésta “... , g , ...” tiene algunos valores por defecto, como si fuera escrita así “... , 4g5 , ...”. La letra “p” es una nota especial sin sonido, y el caracter “.” incrementa la duración de la nota x1,5.
Intentaré escribir algunas palabras sobre cómo se implementa el sonido con un PIC16F628. Básicamente, la frecuencia de la nota es generada por el módulo PWM en el pin_b3, la duración de ésta está controlada por interrupciones del módulo TMR1, la envolvente de la forma de onda se controla con un par de resistencias.

Frecuencia de la nota
En cada nota el PIC configurará el módulo PWM para generar la frecuencia deseada. Suponiendo algunas constantes (fosc, TMR2 prescaler, etc.), el periodo de la onda está controlado por el registro PR2 y el Duty Cycle por el registro CCPR1.

PR2 = Int ( fosc / ( 4 * TMR2presc * fnote ) )
|
Nota |
Frequencia (Hz) |
PR2 (O4) |
TMR2 (ms) |
|
C |
261,6 |
238 |
3,824 |
|
C# |
277,2 |
225 |
3,616 |
|
D |
293,7 |
212 |
3,408 |
|
D# |
311,1 |
200 |
3,216 |
|
E |
329,6 |
189 |
3,040 |
|
F |
349,2 |
178 |
2,864 |
|
F# |
370,0 |
168 |
2,704 |
|
G |
392,0 |
159 |
2,560 |
|
G# |
415,3 |
150 |
2,416 |
|
A |
440,0 |
142 |
2,288 |
|
A# |
466,2 |
134 |
2,160 |
|
B |
493,9 |
126 |
2,032 |
Como puedes ver, sólo las notas de la octava 4 están en ésta tabla. Las notas de las octavas 5, 6 and 7 doblan la frecuencia de la octava anterior, por lo que el valor PR2 será la mitad en cada paso. En una primera aproximación, el valor CCPR1 será la mitad del de PR2 para tener un Duty Cycle del 50%.
Duración de la nota
Esto se hace con el módulo TMR1, usando interrupciones para controlar la duración de la nota lo más aproximado posible a un control en tiempo real. Para manejar la duración de la nota de una forma precisa, he dividido cada tiempo (en inglés “beat”) en 32 “tics”, esto me ayudará a manejar notas con un periodo de tiempo corto (como las de 1/32). La interrupción TMR1 es programada para cada “tic”, aqui hay un par de tablas con los valores iniciales necesarios:
|
Duración nota |
Beats |
Tics |
|---|---|---|
|
1 / 1 |
4 / 1 |
128 |
|
1 / 2 |
4 / 2 |
64 |
|
1 / 4 |
4 / 4 |
32 |
|
1 / 8 |
4 / 8 |
16 |
|
1 / 16 |
4 / 16 |
8 |
|
1 / 32 |
4 / 32 |
4 |
Init_TMR1 = int ( 65536 - ( 60 * fosc / ( bpm * tics * 4 * TMR1presc ) ) )
|
bpm |
Init_TMR1 |
Init_TMR1_H |
Init_TMR1_L |
TMR1 (ms) |
|
25 |
28036 |
109 |
132 |
75,000 |
|
28 |
32053 |
125 |
53 |
66,966 |
|
31 |
35294 |
137 |
222 |
60,484 |
|
35 |
38750 |
151 |
94 |
53,572 |
|
40 |
42098 |
164 |
114 |
46,876 |
|
45 |
44702 |
174 |
158 |
41,668 |
|
50 |
46786 |
182 |
194 |
37,500 |
|
56 |
48794 |
190 |
154 |
33,484 |
|
63 |
50655 |
197 |
223 |
29,762 |
|
70 |
52143 |
203 |
175 |
26,786 |
|
80 |
53817 |
210 |
57 |
23,438 |
|
90 |
55119 |
215 |
79 |
20,834 |
|
100 |
56161 |
219 |
97 |
18,750 |
|
112 |
57165 |
223 |
77 |
16,742 |
|
125 |
58036 |
226 |
180 |
15,000 |
|
140 |
58839 |
229 |
215 |
13,394 |
|
160 |
59676 |
233 |
28 |
11,720 |
|
180 |
60327 |
235 |
167 |
10,418 |
|
200 |
60848 |
237 |
176 |
9,376 |
|
225 |
61369 |
239 |
185 |
8,334 |
|
250 |
61786 |
241 |
90 |
7,500 |
|
280 |
62187 |
242 |
235 |
6,698 |
|
310 |
62511 |
244 |
47 |
6,050 |
|
355 |
62895 |
245 |
175 |
5,282 |
Envolvente de la onda
Aplicando todo lo explicado arriba podemos reproducir canciones, quizás no es lo mejor pero funciona. Ciertamente funciona como silbidos. En una primera aproximación, un par de resistencias nos dará cierto control sobre la amplitud de la onda. La idea básica es implementar la caída del sonido de una nota en el piano; esto es, una vez que la tecla del piano es apretada el sonido se apaga en unos pocos segundos.


La caída del sonido de la nota se ajusta por el método de "prueba y error", los valores actuales son: 150 msecs para un 66% amplitud y 300 msecs para un 33% amplitud. Los valores (en tics) a ser controlados por la interrupción TMR1 son:
|
bpm |
66% |
33% |
|
25 |
2 |
4 |
|
28 |
2 |
4 |
|
31 |
2 |
4 |
|
35 |
2 |
5 |
|
40 |
3 |
6 |
|
45 |
3 |
7 |
|
50 |
4 |
8 |
|
56 |
4 |
8 |
|
63 |
5 |
10 |
|
70 |
5 |
11 |
|
80 |
6 |
12 |
|
90 |
7 |
14 |
|
100 |
8 |
16 |
|
112 |
8 |
17 |
|
125 |
10 |
20 |
|
140 |
11 |
22 |
|
160 |
12 |
25 |
|
180 |
14 |
28 |
|
200 |
15 |
31 |
|
225 |
17 |
35 |
|
250 |
20 |
40 |
|
280 |
22 |
44 |
|
310 |
24 |
49 |
|
355 |
28 |
56 |
En una modificación final se ajusta el valor de Duty Cycle al 12,5%, esto aumentará los armónicos de la onda y sonará mejor. Aqui hay algunos ejemplos en formato MP3:
Partitura:
Bach_Badinerie:d=16,o=6,b=125:8b,d7,b,8f#,b,f#,8d,f#,d,4b5,f#5,b5,d,b5,c#,b5,c#,
a#5,c#,e,c#,8d,8b5,8b,d7,b,8f#,b,f#,8d,f#,d,4b5,8d,8d,8d,8d,8b,8d,32d,32c#,b5,32d,32c#,
8c#,8f#,8f#,8f#,8f#,8d7,8f#,32f#,32f,32f#,32f,8f,c#,f#,a,f#,g#,f#,g#,f#,f,g#,b,g#,a,
g#,a,g#,f#,a,f#,f,f#,b,f#,f,f#,c#7,f#,f,f#,d7,f#,f,f#,d7,c#7,b,c#7,a,g#,f#,8a,8g#,4f#,1p
PWM, DC 50%, 100% amplitud: bach_badinerie_1.mp3
PWM, DC 50%, control amplitud: bach_badinerie_2.mp3
PWM, DC 12,5%, control amplitud: bach_badinerie_3.mp3
Una vez que tengas algunas canciones a grabar en la EEPROM, debes crear un fichero de texto con todas ellas. Puedes usar el fichero suministrado para ver cómo hacerlo. De todas maneras, aqui van algunos consejos para construirlo satisfactoriamente:
Prueba las canciones con un reproductor web, algunas no merecen la pena ser grabadas en la EEPROM.
Quita todos los espacios, muchas canciones encontradas en la web los tienen.
Asegúrate que las notas van entre comas “,”. No pongas una coma “,” como último caracter de la canción.
Asegúrate que el Tempo es menor o igual a 355 en todas las canciones.
Pon una canción en cada línea, cualquier caracter por debajo de 0x20 (CR, LF, Bell, TAB, etc.) será interpretado como el final de la canción.
Pon un espacio “p” (nota sin sonido) al final de cada canción. Esto te dará un intervalo de tiempo entre canciones. Te sugiero insertar al menos “4p” para Tempo <= 60, “2p” para Tempo > 60 y Tempo < 240 y “1p” para Tempo >= 240. Mira el fichero suministrado, los tiene.
Al final del fichero de texto, pon un “/”. No lo pongas en una nueva línea, ponlo detrás del último caracter de la última canción; esto hará que la EEPROM se lea indefinidamente.
Para grabar las canciones en la EEPROM necesitarás un adaptador serie externo (como un MAX232). El circuito tiene un conector de 5 pines para ésto. Cierra el puente antes de nada, configura tu terminal serie como “300,8,n,1” (si, 300 baudios) y alimenta el circuito. Verás un pequeño mensaje “RTP” en la ventana del terminal. Ahora envía el fichero de texto con las canciones, el tamaño del fichero está limitado por el tamaño de la EEPROM.
Cuando el fichero de texto esté totalmente transferido, apaga el circuito y quita el puente. Es todo!
Nota: otra manera de programar la EEPROM es usando un programador externo. Usa un zócalo para poner y quitar la EEPROM del circuito.
Una "caja" navideña:

El circuito listo para ponerlo dentro:

Dónde encontrar RingTones:
Reproductor web RTTTL (necesitarás un reproductor MIDI en tu sistema):
... para construir tu propio circuito, están aqui.
El código fuente escrito en JAL para programar el PIC esta aqui.
Fichero HEX.
Un fichero de partituras de muestra para programar la EEPROM, esta aqui.
El código fuente de éste proyecto es GNU GPL Traducción al castellano
Este fichero, gráficos y fotos con licencia GNU FDL Traducción al castellano
El circuito del programa Eagle se hizo usando la versión freeware.
(c)2005 Javier Martínez.