Problemas con PIC16F690 y TRIAC

#1
Saludos al foro.
Necesito la ayuda de alguien con experiencia en PIC.
Intento hacer un dimmer con PIC, TRIAC y LabVIEW.
He conseguido obtener un dato de LabVIEW hacia el PIC por RS-232 asíncrono y depende ese dato será la intensidad de la lámpara incandescente, pero no funciona lo del PIC y TRIAC.
Lo que logro que funcione es el PIC con LabVIEW.

Uso el PIC16F690 con PICkit2 de Microchip y MPLABX IDE para programarlo.

Soy nuevo en este foro y no sé cómo poner los diagramas de los circuitos.

Este es el código:
Código:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#define _XTAL_FREQ 4000000

unsigned char BUFFER=127;

void interrupt isr(void){
    if(INTCONbits.T0IF==1) {
        INTCONbits.T0IF=0;
        PORTCbits.RC0=1;
        INTCONbits.T0IE=0;
    } else if (PIR1bits.RCIF==1) {
        PIR1bits.RCIF=0;
        BUFFER=RCREG;
        
    }
        
}

/*
 * 
 */
void main(void) {
    OPTION_REGbits.T0CS=0;
    OPTION_REGbits.PS0=0;
    OPTION_REGbits.PS1=0;
    OPTION_REGbits.PS2=1;
    OPTION_REGbits.PSA=0;
    //WDTCONbits.SWDTEN=0;
    //ADCON0=0;
    //CM1CON0=0;
    //CM2CON0=0;
    ANSEL=0;
    ANSELH=0;
    TRISC=0;
    PORTC=0;
    TRISA=1;
    TXSTAbits.BRGH=1;
    SPBRG=25;
    RCSTAbits.CREN=1;
    TXSTAbits.SYNC=0;
    RCSTAbits.SPEN=1;
    PIE1bits.RCIE=1;
    INTCONbits.PEIE=1;
    INTCONbits.GIE=1;
   
    while(1) {
        if(PORTAbits.RA0==1){
        TMR0=BUFFER;
        INTCONbits.T0IE=1;
        PORTCbits.RC0=0;
        while(PORTAbits.RA0==1);
        TMR0=BUFFER;
        INTCONbits.T0IE=1;
        PORTCbits.RC0=0;
        while(PORTAbits.RA0==0);
                  }
       
    }
     
    
}
 
Última edición por un moderador:
#2
Para subir archivos das click dónde dice; Adjuntar archivos y más, que está a un lado del botón responder.

Y explica más qué es lo que no te funciona, porque por lo que veo del código, no tiene nada con respecto a lo del triac. ¿Será por eso que no te funciona?

¿Está en RC0?
 
Última edición por un moderador:
#3
Ok. papirrin. Con la instrucción PORTCbits.RC0 es el puerto por el cual activo el MOC3011 para que éste a su vez dispare el TRIAC.

Lo que pasa es que la lámpara queda parpadeando y no aumenta ni disminuye la intensidad.

Éste es el diagrama.
 

Adjuntos

Última edición por un moderador:
#4
¿Te pregunto de nuevo qué hace, por lo qué no funciona?
¿Ya revisaste que el módulo de comparadores esté desactivado y el puerto RA0 esté como digital?

Al parecer debería funcionar el código, aunque yo la detección la haría por interrupción externa RA2, y cambiar el flanco de interrupción.

EDITO: Ya vi qué es por lo que no te funciona, y una posibilidad es que RA0 está como análogo.

También prueba quitar la línea ésta:
Código:
if(PORTAbits.RA0==1){
        TMR0=BUFFER;
        INTCONbits.T0IE=1;
        PORTCbits.RC0=0;
        while(PORTAbits.RA0==1);
        TMR0=BUFFER;
        INTCONbits.T0IE=1;
        PORTCbits.RC0=0;
        while(PORTAbits.RA0==0);/<-esta quitala
                  }
 
Última edición por un moderador:
#5
Gracias, papirrin, por estar al pendiente.
Ya probé quitando la línea de código y asegurándome que estén apagados los comparadores y que RA esté como digital.
Código:
ADCON0=0;
    CM1CON0=0;
    CM2CON0=0;
 ANSEL=0;
TRISA=1;

y ya probe con interrupción externa por pin RA2:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <stdbool.h>
#define _XTAL_FREQ 4000000

unsigned char BUFFER=127;
bool edge=true;

void interrupt isr(void){
    if(INTCONbits.T0IF==1) {
        PORTCbits.RC0=1;
        INTCONbits.T0IF=0;
        INTCONbits.T0IE=0;
    } else if (PIR1bits.RCIF==1) {
        PIR1bits.RCIF=0;
        BUFFER=RCREG;
        
    } else if (INTCONbits.INTF==1) {
        INTCONbits.INTF=0;  //limpiar vandera de interrupcion
        PORTCbits.RC0=0;
        TMR0=BUFFER;
        edge=!edge;
        OPTION_REGbits.INTEDG=edge;    //edge 1=rising,0=filling
    }
        
}

/*
 * 
 */
void main(void) {
    INTCONbits.INTE=1;//ra2
    OPTION_REGbits.INTEDG=1;    //edge 1=rising,0=filling
    
    OPTION_REGbits.T0CS=0;
    OPTION_REGbits.PS0=0;
    OPTION_REGbits.PS1=0;
    OPTION_REGbits.PS2=1;
    OPTION_REGbits.PSA=0;
    ANSEL=0;
    ANSELH=0;
    TRISC=0;
    PORTC=0;
    TRISA=1;
    TXSTAbits.BRGH=1;
    SPBRG=25;
    RCSTAbits.CREN=1;
    TXSTAbits.SYNC=0;
    RCSTAbits.SPEN=1;
    PIE1bits.RCIE=1;
    INTCONbits.PEIE=1;
    INTCONbits.GIE=1;
   
    while(1) {
          INTCONbits.T0IE=1;
        //if(PORTAbits.RA0==1){
        //TMR0=BUFFER;
        //INTCONbits.T0IE=1;
        //PORTCbits.RC0=0;
        //while(PORTAbits.RA0==1);
        //TMR0=BUFFER;
       // INTCONbits.T0IE=1;
       // PORTCbits.RC0=0;
        //while(PORTAbits.RA0==0);
                //  }
       
    }
     
    
}
 
Última edición por un moderador:
#6
¿Y sigue sin funcionar? Supongo.

Me parece que algo está mal.

Código:
if(INTCONbits.T0IF==1) {
PORTCbits.RC0=1;
INTCONbits.T0IF=0;
INTCONbits.T0IE=0;
} else if (PIR1bits.RCIF==1) {
PIR1bits.RCIF=0;
BUFFER=RCREG;

} else if (INTCONbits.INTF==1) {
INTCONbits.INTF=0; //limpiar vandera de interrupcion
PORTCbits.RC0=0;
TMR0=BUFFER;
  [B]<-aqui debes iniciar la interrupcion del timer
INTCONbits.T0IE=1;[/B]
edge=!edge;
OPTION_REGbits.INTEDG=edge; //edge 1=rising,0=filling
}
Y en el bucle principal no pongas nada. Checa eso.
 
Última edición por un moderador:
#8
en teoria el codigo podria funcionar, tienes simulacion en proteus y el archivo hex pare ver la simulacion.

otra cosa que puede pasar es que el triac no este gatillando bien, ¿revisate su ficha tecnica?

yo tambien intentaria gatillar solo por un momento.. es decir asi o similar porque no me gustan los delay en las interrupciones.

Código:
if(INTCONbits.T0IF==1) {
[B]PORTCbits.RC0=1;
delay_ms(X); /X=el tiempo minimo de gatilleo segun ficha tecnica.
PORTCbits.RC0=0;[/B]
INTCONbits.T0IF=0;
INTCONbits.T0IE=0;
} else if (PIR1bits.RCIF==1) {
PIR1bits.RCIF=0;
BUFFER=RCREG;

} else if (INTCONbits.INTF==1) {
INTCONbits.INTF=0; //limpiar vandera de interrupcion
TMR0=BUFFER;
  <-aqui debes iniciar la interrupcion del timer
INTCONbits.T0IE=1;
edge=!edge;
OPTION_REGbits.INTEDG=edge; //edge 1=rising,0=filling
}
 
Última edición:
#9
el triac que uso es el BTA24-800BW

ya de plano no abra un modulo comercial de dimmer que lo controle por voltaje de 0 a 5 v o 0 a 10 v.
o dimer con potenciómetro digital... jejje
 
#11
el triac que uso es el BTA24-800BW
me parece que la resistencia de 100R es muy dura, prueba con una de 2K2
mira segun mis calculos
Rgate=?
IGt=50mA
Vc=110V

Rgate=(110-.7)/.05=2200

ya me late que va por ahi, si esta bien conectado el MT1 y MT2 verdad?


ya de plano no abra un modulo comercial de dimmer que lo controle por voltaje de 0 a 5 v o 0 a 10 v.
o dimer con potenciómetro digital... jejje
Jajaja, no, no se, pero no te desanimes XD.

:EDITO:

Me equivoque de calculo, sabras disculpar ya tengo alzhimer XD

se supone que es :

Rgate=Vp/MocITMS
osea
Rgate=(110*1.41)/1=160R como minimo

asi que prueba con una de 180R
 
Última edición:
#14
jejje ami también para mi la lógica funciona pero pues ya ves en la practica no se deja.

oyes y si armamos mejor un circuito dimmer básico con potenciómetro, pero reemplazamos el potenciómetro convencional por uno digital. lo podremos hacer
 
#15
Aclara eso de basico , si es el que me imagino no creo que sea tan facil.
Me parece mas factible el que puso dosme.

Como quiera voy a ver que esta fallando no me gusta quedarme con la duda XD
 
#18
ya lo encontre el error creo XD

mira yo uso CCS pero es mas o menos lo mismo:

Código:
[COLOR="Red"]#include "C:\Documents and Settings\Jorge\Escritorio\Dimer\main.h"
int rcreg=10;
short ED;

#int_EXT                                          //Interrupcio RA2 externa
void EXT_isr() 
{
 set_timer0(rcreg);                            //Precarga del timer
 enable_interrupts(INT_TIMER0);        //Interrupcion TMR0 Habilitada
 if (ED==1){                             
  ext_int_edge( H_TO_L );ED=0;}         //Cambio de Flanco
 else{
  ext_int_edge( L_TO_H );ED=1;}
}

#int_TIMER0                       // Interrupcion del Timer0
void TIMER0_isr() 
{
 output_high(pin_C0);  // Gatillo
 delay_us(2);             // espero un poco de tiempo esto se checa en el Datasheet
 output_low(pin_C0); // desgatillo
 disable_interrupts(INT_TIMER0);  // desabilito interrupcion
}



void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32); //Checa si esta bien la division
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   setup_oscillator(False);
   ext_int_edge( H_TO_L );
   while(true);

}
mira el amarillo es el gatillo y el azul la frecuencia...

Dibujo.JPG

obviamente es simualdo pero la logica del programa creo que esta bien
 
Última edición:
#19
ok nomas dime que es ED?
if (ED==1){
por que yo uso la entrada RA2 o ya asi lo puedo copilar para el pic 16f690?



yo uso el mplab x ide necesitaría el .hex
 
Última edición:
#20
ED es la misma variable boolean que tu nombraste como edge.

asi quedaria en tu compilador

Código:
if(INTCONbits.T0IF==1) {  
 PORTCbits.RC0=1;
 delay_us(2); 
 PORTCbits.RC0=0;
 INTCONbits.T0IF=0;
 INTCONbits.T0IE=0;}
else if (PIR1bits.RCIF==1) {
 PIR1bits.RCIF=0; 
 BUFFER=RCREG;}
else if (INTCONbits.INTF==1) {
 INTCONbits.INTF=0; //limpiar vandera de interrupcion 
 TMR0=BUFFER;
 INTCONbits.T0IE=1; 
 edge=!edge;
 OPTION_REGbits.INTEDG=edge; //edge 1=rising,0=filling
}
si quieres compilalo y subes el hex para ver si lo hace igual que el mio.

pongo el hex sin cristal y sin el mclr



Sabes que me acabo de dar cuenta...

que no tienes definido el registro osccon y creo que tiene que llevar el valor 0x61 no?

que tonteria :LOL: si es eso del registro Osccon ponlo con 0x61, si usas el oscilador interno, y el delay_uS(2); aumentalo a unos 6, no encuentro el valor del pulso minimo en la ficha tecnica y no recuerdo de como cuanto debe ser.

Código:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <stdbool.h>
#define _XTAL_FREQ 4000000

#pragma config FOSC = INTRCIO  
#pragma config WDTE = OFF       
#pragma config PWRTE = ON      
#pragma config MCLRE = OFF      
#pragma config CP = OFF   
#pragma config CPD = OFF       
#pragma config BOREN = OFF     
#pragma config IESO = OFF       
#pragma config FCMEN = OFF     

unsigned char BUFFER=127;
bool edge=true;

void interrupt isr(void){
 if(INTCONbits.T0IF==1) {
  PORTCbits.RC0=1;
  __delay_us(6);
  PORTCbits.RC0=0;
  INTCONbits.T0IF=0;
  INTCONbits.T0IE=0;}
 else if (PIR1bits.RCIF==1) {
  PIR1bits.RCIF=0;
  BUFFER=RCREG;}
 else if (INTCONbits.INTF==1) {
  INTCONbits.INTF=0; 
  TMR0=BUFFER;
  INTCONbits.T0IE=1;
  edge=!edge;
  OPTION_REGbits.INTEDG=edge;}
}

void main(void) {
    INTCONbits.INTE=1;//ra2
    OPTION_REGbits.INTEDG=1;
    OPTION_REGbits.T0CS=0;
    OPTION_REGbits.PS0=0;
    OPTION_REGbits.PS1=0;
    OPTION_REGbits.PS2=1;
    OPTION_REGbits.PSA=0;
    ANSEL=0;
    ANSELH=0;
    TRISC=0;
    PORTC=0;
    TRISA=0b100;
    TXSTAbits.BRGH=1;
    SPBRG=25;
    RCSTAbits.CREN=1;
    TXSTAbits.SYNC=0;
    RCSTAbits.SPEN=1;
    PIE1bits.RCIE=1;
    INTCONbits.PEIE=1;
    INTCONbits.GIE=1;
    OSCCON=0x61;
   
    while(true);
       
    }
Dibujo.JPG
 
Última edición:

Temas similares

Arriba