Advertisement
Guest User

Untitled

a guest
Dec 4th, 2014
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.54 KB | None | 0 0
  1. #include "fix_fft.h"
  2.  
  3. #define MUESTRAS 128 // Numero de muestras para el cálculo de la FFT
  4. #define LOGM 7 // Logaritmo en base 2 del número de muestras
  5.  
  6. #define BAJOS_MEDIOS 7 // Nº de banda para el corte entre Bajos y Medios
  7. #define MEDIOS_AGUDOS 35 // Nº de banda para el corte entre Medios y Agudos
  8.  
  9. #define BPIN 2 // Pin de salida Bajos
  10. #define MPIN 3 // Pin de salida Medios
  11. #define APIN 4 // Pin de salida Agudos
  12.  
  13. #define MAX_PASADAS 10 // Nº de pasadas para el cálculo de los límites
  14.  
  15. char data[MUESTRAS]; // Array con los valores muestreados (parte real)
  16. char im[MUESTRAS]; // Array con los valores muestreados (parte imaginaria)
  17.  
  18. unsigned char salida[MUESTRAS/2]; // Valores obtenidos de la FFT (espectro de 64 bandas)
  19. unsigned char bajos,medios,agudos; // Valores calculados para cada canal
  20.  
  21. byte pasada, // nº de pasada para el cáculo de los límites
  22. acumBajos,acumMedios,acumAgudos, // acumuladores de veces que se supera el límite
  23. limBajos,limMedios,limAgudos; // límites calculados para cada canal
  24.  
  25.  
  26. const int boton1 = 5;
  27. const int boton2 = 6;
  28. const int boton3 = 7;
  29.  
  30. const int interruptor = 8;
  31. const int ledInterruptor = 9;
  32.  
  33. const int tiempoAntirebote = 10;
  34.  
  35. int estadoBoton1;
  36. int estadoBoton2;
  37. int estadoBoton3;
  38.  
  39. int estadoInterruptor;
  40.  
  41. int estadoBotonAnterior1;
  42. int estadoBotonAnterior2;
  43. int estadoBotonAnterior3;
  44.  
  45. /*
  46. * Funcion que aplica una ventana de Hann a los datos muestreados para reducir el
  47. * efecto de las discontinuidades en los extremos
  48. */
  49. void aplicaVentana (char *vData) {
  50. double muestrasMenosUno = (double(MUESTRAS) - 1.0);
  51. // Como la ventana es simétrica , se calcula para la mitad y se aplica el factor por los dos extremos
  52. for (uint8_t i = 0; i < MUESTRAS/2 ; i++) {
  53. double indiceMenosUno = double(i);
  54. double ratio = (indiceMenosUno / muestrasMenosUno);
  55. double factorPeso = 0.5 * (1.0 - cos(6.28 * ratio));
  56. vData[i] *= factorPeso;
  57. vData[MUESTRAS - (i + 1)] *= factorPeso;
  58. }
  59. }
  60.  
  61. boolean antirebote(int pin){ //funcion que se usa para el correcto funcionamiento de los botones
  62. int contador = 0;
  63. boolean estado;
  64. boolean estadoAnterior;
  65.  
  66. do{
  67. estado = digitalRead(pin);
  68.  
  69. if(estado!=estadoAnterior){
  70. contador = 0;
  71. estadoAnterior = estado;
  72. }else{
  73. contador++;
  74. }
  75.  
  76. delay(1);
  77. }while (contador<tiempoAntirebote);
  78.  
  79. return estado;
  80. }
  81.  
  82. void envioSenal(int boton, int botFrec,int estadoBotonAux,int estadoBotonAnteriorAux){ //funcion que comunica los botones con los canales
  83. if (estadoBotonAux!=estadoBotonAnteriorAux){
  84. if (antirebote(boton)){
  85. digitalWrite(botFrec,HIGH);
  86. }else{
  87. digitalWrite(botFrec,LOW);
  88. }
  89. }else{
  90. digitalWrite(botFrec,LOW);
  91. }
  92. estadoBotonAnteriorAux = estadoBotonAux;
  93. }
  94.  
  95. void setup() {
  96. // Configuramos el prescaler a 32 -> 16Mhz/32 = 500 KHz
  97. // como cada conversion son 13 ciclos 500/13 ~ 38.4KHz
  98. // Es decir podemos medir en teoria hasta unos 19KHz,
  99. // que para este proyecto sobra.
  100. bitWrite(ADCSRA,ADPS2,1);
  101. bitWrite(ADCSRA,ADPS1,0);
  102. bitWrite(ADCSRA,ADPS0,1);
  103.  
  104. // Como la señal es muy baja,utilizamos la referencia interna
  105. // de 1.1 V en vez de la de defecto de 5 V.
  106. analogReference(INTERNAL);
  107.  
  108. // Salidas para los canales de Bajos,Medios y Agudos
  109. pinMode(BPIN,OUTPUT);
  110. pinMode(MPIN,OUTPUT);
  111. pinMode(APIN,OUTPUT);
  112.  
  113. // Variables para el cálculo de los límites
  114. pasada = 0;
  115. acumBajos = acumMedios = acumAgudos = 0;
  116. limBajos = limMedios = limAgudos = 50;
  117.  
  118. //entradas de los botones
  119. pinMode(boton1,INPUT);
  120. pinMode(boton2,INPUT);
  121. pinMode(boton3,INPUT);
  122.  
  123. pinMode(interruptor,INPUT);
  124. pinMode(ledInterruptor,OUTPUT);
  125. }
  126.  
  127. void loop() {
  128.  
  129. estadoInterruptor = digitalRead(interruptor);
  130.  
  131. if (estadoInterruptor){
  132.  
  133. digitalWrite(ledInterruptor,HIGH);
  134.  
  135. // Realizamos el muestreo
  136. for( int i=0; i < MUESTRAS; i++) {
  137. data[i] = analogRead(0)/4 -128; //Convertimos de 0..1024 a -128..127
  138. im[i] = 0; // parte imaginaria = 0
  139. }
  140.  
  141. // Aplicamos la ventana de Hann
  142. aplicaVentana (data);
  143.  
  144. // Calculamos la FFT
  145. fix_fft(data,im,LOGM,0);
  146.  
  147. // Sólo nos interesan los valores absolutos, no las fases, asi que
  148. // calculamos el módulos de los vectores re*re + im*im.
  149. // Dado que los valores son pequeños utilizamos el cuadrado
  150. for (int i=0; i < MUESTRAS/2; i++){
  151. salida[i] = data[i] * data[i] + im[i] * im[i];
  152. }
  153.  
  154. // Ahora repartimos las bandas entre las 3 salidas
  155. // En vez de sacar la media, utilizo sólo el valor máximo de
  156. // una banda
  157. bajos = 0;
  158. for (int i=2; i < BAJOS_MEDIOS; i++){
  159. bajos += salida[i];
  160. }
  161. bajos = bajos/2;
  162.  
  163. medios = 0;
  164. for (int i=BAJOS_MEDIOS ; i < MEDIOS_AGUDOS; i++){
  165. medios += salida[i];
  166. }
  167. medios = medios/2;
  168.  
  169. agudos = 0;
  170. for (int i=MEDIOS_AGUDOS; i < MUESTRAS/2; i++){
  171. agudos += salida[i];
  172. }
  173. agudos = agudos/2;
  174.  
  175. // Calculamos si el canal correspondiente
  176. // supera le límite para encenderlo
  177. int siBajos = bajos > limBajos;
  178. int siMedios = medios > limMedios;
  179. int siAgudos = agudos > limAgudos;
  180.  
  181. digitalWrite(BPIN,siBajos ? HIGH : LOW);
  182. digitalWrite(MPIN,siMedios? HIGH : LOW);
  183. digitalWrite(APIN,siAgudos? HIGH : LOW);
  184.  
  185. // Utilizamos las veces que se supera para
  186. // recalcular el límite y evitar que con los
  187. // cambios de volumen los canales se saturen
  188. // o no funcionen.
  189. acumBajos += siBajos;
  190. acumMedios += siMedios;
  191. acumAgudos += siAgudos;
  192.  
  193. if ( ++pasada > MAX_PASADAS ) {
  194. pasada = 0;
  195. limBajos = 20 + acumBajos*5;
  196. limMedios = 20 + acumMedios*5;
  197. limAgudos = 20 + acumAgudos*5;
  198. acumBajos = 0;
  199. acumMedios = 0;
  200. acumAgudos = 0;
  201. }
  202. }
  203.  
  204. else{
  205.  
  206. digitalWrite(ledInterruptor,LOW);
  207.  
  208. estadoBoton1 = digitalRead(boton1);
  209. estadoBoton2 = digitalRead(boton2);
  210. estadoBoton3 = digitalRead(boton3);
  211.  
  212. envioSenal(boton1,BPIN,estadoBoton1,estadoBotonAnterior1);
  213. envioSenal(boton2,MPIN,estadoBoton2,estadoBotonAnterior2);
  214. envioSenal(boton3,APIN,estadoBoton3,estadoBotonAnterior3);
  215. }
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement