Autor Tema: Problema con conversor A/D de PIC18F2550 (proyecto: afinador de guitarra)  (Leído 5233 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Felipe S.

  • PIC10
  • *
  • Mensajes: 6
Hola, parto mi posteo agradeciendo por toda la ayuda que me han dado los temas de este foro para conocer más a fondo el mundo de los microcontroladores PIC. :)

Ahora estoy haciendo mi Proyecto de Título (un afinador de guitarra eléctrica basado en un PIC18F2550) y tengo un gran dilema que me ha complicado bastante la cosa. Para explicarlo de manera sencilla, el funcionamiento del afinador se basa en la lectura de una señal de guitarra (preamplificada, obviamente) y el sampleo por parte del conversor A/D del microcontrolador. Una vez sampleada, el programa contaría los períodos de la señal digitalizada mediante una rutina if y luego compararía el resultado con un registro en memoria para comprobar que la cuerda está en el tono correcto o no.

Todo esto ocupa filtraje digital y el procedimiento anteriormente descrito, sin embargo, para probar que las etapas de conversión y cuenta de períodos funcionaba correctamente, ocupé el siguiente código de prueba (como se puede deducir del mismo, ocupo como salida un display LCD y como interfaces de entrada un par de pulsadores):

Citar
#include <18F2550.h>

#fuses XT,NOWDT,NOPROTECT,NOLVP

#define adc=8

#use delay(clock=4000000)

#include "lcd.c"

#byte port_a = 0xF80
#byte port_b = 0xF81
#byte port_c = 0xF82

#reserve 0x20:0x232   // Reserva los siguientes bytes de memoria RAM

long sample;

/* Subrutinas del display LCD------------------------------------------------------------------------------------------------------------------------------*/

void menu1() {
 
   printf(lcd_putc, "Seleccione cda:\n");

}


void menu(int valor){

   if (valor==1) {
   
      menu1();
      printf(lcd_putc, "1era  Mi");

   }

   if (valor==2) {
   
      menu1();
      printf(lcd_putc, "2da   Si");

   }

   if (valor==3) {
   
      menu1();
      printf(lcd_putc, "3era  Sol");

   }

   if (valor==4) {
   
      menu1();
      printf(lcd_putc, "4a    Re");
     
   }

   if (valor==5) {
   
      menu1();
      printf(lcd_putc, "5a    La");

   }

   if (valor==6) {
   
      menu1();
      printf(lcd_putc, "6ta   Mi");

   }

}

/* Subrutina de prueba de la cuenta de período (sin filtrado - borrar una vez comprobada)------------------------------------------------------------------*/


void muestra() {

printf(lcd_putc, "\fN. samples\n= %ld", sample);

}


void cuenta1() {

int per, *p;
long buc;

p = 0x20;         


for(per=0;per<=10;) {
 
   if ((*(p+buc)!=0)&&(*(p+buc-1)==0)) {
      ++per;
      };
   ++buc;
   if (per>=1) {
   ++sample;
   }

   };

muestra();            // Llama a subrutina 'muestra'


}



/* Subrutina del Conversor---------------------------------------------------------------------------------------------------------------------------------*/


void conversor() {

   int i, value, *p;
   long buc;

   p = 0x20;          // Graba la dirección 0x20 en el puntero 'p'   

   setup_adc_ports(AN0|VSS_VDD);      // Vref+ = Vdd, Vref- = Vss
   setup_adc(ADC_CLOCK_DIV_2);      // Frecuencia de clk es de Fosc / 4
   set_adc_channel(0);         // RA0 como entrada analógica

   printf(lcd_putc, "\fToque nota");

   for(i=1;i<=30;++i) {                 // Espera 3 segs. (Tiempo de espera para tocar la nota)

      delay_ms(100);

           }

   printf(lcd_putc, "\fConvirtiendo..");

   for(buc=0;buc<=522;++buc) {         // Se harán 522 conversiones

      value = read_adc();      // Lee el valor
      *(p+buc) = value;         // Guarda el valor en la dirección de RAM correspondiente
                             // incrementa en uno la dirección de memoria
      delay_us(209);           // Retraso de 209 microsegundos (de manera de hacer que frecuencia sampling = 4300 Hz. Ver archivo .lst
   
      };

   printf(lcd_putc, "\fConversion lista");
   
   for(i=1;i<=10;++i) {                 // Espera 1 seg.

      delay_ms(100);

           }

   cuenta1();            // Llama a subrutina 'cuenta1' (de prueba)

}                // Fin de subrutina 'conversor'


/* Parte principal del programa----------------------------------------------------------------------------------------------------------------------------*/

void main() {

   int i, val;

   set_tris_a(00000001);     // Fija RA0 como entrada y el resto de los pines del puerto A como salidas     

   set_tris_b(00000000);            // Fija puerto B como salida

   set_tris_c(10100000);         // Puerto C como entrada para los pulsadores (RC5, RC6) y el resto de los pines como salidas

   
   port_a = 0xFF;      // Fija el valor '1' en todos los pines que no se ocuparán
   port_b = 0XFF;
   port_c = 0XFF;           
         
     

   /* Carga los valores (en número de samples por diez períodos) de las fundamentales en registros. (Frecuencia de sampling = 4300 Hz)----------------*/

   


   /*Bienvenida y menú selección----------------------------------------------------------------------------------------------------------------------*/

   lcd_init();                  // Inicia el display LCD

   lcd_putc("\f");
   
   printf(lcd_putc, "\fBienvenido");

   for(i=1;i<=30;++i) {                 // Espera 3 segs.

      delay_ms(100);

           }

   lcd_putc("\f");                // borra el display

   val=1;               // Rutina de selección. Si RC5 pasa a estado bajo, cambia la pantalla (subrutinas 'menu1' y 'menu'). Si RC6 pasa a estado bajo, se dirige a la subrutina de conversión.

   menu(val);

   while(true) {

      if (!input(pin_c7)) {

         delay_ms(500);
         ++val;
         if (val==7) {
            val=1;
            }
         lcd_putc("\f");
         menu(val);
   
         }

      if (!input(pin_c6)) {
         
         lcd_putc("\f");
         
         conversor();
   
         }

      }


}               // Final de programa principal




La finalidad de este programa es efectuar la conversión y la cuenta de períodos y mostrar en el display LCD el número de samples contados (que es proporcional a la frecuencia). La frecuencia de sampling es de 4300 Hz y la simulación en Proteus corre bastante bien, salvo algún par de correcciones que deberé hacer ya que le cuenta de samples no es siempre muy precisa. La susodicha simulación vendrá adjunta a este posteo.

El punto es que, al comprobar el mismo programa en el protoboard, el mismo me lee cualquier cosa, no me lee, resetea el programa, en fin, problemas que yo asocio con la presencia de ruido tanto en el PIC como en el conversor A/D mismo. He tratado de poner condensadores en la alimentación del PIC y de filtrar la señal análoga de entrada al conversor, sin éxito. Mi problema no creo que sea de impedancia del conversor, ya que la hoja de datos del PIC dice que la fuente de la señal análoga no debe tener más de 2.5 KOhms de entrada, y el generador de funciones que ocupo para la prueba es de 50 Ohms.

Para comprobar si el conversor A / D tenía problemas de resolución por ruido, escribí un programa simple que medía el valor de una señal DC y escribía el resultado de la conversion en el display LCD. No tuve problema alguno.

Sospecho que mi problema debe ser con la lectura de una señal AC. Las que yo ocupo están entre los 80 y 330 Hz.

Perdón por lo largo y latoso de mi posteo, pero quise darles todos los detalles que podía. Ahora estoy un poco apurado así que algo se me puede haber escapado, cualquier cosa, no duden en preguntar. ¡Muchas gracias!

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con conversor A/D de PIC18F2550 (proyecto: afinador de guitarra)
« Respuesta #1 en: 24 de Septiembre de 2008, 14:06:25 »
Hola.

La senal de salida de la guitarra que valor de amplitud tiene? Al micro hay que llevarle senales de 0 a 5 voltios. Si quieres afinar mas precisamente la guitarra seria mejor adecuar esa salida por un sistema que la haga cuadrada y usar la interrupcion de algun timer y la del CCPx.

Saludos
El papel lo aguanta todo

Desconectado Felipe S.

  • PIC10
  • *
  • Mensajes: 6
Re: Problema con conversor A/D de PIC18F2550 (proyecto: afinador de guitarra)
« Respuesta #2 en: 24 de Septiembre de 2008, 23:51:57 »
Hola.

La senal de salida de la guitarra que valor de amplitud tiene? Al micro hay que llevarle senales de 0 a 5 voltios. Si quieres afinar mas precisamente la guitarra seria mejor adecuar esa salida por un sistema que la haga cuadrada y usar la interrupcion de algun timer y la del CCPx.

Saludos

Qué tal. Como mencioné, estoy haciendo la prueba de la cuenta de los períodos con un generador de funciones, alimentando al conversor A/D con una señal análoga senoidal de un poco menos de 5 V de amplitud peak. ¿No afectaría al conversor meterle señales de ciclo negativo senoidal? Yo creo que simplemente no las leería o las tomaría como cero, así lo hizo la simulación del Proteus por lo menos, ahora yo no sé cómo el PIC real se lo tomaría.

Hacer la señal cuadrada como dices no serviría de nada, ya que después de convertir la señal, esta pasaría a ser filtrada digitalmente y ahí se recuperaría la figura de la senoidal.

Saludos.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con conversor A/D de PIC18F2550 (proyecto: afinador de guitarra)
« Respuesta #3 en: 25 de Septiembre de 2008, 12:53:33 »
Hola.

Lo que quiero decirte es que para afinar la guitarra es mas util el calculo de la frecuencia (para una senal cualquiera, sea senoidal o cuadrada). Si tienes la senal de salida de la guitarra que se supone senoidal ( obviando los armonicos que caracterizan al timbre del instrumento ) para la cuerda determinada, resulta mas sencillo pasarla a onda cuadrada con aplitudes entre 0 y 5, estos "pulsos" corresponden en frecuencia a la original, asi que si mido la frecuencia de esa senal por medio de interrupciones me acercare mas al valor real de esta.

Al hacerla por medio de un sampling de una senal analogica como tal es mas complicado ya que tendrias que muestrear como minimo al doble de frecuencia de la mayor frecuencia que en este caso seria el MI de la primera cuerda.

Es decir, puedes tener mayor facilidad del calculo midiendo frecuencia por medio de las interrupciones CCPx, ya que en este caso estamos hablando de frecuencias menores a 10kHz. Si soy claro?

Yo no usaria el ADC para averiguar la frecuencia, usaria el CCPx en modo capture, ya que para afinar la guitarra necesito saber si el valor de frecuencia que emite la nota es el adecuado.

Saludos
El papel lo aguanta todo

Desconectado Felipe S.

  • PIC10
  • *
  • Mensajes: 6
Re: Problema con conversor A/D de PIC18F2550 (proyecto: afinador de guitarra)
« Respuesta #4 en: 03 de Octubre de 2008, 01:05:36 »
Hola.

Lo que quiero decirte es que para afinar la guitarra es mas util el calculo de la frecuencia (para una senal cualquiera, sea senoidal o cuadrada). Si tienes la senal de salida de la guitarra que se supone senoidal ( obviando los armonicos que caracterizan al timbre del instrumento ) para la cuerda determinada, resulta mas sencillo pasarla a onda cuadrada con aplitudes entre 0 y 5, estos "pulsos" corresponden en frecuencia a la original, asi que si mido la frecuencia de esa senal por medio de interrupciones me acercare mas al valor real de esta.

Al hacerla por medio de un sampling de una senal analogica como tal es mas complicado ya que tendrias que muestrear como minimo al doble de frecuencia de la mayor frecuencia que en este caso seria el MI de la primera cuerda.

Es decir, puedes tener mayor facilidad del calculo midiendo frecuencia por medio de las interrupciones CCPx, ya que en este caso estamos hablando de frecuencias menores a 10kHz. Si soy claro?

Yo no usaria el ADC para averiguar la frecuencia, usaria el CCPx en modo capture, ya que para afinar la guitarra necesito saber si el valor de frecuencia que emite la nota es el adecuado.

Saludos

Hola, disculpa por el tiempo de silencio, pero estaba fuera de vacaciones.

Gracias por la aclaración. La verdad no sabía acerca de las interrupciones CCPx y leyendo la hoja de datos y uno que otro topic en este foro me pude familiarizar con esto y el proceso que yo quiero sería muchísimo más simple con esto que con el método anterior. Lo único, a la parte de hardware habría que agregarle un conversor A/D externo (que convierta la señal a cuadrada) y algún filtro activo para eliminar los armónicos, que en el caso de una señal de guitarra molestan bastante.

En parte me siento decepcionado, ya que tenía muchas ganas de usar de la conversión A/D del PIC y de filtros digitales, pero qué más da, a lo mejor me estoy metiendo en camisa de once varas con la complejidad de este método. Probaré lo que tú me dices y te mantendré al tanto.

Saludos.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con conversor A/D de PIC18F2550 (proyecto: afinador de guitarra)
« Respuesta #5 en: 03 de Octubre de 2008, 02:14:25 »
Hola.

Que bueno que hallas descansado  :-/ :-/

Para pasar la onda a cuadrada no necesitas un ADC, con un comparador de ventana es suficiente. El filtro si es necesario.

Puedes hacer un ejemplo simple de ADC con algun filtro digital paralelo al afinador.
El papel lo aguanta todo


 

anything