TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: jhozate en 29 de Abril de 2009, 15:36:19

Título: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 29 de Abril de 2009, 15:36:19
Contro de nivel y Temperatura de un calderin por medio de RF, interfaz RS232, LABVIEW
Saludos a todos

Bueno, resulta que estoy realizando un proyecto de control de nivel y temperatura para un calderin, la idea es realizar el control de estas variables estableciendo comunicacion entre el calderin y el PC por medio de RF y en el PC tener la interfaz gráfica del estado de las variables y asi mismo generar las señales de control necesarias.

A continuacion una imagen del planteamiento para el nivel
(http://img148.imageshack.us/img148/4161/plantanivel.jpg)

Entonces el funcionamiento deberia ser asi: dado un estado X de nivel en el tanque, el transmisor de nivel entrega una señal de 4-20mA y esta es llevada a un conversor de Corriente-Voltaje, este voltaje 1-5V es llevado a uno de los canales analogos del PIC, posterior conversion A/D, se realiza el envio de la variable sensada a traves de la usart del pic hacia el modulo tranceiver, del otro lado, se reciben los datos y se comunica RS232 con el PC, el PC en su interfaz grafica debe mostrar el estado de la variable y realizar las correspondientes acciones para enviar  señales de control hacia el PIC y este hacia la valvula.

Del lado del PC la interfaz seria por LABVIEW, que cuenta con buena interfaz grafica y la comunicacion serial es relativamente facil de configurar.

Entonces empezando desde lo mas basico, la conversion A/D de la señal esta realizada a nivel de señal analoga-binario, pero entonces me surgen unas dudas, porque no tengo entendido si para realizar la comunicacion con el PC necesariamente debo enviar los datos en formato ASCII,por que tengo entendido que labview solo recibe datos en este formato,  la configuracion de registros para conversion AD y USART podria decir que ya los tengo claro (Programo en ASM), y tambien se puede asumir que se cuenta con el equipo necesario(transmisores y valvulas), entonces a mi me restaria la parte electronica y la de programacion. Bueno espero haberme hecho entender contar con sus aportes y culminar con este proyecto saludos

Actualizacion 1 de mayo 2009 4:00PM (Hora Colombiana)
para ir visualizando lo que quiero lograr les presento una imagen donde se muestra la motobomba y el transmisor de nivel instalado
(http://img119.imageshack.us/img119/5696/tanquea.jpg)

Describiendo un poco los instrumentos a utilizar

VALVULA DE CONTROL PROPORCIONAL
La válvula de control es básicamente un orificio variable por efecto de un actuador. Esta válvula es de tipo globo con actuador neumático de diafragma.Por seguridad esta válvula es de aire para abrir, es decir que la acción neumática actúa para que ella abra, en ausencia de presión ella se cierra.
 (http://img13.imageshack.us/img13/8325/valvulacontrol.jpg)

TRANSMISOR DE NIVEL YOKOGAWA
El Transmisor de Presión Diferencial es un dispositivo utilizado para medir presiones de líquidos ó gases dentro de procesos industriales. El Transmisor de Presión Diferencial cuenta con dos entradas de presión y una salida de señal eléctrica. Esta salida entrega una corriente proporcional a la diferencia entre las presiones que se encuentran en las entradas, la corriente varía de 4 a 20 mA. En la Planta, una de las entradas permanece abierta al medio ambiente y la otra está conectada en la parte baja del tanque.
(http://img204.imageshack.us/img204/3727/transmisornivel.jpg)


CONVERSOR DE CORRIENTE-PRESION (I/P)
El conversor de corriente a presión es un dispositivo que permite controlar la presión de aire por medio de una señal de corriente.
Este dispositivo cuenta con una entrada de señal eléctrica, una entrada de presión de aire constante y una salida de presión de aire regulada. El aire que ingresa en la entrada neumática es suministrado por un compresor a 20 PSI. En la entrada de señal eléctrica, se conecta una corriente que puede variar de 4 a 20 mA. En la salida neumática, obtenemos una presión que puede variar de 3  a 15 PSI, dependiendo de la corriente que se le suministre, es decir, que a menor corriente menor presión y viceversa.
(http://img523.imageshack.us/img523/6286/22225191.jpg)

MOTOBOMBA SIEMENS
El objetivo de la motobomba es la de impulsar el liquido o fluido por las diferentes tuberías del proceso. Cambian la energía eléctrica en movimiento.
(http://img245.imageshack.us/img245/7969/motobomba.jpg)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 29 de Abril de 2009, 16:38:30
Hola.

Se le puede enviar los dos bytes, resultado de la conversion, al COM, lo unico que deberias hacer en LabView seria concatenarlo. El modulo RF que vas a usar es bidireccional? es decir el mismo modulo permite enviar y recibir?

Me hiciste acordar de una practica en la U ... alla en el 2003 cuando estudiaba mi carrera ....
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 29 de Abril de 2009, 17:12:35
pero tendria que hacerlo en ASCII o el binario a secas?..estuve haciendo una prueba en labview con el ejemplo basico de lectura/escritura puerto serie que trae el programa,  uniendo los pines 2 y 3 del DB9, el programa como esta configurado dice que se escribe "string" y recibe "string"(no se si es lo mismo que el ASCII) y tambien trae una ventana donde dice los bytes recibidos, osea que si escribo un "string" de dos digitos he enviado 2bytes

si, el modulo que voy a utilizar es bidireccional...adjunto la hoja de datos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 29 de Abril de 2009, 22:30:17
A ver.

Tu usas la conversion a 10bits, pero por el serial solo se pueden mandar 8, por lo tanto se hacen dos envios de 8bits, cuando los envias al PC -si verificas en el hyperterminal- vas a ver el ASCII correspondiente a el valor enviado, pero, puedes leer estos datos y concatenarlos en LabView para formar el dato de 10bits -16 en realidad- y hacer los calculos correspondientes.

Otra opcion es enviar el dato completo como string, lo que harias en LabView es leer el string y visualizarlo, en este casi si verificas en el hyperterminal vas a ver el string.


Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 30 de Abril de 2009, 14:22:47
Cual es la diferencia entre el string y ASCII?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 01 de Mayo de 2009, 00:41:36
Hola.

El string esta hecho por caracteres ASCII. Si la conversion que haces a 10 bits la envias en 2 bytes, estaras enviando un string de 2 bytes, pero si envias un string desde el CCS con el printf, estaras enviando un string de mas de 2 bytes.

Ejemplo.

Supongamos que el resultado de la conversion es: 818.
Si envio los 2 bytes para concatenarlos en LabView -ADRESH y ADRESL- se enviarian: 3 y 50, que en ASCII son <ETX> y '2', es decir si envias al hyperterminal, se veran esos dos ASCII, pero si usas printf("Resultado: %lu", adc_conv); -donde en adc_conv guardo la conversion ya concatenada, en el terminal voy a ver : "Resultado 818".

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 01 de Mayo de 2009, 12:08:55
ya...entonces si entendí bien, se podria decir que un string es una cadena ASCII?
pero entonces, yo estoy realizando conversion de 8 bits y para efectos de prueba no se si lo que estoy haciendo es innecesario, el dato binario lo convierto a BCD y este lo convierto  ASCII y lo envio por la usart en 3 partes: UNIDAD_ASCII, DECENA_ASCII y CENTENA_ASCII
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 01 de Mayo de 2009, 12:41:41
Hola.

Pues si ... te estas complicando. Solo es necesaria la conversion ad y luego colocar el socorrido printf("%u",dato_ad); y listo.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 01 de Mayo de 2009, 13:07:31
Pregunta jhozate, ¿cuánto alcance tiene este transeiver? (No está en el datasheet)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 01 de Mayo de 2009, 13:46:50
psss el distribuidor asegura q se tiene un alcance aproximado de 1Km aprox. pero seguro es adaptandole otro tipo de antena y en campo abierto, supongo q en condiciones normales alcanzará almenos los 500mtr.

MLO_ Cabe aclarar que programo en ASM pero me vienen bien tus observaciones.

pero es precisamente eso lo q me confunde, quiero hacer q el rendimiento sea optimo y rapido, pero entonces no se estoy seguro si labview me aceptará que yo le envie el dato de la conversion o si debo convertirlo a ASCII para poder leerlo. Porque de no necesitar la conversion a algun tipo de formato entonces todo se reduciria a realizar la conversion A/D y enviar a la usart, obviamente por software ya habria q hacerle tratamiento a los datos

saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 01 de Mayo de 2009, 14:00:25
Gracias jhozate :-/
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 01 de Mayo de 2009, 14:27:36
los vas a comprar?, de todas manera yo creo que para la otra semana ya los tengo para hacerle las pruebas de alcance, por eso me urge crear el codigo para empezar a probarlo en el entorno del tanque

saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 01 de Mayo de 2009, 14:33:10
No, no me sirve. Ando buscando un transmisor de mas de 3km de alcance para un proyecto que voy a empezar a mediano plazo.
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 01 de Mayo de 2009, 18:08:22
leon_pic mira este (http://spanish.alibaba.com/product-gs/433mhz-rf-module-3km-wireless-data-transceiver-208155865.html) link a lo mejor te puede servir
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 01 de Mayo de 2009, 19:30:15
Graciassssssssssssssssssssssss :-/ :-/
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 05 de Mayo de 2009, 12:29:41
resulta q pensando en mi proyecto me surguió una de tantas dudas posibles, si estoy mandando datos de temperatura y nivel hacia labview a traves de modulo de RF, como haría para diferenciar cuales datos son de temperatura y cuales son los datos de nivel, por que en el micro puedo cada cierto tiempo alternar el sensado de las dos variables y enviarlas por el modulo RF, pero cuando lleguen a labview como hago para diferenciar una de otra
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 05 de Mayo de 2009, 13:23:00
Lo que puedes hacer es enviar un dato antes del valor censado. Por ejemplo, utilizas una variable llamado dato_censado. Si el bit 0 es 0, el dato a enviar es de temperatura, si es 1, el dato a enviar es el nivel. Entonces cuando lees en el receptor, primero chequeas este bit para saber que dato es el que se recibe (temperatura o nivel)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 05 de Mayo de 2009, 13:33:45
estaba pensando q tambien podria implementar el noveno bits de datos? el TX9? y comprobar el estado de ese bit, asi solo enviaria una trama con "dato + ID de la variable"
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 05 de Mayo de 2009, 14:39:36
Hola.

Lo mejor es discriminar la trama enviada. Podes colocar entre dos T el valor de la temperatura: TxT y entre dos N el valor del nivel: NxN, como sabes que tu envio es de 1byte -si la conversion es de 8bits- en LabView lo que haces es tomar el valor entre T y T y discriminarlo del de nivel. De haber algun fallo en la transmision, podes validar el dato, seteando el contador de recepcion a 0 y esperar el string de T o de N.

Saludos

Edito: Este metodo te permite adicionar muchas mas variables de medida.
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 05 de Mayo de 2009, 19:00:54
aaaa ya, bien MLO_,

ahora pasando la idea de MLO_ al assembler, hice esto
Código: [Seleccionar]
MOVLW 'T'                      ;CARGO EL CARACTER N
CALL TX_DATO               ;ENVIO N
MOVF TEMPERATURA,W   ;CARGO W CON LA VARIABLE TEMPERATURA
CALL TX_DATO               ;ENVIO LA VARIABLE TEMPERATURA
MOVLW 'T'                      ;CARGO W CON T
CALL TX_DATO               ;ENVIO T, ES DECIR ENTRE T y T  VA EL DATO
CALL DEMORA

MOVLW 'N'                     ;CARGO EL CARACTER N
CALL TX_DATO               ;ENVIO N
MOVF NIVEL,W                ;CARGO W CON LA VARIABLE NIVEL
CALL TX_DATO                ;ENVIO LA VARIABLE NIVEL
MOVLW 'N'                       ;CARGO W CON N
CALL TX_DATO                 ;ENVIO N, ES DECIR ENTRE N y N  VA EL DATO

a modo de prueba cargué nivel con 0x1 y temperatura con 0x50 y el hiperterminal me muestra entre las N una carita que supongo corresponde al 0x01 y entre la T me muestra una P que corresponderia al 0x50, en labview pasa lo mismo con lo que envio entre las T y entre las N muestra un cuadrado que será porque no reconoce ese caracter, pero en ultimas supongo que con esa prueba podria asumir que estoy enviando bien el dato?

adjunto la captura de la prueba en hiperterminal


por otro lado, empecé a hacer esta rutina para alternar las conversiones A/D del canal0 y el canal1, entonces pongo el codigo y luego la duda
Código: [Seleccionar]
                                                LIST P=16F877A
#INCLUDE "P16F877A.INC"

CBLOCK 0X20
PDel0
PDel1
PDel2
_INT_SAVE_W
_INT_SAVE_STATUS
_INT_SAVE_FSR
_INT_SAVE_PCLATH

ENDC

ORG 0
GOTO INICIO






ORG 4
GOTO INTER




;@@@@@@@@@@@@@@@@@ SELECCION DE CANALES ANALOGOS @@@@@@@@@@@@@@@@@@@@@@@
CANAL0                  BCF STATUS,RP0
MOVLW B'01000001' ; Fosc/8, CANAL0 ACTIVO, CONVERSION OFF, CONVERSOR ON
MOVWF ADCON0
RETURN ; PARA EMPEZAR CONVERSION SETEAR ADCON0,2 = GO_DONE

CANAL1                  BCF STATUS,RP0
MOVLW B'01001001' ;Fosc/8, CANAL1 ACTIVO, CONVERSION OFF, CONVERSOR ON
MOVWF ADCON0
RETURN

CONVERSION                             BSF ADCON0,GO_DONE
ESPERE                  CALL DEMORA
BTFSC ADCON0,GO_DONE
GOTO ESPERE
MOVF ADRESH,W
MOVWF PORTB
RETURN
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


;@@@@@@@@@@@@ RUTINA CONTROL DEL TX @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

TX_DATO                 BCF PIR1,TXIF ;RESTAURA FLAG DEL TRANSMISOR
MOVWF TXREG ;ALMACENA EL DATO A ENVIAR Y ENVIA
BSF STATUS,RP0 ; BANCO1

TX_DATO_WAIT
BTFSS TXSTA,TRMT ; BYTE TRANSMITIDO?
GOTO TX_DATO_WAIT ;NO
BCF STATUS,RP0 ;SI, BANCO0
RETURN
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


;@@@@@@@@@@@@@@@@@@@@@@@@ MANEJO DE INTERRUPCION @@@@@@@@@@@@@@@@@@@@@@@@@@
INTER

PUSH                 MOVWF _INT_SAVE_W ;GUARDAR W
SWAPF STATUS,W ;GUARDAR STATUS
MOVWF _INT_SAVE_STATUS
SWAPF FSR,W ;GUARDAR FSR
MOVWF _INT_SAVE_FSR
SWAPF PCLATH,W ;GUARDAR PCLATH (PAGINA DE PROGRAMA)
MOVWF _INT_SAVE_PCLATH
SWAPF OPTION_REG,W ;GUARDAR OPTION_REG (BANCOS)
MOVWF _INT_SAVE_OPTION_REG

;>>>>>>>AQUI RUTINAS DE INTERRUPCION POR RECEPCION DE LA USART<<<<<<<<<<<<<<<<

POP                 SWAPF _INT_SAVE_PCLATH,W ;RESTAURAR VALOR DE PCLATH
MOVWF PCLATH
SWAPF _INT_SAVE_FSR,W ;RESTAURAR VALOR DE FSR
MOVWF FSR
SWAPF _INT_SAVE_STATUS,W ;RESTAURAR VALOR DE STATUS
MOVWF STATUS
SWAPF _INT_SAVE_W,W
RETFIE
;@@@@@@@@@@@@@@@@@@@@@@@@@@ FIN DE INTERRUPCION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@

INICIO                 BSF STATUS,RP0
BCF STATUS,RP1 ;BANCO1

MOVLW 0XFF
MOVWF TRISA ;PORTA COMO ENTRADA
MOVLW B'00000001'
MOVWF ADCON1 ;TODAS ENTRADAS ANALOGAS, +VREF=RA3 -VREF=GND
;8 bits mas significativo=ADRESH                                     
;Los 2 BIT memos significativos se quedan en ADRESL.

CLRF TRISB
CLRF TRISE

BCF STATUS,RP0 ; BANCO0
BSF ADCON0,ADCS0
BCF ADCON0,ADCS1 ;RELOJ PARA EL CONVERSOR AD = Fosc/8
BSF ADCON0,ADON


;@@@@@@@@@@@@@@@ CONFIG USART @@@@@@@@@@@@@@
BSF STATUS,RP0 ;BANCO1
MOVLW B'10111111' ;RC6 SALIDA(TX), RC7 ENTRADA(RX)
MOVWF TRISC
MOVLW B'00100100'
MOVWF TXSTA ;TX en On, modo asíncrono con 8 bits y alta velocidad
MOVLW .25
MOVWF SPBRG ;9600 baudios con Fosc=4MHz
BSF PIE1,RCIE ;Habilita interrupción en la recepción
BCF STATUS,RP0 ; BANCO0

MOVLW B'10010000'
MOVWF RCSTA ;USART en On, recepción contínua
BSF INTCON,PEIE ;Activa interrupción de periféricos
BSF INTCON,GIE ;Activa interrupciones
CLRF RCREG
CLRF PORTB

;@@@@@@@@@@@@@@ FIN CONFIG USART @@@@@@@@@@@@@


;########## PROGRAMA PRINCIPAL ####################
ALT          CALL CANAL0
CALL CONVERSION
CALL CANAL1
CALL CONVERSION
GOTO ALT


;########################## RUTINA 1 SEGUNDO ###############################
DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .72       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .247      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.

      end         ;Fin del programa fuente

simulando el proteus me tira " ADC conversion started before 'wait' time has expired following previous conversion or channnel change", igual funciona bien pero me sale este error multiples veces, entonces no si es por el tiempo de espera ( 1 SEGUNDO!!!!! ) q doy al preguntar si ya se termino la conversion o es por la configuracion de los bits ADCS1, ADCS0 que son los que determinan la Fosc del conversor. cualquier sugerencia es bienvenida
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 06 de Mayo de 2009, 19:06:33
buenos, respondiendome, con respecto al AD el problema no resulta ser ni la configuracion de los bits ADCS0 ADCS1 porque ya use todas las combinaciones y sigue proteus sigue dando el mismo mensaje, tampoco es el tiempo en q espero para preguntar si ya se termino la conversion AD porque incluso le puse dos segundo y dos segundos ya es una eternidad en el PIC
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 07 de Mayo de 2009, 13:53:26
tenia configurado todo como entradas analogas, pero segun lei era mejor poner como entradas analogas solo las q necesite, tambien pude encontrar que para alternar los canales al realizar la conversion A/D debia esperar almenos 10 microsegundos, pero tampoco eso solucionó el mensaje q muestra proteus, ni siquiera poniendole un segundo
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Junio de 2009, 12:45:24
a que elemento puedo recurrir  para mantener caliente el agua, en un tanque?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 12 de Junio de 2009, 14:20:00
Podrías ponerle una resistencia de la duchas eléctricas.

(http://www.cymfer.com.ar/articulos/2068.jpg)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Junio de 2009, 14:26:08
pero como se llaman ...o como se consiguen comercialmente? lo que pasa es que la idea es que me sea posible configurarla o hacerle un arreglo para comunicarla con el pic y tratar de mantener muy constante la temperatura del agua en el tanque
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Leon Pic en 12 de Junio de 2009, 14:28:56
¿Resistencia para calefón eléctrico?


Para controlarlo, lo podes hacer con un relay y a medida que vas censado la temperatura, sabes si tenés que seguir dándole mas temperatura o no.
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Junio de 2009, 14:43:53
seria mas rapido switchear con relé o con transistor??
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 12 de Junio de 2009, 15:57:33
Mejor con control de fase no? y con un PID quedaria bien.
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Junio de 2009, 16:21:27
si la idea es q el PID se realiza en el PC y enviar desde el PC las acciones de control hacia el PIC para  tratar mantener el agua a temperatura constante... como seria lo de control de fase?...tengo un compañero que lo q esta haciendo es controlar intensidad luminica y lo que hace el algo así como recortar o dejar pasar la solo fragmentos de la onda seno..esto lo hace con un triac creo...sera que puedo pensar en el mismo sistema?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 14 de Junio de 2009, 14:11:14
como estoy en un proceso migratorio de ASM a CCS, pss he decidido empezar el sensor de temperatura en lenguaje c, me dio por empezar a ensayar con el conversor AD y mostrar el resultado por el puerto B y tambien enviar la lectura del ADC al lcd, para simular la entrada analoga puse el LM35, y me encuentro con la sorpresa de que el valor representado en el lcd corresponde a la temperatura, salvo que apartir de los 30° se empieza a descuadrar
pongo el codigo y disculpen cualquier torpeza pero es q apenas en el C
Código: CSS
  1. #include "C:\PICC\Projects\proyecto_temp_niv.h"
  2. #include <lcd.c>
  3.  
  4. char i;
  5. char a;
  6. char b;
  7. int q;
  8. float p;
  9. void main()
  10. {
  11.    SETUP_ADC_PORTS(RA0_RA1_ANALOG_RA3_RA2_REF);
  12.    SETUP_ADC(ADC_CLOCK_DIV_32);
  13.    setup_psp(PSP_DISABLED);
  14.    setup_spi(SPI_SS_DISABLED);
  15.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  16.    setup_timer_1(T1_DISABLED);
  17.    setup_timer_2(T2_DISABLED,0,1);
  18.    setup_comparator(NC_NC_NC_NC);
  19.    
  20.    #define use_portd_lcd true
  21.    SET_TRIS_C(0X00);
  22.    lcd_init();
  23.    OUTPUT_C(0X00);
  24.  
  25.    // TODO: USER CODE!!
  26.    for(;;)
  27.    {
  28.    SET_ADC_CHANNEL(0);
  29.    DELAY_MS(20);
  30.    Q=READ_ADC();
  31.    OUTPUT_B(Q);
  32.     lcd_gotoxy(1,1);
  33.      printf( lcd_putc "ADC= %4U", Q );
  34.    
  35.    }
  36. }


fuses
Código: CSS
  1. #include <16F877A.h>
  2. #device adc=8
  3.  
  4. #FUSES NOWDT                    //No Watch Dog Timer
  5. #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
  6. #FUSES NOPUT                    //No Power Up Timer
  7. #FUSES NOPROTECT                //Code not protected from reading
  8. #FUSES NODEBUG                  //No Debug mode for ICD
  9. #FUSES NOBROWNOUT               //No brownout reset
  10. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  11. #FUSES NOCPD                    //No EE protection
  12. #FUSES NOWRT                    //Program memory not write protected
  13.  
  14. #use delay(clock=20000000)
  15. #use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

una de las cosas q aun no asimilo bien es la representacion de datos en el lcd, cuando debo poner eso de %d y todas esos detalles, tienen q ver algo con el tipo de variable a representar?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 14 de Junio de 2009, 16:43:07
cacharreando cacharreando hice esto
Código: CSS
  1. char i;
  2. char a;
  3. char b;
  4. int q;
  5. char p;
  6. void main()
  7. {
  8.    SETUP_ADC_PORTS(RA0_RA1_ANALOG_RA3_RA2_REF);
  9.    SETUP_ADC(ADC_CLOCK_DIV_32);
  10.    setup_psp(PSP_DISABLED);
  11.    setup_spi(SPI_SS_DISABLED);
  12.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  13.    setup_timer_1(T1_DISABLED);
  14.    setup_timer_2(T2_DISABLED,0,1);
  15.    setup_comparator(NC_NC_NC_NC);
  16.    
  17.    #define use_portd_lcd true
  18.    SET_TRIS_C(0X00);
  19.    lcd_init();
  20.    OUTPUT_C(0X00);
  21.  
  22.    // TODO: USER CODE!!
  23.    for(;;)
  24.    {
  25.       SET_ADC_CHANNEL(0);
  26.       DELAY_MS(20);
  27.       Q=READ_ADC();
  28.       OUTPUT_B(Q);
  29.       P=(( Q * 2.56 )/ 256)*100;
  30.       LCD_GOTOXY(1,1);
  31.       PRINTF( lcd_putc "TEMPERATURA= %3u", P );
  32.       LCD_GOTOXY(1,16);
  33.       PRINTF(LCD_PUTC " NIVEL=" );
  34.  
  35.    }
  36. }

el problema del grado q se pasa es q cuando el LM35 esta en 29° y lo subo a 30° el conversor AD hace 2 cambios osea q muestra en el LCD 31°  cuando en el LM35 esta en 30.

tengo otra duda, tengo un transmisor de nivel que entrega señal 4-20mA o 1-5V, y para la conversion tengo configurado 2.5V de referencia, lo quiero es tambien mostrar el nivel en porcentaje, deberia cambiar el voltaje de referencia?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 15 de Junio de 2009, 14:20:04
dejando por ahora a un lado la programacion me puse a pensar en lo necesario para poder calentar el agua y para activar la motobomba y encontre lo siguiente

(http://josepino.com/pic_projects/water_level/JP6751.gif)

segun veo ese me serviria para activar motobomba. Si quito la motobomba y pongo un artefacto para calentar agua tambien me serviría la misma conexion?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 15 de Junio de 2009, 14:49:26
Hola.

Aca un link para el control de fase.

Control de fase (http://www.todopic.com.ar/foros/index.php?topic=21584.0;do=Bookmark)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 15 de Junio de 2009, 21:36:33
leyendo tu hilo y otra pag..si la cogi bien seria: una señal senoidal de 110V a 60Hz demora 16mS en un ciclo completo, medio ciclo en  8,3mS que es lo mismo cruce por cero.

Ahora para mi problema deberia definir temperaturas para el agua diciendo que
Ta=temperatura alta
Td=temperatura deseada       
Tn=temperatura normal     

entonces si eligo segmentar medio ciclo de onda en 3, tendria cada ciclo a 2,7 mS, entonces para un Tn pongo el triac por un tiempo de 8,3mS, para un Ta no le doy disparo y para un Td un disparo de 5.4mS. O que seria mejor??
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 15 de Junio de 2009, 22:03:28
Hola.

Los triacs normalmente responden despues de los 30°, asi que podrias asignar el maximo al tiempo correspondiente a los 30°, el medio, tal como dices y el minimo a los 180° (o unos microsegundos antes para evitar inconvenientes).

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 16 de Junio de 2009, 22:37:46
consultando he tenido ciertas confuciones...es decir, el TRIAC esta en condiciones de conducir luego de los 30° que son aproximadamente 1,3mS despues de cruce por cero...entonces si le doy pulso de disparo 1.3mS despues del cruce por cero conduciría al "maximo"....entonces si quiero menos potencia en la carga debo demorarme mas tiempo para darle el disparo? tal como me lo dijiste antes del 180°..ahora cuanto debe durar ese pulso de disparo? diciendo que estoy en lo correcto..hay algo q no logro asimilar de la siguiente grafica...por qué cuando el TRIAC entra en conduccion en la grafica se pone a cero?
(http://www.monografias.com/trabajos14/triac/Image2816.gif)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 17 de Junio de 2009, 02:36:43
Hola.

Las graficas indican el voltaje que le cae al triac. Si se pone a conducir al maximo, es decir 180° se supone que al TRIAC no debe caerle voltaje -en si le cae muy poquito-, la grafica de abajo indica el voltaje de la carga.

A mayor tiempo de espera para el disparo, menor sera la potencia resultante, durante el tiempo que no se dispare el TRIAC el voltaje caerá sobre él.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Micro23 en 17 de Junio de 2009, 02:48:14
Hola jhozate, lindo proyecto.
Cuando el TRIAC conduce, la caida de potencial se considera nula respecto de la tension que maneja.
Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 18 de Julio de 2009, 18:15:48
Despues de tantos dias, he venido instruyendome en esto del ccs, haciendo programitas, leyendo aqui y alla, al fin y decidido a llevar a cabo este proyeto en lenguaje c. Ahora vengo con nuevas dudas: una de ellas es la siguiente:
1-resulta qu tengo  la termocupla conectada al AD594 que lo que hace tratar de linealizar la lectura de temperatura y asi tengo un comportamiento muy similar al del LM35 con sus 10mV/°C entonces he configurado en el pic un voltaje de referencia de 2,5V y conversion 8bits con lo cual tengo una sensibilidad de aproximadamente 10mV, pero eso tan solo para temperatura y para nivel se tiene un transmisor que entrega 1-5V, entonces no se me serviria el voltaje de referencia de 2.5V.
 q podria hacer entonces?,,,,me preguntaba si programando en c antes de leer el canal que corrresponde a nivel puedo cambiar el voltaje de referencia al voltaje interno osea 5V
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Micro23 en 27 de Julio de 2009, 18:58:03
Hola jhozate si querés mantener esa precisión tendrías que amplificar la senal con algún amplificador operacional con ganancia de 2, sino usándolo así con referencia de 5V te quedaría con precision de 20mV/°C.

Ahora lo que comentas de cambiar la referencia al medir temperatura pienso que es posible, habría que ver en el datasheet si los demás pines del conversor soportan una tensión mayor que la de referencia, ya que la entrada de nivel en caso de superar la referencia se estaría saturando, pero pienso que andaría.

Esperamos tus comentarios si haces esa prueba.
Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 28 de Julio de 2009, 21:23:03
psss hice un pequeño programa para tratar de hacer lo q queria..tener un voltaje de referencia de 2.5V para temperatura y un voltaje de referencia de 5V para nivel..basicamente lo que hice fue
Código: CSS
  1. SET_ADC_CHANNEL(0);
  2.    DELAY_US(20);
  3.    Q=READ_ADC();
  4.    OUTPUT_B(Q);
  5.    P=(2.5*Q)/255.0;
  6.    PRINTF(LCD_PUTC,"\fADC=%3U V=%1.2F",Q,P);
  7.    DELAY_MS(1000);
  8.    setup_adc_ports(AN0_AN1_AN3);
  9.    DELAY_US(20);
  10.    Q=READ_ADC();
  11.    OUTPUT_B(Q);
  12.    P=(5*Q)/255.0;
  13.    PRINTF(LCD_PUTC,"\fADC=%3U V=%1.2F",Q,P);

aunque no lo monte por q no tengo el hardware a mano,,,en proteus no funciona..solo funciona bien con una referencia, lo que hice fue poner un voltaje de 2,5 en una de las entradas analogas y alternar el voltaje de referencia, entonces para un voltaje de referencia de 2,5V se deberia mostrar en el LCD el valor 1,2V(esto lo hace correctamente) y para un Vref de 5V se deberia mostrar 2,5V pero NO, resulta q muestra 0,48V...en conclusion creo q
*debo recurri a diseñar un nuevo hardware en donde amplifique dos veces la señal de AD594 y asi podré utilizar el voltaje de referencia de 5v

Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Micro23 en 28 de Julio de 2009, 22:00:49
Hola jhozate, en la linea 8 no deberias poner:

setup_adc_ports(AN0_AN1_VSS_VREF);  // A0=Analog; A1=Analog;  A3=VRef

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 28 de Julio de 2009, 22:24:51
la intencion mia seria cambiar los bits PCFG3-PCFG0 del registro ADCON1, supongo q en ccs es asi..no?
si se ponen en esos bit 0010 corresponde a q habilito AN0 AN1 y voltajes de referencia internos es decir VDD Y VSS
y si pongo 1101 habilito AN0 AN1 pero con voltajes  de referencia AN3 AN2
y creo q para hacer estas configuraciones en ccs es con SETUP_ADC_PORT()..no??
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Micro23 en 29 de Julio de 2009, 12:20:02
Hola jhozate, en CCS para  setear directamente un registro del PIC lo podes hacer asi:

Código: CSS
  1. #BYTE ADCON1 = 0x9F  //0x9F es la posicion del registro
  2. ADCON1=0x03;

Otra forma es hacerlo con la funcion que mencionas, donde los paramentros que acepta la funcion son:

Código: CSS
  1. // Constants used in SETUP_ADC_PORTS() are:
  2. #define NO_ANALOGS                           7    // None
  3. #define ALL_ANALOG                           0    // A0 A1 A2 A3 A5 E0 E1 E2
  4. #define AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF 1    // A0 A1 A2 A5 E0 E1 E2 VRefh=A3    
  5. #define AN0_AN1_AN2_AN3_AN4                  2    // A0 A1 A2 A3 A5          
  6. #define AN0_AN1_AN2_AN4_VSS_VREF             3    // A0 A1 A2 A4 VRefh=A3              
  7. #define AN0_AN1_AN3                          4    // A0 A1 A3
  8. #define AN0_AN1_VSS_VREF                     5    // A0 A1 VRefh=A3
  9. #define AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF 0x08    // A0 A1 A5 E0 E1 E2 VRefh=A3 VRefl=A2    
  10. #define AN0_AN1_AN2_AN3_AN4_AN5           0x09    // A0 A1 A2 A3 A5 E0        
  11. #define AN0_AN1_AN2_AN4_AN5_VSS_VREF      0x0A    // A0 A1 A2 A5 E0 VRefh=A3          
  12. #define AN0_AN1_AN4_AN5_VREF_VREF         0x0B    // A0 A1 A5 E0 VRefh=A3 VRefl=A2          
  13. #define AN0_AN1_AN4_VREF_VREF             0x0C    // A0 A1 A4 VRefh=A3 VRefl=A2              
  14. #define AN0_AN1_VREF_VREF                 0x0D    // A0 A1 VRefh=A3 VRefl=A2
  15. #define AN0                               0x0E    // A0
  16. #define AN0_VREF_VREF                     0x0F    // A0 VRefh=A3 VRefl=A2
  17. #define ANALOG_RA3_REF         0x1         //!old only provided for compatibility
  18. #define A_ANALOG               0x2         //!old only provided for compatibility  
  19. #define A_ANALOG_RA3_REF       0x3         //!old only provided for compatibility  
  20. #define RA0_RA1_RA3_ANALOG     0x4         //!old only provided for compatibility
  21. #define RA0_RA1_ANALOG_RA3_REF 0x5         //!old only provided for compatibility
  22. #define ANALOG_RA3_RA2_REF              0x8   //!old only provided for compatibility
  23. #define ANALOG_NOT_RE1_RE2              0x9   //!old only provided for compatibility  
  24. #define ANALOG_NOT_RE1_RE2_REF_RA3      0xA   //!old only provided for compatibility  
  25. #define ANALOG_NOT_RE1_RE2_REF_RA3_RA2  0xB   //!old only provided for compatibility  
  26. #define A_ANALOG_RA3_RA2_REF            0xC   //!old only provided for compatibility  
  27. #define RA0_RA1_ANALOG_RA3_RA2_REF      0xD   //!old only provided for compatibility
  28. #define RA0_ANALOG                      0xE   //!old only provided for compatibility
  29. #define RA0_ANALOG_RA3_RA2_REF          0xF   //!old only provided for compatibility

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 29 de Julio de 2009, 14:02:41
 :-/ :-/ :-/ :-/ :mrgreen: :mrgreen: :mrgreen: :mrgreen: si funcionó definiendo primero el ADCON1
lo hice asi tal cual como dijiste, empezando el programa defino:
Citar
#BYTE ADCON1=0X9F

luego para alternar los dos voltajes de referencia del PIC, es decir ponerlo a correr con voltaje de referencia externo e interno hice lo siguiente
Citar
FOR(;; )
   {
   ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
   SET_ADC_CHANNEL(0);
   DELAY_US(20);
   Q=READ_ADC();
   
   ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
   SET_ADC_CHANNEL(1);
   DELAY_US(20);
   O=READ_ADC();
   
   P=(2.5*Q)/255.0;
   R=(5.0*O)/255.0;
   PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
   PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
   PRINTF("%u\r\n",Q);

bueno almenos simulado funciona de lujo y eso me salva de tener q hacer un nuevo hardware
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: Micro23 en 29 de Julio de 2009, 16:03:07
 :-/ :mrgreen: Me alegro que funcione  :mrgreen: :-/

Saludos y esperamos tus avances
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 04 de Agosto de 2009, 23:01:16
siguiendo con mis pruebas  est pasando lo siguiente:

* no me ha funcionado el LCD...estoy usando la flex_lcd..aunque voy a hacerme un nuevo hard para el lcd
* El 7805, con el tiempo se calienta de una manera preocupante y lo unico que tengo conectado son el modulo RF y ocho led q por ahora no los utilizo todos, y el AD594
* Siguiendo la sugerencia de MLO_  de enviar los datos de temperatura y nivel entre las letras T%uT y N%uN, esto funciona bien simulado, pero cuando verifico conectado mi circuito y comunicando con Terminal de bray me aparece el dato sin la´s letras, lo estoy enviando asi:

printf("T%uT\r\n",Q);

por otro lado, podria asociar el control de fase a un dimmer...seria lo mismo no?

saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: albejanon en 06 de Agosto de 2009, 04:10:17
Despues de tantos dias, he venido instruyendome en esto del ccs, haciendo programitas, leyendo aqui y alla, al fin y decidido a llevar a cabo este proyeto en lenguaje c. Ahora vengo con nuevas dudas: una de ellas es la siguiente:
1-resulta qu tengo  la termocupla conectada al AD594 que lo que hace tratar de linealizar la lectura de temperatura y asi tengo un comportamiento muy similar al del LM35 con sus 10mV/°C entonces he configurado en el pic un voltaje de referencia de 2,5V y conversion 8bits con lo cual tengo una sensibilidad de aproximadamente 10mV, pero eso tan solo para temperatura y para nivel se tiene un transmisor que entrega 1-5V, entonces no se me serviria el voltaje de referencia de 2.5V.
 q podria hacer entonces?,,,,me preguntaba si programando en c antes de leer el canal que corrresponde a nivel puedo cambiar el voltaje de referencia al voltaje interno osea 5V


Ante todo hola a todos, soy novato en este foro (y con los PICs) y la verdad es que este proyecto me ha llamado mucho la atención... llevo algún tiempo probando aquí y allá para crear un termómetro que tenga una precisión buena y la verdad es que lo que más me ha convencido es el uso de resistencias de platino. Estas resistencias tienen un comportamiento muy bueno y, además con un simple divisor de tensión mediante una resistencia de precisión puedes conseguir fijar los niveles de tensión como gustes (dentro de los 5 voltios de trabajo del PIC) y, además, dependiendo del modelo de la resistencia, puedes incluso sumergirla en el líquido para una medición más realista. Creo que es una solución barata (las encuentras en ebay a muy buen precio) y que brinda una gran precisión ya que tiene un comportamiento bastante lineal en todo el rango de medición que puede llegar desde decenas de grados bajo cero a centenas de grados sobre cero. Tan sólo debes mirar el datasheet de la resistencia. Te adjunto la tabla de valores para las PT100 y PT1000 estándar (si logro saber como adjuntar) :P.

Además, te dejo este link por si te es de ayuda, aunque usa una circuitería añadida para dar más precisión y estabilidad... yo personalmente me quedo con la versión simple del divisor de tensión ;):

 http://www.amplifier.cd/Technische_Berichte/PT100/Temperature_measurement.htm

Se me olvidaba que con la solución del divisor de tensión necesitas una tensión muy muy estable lo cual puedes conseguir con un un circuito como este que adjunto también (modificándolo a tu necesidad).

Añado también en aporte a tu último mensaje que yo usaría el LM317 en lugar del LM78XX ya que por experiencia se obtienen mejores resultados.



Enhorabuena a todos por este foro, a tí por este gran proyecto y espero haberte sido de alguna ayuda. Un saludo.
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 06 de Agosto de 2009, 18:06:27
gracias albejanon, pero pss es que el hardware en estos momentos lo tengo funcionando con termocupla y el AD594 y hasta ahora todo va bien, con respecto al divisor de tension es valido un divisor con resistencias, lo probe pero fluctuaban un poco entonces implemente un LM336 y dos resistencias y se comporta mejor, pero como no solo debia utilizar un Vref de 2,5V sino de 5V tambien y ademas ya tenia todo montado pues me imagine que podia cambiar los registros para q el micro tome la tension de referencia externa y la tension de referencia interna osea 5V y GND si funcionó bien.

Ahora me encuentro con la duda del control de fase, porque el dato de control lo debo recibir desde el pc, pero entonces ya manejo 3 interrupciones: Desbordamiento del TIMER0, Recepcion USART, interrupcion cambio de nibble(cruce por cero)

entonces en condiciones normales hago dos lecturas de canales analogos, muestro en lcd, envio datos de conversion de los canales, luego:
1-recibo correctivos del PC (se activa interrupcion usart)
2-capturo dato recibido, debo discriminar si el dato es de nivel o temperatura
3-si el dato es de nivel, activo o desactivo un pin
4-si el dato es de temperatura, debo activar el interrupcion cambio de nibble para detectar el cruce por cero luego de detectado el cruce por cero activar el Timer0 para hacer el control de fase


es correcto...mi planteamiento??
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 06 de Agosto de 2009, 20:35:49
bueno dandole dandole al programa lo que he hecho es lo siguiente:
En primera instancia defini tres funciones llamadas:
Código: CSS
  1. VOID LECTURA(VOID);
  2. VOID CONTROL_TEMP(VOID);
  3. VOID CONTROL_NIVEL(VOID);


Código: CSS
  1. ////###########################CONNTROL TEMPEPERATURA#####################################
  2. VOID CONTROL_TEMP(VOID)
  3. {                          //INICIO FUNCION CONTROL TEMP
  4.  
  5.  
  6. }                            //FIN FUNCION CONTROL TEMP
  7. //########################################################################################
  8.  
  9.  
  10.  
  11.  
  12. ////###########################CONNTROL NIVEL#####################################
  13. VOID CONTROL_NIVEL(VOID)
  14. {                          //INICIO FUNCION CONTROL TEMP
  15. IF(DATO=='A')
  16.    OUTPUT_HIGH(PIN_B1);
  17. ELSE IF(DATO=='B')
  18.    OUTPUT_LOW(PIN_B1);
  19. }                          //FIN FUNCION CONTROL
  20. //########################################################################################

en LECTURA esta las lecturas de los AD y el envio serie de las conversiones y el muestreo en lcd.
En CONTROL_NIVEL lo que hago es poner a "1" o "0" el bit1 de puertoB, dependiendo de lo que llegue por la usart.
En CONTROL_TEMP lo que deberia hacer seria activar la interrupcion cambio de nibble y  y luego activar el Timer0 para poder hacer el control de fase.
 
En la interrupcion por recepcion lo que hago es diferenciar entre numeros del 1 al 6 y las letras 'A' y 'B' y activo unos flags para indicar si lo que se recibió fue un numero entonces se hara control sobre temperatura y si lo que recibió fue una letra será control sobre nivel, asi:
Código: CSS
  1. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  2. void  RDA_isr(void)
  3. {
  4.    if(kbhit())
  5.    {
  6.    DATO=GETC();
  7.    IF(DATO=='1'|| DATO=='2' || DATO=='3' || DATO=='4' || DATO=='5' || DATO=='6' ){
  8.       FLAG_TEMP=1;}
  9.    ELSE IF(DATO=='A' || DATO=='B'){
  10.       FLAG_NIVEL=1;}
  11.    
  12.    }
  13. }


ahora todo junto seria asi:
Código: CSS
  1. #BYTE ADCON1=0X9F
  2. #BYTE PORTB=0X06
  3. #include "flex_lcd.c"
  4.  
  5. ////////////VARIABLES//////
  6. int8 O,Q;
  7. FLOAT P,R;
  8. CHAR DATO;
  9. CHAR FLAG_TEMP=0;
  10. CHAR FLAG_NIVEL=0;
  11. ///////////////////////////
  12.  
  13.  
  14. ///////////FUNCIONES//////
  15. VOID LECTURA(VOID);
  16. VOID CONTROL_TEMP(VOID);
  17. VOID CONTROL_NIVEL(VOID);
  18.  
  19. ///////////////////////////
  20.  
  21.  
  22. /* #######################INTERRUPCIONES##########################
  23. #int_RB              //CAMBIO DE NIBBLE
  24. void  RB_isr(void)
  25. {
  26.  
  27. }*/
  28.  
  29. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  30. void  RDA_isr(void)
  31. {
  32.    if(kbhit())
  33.    {
  34.    DATO=GETC();
  35.    IF(DATO=='1'|| DATO=='2' || DATO=='3' || DATO=='4' || DATO=='5' || DATO=='6' ){
  36.       FLAG_TEMP=1;}
  37.    ELSE IF(DATO=='A' || DATO=='B'){
  38.       FLAG_NIVEL=1;}
  39.    
  40.    }
  41. }
  42.          
  43. /*#int_TIMER0          //INTERRUCPION DESBORDAMIENTO TMR0
  44. void  TIMER0_isr(void)
  45. {
  46.  
  47. }
  48.  
  49. #######################FIN INTERRUPCIONES#############################*/
  50.  
  51.  
  52.  
  53.  
  54. void main()
  55. {
  56.  
  57.    
  58.    setup_adc(ADC_CLOCK_DIV_8);
  59.    //setup_psp(PSP_DISABLED);
  60.    //setup_spi(SPI_SS_DISABLED);
  61.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  62.    setup_timer_1(T1_DISABLED);
  63.    setup_timer_2(T2_DISABLED,0,1);
  64.    setup_comparator(NC_NC_NC_NC);
  65.    setup_vref(FALSE);
  66.    //enable_interrupts(INT_RB);
  67.    //enable_interrupts(INT_EXT);
  68.    enable_interrupts(INT_RDA);
  69.    //enable_interrupts(INT_TIMER0);
  70.    //port_b_pullups(TRUE);
  71.    //enable_interrupts(GLOBAL);
  72.  
  73.    // TODO: USER CODE!!
  74.    DELAY_MS(250);
  75.    SET_TRIS_B(0);
  76.    LCD_INIT();
  77.    LCD_PUTC("PRUEBA LCD");
  78.    DELAY_MS(1000);
  79.    LCD_PUTC("\f");
  80.    
  81.    FOR(;;)
  82.    {
  83.       IF(FLAG_TEMP==1)
  84.          {
  85.           disable_interrupts(INT_RDA);
  86.           FLAG_TEMP=0;
  87.           CONTROL_TEMP();
  88.           LECTURA();
  89.           enable_interrupts(INT_RDA);
  90.          }
  91.       ELSE IF(FLAG_NIVEL==1)
  92.          {
  93.           disable_interrupts(INT_RDA);
  94.           FLAG_NIVEL=0;
  95.           CONTROL_NIVEL();
  96.           LECTURA();
  97.           enable_interrupts(INT_RDA);
  98.          }
  99.    
  100.  
  101.    
  102.    
  103.    }//FIN DEL FOR
  104. }//FIN DEL MAIN
  105.  
  106.  
  107. ////################################LECTURA######################################
  108. VOID LECTURA(VOID)
  109. {
  110.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  111.    SET_ADC_CHANNEL(0);
  112.    DELAY_US(20);
  113.    Q=READ_ADC();
  114.    
  115.    
  116.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  117.    SET_ADC_CHANNEL(1);
  118.    DELAY_US(20);
  119.    O=READ_ADC();
  120.    
  121.    P=(2.5*Q)/255.0;
  122.    R=(5.0*O)/255.0;
  123.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  124.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  125.    PRINTF("T%uT\r\n",Q);
  126.    PRINTF("N%uN\r\n",O);
  127.    DELAY_ms(1);
  128.  
  129. }
  130. //#################################################################################
  131.  
  132.  
  133.  
  134. ////###########################CONNTROL TEMPEPERATURA#####################################
  135. VOID CONTROL_TEMP(VOID)
  136. {                          //INICIO FUNCION CONTROL TEMP
  137.  
  138.  
  139. }                            //FIN FUNCION CONTROL TEMP
  140. //########################################################################################
  141.  
  142.  
  143.  
  144.  
  145. ////###########################CONNTROL NIVEL#####################################
  146. VOID CONTROL_NIVEL(VOID)
  147. {                          //INICIO FUNCION CONTROL TEMP
  148. IF(DATO=='A')
  149.    OUTPUT_HIGH(PIN_B1);
  150. ELSE IF(DATO=='B')
  151.    OUTPUT_LOW(PIN_B1);
  152. }                          //FIN FUNCION CONTROL
  153. //########################################################################################


Pero me poner  a dudar el uso de los flags, al estar en el FOR infinito  verifico el estado de los flags,deshabilito la INT_RDA reseteo los flags y luego llamo a la funcion de control que corresponde....
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 06 de Agosto de 2009, 21:52:02
Hola.

El control de fase debes hacerlo siempre. Me imagino que los numeros son para asignar un nivel de calentamiento, a lo cual correspondera un cambio al angulo de disparo cierto?

El valor de asignacion de angulo de disparo lo puedes hacer directamente en la interrupcion, e inmediatamente se actualizara en el control de fase. Para que quede mejor, podrias usar del 1 al 9 para los valores de control de temperatura.

El programa principal podria dedicarse a hacer la conversion AD y mostrar los datos en la LCD.

Código: [Seleccionar]
while(true)
{
 Lectura();
}

y en la interrupcion RDA hacer las asignaciones.

Código: [Seleccionar]
#int_RDA
void RDA_isr(void)
{
 dato=0;
 if(knhit())
 {
  dato=getc();
  switch(dato)
  {
   case '1' : SetPointFase = 10;//Asigno el angulo de disparo
                 break;
   case '2' : ...
   ...
   case 'A' : output_high(pin_b1);
                 break;
   ...
  }
 }
}

Saludos

Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 06 de Agosto de 2009, 22:26:39
exactamente, los numero son para los angulos...habia estructurado mi programa de otra manera pero esta q me decís esta mucho mejor...entonces seria algo asi:

Código: CSS
  1. #BYTE ADCON1=0X9F
  2. #BYTE PORTB=0X06
  3. #include "flex_lcd.c"
  4.  
  5. ////////////VARIABLES//////
  6. int8 O,Q;
  7. FLOAT P,R;
  8. CHAR DATO;
  9. CHAR SETPOINTFASE=0;
  10.  
  11.  
  12. ///////////////////////////
  13.  
  14.  
  15. ///////////FUNCIONES//////
  16. VOID LECTURA(VOID);
  17. ///////////////////////////
  18.  
  19.  
  20.  //#######################INTERRUPCIONES##########################
  21. #int_RB              //CAMBIO DE NIBBLE
  22. void  RB_isr(void)
  23. {
  24. #ASM
  25. MOVF PORTB,W
  26. #ENDASM
  27. SET_TIMER0(128);
  28. }
  29.  
  30. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  31. void  RDA_isr(void)
  32. {
  33.  DATO=0;
  34.  IF(KBHIT())
  35.    {
  36.    DATO=GETC();
  37.    SWITCH(DATO)
  38.    {
  39.    CASE '1':disable_interrupts(INT_RDA);
  40.             SETPOINTFASE=1;
  41.             enable_interrupts(INT_RB);
  42.             break;
  43.    CASE '2':disable_interrupts(INT_RDA);
  44.             SETPOINTFASE=2;
  45.             enable_interrupts(INT_RB);
  46.             break;
  47.    CASE '3':disable_interrupts(INT_RDA);
  48.             SETPOINTFASE=3;
  49.             enable_interrupts(INT_RB);
  50.             break;
  51.    CASE '4':disable_interrupts(INT_RDA);
  52.             SETPOINTFASE=4;
  53.             enable_interrupts(INT_RB);
  54.             break;
  55.    CASE '5':disable_interrupts(INT_RDA);
  56.             SETPOINTFASE=5;
  57.             enable_interrupts(INT_RB);
  58.             break;
  59.    CASE '6':disable_interrupts(INT_RDA);
  60.             SETPOINTFASE=6;
  61.             enable_interrupts(INT_RB);
  62.             break;
  63.  
  64.    CASE 'A':OUTPUT_HIGH(PIN_B1);
  65.             break;
  66.  
  67.    CASE 'B':OUTPUT_LOW(PIN_B1);
  68.             break;
  69.    }
  70.   }
  71. }
  72.          
  73. #int_TIMER0
  74. void  TIMER0_isr(void)
  75. {
  76. disable_interrupts(INT_RB);
  77. DELAY_MS(2); ///TIEMPO INACTIVO TRIAC
  78. DELAY_MS(SETPOINTFASE);
  79. OUTPUT_HIGH(PIN_B0);
  80. DELAY_US(100);
  81. OUTPUT_LOW(PIN_B0);
  82. }
  83.  
  84.  
  85.  
  86. //#######################FIN INTERRUPCIONES#############################
  87.  
  88.  
  89.  
  90.  
  91. void main()
  92. {
  93.  
  94.    
  95.    setup_adc(ADC_CLOCK_DIV_8);
  96.    setup_psp(PSP_DISABLED);
  97.    //setup_spi(SPI_SS_DISABLED);
  98.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
  99.    setup_timer_1(T1_DISABLED);
  100.    setup_timer_2(T2_DISABLED,0,1);
  101.    setup_comparator(NC_NC_NC_NC);
  102.    setup_vref(FALSE);
  103.    //enable_interrupts(INT_RB);
  104.    //enable_interrupts(INT_EXT);
  105.    //enable_interrupts(INT_RDA);
  106.    //enable_interrupts(INT_TIMER0);
  107.    //port_b_pullups(TRUE);
  108.    enable_interrupts(GLOBAL);
  109.    
  110.    DELAY_MS(250);
  111.    LCD_INIT();
  112.    LCD_PUTC("PRUEBA LCD");
  113.    DELAY_MS(1000);
  114.    LCD_PUTC("\f");
  115.    output_high(PIN_B0);
  116.    DELAY_MS(1000);
  117.    OUTPUT_LOW(PIN_B0);
  118.    
  119.    
  120.    while(true)
  121.    {
  122.     enable_interrupts(INT_RDA);
  123.     LECTURA();
  124.    }
  125.    
  126.      
  127.    
  128. }//FIN DEL MAIN
  129.  
  130.  
  131. ////################################LECTURA######################################
  132. VOID LECTURA(VOID)
  133. {
  134.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  135.    SET_ADC_CHANNEL(0);
  136.    DELAY_US(20);
  137.    Q=READ_ADC();
  138.    
  139.    
  140.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  141.    SET_ADC_CHANNEL(1);
  142.    DELAY_US(20);
  143.    O=READ_ADC();
  144.    
  145.    P=(2.5*Q)/255.0;
  146.    R=(5.0*O)/255.0;
  147.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  148.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  149.    PRINTF("T%uT\r\n",Q);
  150.   //PRINTF("N%uN\r\n",O);
  151.    DELAY_MS(500);
  152.  
  153. }
  154. //#################################################################################

compilando me tira un warning: line 161(0,1) interrupts disable during call to prevent re-entrancy: [@delay_ms1], pero lo dice en una linea en donde no hay codigo

Detecto algunos inconvenientes, por ahora, despues de que envio los datos le doy una delay de medio segundo, y al recibir datos como q se genera algun conflicto...pero es por q casi q coinciden el envio y la recepcion de datos..pero lo que mas me preocupa es q no me funciona el control de fase, ahora solo lo simulo con un bombillo a 110V y deberia ver cambiar la intensidad pero no funciona...sera q tengo error de codigo en cuanto eso?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 07 de Agosto de 2009, 02:16:22
Hola

El warning es por el delay_ms(2); que tienes en la interrupcion del Timer0.

Te puedes ahorrar el deshabilitar las interrupciones RDA en el switch (asignar la variable no toma tiempo critico en la interrupcion).

El control de fase no te funciona, porque no esta trabajando constantemente y solo se activan si llega un dato por la RDA. Si quieres que funcione correctamente, se debe estar atento al cambio de flanco para asignar el tiempo de espera.

Código: C#
  1. //Haciendolo con la interrupcion de RB0
  2. #int_EXT
  3. void ZeroCross(void)
  4. {
  5.         if(Flanco==subida)//Detecto el flanco
  6.         {
  7.                 enable_interrupts(INT_TIMER0);//Habilito el Timer para que comience el conteo de espera de activacion del TRIAC
  8.                 ext_int_edge(L_TO_H);
  9.                 Flanco=bajada;
  10.         }
  11.         else
  12.         {
  13.                 enable_interrupts(INT_TIMER0);
  14.                 ext_int_edge(H_TO_L);
  15.                 Flanco=subida;
  16.         }
  17. }

Y en la interrupcion del Timer0 seria:
Código: C#
  1. #int_TIMER0
  2. void pulse0_isr(void)
  3. {
  4.         IntsTimer++;
  5.         if(IntsTimer>SetPoint)//Hasta que no llegue al valor, el pin trigger0 estara en bajo
  6.         {
  7.                 on(trigger0);//Habilito el pulso de activacion del TRIAC
  8.                 IntsTimer=0;
  9.                 disable_interrupts(INT_TIMER0);
  10.                 delay_us(100);
  11.                 off(trigger0);
  12.         }
  13.         set_timer0(0);
  14. }

Esto siempre debe estar activo para garantizar el control, ya que la onda senoidal es continua. En el codigo principal, debes habilitar la interrupcion en RB0, para que comience a hacer el control de fase en un valor predefinido -por lo general, el minimo-
Código: C#
  1. void main(void)
  2. {
  3.  ...
  4.  ext_int_edge(H_TO_L);
  5.  Flanco=subida;
  6.  SetPoint=1;
  7.  enable_interrupts(INT_EXT);
  8.  ...
  9. }
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 07 de Agosto de 2009, 19:26:28
Con dificultad y de manera Incorrecta logro ver el cambio de intensidad, creo q como cambie el programa se esta mas atento del control de fase, ahora lo q hice fue que el pic solo envia hacia el PC las conversiones AD cuando recibe el '7', el resto del tiempo se la pasa leyendo los canales AD y mostrando en lcd, ademas del control de fase.

asi:
Código: CSS
  1. int8 O,Q;
  2. FLOAT P,R;
  3. CHAR DATO;
  4. CHAR SETPOINTFASE=1;
  5. CHAR CONTADOR=0;
  6. CHAR FLAG_LECTURA=0;
  7.  
  8.  
  9. ///////////////////////////
  10.  
  11.  
  12. ///////////FUNCIONES//////
  13. VOID LECTURA(VOID);
  14.  
  15. ///////////////////////////
  16.  
  17.  
  18.  //#######################INTERRUPCIONES##########################
  19. #int_RB              //CAMBIO DE NIBBLE
  20. void  RB_isr(void)
  21. {
  22. #ASM
  23. MOVF PORTB,W
  24. #ENDASM
  25. SET_TIMER0(131);
  26. enable_interrupts(INT_TIMER0);
  27. }
  28.  
  29. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  30. void  RDA_isr(void)
  31. {
  32.  DATO=0;
  33.  IF(KBHIT())
  34.    {
  35.    DATO=GETC();
  36.    SWITCH(DATO)
  37.    {
  38.    CASE '1':SETPOINTFASE=1;
  39.             break;
  40.            
  41.    CASE '2':SETPOINTFASE=2;
  42.             break;
  43.            
  44.    CASE '3':SETPOINTFASE=3;
  45.             break;
  46.            
  47.    CASE '4':SETPOINTFASE=4;
  48.             break;
  49.            
  50.    CASE '5':SETPOINTFASE=5;
  51.             break;
  52.            
  53.    CASE '6':SETPOINTFASE=6;
  54.             break;
  55.    
  56.    CASE '7':FLAG_LECTURA=1;
  57.             break;
  58.  
  59.    CASE 'A':OUTPUT_HIGH(PIN_B1);
  60.             break;
  61.  
  62.    CASE 'B':OUTPUT_LOW(PIN_B1);
  63.             break;
  64.    }
  65.    
  66.   }
  67.  
  68. }
  69.          
  70. #int_TIMER0
  71. void  TIMER0_isr(void)
  72. {
  73. CONTADOR++;
  74.                              
  75. IF(CONTADOR==7){
  76.    CONTADOR=0;}
  77. IF(CONTADOR==SETPOINTFASE)
  78.    {
  79.    DELAY_MS(SETPOINTFASE);
  80.    OUTPUT_HIGH(PIN_B0);
  81.    DELAY_US(300);                        
  82.    OUTPUT_LOW(PIN_B0);                    
  83.    }
  84. }
  85.  
  86.  
  87.  
  88. //#######################FIN INTERRUPCIONES#############################
  89.  
  90.  
  91.  
  92.  
  93. void main()
  94. {
  95.  
  96.    
  97.    setup_adc(ADC_CLOCK_DIV_8);
  98.    setup_psp(PSP_DISABLED);
  99.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
  100.    setup_timer_1(T1_DISABLED);
  101.    setup_timer_2(T2_DISABLED,0,1);
  102.    setup_comparator(NC_NC_NC_NC);
  103.    setup_vref(FALSE);
  104.    //enable_interrupts(INT_RB);
  105.    //enable_interrupts(INT_EXT);
  106.    //enable_interrupts(INT_RDA);
  107.    //enable_interrupts(INT_TIMER0);
  108.    //port_b_pullups(TRUE);
  109.    enable_interrupts(GLOBAL);
  110.    
  111.    DELAY_MS(250);
  112.    LCD_INIT();
  113.    LCD_PUTC("PRUEBA LCD");
  114.    DELAY_MS(1000);
  115.    LCD_PUTC("\f");
  116.    output_high(PIN_B0);
  117.    DELAY_MS(1000);
  118.    OUTPUT_LOW(PIN_B0);
  119.    
  120.    
  121.    while(true)
  122.    {
  123.     LECTURA();
  124.     enable_interrupts(INT_RDA);
  125.     enable_interrupts(INT_RB);
  126.     IF(FLAG_LECTURA==1)
  127.       {
  128.       FLAG_LECTURA=0;
  129.       PRINTF("T%uT\r\n",Q);
  130.       PRINTF("N%uN\r\n",O);
  131.       }
  132.     }
  133.    
  134.      
  135.    
  136. }//FIN DEL MAIN
  137.  
  138.  
  139. ////################################LECTURA######################################
  140. VOID LECTURA(VOID)
  141. {
  142.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  143.    SET_ADC_CHANNEL(0);
  144.    DELAY_US(20);
  145.    Q=READ_ADC();
  146.    
  147.    
  148.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  149.    SET_ADC_CHANNEL(1);
  150.    DELAY_US(20);
  151.    O=READ_ADC();
  152.    
  153.    P=(2.5*Q)/255.0;
  154.    R=(5.0*O)/255.0;
  155.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  156.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  157.    
  158. }  
  159.  
  160.  
  161. //#################################################################################

estoy cometiendo algun error???
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 07 de Agosto de 2009, 21:41:12
Hola.

Mira el codigo que te postee para el control de fase. Tu estas asignando un delay_ms() dentro de la interrupcion del Timer0, la idea es NO hacerlo, ya que en ese tiempo el PIC no atiende nada mas. Si lo haces como te indique arriba, la cuenta del tiempo es independiente de todo lo demas que estas haciendo.

Debes asignar bien el tiempo de desborde el Timer0, para contar asi los mS de espera antes de dispara el TRIAC.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 07 de Agosto de 2009, 23:02:24
 :-) :-) efectivamente  :D..ya capte mas o menos la idea..lo que pasa es que yo no tomaba muy encuenta los tiempos de las interrupciones..y es que despues de la interrupcion por cambio nibble(cruce por cero) tengo aprox 7mS hasta el proximo cruce, ademas ese delay dentro de la int_rda somete al pic a no prestar atencion a nada mas pero suponia ese delay para el tiempo de espera para activar el triac...ya lo corregì...sin embargo, funciona bien para las primeras 3 intensidades y es mas notorio el cambio de la 1 a la 3..en las siguientes se observa una oscilacion de la luminosidad...q podría ser??en la interrupcion hice esto:
Código: CSS
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4. CONTADOR++;
  5.                                          
  6.  
  7. IF(CONTADOR==SETPOINTFASE)        
  8.    {
  9.    OUTPUT_HIGH(PIN_B0);
  10.    CONTADOR=0;
  11.    disable_interrupts(INT_TIMER0);
  12.    DELAY_US(300);                        
  13.    OUTPUT_LOW(PIN_B0);
  14.        
  15.    }
  16.    SET_TIMER0(131);
  17.   enable_interrupts(INT_TIMER0);
  18. }

estoy utilizando una fuente de pc..sera q introduce ruido??
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 08 de Agosto de 2009, 01:19:31
Hola.

Que cristal estas usando? Si quieres que el tiempo que toma la int_RDA no te afecte mucho el cruce por cero, usa un cristal de mas de 12MHz.

Si te titila la luminosidad, puede ser por que el tiempo de disparo del TRIAC no es el mismo y esta desfasado algunos uS.

Segun veo en tu codigo, activas la interrupcion int_TIMER0 en la int_TIMER0 y no deberia ser asi, si miras bien el codigo que te postee, yo activo la interrupcion del Timer0 en la interrupcion del cambio de fase, para que el timer comience a contar, luego, cuando el valor de conteo del Timer llega al SetPoint, activo el pulso y desactivo la interrupcion del Timer0, ya que solo me interesa que comience a contar desde el punto del cruce por cero  :z) -espero no enredarte-

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 08 de Agosto de 2009, 01:39:03
si estoy un XT de 4Mhz...probare uno de 20Mhz...tengo una duda,,cuando ser escribe set_timer() se escribe solo el valor a cargar en el TIMER0 y cuando se escribe enable_interrupts(INT_TIMER0) se modifica el bit el TMROIE del registro de interrupcion? es decir habilita el bit de interrupcion del TMR0 pero no habilita el permiso goblal (bit GIE de INTCON)?

ahora, en el codigo q me pusiste cuando no se cumple
Código: CSS
  1. if(IntsTimer>SetPoint)
haces una carga del timero set_timer(0); ...habilitas de nuevo el valor de tiempo a desbordar?

supongo que debeeria funcionar asi: cuando se detecta el cruce por cero hay q activar el timer0, luego este se desborda en 1ms y se hace la comparacion con el setpoint if(contador==setpoint), sin son iguales desactivo el timer0 y envio pulso, si son diferentes debo poner otra vez la precarga del timer0 y habilitar la interrupcion para q vuelva a contar 1ms...y asi es como veo tu codigo..

mirando los dos codigos:
Código: CSS
  1. #int_TIMER0
  2.  
  3.  void pulse0_isr(void)
  4.   {
  5.    IntsTimer++;
  6.     if(IntsTimer>SetPoint)                   //Hasta que no llegue al valor, el pin trigger0 estara en bajo
  7.       {
  8.         on(trigger0);//Habilito el pulso de activacion del TRIAC
  9.         IntsTimer=0;
  10.         disable_interrupts(INT_TIMER0);
  11.         delay_us(100);
  12.         off(trigger0);
  13.       }
  14.       set_timer0(0);
  15.        }

el mio:
Código: CSS
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4. CONTADOR++;
  5.                                          
  6.  
  7. IF(CONTADOR==SETPOINTFASE)        
  8.    {
  9.    OUTPUT_HIGH(PIN_B0);
  10.    CONTADOR=0;
  11.    disable_interrupts(INT_TIMER0);
  12.    DELAY_US(300);                        
  13.    OUTPUT_LOW(PIN_B0);
  14.        
  15.    }
  16.    SET_TIMER0(131);
  17.   enable_interrupts(INT_TIMER0);     ////// si quito esta linea ya no prende el bombillo
  18. }
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 08 de Agosto de 2009, 02:23:06
Hola.

Para habilitar la interrupcion particular se usa enable_interrupts(INT_xxx), si escribo: enable_interrupts(GLOBAL); habilito el permiso global de interrupciones.

La carga del Timer0 es para garantizar que siempre va a contar el mismo tiempo siempre sin que me afecte los uS tomados dentro de la interrupcion, si quitas la precarga se vera que el pulso de habilitacion es inestable, lo que se traduce en un titileo en el bombillo.

Creo que lo que esta fallando en tu codigo es la deteccion de cruce por cero. Creo que lo que estas haciendo es detectar el cruce y de ahi empiezas a temporizar, el Timer siempre esta contando, asi que siempre esta disparando el TRIAC, pero ese disparo no es sincronizado con el cruce por cero.

En tu codigo de la interrupcion del Timer0, cuando se cumple que CONTADOR=SETPOINTFASE envia el pulso de activacion, deshabilitas la interrupcion y luego la vuelves a habilitar. Al no tener sincronia el pulso de disparo del TRIAC con el cruce por cero, puede pasar cualquier cosa.

El timer0 debe contar el tiempo desde el cruce por cero hasta el tiempo en el cual se da el disparo del GATE del TRIAC, luego permanece inactivo hasta el nuevo cruce por cero:
(http://img44.imageshack.us/img44/4852/zerotimer.png)

Hasta que no se ponga disable_interrupts(INT_TIMER0), la interrupcion sigue activa, y por ende, el Timer0 sigue su cuenta.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 08 de Agosto de 2009, 14:17:47
si...es q el problema esta en la interrrupcion del timer, por que cuando entra en la interrupcion y se cumple que IF(CONTADOR==SETPOINTFASE) deshabilito la interrupcion del timer0, pero se cumpla o no se cumpla la condicion vuelvo y habilito el timer0 entonces siempre esta desbordandose cada 1ms.....y lo que debe pasar el que al cumplirse el IF se debe deshabilitar el timer0, enviar el pulso..y esperar el proximo cruce por cero...

para tratar de solucionar eso hice esto:
Código: CSS
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4. CONTADOR++;
  5. IF(CONTADOR==SETPOINTFASE)
  6.    {
  7.    disable_interrupts(INT_TIMER0);
  8.    OUTPUT_HIGH(PIN_B0);
  9.    CONTADOR=0;
  10.    DELAY_US(300);                        
  11.    OUTPUT_LOW(PIN_B0);
  12.    FLAG_TIMER=1;
  13.    }
  14.  
  15. IF(FLAG_TIMER==1){
  16.    disable_interrupts(INT_TIMER0);}
  17. ELSE
  18.    SET_TIMER0(131);
  19.    enable_interrupts(INT_TIMER0);
  20. }

ya lo puse a correr a 20Mhz, mejoró mucho pero la intensidad 5 oscila

Otra aspecto, tengo dos triac de gate sensible, pero solo necesito uno para el control de fase, el otro quiero cambiarlo para switchear nada mas, es decir, on-off y asi no tener q preocuparme tambien por el cruce por cero y poder activar ese triac..cual seria recomendable?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 08 de Agosto de 2009, 15:56:58
Hola.

No te compliques, si se debe esperar al proximo cruce por cero para volver a activar la interrupcion del Timer0, pues no hay necesidad de modificarla en la funcion que tienes para int_TIMER0. La activas en la interrupcion de cruce por cero y la desactivas luego de enviar el pulso de activacion al TRIAC -es como lo tengo en el codigo que te he posteado-. El setear el timer con set_timer0(); no habilita la interrupcion.

Si vas a hacer control ON-OFF debes usar un opto-triac que tenga detector de cruce por cero como el MOC3041.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 08 de Agosto de 2009, 23:30:58
no me fue posible identificar el problema..ya te entendí la idea pero si utilizo tu codigo por alguna razon no funciona...con mi rutina funciona pero estoy perdiendo preciosos milisegundos...

por otro lado, tengo los dos triac de gate sensible, y el MOC3011. Con el MOC3041 solo debo enviar pulso y el solo se encarga de activar el triac en el cruce por cero y ya no tendria q detectar los flancos?..de ser asi solo debo cambiar el MOC
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 09 de Agosto de 2009, 14:42:50
Hola.

Es diferente el control ON-OFF al control de fase.

ON-OFF:
(http://img198.imageshack.us/img198/1913/ask1.png)

Fase:
(http://img36.imageshack.us/img36/7047/figura2ca.jpg)

recuerda que yo hago la deteccion del cruce por cero con la interrupcion en RB0.
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 09 de Agosto de 2009, 22:01:50
ok, pero lo que quiero decir es q si con el MOC3041 lo  unico q tengo q hacer es enviarle el '1' o '0'  y el con su cruce por cero activa o desactiva la carga?
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 09 de Agosto de 2009, 22:05:09
Hola.

El resultado seria como el de la grafica de arriba. Lo que garantiza el MOC es que cuando envias el '1', el espera al cruce por cero para activar la carga, esto ayuda a reducir los transcientes de corriente y voltaje sobre la carga, ya que la señal de voltaje comienza desde ceros.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 11 de Agosto de 2009, 23:36:39
estoy teniendo problemas con una de las plaquetas de potencia, cuando la conecto se me resetea el micro y tambien me corrompe los datos del LCD. Como voy a cambiar el hardware de potencia pss voy a aprovechar para cambiar el detector de cruce por cero hacia la interrupcion externa y es que por cambio de nibble de pronto se me puede estar presentando problemas de ruido por esos pines y solo utilizo uno.

resulta que para la parte de potencia, tengo identificadas la fase y el neutro del tomacorriente, para hacer una sola tierra comun a todo el circuito lo q hice fue enviar neutro con resistencia de 10K a tierra digital, es decir una sola tierra, pero entonces yo supuse que en un toma doble pss la fase y neutro son los mismos y como conecto dos plaquetas de potencia de la misma red pss el otro neutro tambien estaria enviado a tierra con la misma resistencia de 10K, entonces no se si estoy haciendo bien asi? o q podria hacer...adjunto la imagen como haria las nuevas plaquetas de potencia pero ahora le puse a cada una una resistencia de 10K en el neutro...entonces independientemente de donde conecte la plaqueta el neutro ira a tierra digital con 10K.
otra cosa a tener en cuenta es que a la primera plaqueta de potencia le envio un solo conector desde el puertoB con las dos señales necesarias para activar y de esa plaqueta  pongo otro conector hacia la segunda plaqueta con el bit de activacion y las tierra general...espero haberme hecho entender

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=25798.0;attach=9849)

la que actualmente me resetea el micro es la segunda y esa la tengo sin resistencia...el valor de la resistencia deberia ser mas alto???
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Agosto de 2009, 13:13:10
cambiando el programa para detectar el cruce por cero utilizando la interrupcion externa
lo puse asi, de entrada pongo el flanco en 0...y ya dentro de la interrupcion se actualiza
Código: CSS
  1. #int_EXT
  2. void  EXT_isr(void)
  3. {
  4.    DELAY_US(1300);
  5.    IF(FLANCO==0)
  6.       {
  7.       FLANCO=1;
  8.       ext_int_edge(H_TO_L);
  9.       SET_TIMER0(99);
  10.       enable_interrupts(INT_TIMER0);
  11.       }
  12.    ELSE
  13.       {
  14.       FLANCO=0;
  15.       ext_int_edge(L_TO_H);
  16.       SET_TIMER0(99);
  17.       enable_interrupts(INT_TIMER0);
  18.       }
  19. }
  20.  
  21. #int_TIMER0
  22. void  TIMER0_isr(void)
  23. {
  24. CONTADOR++;
  25. IF(CONTADOR==SETPOINTFASE)
  26.    {
  27.    disable_interrupts(INT_TIMER0);
  28.    OUTPUT_HIGH(PIN_B1);
  29.    CONTADOR=0;
  30.    DELAY_US(300);                        
  31.    OUTPUT_LOW(PIN_B1);
  32.    FLAG_TIMER=1;
  33.    }
  34. SET_TIMER0(99);
  35.  
  36.  
  37. /*IF(FLAG_TIMER==1){
  38.    disable_interrupts(INT_TIMER0);}
  39. ELSE
  40.    SET_TIMER0(99);
  41.    enable_interrupts(INT_TIMER0);*/
  42.  
  43. }
  44.  
  45.  
  46. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  47. void  RDA_isr(void)
  48. {
  49.  DATO=0;
  50.  IF(KBHIT())
  51.    {
  52.    DATO=GETC();
  53.    SWITCH(DATO)
  54.    {
  55.    CASE '1':SETPOINTFASE=1;
  56.             break;
  57.            
  58.    CASE '2':SETPOINTFASE=2;
  59.             break;
  60.            
  61.    CASE '3':SETPOINTFASE=3;
  62.             break;
  63.            
  64.    CASE '4':SETPOINTFASE=4;
  65.             break;
  66.            
  67.    CASE '5':SETPOINTFASE=5;
  68.             break;
  69.            
  70.    CASE '6':SETPOINTFASE=6;
  71.             break;
  72.    
  73.    CASE '7':FLAG_LECTURA=1;
  74.             break;
  75.  
  76.    CASE 'A':OUTPUT_HIGH(PIN_B2);
  77.             LCD_GOTOXY(7,2);
  78.             PRINTF(LCD_PUTC,"ON ");
  79.             break;
  80.  
  81.    CASE 'B':OUTPUT_LOW(PIN_B2);
  82.             LCD_GOTOXY(7,2);
  83.             PRINTF(LCD_PUTC,"OFF");
  84.             break;
  85.    }
  86.    
  87.   }
  88.  
  89. }
  90.          
  91.  
  92.  
  93.  
  94.  
  95.  
  96. //#######################FIN INTERRUPCIONES#############################
  97.  
  98.  
  99.  
  100.  
  101. void main()
  102. {
  103.  
  104.    
  105.    setup_adc(ADC_CLOCK_DIV_32);
  106.    setup_psp(PSP_DISABLED);
  107.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
  108.    setup_timer_1(T1_DISABLED);
  109.    setup_timer_2(T2_DISABLED,0,1);
  110.    setup_comparator(NC_NC_NC_NC);
  111.    setup_vref(FALSE);
  112.    //enable_interrupts(INT_RB);
  113.    //enable_interrupts(INT_EXT);
  114.    //enable_interrupts(INT_RDA);
  115.    //enable_interrupts(INT_TIMER0);
  116.    //port_b_pullups(TRUE);
  117.  
  118.    
  119.    DELAY_MS(250);
  120.    LCD_INIT();
  121.    LCD_PUTC("PRUEBA LCD");
  122.    DELAY_MS(1000);
  123.    LCD_PUTC("\f");
  124.    output_high(PIN_B1);
  125.    DELAY_MS(1000);
  126.    OUTPUT_LOW(PIN_B1);
  127.    
  128.    LCD_GOTOXY(1,1);
  129.    PRINTF(LCD_PUTC,"TEMPERATURA:");
  130.    LCD_GOTOXY(1,2);
  131.    PRINTF(LCD_PUTC,"BOMBA:");
  132.    enable_interrupts(INT_EXT);
  133.    ext_int_edge(L_TO_H);
  134.    enable_interrupts(GLOBAL);
  135.    
  136.    
  137.    while(true)
  138.    {
  139.     LECTURA();
  140.     enable_interrupts(INT_RDA);
  141.     enable_interrupts(INT_RB);
  142.     IF(FLAG_LECTURA==1)
  143.       {
  144.       FLAG_LECTURA=0;
  145.       PRINTF("T%uT\r\n",Q);
  146.       PRINTF("N%uN\r\n",O);
  147.       }
  148.     }
  149.    
  150.      
  151.    
  152. }//FIN DEL MAIN
  153.  
  154.  
  155. ////################################LECTURA######################################
  156. VOID LECTURA(VOID)
  157. {
  158.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  159.    SET_ADC_CHANNEL(0);
  160.    DELAY_US(100);
  161.    Q=READ_ADC();
  162.    
  163.    
  164.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  165.    SET_ADC_CHANNEL(1);
  166.    DELAY_US(100);
  167.    O=READ_ADC();
  168.    
  169.    //P=((2.5*Q)/255.0)*0.001;
  170.    //R=(5.0*O)/255.0;
  171.    LCD_GOTOXY(13,1);
  172.    PRINTF(LCD_PUTC,"%d",Q);
  173.    
  174.    
  175.    
  176. }  
  177.  
  178.  
  179. //#################################################################################
el control de fase se puede simular con los numeros del 1 al 7 y con "A" y "B" pongo on off en el lcd pero me aparecen unos numeros al lado

lo q no entiendo por q pasa q cuando le mando al lcd poner on off en la segunda linea me salen unos numeros??
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 12 de Agosto de 2009, 14:06:54
Que version del ISIS usas? no abrio  :(

Pon una captura de pantalla para ver de que se trata.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Agosto de 2009, 14:29:50
uso la version 7.5
te adjunto la imagen, a veces me salen unos 7 al lado de la palabra on u off
(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=25798.0;attach=9854)
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 12 de Agosto de 2009, 15:36:24
Hola.

Creo que los printf() que estan en la #int_RDA seria mejor ponerlos en el programa principal.

Saludos
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Agosto de 2009, 16:16:53
 :mrgreen: ..si .era eso...pero q me recomiendas con lo de potencia?..pongo una resistencia mas grande para enviar neutro a tierra digital y asi tener una sola tierra
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: jhozate en 12 de Agosto de 2009, 18:31:55
enfrento un pequeño detalle...cuando quiero apagar totalmente la carga a la que le hago control de fase..me alcanza a destellar... cuando recibo el 7 cargo el setpoint con 0..adjunto el codigo..
Título: Re: Contro de nivel y Temperatura de un calderin por medio de RF
Publicado por: MLO__ en 12 de Agosto de 2009, 21:02:49
Pues, yo no soy amigo de mezclar AC con DC de esa manera. Prefiero usar algo que aisle las dos señales. Hay varias formas de hacerlo: con transformador, con optoacoplador (este es mas pequeñin).

Para apagar la carga yo envio a ceros el pin que habilita el GATE del TRIAC. Puedes asignar un if dentro de la interrupcion del Timer0, que solo tome el conteo del tiempo cuando el valor del SetPoint sea diferente del maximo, si es el maximo, pues pones a 0 el pin y listo.

Saludos