Fork me on GitHub

11/01/13

Projeto 22: Dimmer utilizando PIC

Dimmer com PIC


Dimmers são dispositivos utilizados para variar a intensidade de uma tensão elétrica média em uma carga.

VERSÃO COM PIC16F628A

VERSÃO COM PIC16F877A E POTENCIÔMETRO


Principio de Funcionamento: O circuito de detecção de passagem por zero ou Zero Crossing Detector, é um circuito que produz um pulso positivo de curta duração, quando o sinal senoidal de entrada passar pelo seu ponto de 0V. Esse sinal vai para o pino RB0/INT, gerando uma interrupção externa. Para cada interrpção gerada, também é gerado um pulso, com um atraso controlado, na saída do pino RB3. Esse pulso (pulso de trigger) irá disparar o TRIAC.

Na versão com PIC16F877A utilizou-se um potenciômetro para variar a tensão. Já na versão com PIC16F628A, foi utilizado dois botões.

No PIC16F628A, utilizou-se o próprio oscilador interno de 4Mhz.

Pulso de disparo

Forma de Onda( AZUL: pulso de trigger; AMARELO: Sinal de Entrada; VERMELHO: Sinal Seifado pelo Triac)



DOWNLOAD:

Versão com PIC16F628A
Firmware: Dimmer.hex;
Arquivo de simulação do Proteus: dimmer.DSN;


Versão com PIC16F877A

Firmware: DimmerV2.hex;
Arquivo de simulação do Proteus: dimmerV2.DSN;


CÓDIGO-FONTE:

PIC16F628A
unsigned short nivel;
bit oldstate, oldstate1;
unsigned short i;

void main()
{
 TRISB=0b00000111;//pino rb0,rb1,rb2 entradas e rb3 saida
 oldstate=0;
 oldstate1=0;
 nivel=1;

 while(1)
{
  //A cada passagem por zero
  if(INTCON.INTF)
  {
  //atraso controlado
  for(i=0;i<nivel;i++)
  {
   delay_us(100);
  }
  //pulso de trigger
  PORTB.F3=1;
  delay_us(100);
  PORTB.F3=0;
  INTCON.INTF=0;
  }

//Botao pra diminuir a tensao
  if(PORTB.F1)  oldstate=1;
  if(!PORTB.F1 && oldstate)
  {
     nivel++;
     if(nivel>70) nivel=1;
     oldstate=0;
  }


//Botao pra aumentar a tensao
  if(PORTB.F2)  oldstate1=1;
  if(!PORTB.F2 && oldstate1)
  {
     nivel--;
     if(nivel < 1) nivel = 70;
     oldstate = 0;
  }
}
}
PIC16F877A
unsigned nivel,i;

void main()
{
 TRISB=0b00000011;
 nivel=1;

 while(1)
{
 if(INTCON.INTF)
 {
  for(i=0;i<nivel;i++)
  {
   delay_us(100);
  }
  PORTB.F3=1;
  delay_us(100);
  PORTB.F3=0;
  INTCON.INTF=0;
  }
 
 nivel = ADC_Read(0);
 nivel = (20 * nivel) / 290;

 }
}

31 comentários:

  1. Não estou conseguindo adaptar para o 12F675. Pode me ajudar? Segue o código feito no MikroC.

    int nivel,i;

    void main(){

    TRISIO = 0b00101111;
    ANSEL = 0b00000001;
    CMCON = 0x07;
    GPIO = 0;
    nivel=1;



    while(1){

    if(INTCON.INTF){
    for(i=0;i<nivel;i++){
    Delay_us(100);
    }
    GPIO.F1=1;
    Delay_us(100);
    GPIO.F1=0;
    INTCON.INTF=0;
    }

    nivel = ADC_Read(0);
    nivel = (20 * nivel) / 290;
    }

    }

    GP0 - DIV RES - POTENCIOMETRO
    GP1 - SAIDA TRIAC
    GP2/INT - PULSO PASS. ZERO
    GP3 - NC
    GP4 - NC
    GP5 - NC
    Clock Interno 4Mhz


    Obrigado.
    Patrick Ramos

    ResponderExcluir
  2. Veja que vc definiu GP1 como saida, mas no codigo está como entrada(TRISIO = 0b00101111); O certo é 0b00101101;

    ResponderExcluir
    Respostas
    1. Obrigado Tiago, eu corrigi, mas ainda nada de rodar.. Já fiz de tudo, não acho onde estou errando.. =/

      Excluir
    2. Você está simulando no Proteus?
      Porque eu utilizei esse mesmo codigo, e a simulação funcionou perfeito!!!

      Excluir
  3. Sim, proteus. Você simulou com meu código no 12F675? Com o F877 eu tbm testei e tá tudo beleza, o negocio está sendo comigo mesmo.. hehehe

    ResponderExcluir
  4. Era algum problema com o compilador. Depois de reinstalar foi resolvido. Estranho, pq com o 877 funcionou..

    ResponderExcluir
  5. Tem algum jeito de colocar outro botão para fazer a simulação reversa. Por exemplo: A intensidade está baixando e eu aperto o outro botão e ela começa a aumentar.

    ResponderExcluir
    Respostas
    1. Alterei o código, coloquei um outro botão ligado ao pino RB2!

      Excluir
  6. Tiago... teria como você colocar o codigo em c para que eu consiga compilar no ccs? Obrigado

    ResponderExcluir
  7. Pessoal... troquei o Potenciometro por um LM35... para fazer a variação da luminosidade da lampada com o aumento da temperatura... segue abaixo o codigo:

    #define use_portd_lcd true
    #include
    #use rs232(baud = 9600, parity = N, xmit = PIN_C6, rcv = PIN_C7, bits = 8)

    int x;
    float i;
    float transf;
    float temperatura, tensao_real, sensor;
    void trata_interrupcao(void);

    #int_EXT
    void EXT_isr(void)
    {
    x = 1;
    trata_interrupcao();

    }

    void trata_interrupcao()
    {

    if(x == 1)
    {
    // for(i = 0 ; i < transf; i = i + 0.3819)
    for(i = 0 ; i < transf; i = i + 0.31)
    {
    x = 0;
    delay_us(100);
    }
    x = 0;
    output_low(pin_B3);
    delay_us(30);
    output_high(pin_B3);
    delay_us(30);
    output_low(pin_B3);

    }
    i = 0;
    }

    void main()
    {

    setup_adc_ports(AN0);
    setup_adc(ADC_CLOCK_INTERNAL);
    setup_psp(PSP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DIV_BY_16,255,1);
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);

    ext_int_edge(H_TO_L);

    set_adc_channel(0);

    lcd_init();


    while(true)
    {
    sensor = (float)(read_adc()); // Leitura do sensor
    //delay_ms(10);

    //Calculo para LM35
    tensao_real = (5000.0/1024.0)*(sensor); //10 bits (5v / pela resolução)
    temperatura = (tensao_real)/(10);

    printf(lcd_putc, "\f Tensao= %f \n Temp.= %f", tensao_real, temperatura);
    delay_ms(100);

    //transf = (float)(0.065*(temperatura) + 0.3819);
    //transf = (float)(0.120*(temperatura) + 0.3819); ok!
    transf = (float)(0.120*(temperatura) + 0.31);

    printf("%2.1f\r", (float)temperatura);
    delay_ms (100); // Dá um tempinho

    }
    }

    Estou usando o PIC 16F877A com cristal de 16 MHz...
    O problema quando eu conecto o fio que sai do transistor para ligar na interrupção externa a lampada apaga... e se eu tiro esse fio funciona normalmente... o estranho ainda que a simulação no proteus ocorre perfeitamente.

    Ja tentei trocar o delay por um delay utilizando o timer 2... e nada...

    Valeu pela akjuda

    ResponderExcluir
  8. Olá! Colega, estou me matando mas não consigo fazer esses circuitos de dimmer funcionar. Já tenho o circuito montado em protoboard. quando tento gravar seu programa (16F877A), dá erro nos fuses. Por favor, você poderia postar um circuito de dimmer que rodasse no CCS, completo, desde os #define. Por favor, me ajude. Não é preguiça. Já tentei por várias semanas fazer esse dimmer, mas está faltando um empurrãozinho para coisa andar. Obrigado!

    ResponderExcluir
  9. Olá, Estou tentando utilizar o arquivo acima do 877, no meu compilador e não estou conseguindo.
    Você poderia me enviar o arquivo em "C" para rodar no PCW?
    Obrigado.

    ResponderExcluir
  10. GOstaria de saber o motivo de ter o delay de 100us no programa... na parte do atraso controlado.

    Não precisaria ter algum tempo relacionado com a senoide? 8.3ms por ex... ?


    Att.

    ResponderExcluir
  11. Preciso saber também o motivo de quando o brilho está baixo, a lampada fica oscilando bastante..
    tentei usar capacitores na entrada do AD, mas não está resolvendo...

    ResponderExcluir
  12. Ola pessoal como eu posso gerar um sinal triangular e senoidal mediante linguagem c.
    A ideia e um gerador de sinal, como eu posso matematicamente fazer uma função capaz de gerar um grafico

    ResponderExcluir
  13. Olá tem como me passar o PC817?? agradeço desde ja! rafaelmmoraes91@gmail.com

    ResponderExcluir
  14. Projeto muito bom parabéns, já fiz algo parecido com o Arduíno + Processing variando a intensidade com o mouse.
    http://bragamarcos.blogspot.com.br/2013/12/controle-de-angulo-de-disparo.html

    ResponderExcluir
  15. Boa noite. Esses dois GND no U2-PC817 pino 1 e 3 são ambos alternados VCA? Ou somente no pino 1, sendo o pino 3 contínuo VCC? Grato.

    ResponderExcluir
  16. Bom dia. Alguém pode dar dica (não precisa do programa) de como eu possa fazer uma rampa de aceleração e desaceleração (carga indutiva), pois se coloco valores e espero delay, o programa para ali. Grato.

    ResponderExcluir
  17. Em um programa estruturado, sem RTOS, a sequencia de instruções não pode ficar parada em uma função (como delays), e sim verifica-la de tempo em tempo, através de interrupções... Como no programa acima... Assim, por exemplo, a cada 1 ms que entra na interrupção, o Código verifica o andamento do processo daquela função para verificar se o processo já acabou ou não, retornando a interrupção, e tomando suas devidas providencias.... Assim o microcontrolador poderá efetuar diversas funções ao mesmo tempo...
    ***************** esquemas.org - ordemferme.org ********************************

    ResponderExcluir
  18. preciso adaptar para o 18f4550, algéum poderia me ajudar, não estou conseguindo

    ResponderExcluir
  19. Parabéns pelo blog e pelo ótimo trabalho !
    Só tenho uma duvida, porque você multiplica a variavel nivel por 20 e divide por 290 ?
    Grato

    ResponderExcluir
    Respostas
    1. Olá, muito obrigado.
      É por causa do delay de no máximo 7000ms ( 70 * 100 ). Multplicando a variavel por 20 e dividindo por 290 faz com que varie de 0 até 70.
      Abraços.

      Excluir
    2. Cara eu estou utilizando um cristal de 4MHz, o que você me sugere para que funcione corretamente, desde já muito obrigado !
      Abraços.

      Excluir
  20. Olá tudo bem ?
    Estou fazendo um projeto de controlador de temperatura e preciso de uma ajuda pois não estou entendendo a parte de programação em relação ai TRIAC,eu vou usar o lm35 para a medição da temperatura e vou visualizar os valores das saídas no display.
    Estou com dificuldade nessa parte do TRIAC poderia me ajudar ?

    Desde ja obrigado !

    ResponderExcluir
  21. Não pode acionar um TRIAC sem o uso de um optoacoplador, neste caso pode ser usado um MOC3010 que tem DIAC

    ResponderExcluir
  22. O transistor Q1 é usado apenas pra inverter a fase do sinal dos optos? Obrigado

    ResponderExcluir

Postagens Relacionadas!!