Medidor de potencia con 18F4550

Hola compañeros del foro, estoy empezando en la programación de pic ccs, ya tengo mis conocimientos en protón y asm, ya he realizado ciertos proyectos, pero ahora me he decidió a realizar algo mas complejo, un medidor de potencia para AC, los parámetros son los siguientes:

- Pic 18F4550
- Sensor de corriente ACS 712-30A
- Sensor de voltaje un pequeño transformador q me convierte de los 120v a 5v, junto con un amplificador para subir dicha señal a un nivel de offset, de tal manera que en la salida obtenga la señal periódica en todo el rango positivo.
- Mostrar los valores obtenidos en un LCD 16*2 (Vrms, Irms, P, Prms, Vpp, Vp)

Lo que pienso debería tener en cuenta es esto:

- Debo realizar un cruce por cero, en mi caso seria un cruce por 2.5v
- Realizar una interrupción cada cierto tiempo, que inicie en sincronía con el cruce por cero de señal para realizar el muestreo de la señal siempre en el mismo "lugar" donde se tomó la anterior muestra.
- Almacenar los valores del muestreo para luego procesarlas, quiero tonar 128 muestras y muestrear 30 periodos por cada ciclo, para minimizar el error.

Debo aclarar que exagerado un poco en la cantidad de muestras, esto es porque mas adelante, cuando ya tenga esta parte lista y funcionando, junto con un compañero queremos enviar esa información al PC, a través de comunicación BULK, y visualizarlo en una interfaz que mi compañero creará en labview.

... No se que mas se les ocurre... Que opinión me pueden dar?

De mate mano gracias...
 
Última edición:
Última edición:
Hola cguerrero1205, curiosamente un amigo esta iniciando un proyecto parecido al que tu estas emprendiendo..., la metodología que planteas me parece correcta, pero tengo algunas dudas sobre el metodo que planeas usar para obtener el rms tanto del voltaje como de la corriente, por ejemplo: si vas a detectar "cruce por cero" y luego esperar T/4(periodo/4) para tomar la muestra y obtener el Vp y con ese dato calcular el rms no es buena idea ya que las formulas solo son para onda senoidal, para voltaje mas o menos se aproximaría pero la forma de onda de la corriente va a variar en función de la carga a menos que solo uses cargas resistivas.

Por otro lado si el tratamiento de señales lo va hacer el microcontrolador al interface en labview solo le quedaría revivir los datos de Vrms,Irms,y Prms para lo cual no necesitas un transferencia de alta velocidad una clase HID o CDC bastan y sobran, incluso si se le mandaria a la PC solo los datos maestreados (sin prosesar) para el caso tuyo alcanzaría con la clase CDC que en PIC18 llega casi a 1Mbps, mas exactamente 921600bps.
 
seguramente ya conoces:

http://picfernalia.blogspot.com.es/2013/06/proyecto-medidor-de-potencia.html

http://www.todopic.com.ar/foros/index.php?topic=40938.msg340573#msg340573

tambien si te sirve de data, existen pic con ADC de 12bit en encapsulado DIP. o sea que son manejables en una protoboard.
No me enojo si subis tus avances o resuldados del proyecto, Yo nunca lo encare...

Olvido:
pic serie
PIC18F2458/2553/4458/4553
PIC16C77X

Gracias por tu respuesta. Estuve ausente por esta semana de vacaciones, no estuve en mi casa, pero ya volví.

Si, ya había visto ese proyecto, me gusta porque está en C, un C mucho más complejo ya que es casi como un assembler, ya que toca realizar todo comando por comando, por ejemplo el ADC, toca configurar registro por registro, cosa que con pic CSS lo realizo con 1 sola línea, aparte de que hay cosas que no entiendo mucho, ese pic c18 no lo manejo mucho. Mañana subiré lo que tengo adelantado. Aprovecho para pedirte cualquier ayuda, si sabes de pic c18 y me puedes ayudar a descifrar un poco el proyecto pusiste aquí, te lo agradecería.



Hola cguerrero1205, curiosamente un amigo esta iniciando un proyecto parecido al que tu estas emprendiendo..., la metodología que planteas me parece correcta, pero tengo algunas dudas sobre el metodo que planeas usar para obtener el rms tanto del voltaje como de la corriente, por ejemplo: si vas a detectar "cruce por cero" y luego esperar T/4(periodo/4) para tomar la muestra y obtener el Vp y con ese dato calcular el rms no es buena idea ya que las formulas solo son para onda senoidal, para voltaje mas o menos se aproximaría pero la forma de onda de la corriente va a variar en función de la carga a menos que solo uses cargas resistivas.

Por otro lado si el tratamiento de señales lo va hacer el microcontrolador al interface en labview solo le quedaría revivir los datos de Vrms,Irms,y Prms para lo cual no necesitas un transferencia de alta velocidad una clase HID o CDC bastan y sobran, incluso si se le mandaria a la PC solo los datos maestreados (sin prosesar) para el caso tuyo alcanzaría con la clase CDC que en PIC18 llega casi a 1Mbps, mas exactamente 921600bps.

Hola, gracias por tu respuesta.

Si, esa parte la tengo bastante clara, cuando se conecta una carga inductiva ó capacitiva, sé que el voltaje puede adelantarse ó atrasarse respecto a la corriente dependiendo cual sea el caso, esa parte mañana te la comparto, para que veas como pienso hacerlo, igual, si puedes decirle a tu amigo, podríamos ponernos en contacto, y así compartir conocimientos. Lo de la comunicación, como comenté al principio del tema, mi idea es inicialmente mostrar los datos en un LCD, por lo que tengo que procesar todos los datos en el PIC, ya luego de que tenga toda esa parte funcionando, haré la comunicación del PIC, enviando ya los datos procesados (ya que obviamente los tendré listos porque ésta parte ya estaría lista). Utilizaré comunicación bulk porque es algo de lo que he encontrado muy poca información y me gustaría compartir ese "nuevo conocimiento" en algún tutorial o algo así, además que quiero saber algo mas allá de CDC ó HID. Muchas gracias por tu ayuda. Estaré atento a tus comentarios.
 
Última edición:
Hola compañeros del foro. He tenido abandonado este tema, pero no el proyecto. Les cuento...

Ya finalicé gran parte del proyecto, pero fui cambiando ciertas cosas a medida que fui avanzando, que son:

- Ya no estoy usando comunicación bulk, sino serial, a través de un conversor de USB-TTL de RS232
- No hice la interface con LabView, sino en MatLab con el Guide

Como dije, ya tengo casi todo finalizado, pero tengo un problema, más bien es duda, no he podido graficar las variables en tiempo real, es decir, las variables que envía el PIC no son graficadas inmediatamente por MatLab, sino que las guarda primero todas en un buffer y luego sin más, gráfica, pero mi idea es que dato que yo envíe, dato que se grafique de inmediato.

No creo que sea problema en el código del PIC, más bien creó debe ser en MatLab, porque la parte de la graficación la tengo en un bucle for, donde se supone debe tomar un valor y de inmediato graficarlo, pero como dije, no lo hace.

Adjunto los códigos de MatLab y PIC C de CCS. Espero puedan ayudarme.

Cualquier duda, sólo escriban.
 

Adjuntos

  • Grado.zip
    549.4 KB · Visitas: 47
Última edición por un moderador:
Hola, revisando el código tanto en matlab como el del Pic.. todo parece estar bien, es mas, le mande a Matlab los datos mas lentamente (con un retardo de 500ms por dato) e hizo la grafica conforme a los datos que llegaban.
 
Hola, revisando el código tanto en matlab como el del Pic.. todo parece estar bien, es mas, le mande a Matlab los datos mas lentamente (con un retardo de 500ms por dato) e hizo la grafica conforme a los datos que llegaban.
Si, esa prueba también la hice, coloqué un retardo de 100ms pero iba igual.
Lo que pasa es que la gráfica no se hace en tiempo real, el pic está trabajando bien, envía rápido los datos, el problema está en que matlab, al parecer, primero guarda los datos en un buffer y luego los gráfica, lo que quiero es que lo haga mucho más rápido y no he podido. ¿Qué opinión me das?
 
Última edición por un moderador:
hola, una pregunta, cuando verificaste el funcionamiento lo hiciste con harware o lo simulaste... te comento que yo observe algo parecido a lo que comentas pero eso era debido a que yo verifique todo en simulación, tanto matlab como con proteus (usando puertos series virtuales).
Por otro lado ten en cuenta que por cada dato que recibe matlab tiene que graficar, ajustar la escala, etc., y eso repercute en el rendimiento haciendo que sea mas lento al momento de graficar... para hacer lo que quieres seria mejor Labview o simulink, pero ese es otro lio.
bien, mas tarde voy a armar un harware para verificar mas correctamente.
 
hola, una pregunta, cuando verificaste el funcionamiento lo hiciste con harware o lo simulaste... te comento que yo observe algo parecido a lo que comentas pero eso era debido a que yo verifique todo en simulación, tanto matlab como con proteus (usando puertos series virtuales).
Por otro lado ten en cuenta que por cada dato que recibe matlab tiene que graficar, ajustar la escala, etc., y eso repercute en el rendimiento haciendo que sea mas lento al momento de graficar... para hacer lo que quieres seria mejor Labview o simulink, pero ese es otro lio.
bien, mas tarde voy a armar un harware para verificar mas correctamente.
Hola, lo estoy probando con hardware, ya tengo todos los circuitos montados y funcionando.
Si, eso lo tengo en cuenta, que matlab se demora su rato en hacer todos esos procesos para poder graficar, pero no sé, creó que se demora mucho, porque por ejemplo, en la LCD los resultados se muestras después de 1 segundo, pero en matlab lo hace después de 10 o 15 segundos, eso es lo que me gustaría mejorar si se puede...

uploadfromtaptalk1434638004648.jpg
 
10a 15 segundos, eso es mucho tiempo, estoy seguro que ese tiempo se puede mejorar.
... por lo que veo en el codigo... primero hay que hacer una petición de datos mediante un botón el matlab y luego dispara la interrupción externa para que el pic le envié los datos, comento ya que el esquema que subiste esta en la vercion 8 de proteus y yo tengo la vercion 7 por lo cual no puedo ver como es realmente tu esquema.
 
Última edición:
10a 15 segundos, eso es mucho tiempo, estoy seguro que ese tiempo se puede mejorar.
... por lo que veo en el codigo... primero hay que hacer una petición de datos mediante un botón el matlab y luego dispara la interrupción externa para que el pic le envié los datos, comento ya que el esquema que subiste esta en la vercion 8 de proteus y yo tengo la vercion 7 por lo cual no puedo ver como es realmente tu esquema.
Si, el problema está en que esa simulación de proteus no la tengo funcionando, sólo es un esquema que hice para agregarlo al informe del proyecto, dime que información necesitas y yo te explico
 
Bien. ¿Qué tiene que suceder para que el PIC envíe los datos a la PC?
Hola. Ya realicé los diagramas de flujo, realicé una modificaciones a los códigos, tanto del PIC como de MatLab.
En el archivo verás un archivo de instalación, es para instalar Pseint, que es el software que usé para crear el diagrama.
Cuando abras el programa podrás ver en la parte superior el dibujo que te muestro en la imagen, dando clic ahí, podrás ver el diagrama.

Me comentas cualquier duda [emoji106] [emoji106]

https://mega.nz/#!atwxWDBb!9I0n5vmluuVaNgMBOjHquUzthQNZ2u3CyNGwoqVJpqs

uploadfromtaptalk1434664796878.jpg
 

Adjuntos

  • Grado.part1.rar
    5 MB · Visitas: 24
  • Grado.part2.rar
    2.5 MB · Visitas: 18
Última edición por un moderador:
El motivo por que matlab tarda tanto en mostrar la gráfica en pantalla es por que:

convertir de cadena a numero+ajustar escala+mostrar el valor en la consola+... +, etc., se tarda mas o menos 0.09s (al menos es asi en la PC que uso), eso multiplicado por las 128 veces que se repite el ciclo for, de ahi que se tarda mucho.
Para este caso sera mejor guardar todo los datos e un buffer y luego gratificarlo, al menos asi mejorara notoriamente el rendimiento del programa.

Adjunto unas modificaciones a los códigos que subiste, tanto de matlab como de Pic.

Vi cámbiate el codigo del Pic, de puerto serie a USB CDC, pero yo estaba armando el hardware con puerto serie y me dio algo de flojera hacerlo por puerto USB (ya todo estaba hecho para puerto serie), asi que las modificaciones que hice siguen siendo para puerto serie.
 

Adjuntos

  • Nueva carpeta (2).rar
    91.2 KB · Visitas: 31
El motivo por que matlab tarda tanto en mostrar la gráfica en pantalla es por que:

convertir de cadena a numero+ajustar escala+mostrar el valor en la consola+... +, etc., se tarda mas o menos 0.09s (al menos es asi en la PC que uso), eso multiplicado por las 128 veces que se repite el ciclo for, de ahi que se tarda mucho.
Para este caso sera mejor guardar todo los datos e un buffer y luego gratificarlo, al menos asi mejorara notoriamente el rendimiento del programa.

Adjunto unas modificaciones a los códigos que subiste, tanto de matlab como de Pic.

Vi cámbiate el codigo del Pic, de puerto serie a USB CDC, pero yo estaba armando el hardware con puerto serie y me dio algo de flojera hacerlo por puerto USB (ya todo estaba hecho para puerto serie), asi que las modificaciones que hice siguen siendo para puerto serie.
Ya lo revisé y analicé, en verdad quedó perfecto, mejor de lo que esperaba, pero hasta ahora no he podido adaptarlo para que funcione con la comunicación CDC, con serial funciona perfecto, es casi en tiempo real, pero al modificar el código del pic para que funcione en CDC se demora mucho en graficar, hasta más de los que demoraba antes, tanto que en la ventana de comandos de matlab me sale un mensaje de advertencia que dice que el tiempo de espera es insuficiente... Sigo revisando que pasa, porque la verdad me gustaría que funciona mejor con la comunicación CDC

Muchas gracias por tu ayuda, en verdad a quedado genial lo has hecho
 
... Genial!
En teoria para cambiar de puerto serie a USB CDC vastaria con crear el puerto serie virtual con el USB y luego en vez de usar printf("..."); seria printf(usb_cdc_putc,"..."); y listo.

Si en la consola de comandos te sale el error de tiempo de espera es por que a matlab no le llego el caracter terminador 'LF' ('\n' en C o 0x0A) y matlab se canso de esperar, te sugiero que depures esa parte con algún software que acceda al puerto serie y veas si efectivamente están llegando los datos a la PC y se le llega el carácter terminador ('LF').
 
... Genial!
En teoria para cambiar de puerto serie a USB CDC vastaria con crear el puerto serie virtual con el USB y luego en vez de usar printf("..."); seria printf(usb_cdc_putc,"..."); y listo.

Si en la consola de comandos te sale el error de tiempo de espera es por que a matlab no le llego el caracter terminador 'LF' ('\n' en C o 0x0A) y matlab se canso de esperar, te sugiero que depures esa parte con algún software que acceda al puerto serie y veas si efectivamente están llegando los datos a la PC y se le llega el carácter terminador ('LF').
Ya pude solucionarlo, era error mío, por eso no funcionaba, ya lo tengo funcionando con CDC y anda perfecto :D igual le agregué más opciones al guide para que mostrara el periodo que esta mostrando en gráfica y el tiempo que demora en mostrar cada una de ellas...

Aunque no entiendo muy bien lo del terminator, no tengo muy claro como funciona eso, ósea, ese LF lo envía el pic? O como es?? Porque no veo que el pic envíe eso... :/ también no tengo muy claro la modificación que hiciste en el código del pic, la parte de "%05Lu, adc", tengo entendido que es para convertir adc, que es un número, en una cadena de 5 cifras ASCII, pero no entiendo mucho de eso, porque en el código que tenis antes yo enviaba el valor en números y en matlab no hacia ninguna conversión de un tipo a números, porque el valor q recibía ya era un número y veo que en el código que me enviaste si lo hace, y concierto de número a texto en el pic, luego lo envío, recibo el texto en matlab, convierto de texto a número u por último hago los cálculos del vector y gráfico, o eso creo, la verdad es que esta es la primera vez que uso matlab, fue algo que me tocó leer y aprender rápido así que hay cosas que no se...
El resto lo entiendo bien... Si pudieras aclararme, sería genial...
 
Última edición:
... El terminador es el caracter que espera antes de leer el buffer de rx de datos, es decir que para el caso matlab recibe los datos en el buffer hasta que encuentra el caracter terminador, una vez encontrado recién procede a la lectura del buffer.
En este caso el caracter terminador es el 'LF', que es lo mismo que (en lenguaje C) "\n"... al final de cuentas ese caracter terminador 'LF' es numéricamente el 0x0A hexadecimal.
En el codigo que corregi, el ultimo dato que se manda por el puerto serie se le añadió el caracter terminador...printf("...\n");
para el caso de "%05Lu" esto hace que se envie el valor en formato ascii de tamaño 5,por ejemplo.

unsigned int16 n;
x=12 => printf("%05Lu",x) => "00012" , así siempre se sabrá que cada valor consta de 5 bytes, por tanto si se quiere rescatar los valores habría que hacerlo de a 5 en 5.
 
... El terminador es el caracter que espera antes de leer el buffer de rx de datos, es decir que para el caso matlab recibe los datos en el buffer hasta que encuentra el caracter terminador, una vez encontrado recién procede a la lectura del buffer.
En este caso el caracter terminador es el 'LF', que es lo mismo que (en lenguaje C) "\n"... al final de cuentas ese caracter terminador 'LF' es numéricamente el 0x0A hexadecimal.
En el codigo que corregi, el ultimo dato que se manda por el puerto serie se le añadió el caracter terminador...printf("...\n");
para el caso de "%05Lu" esto hace que se envie el valor en formato ascii de tamaño 5,por ejemplo.

unsigned int16 n;
x=12 => printf("%05Lu",x) => "00012" , así siempre se sabrá que cada valor consta de 5 bytes, por tanto si se quiere rescatar los valores habría que hacerlo de a 5 en 5.
Aaaaa ya entendí, por eso del terminator fue que cuando quise pasar de serial a CDC no me funcionaba y matlab me daba error de espera porque cuando Reescribí el código para el pic, al último dato que se envía no le puse "/n" entonces por eso me daba error, porque se quedaba esperando esa orden para que terminara de recibir datos y empezara a procesar esos datos...

Lo del "%05Lu" también ya lo entendí :D

Gracias por toda tu ayuda, aún quiero hacer algunas mejoras al código del pic, como escribir un cruce por cero o algo así, tengo más o menos la idea, como sabes el cruce por cero que tengo es por hardware, con un optoacoplador, pero quiero hacerlo por software, tienes alguna idea de como hacerlo?

Estuve leyendo uno que vi, pero está en C18 y es medio enrredado... Aunque lo he ido entendiendo de a poco...
 
... detectar un cruce por cero mediante foftware...mmm.... como que podria ser mas complicado, una forma seria usando el comparador analogico que tiene el pic 18f4550 pero igual tendria que aumentarle componentes para que se comporte como un schmitt trigger, por otro lado el pin de interrupción externa ya tiene incorporado eso dentro de su hardware asi que lo que estas haciendo esta bien.
Lo mas cercano a lo que quieres puede hacerse pero seria un trabajo exhaustivo del ACD del PIC.
Para maestrear la señal ya sea de corriente o voltaje, obviamente estas usando un Voffset de X voltios, ya sea en el PIC o matlab tendrías que comparar cada dato si es mayor o menor que se offset y cuando se detecte que haya un cambio de menor a mayor que el offset ahí se tendría el cruce por cero.
 
Atrás
Arriba