Autor Tema: Proyecto para medir el valor eficaz verdadero (True RMS)  (Leído 26576 veces)

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

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #60 en: 21 de Septiembre de 2023, 14:17:31 »
¿Pero necesitas estar calculando en tiempo real?.
Yo en mi Dimmer con medición de consumo tomo 10 ondas completas y luego hago todos los cálculos y espero al siguiente cruce por cero para arrancar el proceso de nuevo.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #61 en: 21 de Septiembre de 2023, 14:21:42 »
¿Pero necesitas estar calculando en tiempo real?.
Yo en mi Dimmer con medición de consumo tomo 10 ondas completas y luego hago todos los cálculos y espero al siguiente cruce por cero para arrancar el proceso de nuevo.

Claro, podría ser como dices, pero creo que no sería lo que se denomina "True RMS", y si se puede y no es complicado, hay que intentarlo.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #62 en: 23 de Septiembre de 2023, 13:52:21 »
Estos son los ejemplos que voy a tomar de referencia.

1. Interrupción del conversor ADC

El ejemplo se denomina adc_interrupt_pic32mx470_curiosity

Y el ejemplo es el siguiente:

Código: C
  1. void ADC_ResultHandler(uintptr_t context)
  2. {
  3.     /* Read the ADC result */
  4.     adc_count = ADC_ResultGet(ADC_RESULT_BUFFER_0);
  5.     result_ready = true;
  6. }
  7.  
  8.  
  9. int main ( void )
  10. {
  11.     /* Initialize all modules */
  12.     SYS_Initialize ( NULL );
  13.     ADC_CallbackRegister(ADC_ResultHandler, (uintptr_t)NULL);
  14.  
  15.     printf("\n\r---------------------------------------------------------");
  16.     printf("\n\r                    ADC Demo                 ");
  17.     printf("\n\r---------------------------------------------------------\n\r");
  18.  
  19.     /* Start ADC conversion */
  20.     ADC_ConversionStart();
  21.  
  22.  
  23.     while (1)
  24.     {
  25.         /* Maintain state machines of all polled MPLAB Harmony modules. */
  26.         SYS_Tasks ( );
  27.  
  28.         /* Auto sampling mode is used, so no code is needed to start sampling */
  29.  
  30.         /* Wait till ADC conversion result is available */
  31.         if(result_ready == true)
  32.         {
  33.             result_ready = false;
  34.             input_voltage = (float)adc_count * ADC_VREF / ADC_MAX_COUNT;
  35.             printf("ADC Count = 0x%03x, ADC Input Voltage = %d.%02d V \r", adc_count, (int)input_voltage, (int)((input_voltage - (int)input_voltage)*100.0));
  36.  
  37.             /* Start ADC conversion */
  38.             ADC_ConversionStart();
  39.         }
  40.     }
  41.  
  42.     /* Execution should not come here during normal operation */
  43.  
  44.     return ( EXIT_FAILURE );
  45. }

Se puede observar que en la línea 13, se asigna o registra con la función ADC_CallbackRegister, la función que manejará la interrupción al finalizar la conversión del ADC.

Esta función se denomina ADC_ResultHandler y está en la línea 1, donde obtiene el valor de la conversión y la guarda en la variable adc_count

La configuración de dicho periférico, con la zona gráfica del MCC es como se muestra:



2. Interrupción por un temporizador

El ejemplo que voy a tomar de referencia, se llama tmr_timer_mode_pic32mx_12_sk

Código: C
  1. /* This function is called after period matches in Timer 3 (32-bit timer) */
  2. void TIMER2_InterruptSvcRoutine(uint32_t status, uintptr_t context)
  3. {
  4.     /* Toggle LED */
  5.     LED1_Toggle();
  6. }
  7. // *****************************************************************************
  8. // *****************************************************************************
  9. // Section: Main Entry Point
  10. // *****************************************************************************
  11. // *****************************************************************************
  12.  
  13. int main ( void )
  14. {
  15.     /* Initialize all modules */
  16.     SYS_Initialize ( NULL );
  17.    
  18.     TMR2_CallbackRegister(TIMER2_InterruptSvcRoutine, (uintptr_t) NULL);
  19.     TMR2_Start();
  20.  
  21.     while ( true )
  22.     {
  23.         /* Maintain state machines of all polled MPLAB Harmony modules. */
  24.         SYS_Tasks ( );
  25.     }
  26.  
  27.     /* Execution should not come here during normal operation */
  28.  
  29.     return ( EXIT_FAILURE );
  30. }

La función que registra a aquella que se llama cuando la interrupción se produce se denomina TMR2_CallbackRegister y está en la línea 18.

Y la función  TIMER2_InterruptSvcRoutine, lo único que hace es conmutar el estado lógico de un led.

Este ejemplo usa al temporizador 2, en modo de 32 bits, esto implica que el temporizador 3, trabaja en conjunto para conseguir ese ancho en bits.



En el módulo del TMR2, está configurado a 32 bits, y se indica que la habilitación de la interrupción, debe hacerse en el temporizador secundario o esclavo, en este caso es el TMR3, y su configuración es:



En mi caso, pienso usar el temporizador 4, pero no creo que sea necesario trabajar a 32 bits (TMR5) para alcanzar los 100 us.

3. Interrupción por flanco positivo

Aquí viene lo interesante.

Estaba pensando, para detectar el flanco positivo de la onda cuadrada, solamente esperar su transición, de 0 a 1 lógico, pero esto de esperar en una tarea de estados de máquina (que también es un proceso asincrónico), implica que su precisión puede alterarse, debido a los cálculos del RMS anteriormente mencionados.

Busqué ejemplos de Harmony, con respecto a esto, y hay varios ejemplos los cuales corresponden a un ejemplo común denominado GPIO interrupt

Pensé que se utilizaba la interrupción externa, pero, lo que en realidad, se utiliza es el cambio de estado de un terminal o un pin.

No logro encontrar un ejemplo que explícitamente posea módulos, como los anteriores periféricos, donde pueda configurar las características de la interrupción externa.

Abrí un hilo en el foro de MCHP:

https://forum.microchip.com/s/topic/a5C3l000000Br5vEAC/t392257

Y también estoy esperando al soporte técnico:

El peor de los casos, sería escribir mi propia configuración, como se hacía en los viejos tiempos.


 




Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #63 en: 24 de Septiembre de 2023, 12:50:16 »
Hola.

Hasta esperar una respuesta del foro (o más seguro, del soporte técnico) de MCHP, voy a intentar lo siguiente.

El terminal que va ser utilizado para el módulo de captura para medir la frecuencia de la señal AC, también dispone de una interrupción externa:



En teoría, sólo se podría usar una de las dos opciones, pero mediante el modulo System, podría habiliar a esa interrupción:



Luego, creo un nuevo grupo, denominado adquisición:



Dentro de este nuevo grupo, agrego el módulo ADC, el cual tiene las siguientes configuraciones.

- La interrupción está habilitada
- La fuente de reloj es del bus de periféricos de 48 MHz.
- El divisor de reloj es 23, para conseguir 1000 ns (1 us) de tiempo de adquisición, como al inicio mencioné.
- La referencia de voltaje es VREF+ y AVSS (GND) donde VERF + será 3.0V
- El canal 0 del ADC, se conectará a la entrada analógica AN1.
- El resultado de lo conversión será un número de 32 bits de tipo entero



También agrego el temporizador 4, en modo de 16 bits para generar 100 us:



Con el módulo Core, creo una nueva tarea denominada appSampling, que será la encargada de inicializar la habilitación de la interrupción externa, y esta a su vez, habilitará las interrupciones del ADC y del TMR4 al mismo tiempo:



Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #64 en: 24 de Septiembre de 2023, 14:15:36 »
Estaba buscando información sobre la interrupción externa con Harmony 3, y encontré este hilo en el foro de MCHP:

https://forum.microchip.com/s/topic/a5C3l000000BqqMEAS/t391969

En base a eso y buscando más información de la función EVIC_ExternalInterruptCallbackRegister:

https://onlinedocs.microchip.com/oxy/GUID-450989FA-38E4-4D68-AB61-15ADB29AD718-en-US-2/GUID-FF33409B-66B4-4FEA-B3BE-8085BC5ACA81_6.html

El estado de la tarea appSampling sería así:

Código: C
  1. void APPSAMPLING_Tasks ( void )
  2. {
  3.     /* Check the application's current state. */
  4.     switch ( appsamplingData.state )
  5.     {
  6.         /* Application's initial state. */
  7.         case APPSAMPLING_ESTADO_INICIAL:
  8.         {
  9.             ICAP1_Disable(); //Deshabilito el módulo de captura
  10.             TMR4_CallbackRegister(ManejarInterrupcionTMR4, (uintptr_t) NULL);// registro función de interrupción por TMR4
  11.             ADC_CallbackRegister(ManejarInterrupcionADC, (uintptr_t)NULL); // registro función de interrupción por ADC
  12.             EVIC_ExternalInterruptCallbackRegister(EXTERNAL_INT_2, &ManejarInterrupcionExterna, (uintptr_t)NULL); //Registro la función que se llama por la interrupción externa
  13.             appsamplingData.state = APPSAMPLING_ESTADO_REPOSO;
  14.             break;
  15.         }
  16.  
  17.         case APPSAMPLING_ESTADO_REPOSO: break;
  18.         /* TODO: implement your application state machine.*/
  19.         /* The default state should never be executed. */
  20.         default: break; /* TODO: Handle error in application's state machine. */
  21.     }
  22. }

Donde en el estado inicial se hace lo siguiente:

1. Deshabilitar el módulo de captura, por el momento, aun no voy a medir la frecuencia de la seña AC.
2. Registrar la función que se invoca cuando la interrupción del TMR4 sucede (100 us)
3. Registrar la función que se invoca cuando la interrupción del ADC sucede.
4. Registrar la función que se invoca cuando la interrupción externa 2 sucede.
5. Ir a un estado de reposo, ya que todos esos tres procesos funcionan en base a interrupciones y no tiene sentido crear más estados de máquina.



Las funciones mencionadas quedarían así:

Código: C
  1. / *****************************************************************************
  2. // *****************************************************************************
  3. // Section: Application Local Functions
  4. // *****************************************************************************
  5. // *****************************************************************************
  6. void ManejarInterrupcionTMR4(uint32_t status, uintptr_t context);
  7. void ManejarInterrupcionADC(uintptr_t context);
  8. void ManejarInterrupcionExterna (EXTERNAL_INT_PIN pin, uintptr_t context);
  9.  
  10. /* TODO:  Add any necessary local functions.
  11. */
  12.  
  13. void ManejarInterrupcionTMR4(uint32_t status, uintptr_t context)
  14. {
  15.  
  16. }
  17. void ManejarInterrupcionADC(uintptr_t context)
  18. {
  19.     //adc_count = ADC_ResultGet(ADC_RESULT_BUFFER_0);
  20. }
  21. void ManejarInterrupcionExterna (EXTERNAL_INT_PIN pin, uintptr_t context)
  22. {
  23.    
  24. }

Estaba pensando que si este voltímetro, no se alimentara con voltaje AC, digamos uno 100 V DC, no aparecería una señal cuadrada, y por lo tanto el proceso para capturar datos con el ADC no funcionaría.

Tenía la idea que, debería existir un retardo asincrónico en el estado de reposo de la tarea appSampling, de tal manera que si sobrepasaba cierto límite, y no ocurría la interrupción externa, debía emitirse una alarma y informar algo en el display de que no se detecta una señal de AC.

Pero luego, pensado, que si se realiza el cálculo RMS de una señal de DC, sería exactamente su valor medio o DC, y serviría también como voltímetro DC.

Entonces, lo que pienso ahora, es que si el temporizador asincrónico sobre pasa cierto límite, en lugar de informar el error, debería iniciar la conversión (similar  a lo que haría la interrupción externa) y de esa manera obtendría el valor DC de la señal.

Es una idea que luego podría implementar.

Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #65 en: 25 de Septiembre de 2023, 11:08:45 »

Recordé que el ADC, es de 10 bits, entonces no tiene sentido que el formato del resultado sea de 32 bits, así que lo modifiqué a 16 bits:



También me faltaba habilitar la interrupción externa 2, para lo cual modifiqué el estado inicial como se indica en la siguiente figura:



Para almacenar las muestras, cree una estructura de datos así:

Código: C
  1. typedef struct
  2. {
  3.     unsigned short  bufferADC[256]; // almacena cada muestra adquirida por el ADC
  4.     unsigned char   muestra;        // apunta a cada uno de los elementos de bufferADC
  5. }EstructuraADC;

Donde bufferADC, va a almacenar cada muestra del ADC.

La razón que escogí un tamaño de 256 bytes, es debido a que si va tomar una muestra cada 100 us, y el periodo de la señal es de 16.667 ms (60 Hz), entonces 16.667 ms / 100 us = 166.67 muestras.

Obviamente la frecuencia no va ser contante, pero no creo que sobrepase o disminuya en gran medida, así que creo que 256 bytes es suficiente.

Mientras que muestra es el puntero a cada elemento del arreglo, también sería el periodo discreto para el cálculo del RMS.

Con esta estructura, creo un arreglo de dos elementos, en la estructura de datos de la tarea así:

Código: C
  1. typedef struct
  2. {
  3.     /* The application's current state */
  4.     APPSAMPLING_STATES state;
  5.     /* TODO: Define any additional data used by the application. */
  6.     EstructuraADC   estructuraADC[0x02];
  7.     unsigned char   punteroABuffer; // De 0 a 1
  8. } APPSAMPLING_DATA;

Mediante punteroABuffer, escojo el primer o segundo buffer.

En el estado inicial de la tarea, las variables muestras las inicializo en cero. pero la variable punteroABuffer, la pongo en 1, ya que cuando suceda la interrupción externa, apuntará al siguiente buffer, que será el 0, y de esa manera se inicializa correctamente:

Código: C
  1. void APPSAMPLING_Initialize ( void )
  2. {
  3.     /* Place the App state machine in its initial state. */
  4.     appsamplingData.state = APPSAMPLING_ESTADO_INICIAL;
  5.     /* TODO: Initialize your application's state machine and other
  6.      * parameters.
  7.      */
  8.     appsamplingData.punteroABuffer  = 0x01; //apunto al segundo buffer, para que con INT2, se inicie 0 (Primer buffer)
  9.     appsamplingData.estructuraADC[0x00].muestra = 0x00; // Muestra de buffer 0 inicializado
  10.     appsamplingData.estructuraADC[0x01].muestra = 0x00; // Muestra de buffer 1 inicializado
  11. }

Cuando ocurre la interrupción externa, se debe inicializar la adquisición de datos del ADC e iniciar el funcionamiento del temporizador.

Esta interrupción, me sirve para conmutar al buffer de almacenamiento de datos, así que la variable punteroABuffer, es incrementada (o inicializada en cero si es mayor que uno) :



Cuando sucede la interrupción del ADC, se debe tomar la muestra, y guardarla en el buffer correspondiente, e incrementar la variable muestra:



Y cuando sucede, la interrupción del temporizador (100 us), se debe realizar una nueva adquisición conversión del ADC:



Hasta aquí, en teoría se estaría siempre muestreando la señal sinusoidal, cada ciclo se almacenaría en dos buffers independientes. Debería probar su funcionamiento, es posible que haya un error que no note u algún otro problema.

Suponiendo que funciona, el siguiente paso, es que la tarea dedicada a calcular el RMS, lo haga con el buffer diferente al que se está usando para almacenar datos.




Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #66 en: 26 de Septiembre de 2023, 18:52:29 »
Estaba analizando en mi mente esto de las tres interrupciones, y creo que si puede existir un problema.

Hice unos diagramas en un cuaderno, ya que no tengo mucho tiempo para hacerlas en un software, me resulta más rápido.

Para entender el proceso, tenemos lo siguiente:



La interrupción 2 (Detección de flanco positivo) es quien desencadena todo, es decir, activa al temporizador 4 y al conversor ADC. De ahí en adelante solo estas dos interrupciones, funcionan de manera sincrónica.

El ADC termina la adquisición y conversión, genera una interrupción para guardar la muestra, y mucho más luego, la interrupción del TMR4, inicia de nuevo el funcionamiento del ADC, repitiéndose este proceso varias veces.

El problema, es cuando sucede de nuevo la interrupción externa INT2, la cual no está en sincronía con las otras dos

Tenemos dos casos.

El primero, cuando la interrupción externa ocurre luego de haber finalizado una adquisición conversión del ADC y antes de los 100 us.



Este caso no es muy problemático, lo que si debe hacerse, es detener y reiniciar el temporizador 4 e iniciar otro proceso del ADC.

El segundo caso, es cuando la interrupción externa, ocurre antes que el proceso del ADC haya finalizado:



En este caso, también debe detenerse y reiniciar el temporizador, pero no debe arrancar o funcionar, hasta que finalice el proceso del ADC.

Tan pronto como el ADC finalice su proceso, se debe iniciar nuevamente una adquisicón y conversión ADC y arrancar nuevamente el TMR4.

En estos días, voy a pensar como implementar este proceso.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #67 en: 28 de Septiembre de 2023, 22:59:02 »
Hoy día tengo un poco más de tiempo para continuar.

Respecto a que la interrupción externa INT2, debe reiniciar al temporizador TMR4, creo que puedo hacer esto:

Código: C
  1. void ManejarInterrupcionExterna (EXTERNAL_INT_PIN pin, uintptr_t context)
  2. {
  3.     TMR4_Stop();                        // Detengo a TMR4:
  4.     TMR4 = 0x0000;                      // Limpio/reinicio el conteo  
  5.     ADC_ConversionStart();              // inicia la conversión
  6.     TMR4_Start();                       // inicia a funcionar el temporizador 4
  7.     /** Cambio de buffer **/
  8.     appsamplingData.punteroABuffer++;   // apunto al siguiente Buffer
  9.     if (appsamplingData.punteroABuffer > 0x01)
  10.     {
  11.         appsamplingData.punteroABuffer = 0x00;
  12.     }
  13.     appsamplingData.estructuraADC[appsamplingData.punteroABuffer].muestra = 0x00; //limpio puntero (muestra) del buffer
  14. }

En cuanto al evento de la interrupción externa sucede cuando aun el ADC está adquiriendo/convirtiendo, aun no sé, es como determinar si el ADC está en cualquiera de esos estados.

El bit SAMP del registro AD1CON1, cuando está cero puede significar dos cosas, no está adquiriendo datos, o el ADC está en modo conversión.

Mientras que en el mismo registro, el bit DONE, sólo se pone a uno para informar que la conversión ADC a finalizado.

Podría recurrir a una bandera para conocer que el ADC está en cualquiera de los dos modos, algo así:

Código: C
  1. TMR4_Stop();                        // Detengo a TMR4:
  2.     TMR4 = 0x0000;                      // Limpio/reinicio el conteo  
  3.     ADC_ConversionStart();              // inicia la conversión
  4.     bandera = true;                     // ADC inicia proceso
  5.     TMR4_Start();                       // inicia a funcionar el temporizador 4

Código: C
  1. void ManejarInterrupcionADC(uintptr_t context)
  2. {
  3.    bandera = false; // ADC finaliza proceso
  4.  
  5. appsamplingData.estructuraADC[appsamplingData.punteroABuffer].bufferADC[appsamplingData.estructuraADC[appsamplingData.punteroABuffer].muestra] = ADC_ResultGet(ADC_RESULT_BUFFER_0);
  6.     appsamplingData.estructuraADC[appsamplingData.punteroABuffer].muestra++;
  7. }


Si no encuentro alguna otra opción, deberé hacerlo de esa manera.

Otra duda que tengo, es que el ejemplo que estoy tomando como referencia, tiene el muestreado en modo automático.

Según las hoja de datos, en ese modo, cuando finaliza una conversión, de manera automática, entra en modo de muestreo:



Pero en mi caso yo debo esperar hasta que el temporizador produzca una interrupción, entonces, lo que entiendo, es que cuando hayan pasado los 100 us, y ejecute la línea ADC_ConversionStart, lo que voy a obtener es la muestra de 100 us atrás, no la de ese momento. Obviamente en una señal de muy baja frecuencia, o DC, no tendría mucha importancia.

O tal vez no sea tan crítico, que mi señal muestreada, sea de hace 100 us en el pasado.

Tal vez deba utilizar el modo manual de activar el muestreado, y también creo que debería manualmente, activar la conversión.

Otra duda que tenía, era con el nivel de prioridad de las interrupciones, y que sucede cuando dos ocurren al mismo tiempo.

La interrupción externa es la que tiene la prioridad más alta, 7, las otras dos tienen prioridad de 1.

Pienso que la interrupción del ADC, debe ser la de más alta que INT2, y la del TMR4, debe ser la más baja.

ADC > INT2 > TMR4.

Hay dos escenarios

1. Sucede la interrupción externa y la del TMR4 al mismo tiempo

En este caso, la interrupción de INT2, bloquea a la interrupción del TMR4, y INT2, lo que hace es inicializar al temporizador, conmuta de buffer y arranca al ADC, luego la interrupción del temporizador no tendría que ser, ya que el ADC ya está funcionando, la bandera antes mencionada sería útil para tal caso.

2.  Sucede la interrupción externa y la del ADC al mismo tiempo

La muestra ADC se guarda en el buffer actual y cuando se reanuda la interrupción externa, se reinicia al temporizador y se cambia de buffer.



La interrupción del TMR4 y del ADC al mismo tiempo, no es posible, ya que el temporizador, es quien inicializa al ADC, y su interrupción sucede luego.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #68 en: 29 de Septiembre de 2023, 11:14:41 »
Estaba leyendo el manual del conversor ADC, y creo, si no comprendí mal que el proceso donde la adquisición es automática, sería como se muestra en esta imagen:



Cuando enciendo el ADC, la adquisición funciona casi inmediatamente.

Luego transcurre un tiempo indeterminado hasta que se configuren otros periféricos, se inicien las tareas y procesos.

Sucede la interrupción externa INT2, y con  ADC_ConversionStart();  se inicia la conversión, y la muestra obtenida, es aquella que se tomó poco después de encender el ADC, y se podría decir que no es tan útil.

También la adquisición se inicia automáticamente.

Cuando sucede la interrupción del TMR4, nuevamente se ejecuta el ADC_ConversionStart(), pero la muestra obtenida es aquella que se muestreo anteriormente.

En pocas, la información contenida en cada buffer, tendría un retrazo de 100 us, pero no creo que sea algo crítico dicho  "atraso".


Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #69 en: 21 de Noviembre de 2023, 18:57:25 »
Al fin llegó el OP con el tamaño correcto y lo he colocado en el PCB.



En los siguientes días voy a continuar con el proyecto.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #70 en: 22 de Noviembre de 2023, 13:59:46 »
He conectado a la red AC de la empresa eléctrica y está es la forma de onda a la entrada del ADC.




El voltaje de la red eléctrica es de aproximadamente 125 VAC, es decir que el voltaje pico es +- 176.78V.

El acondicionamiento de la señal se basa en la ecuación:

Vout = Vin/200 +1.5V, por lo tanto el Voltaje máximo sería:

Vout max = 176.78/200 +1.5 = 2.38V

Y el voltaje mínimo sería:

Vout min = -176.78/200 + 1.5 = 0.6161.

Según la imagen de arriba, el voltaje pico es 2.36V y el mínimo aproximadamente 0.6, así que parece que el acondicionamiento funciona correctamente.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #71 en: 22 de Noviembre de 2023, 14:13:35 »
Muy bien, DominusDRR, muy interesante.

Veo en la onda cierta distorsión justo después de cada cresta. ¿Es así o será cosa de la foto?

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #72 en: 22 de Noviembre de 2023, 14:20:38 »
Muy bien, DominusDRR, muy interesante.

Veo en la onda cierta distorsión justo después de cada cresta. ¿Es así o será cosa de la foto?

La misma red eléctrica no es de buena calidad, me parece que el parámetro de calidad se denomina THD o TDH, no recuerdo, me imagino que es bajo.

Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #73 en: 22 de Noviembre de 2023, 14:22:29 »
Pues si esa es la onda de la red eléctrica realmente es mala

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Proyecto para medir el valor eficaz verdadero (True RMS)
« Respuesta #74 en: 24 de Noviembre de 2023, 10:59:46 »
Hola.

Me olvidé comentar que la respuesta del soporte de MCHP sobre el funcionamiento del ADC es como se describe.

Durante el tiempo de conversión, que dura por lo menos 132 ns, el condensador se va cargando hasta alcanzar el voltaje de la señal de entrada.



Luego el capacitor sigue el voltaje durante los 100 us.

Cuando inicia la conversión, el capacitor se desconecta de la señal de entrada y empieza la conversión del valor que tenga en ese instante.

El capacitor se descarga para nuevamente alcanzar en 132 ns al voltaje de la señal analizada, el siguiente gráfico demuestra lo que ocurre.



Conecte como voltaje de entrada AC, la salida de un transformador reductor de 120VAC a 24VAC y también iba a usa una fuente externa de 9VDC, para energizar al microcontrolador, y de esa manera depurar el código, pero para mi sorpresa, con 24VAC, la fuente transformerless que tiene el PCB funciona correctamente.

Coloqué un punto de ruptura cuando se produzca el segundo flanco de subida en la interrupción externa. Mi idea es ver cuantas muestras adquirió en un periodo de la señal:



Y se puede apreciar que el un periodo de la señal AC, existen 200 muestras.

Si el periodo de la señal AC es de 1/60 ó 16.667 ms y estoy tomando una muestra cada 100 us, por lo tanto el número de muestras sería:

16.667ms / 100us = 166.667, que está cerca al valor de 200, parecería que está bien, por ahora.

El siguiente paso es calcular el RMS con las muestras adquiridas.

Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32


 

anything