Autor Tema: Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I  (Leído 1076 veces)

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

Desconectado padag

  • PIC10
  • *
  • Mensajes: 13
Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« en: 06 de Mayo de 2021, 04:49:45 »
Buenos días a todos,

Estoy intentando hacer un programa que me capture cuatro muestras simultaneas de una señal a 64KHz que lee el ADC, para posteriormente realizar el cálculo de la fase. El problema es que quiero realizar esto de manera indefinida en el tiempo, por lo que necesito que las muestras que almaceno siempre sean consecutivas, es decir: Si el primer grupo de cuatro son las muestras m1, m2, m3 y m4, el siguiente grupo de cuatro muestras tienen que ser la m5, m6, m7 y m8. No me serviría, por ejemplo, las muestras m7, m8, m9 y m10, perdiendo las muestras m5 y m6 por el camino, ya que esto me daría valores de fase incorrectos.

En el programa que he escrito lo que hago es almacenar en el vector1, gracias a la interrupción del ADC, cuatro muestras consecutivas. Una vez que he almacenado cuatro muestras en el vector1, en la función main copio esas muestras en otro vector (vector2), para asegurarme de que lo que se vaya sobreescribiendo en vector1 ya lo tenga guardado. Una vez hecho esto, calculo la fase con las cuatro muestras almacenadas en vector2, y el ciclo se repite indefinidamente.
 
Esta sería la interrupción por ADC:

Código: [Seleccionar]
void __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt() {
    temp = ADCBUF0;
    temp1 = temp;
    temp1 = (temp1 * (3.313)) / 1023.0;
    vector1[cont] = temp1;
    cont++;
    if (cont == 4) {
        chiv = 1;
    }
    IFS0bits.AD1IF = 0; // Reseteamos el Flag del ADC
}

y en la función main tendría lo siguiente:

Código: [Seleccionar]
int main(void) {
    OscConfig();
    Configurar_IO();
    ADCInit(); // Inicializamos el conversor A/D
    Configurar_UART();
    Configurar_Timer32();
    while (OSCCONbits.LOCK != 1);
    ADCStart(); // Encendemos el ADC
    T2CONbits.TON = 1;
    while (1) {
        if (chiv == 1) {
            cont = 0;
            chiv = 0;
            for (i = 0; i <= 3; i++) {
                vector2[i] = vector1[i];
            }
            denom = vector2[0] - vector2[2];
            numer = vector2[3] - vector2[1];
            fase = (atan(numer / denom))*(180 / M_PI);
        }
    }
    return 0;
}


Como podéis ver el código no es complicado, tomo cuatro muestras y hago un calculo con ellas, tomo las cuatro siguientes, y vuelvo a hacer el cálculo, y así indefinidamente.

El problema es que creo que, una vez que tengo las cuatro muestras y procedo a calcular la fase, todos esos cálculos que hago en el main son mas lentos que lo que tarda el ADC en coger las cuatro muestras (el ADC funciona a una frecuencia de muestreo de 256KHz), por lo que no da tiempo a ejecutar la rutina en el main cuando el ADC ya produce la interrupción.

Una de las dudas que tengo es si las interrupciones resetean la funcion main. Es decir, si la interrupción del ADC se produce mientras se está ejecutando la linea 5 del main, una vez que ha finalizado la interrupción, ¿se sigue por la línea 5 del main o se resetea y vuelve a empezar de nuevo? Si fuera la primera opción tendría prácticamente 4 ciclos del ADC para ejecutar todo el main, mientras que si fuera la segunda, solo tendría el último ciclo del ADC para hacer el cálculo. Os adjunto todo el código por si queréis echarle un vistazo al completo.

Independientemente de esta duda, si se os ocurre una forma mas eficiente de hacer lo que estoy intentando hacer, os agradecería enormemente vuestra ayuda.

Muchas gracias a todos!!




Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #1 en: 06 de Mayo de 2021, 11:38:34 »
...
El problema es que creo que, una vez que tengo las cuatro muestras y procedo a calcular la fase, todos esos cálculos que hago en el main son mas lentos que lo que tarda el ADC en coger las cuatro muestras (el ADC funciona a una frecuencia de muestreo de 256KHz), por lo que no da tiempo a ejecutar la rutina en el main cuando el ADC ya produce la interrupción.
Es que no conforme con ser optimista con los tiempos de ejecución de las operaciones en punto flotante y sobre todo las trigonométricas, hacés operaciones inútilmente.

¿Para qué multiplicás las lecturas por una constante si después hacés un cociente????

Eso debe ser
Código: [Seleccionar]
void __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt() {
    vector1[cont] = ADCBUF0;    cont++;      // Ojo!  vector1[]  declarado entero
    if (cont == 4) {
        chiv = 1;
    }
    IFS0bits.AD1IF = 0; // Reseteamos el Flag del ADC
}

El main queda igual salvo la declaración de vector1 y vector2 que ahora son enteros.


Citar
Una de las dudas que tengo es si las interrupciones resetean la funcion main. Es decir, si la interrupción del ADC se produce mientras se está ejecutando la linea 5 del main, una vez que ha finalizado la interrupción, ¿se sigue por la línea 5 del main o se resetea y vuelve a empezar de nuevo?
Después de la interrupción se sigue en donde el código fue interrumpido, valga la redundancia.
Como activás chiv al 4to valor te queda muy poco tiempo para copiar el vector antes que te sobreescriba vector1[0]  -->  si te alcanza todos felices.

Por otro lado, las funciones trigonométricas son muy lentas , no veo sentido a calcularla mientras se adquieren los datos, vos tendrías que como mucho ir enviando las diferencias numer y denom (como enteros)  y las operaciones se hagan en el momento del cálculo y visualizacion.



Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8136
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #2 en: 06 de Mayo de 2021, 21:08:50 »
Y no seria mas simple directamente ver donde esta el cruce por cero y el tiempo transcurrido, y no estar leyendo la señal de 64Khz ?

Además si alguien me puede explicar como es que haciendo un arco tangente de la misma señal tomada 4 veces encuentro su fase.
Tal ves se me este escapando la tortuga, pero lo que veo es el calculo de las diferencias de "altura" de la señal (cuando descendió o se modifico su valor) en dos instantes que supongo con tiempo constante. Y luego su división, como si pudiera plantearlo como un triangulo rectángulo donde la primer diferencia es el lado opuesto y la segunda el lado adyacente. Pero no veo la relacion que tienen uno y otro.

Además esto supone que en algún momento podrías llegar a dividir por 0.

PD:

El dsPIC es un animal totalmente distinto dentro de la fauna de Microchip, este animal posee órganos mas refinados, y uno de ellos es el ADC, el ADC deja de ser lo mas simple del mundo para pasar a ser uno de los mas complicados de configurar, pero así también presenta muchas ventajas.

El ADC posee ventajas como el sampling simultaneo de varias entradas, la conversión y sampling secuencial de entradas. El resultado como fracción con/sin signo, entero con/sin signo. Es posible generar una interrupcion cada X muestras, sin tener que hacerlo 1 por 1 como lo estas haciendo. Modificar los tiempos de adquisicion que mejor responda a nuestro circuito. Podes disparar el DMA para el copiado automático de los datos.

No se el estado que posea Microchip con el DSP, es decir si logro incorporar en su compilador las instrucciones del DSP o no. Pero la última vez que habia visto ejemplos de filtros FIR, terminaban llamando una función en ASM para ejecutar las instrucciones MAC, el cual a vos te podria servir bastante para dividir (me refiero a las instrucciones DIV.xx, ofreciendo la mejor performance.
Pero otra cosa para que tengas en cuenta, lo decimal usa IEEE 754 en los programas de C, y casi siempre en los DSP esta expresado en Q15 o enteros, ya que es en este formato el que se opera. Por lo que seguramente no este incorporado las instrucciones DSP en el compilador C.
« Última modificación: 07 de Mayo de 2021, 06:53:30 por KILLERJC »

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #3 en: 07 de Mayo de 2021, 10:40:08 »
Y no seria mas simple directamente ver donde esta el cruce por cero y el tiempo transcurrido, y no estar leyendo la señal de 64Khz ?
Ya se comentó en un hilo anterior, pero fué como un grito en un bosque deshabitado.

Citar
Además si alguien me puede explicar como es que haciendo un arco tangente de la misma señal tomada 4 veces encuentro su fase.
Tal ves se me este escapando la tortuga, pero lo que veo es el calculo de las diferencias de "altura" de la señal (cuando descendió o se modifico su valor) en dos instantes que supongo con tiempo constante. Y luego su división, como si pudiera plantearlo como un triangulo rectángulo donde la primer diferencia es el lado opuesto y la segunda el lado adyacente. Pero no veo la relacion que tienen uno y otro.
Además esto supone que en algún momento podrías llegar a dividir por 0.
Algunas librerías contemplan funciones como atan2(den,num), que evitan el problema de la división por 0 y te dan el resultado entre (-pi,pi] , en lugar de entre (-pi/2,pi/2)  como atan()

La operación que hace te da un ángulo relacionado con la fase solamente cuando la velocidad de muestreo es 4 veces la frecuencia de la señal (una muestra cada 90°)
Aun asi, es mil veces mas simple y preciso analizar el cruce por 0.

Desconectado padag

  • PIC10
  • *
  • Mensajes: 13
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #4 en: 18 de Mayo de 2021, 04:58:21 »
Y no seria mas simple directamente ver donde esta el cruce por cero y el tiempo transcurrido, y no estar leyendo la señal de 64Khz ?
Ya se comentó en un hilo anterior, pero fué como un grito en un bosque deshabitado.

Citar
Además si alguien me puede explicar como es que haciendo un arco tangente de la misma señal tomada 4 veces encuentro su fase.
Tal ves se me este escapando la tortuga, pero lo que veo es el calculo de las diferencias de "altura" de la señal (cuando descendió o se modifico su valor) en dos instantes que supongo con tiempo constante. Y luego su división, como si pudiera plantearlo como un triangulo rectángulo donde la primer diferencia es el lado opuesto y la segunda el lado adyacente. Pero no veo la relacion que tienen uno y otro.
Además esto supone que en algún momento podrías llegar a dividir por 0.
Algunas librerías contemplan funciones como atan2(den,num), que evitan el problema de la división por 0 y te dan el resultado entre (-pi,pi] , en lugar de entre (-pi/2,pi/2)  como atan()

La operación que hace te da un ángulo relacionado con la fase solamente cuando la velocidad de muestreo es 4 veces la frecuencia de la señal (una muestra cada 90°)
Aun asi, es mil veces mas simple y preciso analizar el cruce por 0.

Hola a ambos,

Perdonad por la tardanza, pero he estado ocupado con otros temas del proyecto y no he podido dedicarle tiempo a este.

Con esto que propones Eduardo2, como puedo calcular el desfase entre ambas señales utilizando solo el cruce por cero de cada una? Si es tan sencillo y eficiente como comentas, me interesa bastante saber como puedo realizar este cálculo.

Muchas gracias!!

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #5 en: 18 de Mayo de 2021, 09:52:00 »
....
Con esto que propones Eduardo2, como puedo calcular el desfase entre ambas señales utilizando solo el cruce por cero de cada una? Si es tan sencillo y eficiente como comentas, me interesa bastante saber como puedo realizar este cálculo.
....

Usas  "Input Capture".  Te guarda el contenido de un timer en el momento de cambio en un pin.

Leyendo varias señales con el mismo micro, la diferencia entre capturas es proporcional al desfasaje existente.

Si las señales son leidas por diferentes micros hay un problema nada trivial que es la sincronización o el offset entre ellos.  Problema que ya tenías antes porque el ángulo que obtenías no era un valor respecto a la emisión sino al instante de lectura.

Obviamente la señal que llega al micro debe estar debidamente acondicionada, aunque un acondicionamiento mas fácil que antes porque te tolera mejor el ruido.

Desconectado padag

  • PIC10
  • *
  • Mensajes: 13
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #6 en: 19 de Mayo de 2021, 07:26:01 »
....
Con esto que propones Eduardo2, como puedo calcular el desfase entre ambas señales utilizando solo el cruce por cero de cada una? Si es tan sencillo y eficiente como comentas, me interesa bastante saber como puedo realizar este cálculo.
....

Usas  "Input Capture".  Te guarda el contenido de un timer en el momento de cambio en un pin.

Leyendo varias señales con el mismo micro, la diferencia entre capturas es proporcional al desfasaje existente.

Si las señales son leidas por diferentes micros hay un problema nada trivial que es la sincronización o el offset entre ellos.  Problema que ya tenías antes porque el ángulo que obtenías no era un valor respecto a la emisión sino al instante de lectura.

Obviamente la señal que llega al micro debe estar debidamente acondicionada, aunque un acondicionamiento mas fácil que antes porque te tolera mejor el ruido.

Pues creo que esto que me comentas puede ser la solución definitiva, ya que este dsPIC tiene hasta ocho canales para este fin, y yo necesitaría 5. La idea es poner uno en cada esquina (formando un cuadrado), y el quinto ponerlo justo en el centro, y medir el desfasaje que tienen las esquinas con respecto al central.

La duda que me asalta ahora es si es posible introducir en el dspic señales senoidales con semiciclos negativos, ya que en principio la idea era la de inyectar una señal senoidal de 3V pico-pico con un offset de 1.5V, por lo que entiendo que no sería posible hacer esta captura de cruce por cero.

Una posible solución que se me ocurre (sin saber exactamente si es posible hacerlo, aun tengo que empollarme el módulo input capture) es si en vez del estudiar el cruce por cero puedo estudiar el cruce, por ejemplo, por 1.5V (que con el offset aplicado a la señal realmente sería el 0 de la señal). Si esto fuera posible, estaría consiguiendo esto que me comentas.

Muchas gracias de nuevo!!!

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #7 en: 19 de Mayo de 2021, 10:48:05 »
...
La duda que me asalta ahora es si es posible introducir en el dspic señales senoidales con semiciclos negativos, ya que en principio la idea era la de inyectar una señal senoidal de 3V pico-pico con un offset de 1.5V, por lo que entiendo que no sería posible hacer esta captura de cruce por cero.

Mientras la corriente esté limitada por una resistencia no se rompe nada pues conducen los diodos de protección de la entrada,  pero no podés meter una señal alegremente una señal analógica en una entrada digital porque no tiene ningún umbral de precisión para el cambio de estado.

El nivel de continua de la señal se desplaza con un simple condensador,  aunque debe estar debidamente acondicionada en amplitud y luego cuadrarse con un schmitt trigger por lo anterior.


Por otro lado...  Vos querés sacar una posición en función a una diferencia de fase en una señal de 64kHz,  pero de qué naturaleza???? 
Si estamos hablando de una onda electromagnética la longitud de onda son casi 5km,  por lo que tus detectores deberían estar separados del orden del kilómetro.
Si se trata de un ultrasonido,  la longitud de onda son 5mm .   --> Si el objeto está a 1m de los detectores van a ser 200 longitudes de onda -->  Con la fase sola vas muerto.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8136
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #8 en: 19 de Mayo de 2021, 19:50:37 »
Además como te interesa solo el cruce por cero, podes eliminar los semi ciclos negativos. Dejando solo el positivo y "amplificándolo" (o pasándolo por un comparador, etc) para que quede como una onda cuadrada. Ya tenes todo.

Si tenes un flanco es un cruce por cero, ambos flancos. Si esta en 1, entonces es el semiciclo positivo, y si esta en 0 es el semiciclo negativo. Es decir, toda la información que necesitas.

Desconectado padag

  • PIC10
  • *
  • Mensajes: 13
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #9 en: 24 de Mayo de 2021, 07:14:58 »
...
La duda que me asalta ahora es si es posible introducir en el dspic señales senoidales con semiciclos negativos, ya que en principio la idea era la de inyectar una señal senoidal de 3V pico-pico con un offset de 1.5V, por lo que entiendo que no sería posible hacer esta captura de cruce por cero.

Mientras la corriente esté limitada por una resistencia no se rompe nada pues conducen los diodos de protección de la entrada,  pero no podés meter una señal alegremente una señal analógica en una entrada digital porque no tiene ningún umbral de precisión para el cambio de estado.

El nivel de continua de la señal se desplaza con un simple condensador,  aunque debe estar debidamente acondicionada en amplitud y luego cuadrarse con un schmitt trigger por lo anterior.


Por otro lado...  Vos querés sacar una posición en función a una diferencia de fase en una señal de 64kHz,  pero de qué naturaleza???? 
Si estamos hablando de una onda electromagnética la longitud de onda son casi 5km,  por lo que tus detectores deberían estar separados del orden del kilómetro.
Si se trata de un ultrasonido,  la longitud de onda son 5mm .   --> Si el objeto está a 1m de los detectores van a ser 200 longitudes de onda -->  Con la fase sola vas muerto.

Pues finalmente me he dado cuenta que usar input capture no me sirve...ya que los tiempos requeridos por el módulo input capture es bastante mayor de lo que yo necesito...

Realmente a la entrada de los ADCs tendré una señal de 2.44GHz en el espectro de las microondas. Utilizando la teoría del submuestreo puedo muestrearla como si fuera una señal de 64KHz ya que lo único que me interesa es su fase, y esta no se ve afectada al submuestrear. Pero claro, el módulo de input capture no es capaz de detectar los cruces en una señal tan rápida.

Alguna otra idea? Sinceramente llevo varias semanas con este tema y estoy super estancado aquí, no sé como podría continuar y os pido una vez más que me orientéis si sabéis como puedo solucionarlo o dónde podría buscar información al respecto. Incluso si conocéis alguna otra herramienta distinta de los dsPIC para poder realizar este trabajo...

Muchísimas gracias de nuevo!!
« Última modificación: 24 de Mayo de 2021, 07:44:26 por padag »

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #10 en: 24 de Mayo de 2021, 12:02:12 »
....
Realmente a la entrada de los ADCs tendré una señal de 2.44GHz en el espectro de las microondas. Utilizando la teoría del submuestreo puedo muestrearla como si fuera una señal de 64KHz ya que lo único que me interesa es su fase, y esta no se ve afectada al submuestrear. Pero claro, el módulo de input capture no es capaz de detectar los cruces en una señal tan rápida.
Y el tiempo de adquisición del sample&hold del ADC está a años luz del necesario.

Citar
Alguna otra idea? Sinceramente llevo varias semanas con este tema y estoy super estancado aquí,
Lo primero es tomar conciencia que señales de 2.44GHz son muy difíciles de procesar.
Incluso comercialmente, normalmente quienes fabrican equipos que trabajan a estas frecuencias usan un módulo de microondas hecho otro fabricante.



Desconectado padag

  • PIC10
  • *
  • Mensajes: 13
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #11 en: 25 de Mayo de 2021, 03:59:37 »
....
Realmente a la entrada de los ADCs tendré una señal de 2.44GHz en el espectro de las microondas. Utilizando la teoría del submuestreo puedo muestrearla como si fuera una señal de 64KHz ya que lo único que me interesa es su fase, y esta no se ve afectada al submuestrear. Pero claro, el módulo de input capture no es capaz de detectar los cruces en una señal tan rápida.
Y el tiempo de adquisición del sample&hold del ADC está a años luz del necesario.

Citar
Alguna otra idea? Sinceramente llevo varias semanas con este tema y estoy super estancado aquí,
Lo primero es tomar conciencia que señales de 2.44GHz son muy difíciles de procesar.
Incluso comercialmente, normalmente quienes fabrican equipos que trabajan a estas frecuencias usan un módulo de microondas hecho otro fabricante.

Pero en mi caso, con que sea capaz de muestrear a 256KHz conseguiría lo que estoy buscando. En teoría este Dspic puede muestrear a 1.1Msps, pero no consigo acercarme siquiera a las 256K por segundo (y eso que solo leo un canal, aún no he intentado leer 4 simultáneamente)

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 521
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #12 en: 25 de Mayo de 2021, 12:09:30 »
...
Pero en mi caso, con que sea capaz de muestrear a 256KHz conseguiría lo que estoy buscando. En teoría este Dspic puede muestrear a 1.1Msps, pero no consigo acercarme siquiera a las 256K por segundo (y eso que solo leo un canal, aún no he intentado leer 4 simultáneamente)
A ver...

En el pin del dsPIC tenés un circuito de este estilo:

 

* ADCsample.jpg
(25.83 kB, 640x274 - visto 84 veces)


En en el "sample time" se carga el capacitor y pasado un tiempo (Tad) se abre la llave y comienza la conversión.
El Tad mínimo en esos dsPIC es 65ns para 10bit y 117.6ns para 12bit 

Aún si el buffer de entrada y la llave fueran ideales  ¿Que pensás que vas a leer ingresando una señal de período 0.4ns (2.44GHz) ?   

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8136
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #13 en: 25 de Mayo de 2021, 17:32:13 »
https://www.analog.com/media/en/analog-dialogue/volume-35/number-1/articles/accurate-gain-phase-measurement-up-to-2-5-ghz.pdf

¿Y un integrado que te de la fase directamente en forma de mV la cual simplificaria todas las operacion y las posibles incertidumbres que hay si va a funcionar o no?

Desconectado padag

  • PIC10
  • *
  • Mensajes: 13
Re:Funcionamiento de las interrupciones en dsPIC33FJ256GP710-I
« Respuesta #14 en: 24 de Junio de 2021, 04:28:33 »
https://www.analog.com/media/en/analog-dialogue/volume-35/number-1/articles/accurate-gain-phase-measurement-up-to-2-5-ghz.pdf

¿Y un integrado que te de la fase directamente en forma de mV la cual simplificaria todas las operacion y las posibles incertidumbres que hay si va a funcionar o no?

Pues creo que al final me voy a quedar con esta opción, ya que me quita de tener que poner otra interfaz para adaptar la señal al circuito.

Muchas gracias a todos!!