# Muestreo de señal de audio con dsPIC



## fragmir (Nov 11, 2008)

Que tal:

Uso un 30f2010 y no se que pasa con mi sistema pero no arroja lo que la simulación hace.
podrían ayudarme a revisar mi código y decirme si está bien programado?
quiero muestrear una señal de audio por AN2 con una frecuencia de muestreo de 2400Hz aprox.
uso el ADC con TIMER3 y pretendo llenar 64 muestras del buffer para mandarlos a una funcion fft.
el codigo está aquí:


```
#define _NOPSV  __attribute__((no_auto_psv))
# include <p30f2010.h>
# include <math.h>
_FOSC(CSW_FSCM_OFF & XT_PLL8); 
_FBORPOR(PBOR_OFF & MCLR_EN);
_FGS(CODE_PROT_OFF);

# define M_PI 3.141592654
unsigned char flag=0;
unsigned AdcValue=0;
void Iniciar_Adc(void);
unsigned char i=0,ind=0;
int *apunta;
int buf[64];
int  P[64];
*apunta=&buf[0];
int interval[6];
volatile int liminf,c=0,prom=0,ii=0,k,p,j=0;
double long   sum=0,sum1=0;
 void _ISR _NOPSV _ADCInterrupt(void)
	{

	IFS0bits.ADIF=0;
	AdcValue=ADCBUF0;
	flag=1;
	}
main()
{
TRISE=0;
Iniciar_Adc();	
Init_Timer();
IFS0bits.ADIF=0;
IEC0bits.ADIE=1;
ADCON1bits.ADON=1;
T3CONbits.TON=1;
while(1)
if(flag==1){
flag=0;
*apunta=ADCBUF0-512;
*apunta++;
ind++;
if(ind==64){
ind=0;
ADCON1bits.ADON=0;
T3CONbits.TON=0;
fft();
apunta=0x800;
*apunta=&buf[0];

ADCON1bits.ADON=1;

T3CONbits.TON=1;
}
}
}
void Init_Timer(void)
{
T3CONbits.TCKPS=3;
T3CONbits.TON=0;
PR3=31;
TMR3=0;

}
void Iniciar_Adc(void)
{
ADCON1bits.SSRC=2;//Autosample
ADCON1bits.FORM=0;
ADCON2bits.SMPI=0;
//ADCON3bits.ADCS=63;
//ADCON3bits.SAMC=31;
ADCHS=0x0002;
ADCSSL=0;
ADPCFG =0;      
ADCON1bits.ASAM=1;
ADCON2bits.VCFG=0;
}
```

Gracias.


----------



## Gradmaster (Nov 12, 2008)

Creo que el uso de un dspic esta muy sobrado para aplicaciones de voz, puedes hacer una prueba muy sencilla antes de comenzar a guardar tus datos, lo que hice fue usar el adc de un 16f873 y pasar los datos directamente al PWM que tiene el pic amplificandola un poco para que pueda escucharse bien con una bocina, con un reloj de 4 MHz tiene la suficiente velocidad de muestreo para lograr un reconocimiento de palabra, intenta hacerlo de esta forma, te dara buenos resultado.

Exito.


----------



## Ardogan (Nov 12, 2008)

Y qué es lo que no te anda en particular?: las muestras no se toman bien, o no se guardan en memoria como esperabas, o el CAD te da valores inesperados, etc.

Me llaman la atención este par de líneas:



> ```
> *apunta=ADCBUF0-512;
> *apunta++;
> ```



Ahí le estás restando 512 al resultado de la conversión y guardando en apunta, que apunte a un int del vector buf. Hasta ahí bien.
Pero no será que la segunda línea en vez de ser "*apunta++; " debiera ser "apunta++; " para incrementar el puntero y no el valor al que apunta?

Lo mismo más arriba con *apunta=&buf[0]; ahí estás diciendo que se guarde la dirección de buf[0] en el int del que tiene la dirección apunta (por no poner el int al que apunta apunta), que ya de entrada es un lugar de la memoria indefinido.

Creo que debería ser "apunta=&buf[0]" sin *.

Este par de líneas:


> ```
> apunta=0x800;
> *apunta=&buf[0];
> ```



No entiendo para que está ese par de líneas ahí, es para usar la fft?. Pero en tal caso debería estar antes de llamar a fft(). 
Lo que me parece raro es guardar una dirección en el registro al que apunta apunta (este juego de palabras ya me marea). Estarías guardando la dirección de buf[0] en el registro ram que tiene dirección 0x800.

unsigned AdcValue=0;  acá debería llevar un int (unsigned int...)

En fin, creo que en resumen, estás teniendo problemas con el manejo de punteros, acordate que el * es el operador de indirección y el & te da la dirección de la variable a la que se aplica.

Y si los punteros están bien, entonces no tengo ni idea de que hace el programa  .

Saludos y suerte, contanos tu sufrimiento.  .

PD: cuando hagas un post en el que metas código usá la etiqueta "Código" al redactar el mensaje, queda más claro y te respeta los espacios. Podés editar el mensaje anterior y corregirlo para que quede mejor.


----------



## fragmir (Nov 12, 2008)

*apunta=ADCBUF0-512; 
*apunta++; 
Esta parte del codigo resta 2.5volts de una señal de offset que tengo metida antes del ADC.
*apunta++ lo que hace es mover sobre el vector buf un lugar para recibir el siguiente valor.
 *apunta=&buf[0]; 
lo que hace apunta este apuntando al primer lugar del vector buf 
apunta=0x800; 
esta instruccion es para regresar el puntero a su localidad d ememoria inicial ya que conforme se repite le ciclo de llenado del ADC, el puntero sigue incrmentando su valor generando errores de localidad d ememoria en la simulación por lo que lo corregí regresando a "apunta" a la localidad inicial, una vez haciendo esto, dispongo a que "apunta" apunte al lugar 0 del vector buf.

*apunta=&buf[0];
mi simulación corre bien pero a mi tambien me hizo ruido eso del *Y el & por lo que revisaré de nuevo la simulación y comentaré mis resultados.
Por cierto , encuentras algo mal en la config del ADC? no s eporque no funciona el sistema físicamente.
gracias.


----------



## Ardogan (Nov 12, 2008)

Si la simulación en el mplab te anduvo bien, entonces voy a tener que retomar práctica.
Mi versión es la que sigue

Vamos a hacer lo siguiente, a partir de ahora soy el compilador C30 del mplab  

Esta primera parte no la comento, no sirve para ilustrar mi punto
    #define _NOPSV  __attribute__((no_auto_psv))
    # include <p30f2010.h>
    # include <math.h>
    _FOSC(CSW_FSCM_OFF & XT_PLL8);
    _FBORPOR(PBOR_OFF & MCLR_EN);
    _FGS(CODE_PROT_OFF);

    # define M_PI 3.141592654

    unsigned char flag=0;
//bueno, acá tengo que meter un char que se llama flag en algún lugar de la memoria ram, que a mí, el compilador, me guste
// me parece linda la dirección 0x900 (esto en realidad depende del archivo .lkr, pero como nadie nunca tiene
//necesidad de abrirlo, bien lo podemos suponer aleatorio)
//a partir de ahora cada que encuentre flag, lo reemplazo por 0x900
//Ah!,  casi me olvido, me dijo que de entrada meta un 0 en 0x900, hecho

    unsigned AdcValue=0;

//similar a lo anterior, ahora es un unsigned, acá la verdad no estoy seguro de que es lo que haría el compilador
//por eso te decía de ponerle un int, ya que lo usás para leer el adc que te da un int:     
//unsigned AdcValue=0;
//bueno, como yo tengo el poder digo que AdcValue va a ser la dirección 0x902
//pero también me reservo 0x903, ya que se trata de un int, de dos bytes 

    void Iniciar_Adc(void);

//ajá, voy a buscar la definición de Iniciar_Adc más adelante

    unsigned char i=0,ind=0;

// decreto que i va a estar en la dirección 0x904, e ind en la dirección 0x905
//además de entrada cargo el registro 0x904 con valor 0 al igual que 0x905

    int *apunta;

//ahora tengo que reservar una variable que apunta a otra variable
//creo que son un par de bytes (ya no soy tan poderoso)
//la variable apunta tendrá la dirección 0x906, y se reservará 0x907 por ser de 2 bytes
//no tiene ningún valor de inicialización así que va a ser (uno aleatorio o por default)
//0x1234

    int buf[64];

//ufff, tengo que reservar 64 int's, decreto que buff va a empezar de 0x908 y el vector ocupará
//los registros desde esa dirección hasta 0x908 + 64 . 2 (0x40)= 0x948

    int  P[64];

//otro vector, ubico a P en 0x950 y llegará a 0x990

    *apunta=&buf[0];

// ajá, el miembro de la derehca me pide aa dirección de donde empieza buf, que ya dije antes
//que es 0x908.
//apunta es el registro en 0x906, pero como está el * me dice que tome el contenido de apunta,
//que es aleatorio y vale 0x1234
//por lo tanto escribo el valor 0x908 en el registro 0x1234
//(se nota el dilema?)

//bueno, las variables que siguen no revisten mayor interés para lo que quiero exponer
//vamos a la parte donde se trabaja con apunta

    int interval[6];
    volatile int liminf,c=0,prom=0,ii=0,k,p,j=0;
    double long   sum=0,sum1=0;[/code]
     void _ISR _NOPSV _ADCInterrupt(void)
       {

       IFS0bits.ADIF=0;
       AdcValue=ADCBUF0;
       flag=1;
       }
    main()
    {
    TRISE=0;
    Iniciar_Adc();   
    Init_Timer();
    IFS0bits.ADIF=0;
    IEC0bits.ADIE=1;
    ADCON1bits.ADON=1;
    T3CONbits.TON=1;
    while(1)
    if(flag==1){
    flag=0;
    *apunta=ADCBUF0-512;

//bien, ya llegué acá a ver que tenemos....
//del lado de la derecha hago la cuenta, me puede dar positivo o negativo, pero si es un offset
//el resultado va a ser positivo
//hice la cuenta, me dió 165 (por decir algo)
//eso lo tengo que guardar en *apunta
//apunta es 0x906
//pero está el asterisco, me dice que lo guarde en el registro cuya dirección es el valor de apunta
//por lo tanto lo guardo en el registro de dirección 0x1234
//por lo tanto el registro 0x1234 ahora guarda el valor 165

    *apunta++;

//en realidad no estoy muy seguro de como interpreta esto el compilador, yo creo que
//lo que hace tomar es como si fuera (*apunta)++
//entonces incrementa el registro 0x1234 en 1
// que ahora tendrá un valor de 166

    ind++;
    if(ind==64){
    ind=0;
    ADCON1bits.ADON=0;
    T3CONbits.TON=0;
    fft();
    apunta=0x800;

//ahora apunta, que antes tenía el valor 0x906 pasa a tener el valor 0x800


    *apunta=&buf[0];

//el lado derecho es la dirección de buff[0]
//el lado izquierdo me dice que lo guarde en el registro cuya dirección es el valor de apunta
//por lo tanto guardo 0x908 en el registro 0x800 (no en apunta)


    ADCON1bits.ADON=1;

    T3CONbits.TON=1;
    }
    }
    }
    void Init_Timer(void)
    {
    T3CONbits.TCKPS=3;
    T3CONbits.TON=0;
    PR3=31;
    TMR3=0;

    }
    void Iniciar_Adc(void)
    {
    ADCON1bits.SSRC=2;//Autosample
    ADCON1bits.FORM=0;
    ADCON2bits.SMPI=0;
    //ADCON3bits.ADCS=63;
    //ADCON3bits.SAMC=31;
    ADCHS=0x0002;
    ADCSSL=0;
    ADPCFG =0;     
    ADCON1bits.ASAM=1;
    ADCON2bits.VCFG=0;
    }

------------------

En la configuración del ADC no ví nada malo a priori (configurar un cad de un dspic cuesta el doble o el triple que el de un pic18 o pic16).
Si no te muestrea nada físicamente, no sé, tenés conectados AVdd y AVss?
AVdd en lo posible que venga de una referencia de tensión.
Para ver si es algo de hard te diría que pongas el circuito.

Bueno, eso es lo que yo creo que hay que corregir, puede ser que me equivoque (50 y 50 te diría), pero si lo solucionás no dejes de comentarlo así queda claro.

Saludos


----------



## fragmir (Nov 12, 2008)

Ok entiendo el punto y de acuerdo a la simulación se puedo definir lo siguiente.
apunta adress 0x800 donde buff[0] es 0x800
cuando hago *apunta++; apunta se va a 0x802; que está el buf[1] eso arroja la simulación.
cuando termino el llenado de buf, apunta invade localidades de memoria que arrojan error por lo que al terminar regreso apunta a la dirección 0x800 para que regrese a la posicion buf[0] de hecho el segundo *apunta=&buf[0] es redundante.
y puedo quitarlo.
me gustaría hablar contigo si es que tu puedes para que me ayudes podríamos hablar por messenger o skype para que podamos hablar fluido.
De verdad agradezco mucho tu ayuda y ah! adjunto mi circuito en el siguiente post


----------



## fragmir (Nov 12, 2008)

http://forum.microchip.com/upfiles.aspx/51619/183B34EB81714C3F909D2476DBDC39EE.jpg

La explicación es así:
señal de mp3 pasa por un filtro pasivo de 12dB despues un capacitor 470nF para remover componente de DC y despues se agrega una señald e offset de 2.5v y así se introduce la señal al AN2, AVdd yAvss estan a Vdd y a Vss respectivamente.
De verrdad agradezco mucho el tiempo tomado.


----------



## Ardogan (Nov 13, 2008)

Uff bueno, yo te diría que para estar seguros de que buf tiene la dirección 0x800,  la declares de esta forma:

int buf[64] __attribute__ ((address(0x800)));

Puede ser que el compilador empiece a guardar las variables en 0x800 por default, pero no hay garantía de que al declarar nuevas variables no te cambie la dirección.
Bueno, cerramos entonces el tema de los punteros, puede ser que sea yo el que tiene que revisar el uso de los operadores.

¿Qué es lo que no te hace el pic?, ¿el programa arranca o ni siquiera eso?, ¿ejecuta el código?,¿el cristal lo pusiste sin capacitores?.

En cuanto a lo del messenger, mandame un mensaje privado con tu cuenta y yo te contacto; con la condición de que después volquemos acá lo hablado.

Saludos y suerte.


----------



## fragmir (Nov 13, 2008)

La simulacion va d emaravilla hace lo que debe de hacer pero fisicamente no lo hace , no se si sea algo de config del ADC o que rayos con el circuito
el compilador le asigna una dirección a apunta sin embargo yo hago que apunte a la dirección 0x800 que es donde esta el buf[0]


----------



## fragmir (Nov 19, 2008)

He seguido con pruebas y no logro entender que pasa, ardagon que puedo estar haciendo mal, 
tu revisaste mi diagrama?
la señal de offset está bien pare evitar quemar el ADC no?
simule el programa con señales generadas del adobe audition y la fft arroja el resultado correcto pero mi sistema fisicamente no.
como puedo saber si queme el ADC? 
gracias.


----------



## Ardogan (Nov 19, 2008)

Bueno, ese circuito para meter un offset a la señal de audio.... yo de audio mucho no entiendo más allá de que es una señal cuyo rango de frecuencias de interés es de 0 a 20 KHz   .

Y ese circuito distorsiona apreciablemente la señal de audio (ver adjunto, eso es en amplitud, y en fase será mucho peor).

Para meterle el offset usaría un operacional (no sé cual se usa para audio) en configuración sumador.

Le pusiste capacitores al cristal de 10 MHz?.

Que amplitud pico a pico tiene la señal de audio?, cuidado que no se vaya (con offset y todo) arriba de +5V o abajo de 0V (el PIC corre peligro).

El PIC funciona bien más allá de lo del ADC?, ejecuta código?.


----------



## fragmir (Nov 19, 2008)

El circuito porque distorsiona?
yo probe el circuito con el sonoscope y no presenta distorsion sino una atenuación en frecuencias por encima de 2kHz por lo que el filtro no es del todo preciso pero no distorsiona.
La prueba para el filtro fue realiada con ruido rosa del adobe audition.
La señal pico pico es de 1V y la señal de offset es de 2.5V por lo que 2.5VRMS mas .7Vrms me dan 3.2 V con los cuales no excedo especificaciones del dsPIc.
los valores del divisor de tensi´n (4.7K) es porque la impedancia recomendada de entrada al ADC es de 5 kOhm y la impedancia de un reproductor mp3 es de 30 ohm.
Consideras que deba cambiar algo del circuito ?
Que sugieres son bienvenidas todas las sugerecias!1
gracias!
PD. Ando en línea.


----------



## Ardogan (Nov 20, 2008)

Bueno, dije que no entiendo mucho de audio, pero el filtrado de agudos se nota al oído. Adjunto imágenes de señal de entrada y de salida.

Por otro lado, es la impedancia de entrada *máxima* de 5Kohm según la hoja de datos.



			
				Hoja datos dspic30f2010 dijo:
			
		

> the *maximum* recommended source imped-
> ance, RS, is 5 kohm



Si es menos que eso mucho mejor.

No me respondiste si le pusiste capacitores al cristal, y si el PIC te ejecuta código, no dejes de contestarlo para la próxima.


----------



## fragmir (Nov 20, 2008)

ok disculpa mi omisión a tu pregunta, el cristal tiene 2 cap. de 22pF a tierra.
el código en mplab corre bien y me da las mismas amplitudes que el matlab. no se si te refieras a eso con "el pic ejecuta el codigo"
como comento , la simulacion corre bien, aunque muy lento my fft jaja pero funciona.
Segun yo mi ADC configurado para recibir 2400 muestras por segundo aprox.
por la terminal AN2 (configurada como analogica), conectado Avdd a Vdd y Avss a Vss y configurado los pines de referencia, el CHOSA, el PR3, TMR y simulo con un stimulus workbook usando un "injection trace" para simular los valores del ADC en la ejecución del código


----------



## Ardogan (Nov 20, 2008)

Al preguntar si el PIC ejecuta código, me refiero a el PIC físicamente hablando. Es decir, meterle un programa sencillo (encender un led por ejemplo) y ver si lo hace (en una protoboard); para saber si el PIC no está quemado, o si se programa bien.


----------



## fragmir (Nov 20, 2008)

si funciona, le meti un programa de interrupcion y funciona bien


----------



## fragmir (Nov 20, 2008)

Hola:
en la simulacion algunos registros aparecen con rojo y otros no, que significa eso?


[/img]


----------



## Ardogan (Nov 21, 2008)

En rojo se destacan  los valores recientemente actualizados. Si uno ejecuta paso a paso y ejecuta una instrucción PORTA = 0xF0; por ejemplo, entonces si ese  registro esta en la ventana watch pasa a rojo.


----------



## fragmir (Nov 21, 2008)

ok ok  entendido .
de verdad aprecio mucho tu ayuda y sigo buscando errores en el codigo o en el circuito para hacer que esto funcione.
has encontrado alguna anomalía, me sería de mucha ayuda tu experiencia.

Gracias.


----------



## Ardogan (Nov 21, 2008)

Si, ando medio complicado estos días, y parece que va a ser así hasta fin de año; el foro lo veo cuando puedo.
No te creas que tengo tanta experiencia, con los PIC empecé hace año y medio (a programarlos), a armar algo en la vida real hace poco menos de 1 año....

En fin, volviendo a lo tuyo, de hardware ya dije que en mi lugar metería con algún operacional; y por otro lado meteria un zener con un operacional (puede ser un chip con dos operacionales para la señal y el zener) para que sea referencia del CAD (pin AVdd). Esto porque la alimentación digital (Vdd) es de por sí bastante "polucionada" (variaciones de nivel por la activación/desactivación de entradas/salidas o señales internas del mismo PIC). Y se requiere que el AVdd sea lo más estable porque el AD usa esa tensión para hacer la conversión, su precisión/exactitud si descartamos los errores propios del CAD será tan buena como la tensión AVdd.
Me habías dicho que la señal variaba entre -1V y 1V; el CAD convertiría (con el offset incluído) tensiones entre 1.5V y 3.5V. Ahí estamos aprovechando solo el 40% de rango del operacional -> perdemos más de 1 bit de resolución

Bueno, en cuanto a probar con el CAD, podrías probar si convierte el offset (en hard) adecuadamente para empezar. Que usás para programar el dspic?, tenés un depurador "in circuit"?.

Ahora reviso la configuración del CAD...


----------



## Ardogan (Nov 21, 2008)

Para empezar, se recomienda declarar la función principal main como

int main(void){----

vos lo tenes como

main()
----------------
Pasos/secuencia para iniciar/usar el CAD según la hoja de datos, página 114 del pdf:



> 1. Configure the ADC module:
> - Configure analog pins, voltage reference and
> digital I/O
> - Select A/D input channels
> ...



El punto 1 sería configurar las referencias de tensión Vcfg<2:0> (ADCON2), entradas digitales (registros TRIS), ADPCFG....

Ahora que me fijo.... en ningún momento pusiste que AN2/----/RB2 tenga su bit tris =1 (entrada).
Sin eso no tendría por qué funcionar.
En la inicialización del CAD meté TRISBbits.TRISB2=1 arriba de todo, a ver si es eso y nada más. De no ser así sigo viendo el programa y después edito este mensaje


----------



## fragmir (Nov 22, 2008)

es buena alternativa lo del diodo zener y la aplicare, referente a lo del operacional, para ponerlo como sumador, tengo que alimentarlo con fuente negativa?
porque mi fuente de offset, trabaja muy bien ya que lo vi en el osciloscopio.
La señal de audio varía entre 2.5 y 4.5 volts ya que el voltaje de mi señal de audio iria de -1 a 1 por lo que si lo monto en la señal de offset sería de 2.5 a 4.5V.
no tengo un simulador de "hardware" solamente utilizo el MPLAB SIM para observar el comportamiento, yo programo sobre MC30.
Y ya corregí lo del TRISB no lo programé!
que tonto olvidé eso .
probare de nuevo con el dspic a ver que tal.
seguimos caminando.
un saludo y buen fin de semana


----------



## Ardogan (Nov 23, 2008)

Sí, altamente que sea probable lo del TRIS. Eso explica por qué andaba la simulación y no al programar el PIC. Como directamente inyectabas valores al registro ADRES....
Lástima no lo ví antes, hubieramos ahorrado mucho tiempo.

En cuanto a lo del op-amp, podés usar un single supply, con salida rail-to-rail (que la salida pueda tomar valores lo más cercano a GND y a Vcc). Desconozco cual se ua para audio en particular.
Bueno, el que la salida sea rail-to-rail dependerá también de que referencia de tensión pongas en AVdd. Mejor dicho, habría que ver que la salida del op-amp (señal + offset) pueda excursionar desde AVss hasta AVdd a partir de la alimentación que tengas en tu circuito para aprovechar la resolución del CAD al máximo (eso en las hojas de datos se pone como "output voltage rail" o algo así, generalmente es el valor de alimentación menos/más un margen respecto de Vcc/GND).


----------



## fragmir (Nov 23, 2008)

Revisaré mi circuito de offset, porque presiento que debe ser algo de hardware, no aseguro eso vdd?
revisaré lo de rail to rail para preguntarte algo ya que no me gustaría hacer preguntas al por mayor sin saber algo del tema.
he configurado el trise y aun obtengo resultados extraños no puedo deducir lo que arroja en el PORTE.
Estas dos líneas que comente no son necesarias verdad? ya que si utilizo el timer3 para interrupcion del ADC, no es necesario configurar TAD... o me equivoco?
las líneas comentadas:
//ADCON3bits.ADCS=63;
//ADCON3bits.SAMC=31;

un saludo


----------



## Ardogan (Nov 23, 2008)

> he configurado el trise y aun obtengo resultados extraños no puedo deducir lo que arroja en el PORTE.



El TRISE?, no usabas AN2 para medir la señal de audio? (habría que configurar TRISB)



> Estas dos líneas que comente no son necesarias verdad? ya que si utilizo el timer3 para interrupcion del ADC, no es necesario configurar TAD... o me equivoco?
> las líneas comentadas:
> //ADCON3bits.ADCS=63;
> //ADCON3bits.SAMC=31;



Siempre va a ser necesario definir un reloj para el CAD. Creo que estás confundiendo los bits SSRC con reloj.
Los bits SSRC solamente seleccionan el disparador (trigger) del CAD, es decir, con que señal se inicia la conversión analógica-digital.

No dejes de el manual de referencia del conversor AD para éste módulo:

Section 17. 10-Bit A/D Converter - dsPIC30F FRM

la información de la hoja de datos es más bien escasa (ni siquiera tiene una explicación registro por registro como en otras hojas de datos).

También hay ejemplos de código:

http://ww1.microchip.com/downloads/en/DeviceDoc/CE001_ADC_DSP_lib_Filter_010908.zip
http://ww1.microchip.com/downloads/en/DeviceDoc/CE002_ADC_1MSPS_010908.zip

Bon apetit


----------



## fragmir (Nov 23, 2008)

si, una disculpa, configuré el TRISBbits.TRISB2=1 para  configurarlo como entrada el AN2.
Es posible que exista algun conflicto por lo del  ADCS y SAMC bits ya que no he comprendido bien eso y por consigiente los he puesto en comentario y a pesar de eso , no presenta problemas la simulación sin embargo he leído un poco y no logro comprender como fncionan, además en que varía si yo pongo el SAMC o el ADCS.


----------



## Ardogan (Nov 24, 2008)

ADCS = clock source del ADC = fuente de reloj, siempre necesaria. Lo mejor es que convierta rapido, hasta que velocidad se puede llegar?->hoja de datos ->características eléctricas-> Tad mínimo; aunque la tabla 18-1 de la hoja de datos está más claro.

SAMC (sample clock) determina el tiempo de muestreo del canal antes de iniciar la conversión. Por ahí en tu caso se puede fijar al mínimo, ya que el Sample/Hold que realiza la muestra siempre va a estar conectado a AN2. El tiempo de muestreo se usa cuando uno cambia de canal (por ejemplo, cuando se pasa de convertir AN2 a convertir AN0, el tiempo de muestreo lo que hace es darle tiempo al circuito Sample/Hold de llegar al nivel de tensión de AN0 después del cambio brusco que significa cambiar de entrada).

Una cosa es el tiempo de muestreo de la señal, que justamente lo fija uno con SAMC; y otra cosa el reloj del CAD.

tiempo muestreo = TSMP = SAMC<4:0>*TAD
Tad = reloj del CAD

Es imprescindible definir ambos, tanto el SAMC como el Tad (a través de bits ADCS).

Fijate en la sección 17.15.1 (página 31/60) del manual de referencia, tenés como configurar el módulo AD para muestrear una sola entrada.
Tendrás que adaptarlo a tus necesidades (cada cuantas conversiones se genera interrupción, frecuencia de muestreo, disparador de conversión...).

A ver como te va...


----------



## fragmir (Nov 24, 2008)

ok hoy programo esto en la noche y postearé de regreso.
Gracias.


----------



## daos (Dic 3, 2008)

Hola, Soy nuevo en esto de los pics y dsPics, de casualidad tieene un programa y diagrama (ejemplo) de como meter la señal de audio en el micro y oirla en el altavoz? les agradeceria mucho su ayuda!

Saludos


----------



## di3gosl (Sep 28, 2009)

Pues mira, no soy un experto en el tema pero vengo trabajando con algunos proyectos de conversión AD y DA de señales de audio sobre todo para telefonía así que conozco sobre el tema y te puedo decir que a esa frecuencia de muestro no podrás reconstruir la señal original.

Las frecuencias audibles para el ser humano van desde los 20 Hz hasta los 20Khz, en el caso de la voz humana las frecuencias van desde los 300 Hz hasta los 10 KHz aprox. y en el caso de telefonía se suele utilizar hasta los 4 KHz.

Y como se sabe por el teorema de Nyquist la frecuencia de muestreo, para posteriormente poder reconstruir la señal sin pérdidas, es el doble de la frecuencia máxima de la señal de entrada, es decir, para telefonía la frrecuencia máxima es 4KHz por lo que se debería tener una frecuencia muestreo de 8 KHz.

Algunas frecuencias de muestreo conocidas son:
8000 muestras/seg - Telefonía
22050 muestras/seg - Radio
44100 muestras/seg - CD de audio
48000 muestras/seg - DVD

Actualmente estoy desarrollando un gateway de voz para telefonía IP utilizando un dsPIC33FJ128GP802 y parte de la funcionalidad incluye muestrear, convertir y codificar señales de audio, para ello utilizo una frecuencia de muestreo de 8000 Hz tanto para el ADC como para el DAC y la señal se reconstruye perfectamente. 

Con 2400 Hz de muestreo solo podrás procesar y reconstruir señales de hasta 1200 Hz que si bien incluye un rango de sonidos de la voz humana no es suficiente para una buena calidad de audio. Solo tendrías que elegir una velocidad de muestreo adecuada para tu aplicación. Espero te sea de utilidad y suerte.


----------

