sábado, 18 de maio de 2013

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte III

IMPORTANTE: como o segundo circuito abaixo taca gerando muita confusão, troquei-o para um desenho mais simples.

No primeiro post a respeito desse assunto, escrevi sobre a teoria por trás do controle de potência em corrente alternada. No segundo post, mostrei o circuito e o programa responsáveis pela indicação de zero na onda senóide de CA.

Agora vamos ver o circuito para controle de uma carga 110 ou 220V. Para fazer isso, usaremos um circuito baseado em TRIAC. O software que roda no Arduino conta com um mecanismo de interrupção semelhante ao descrito no outro post, que monitora a passagem por zero no ciclo. Dentro da rotina que é executada a cada zero, o sistema liga o TRIAC em instantes distintos, de acordo com tensão que deseja-se enviar à carga. O TRIAC se desliga sozinho na próxima passagem pelo zero.



Acima, fritzing dos dois circuitos, o de zero (esquerda) e o de controle (direita).

Lista de componentes:
CI MOC3020
TRIAC BTA12-600
CI H11AA1
Resistores de 180, 2,4k, 10k, 33k.
Capacitor de 0,01 uF, 400 V, de poliéster ou outro material. Não pode ser eletrolítico.

ATUALIZAÇÃO: esse CI, o H11AA1, funciona como um "sensor de zero de onda completa". Ele tem dois diodos, ligados em contraparalelo, que conseguem captar a passagem da corrente por zero nos dois sentidos. Aqui no datasheet vc pode ver como funciona.

Acontece que esse CI não é muito fácil de se achar. Como alternativa, segue abaixo outro circuito que usa como opto o 4N25 (pode ser usado tb o 4N35). Esse CI é mais fácil de ser encontrado (datasheet). Por outro lado, ele é de meia-onda, ou seja, para que vc monitore as duas passagens por zero de um ciclo é necessário o uso de uma ponte retificadora antes do 4N. Abaixo, esquema do circuito com o 4N35, incluindo a ponte. A ponte tb é bem fácil de ser encontrada, e é bem barata.


Nesse circuito, a saída que informa a passagem por zero é a Zerocrossing signal output, que deve ser conectada ao pino 2 digital do Arduino. Já a entrada do sinal de disparo do dimmer, dimmer signal in, deve ser conectada ao pino 4, para ficar compatível com o código abaixo. O circuito funcionará também para 110 V.

Esse LED que tem na entrada de sinal do dimmer pode ser excluído (nesse caso, claro, vc deve conectar a entrada direto no positivo da entrada do MOC). Se vc usá-lo e a sua lâmpada e/ou ele ficarem piscando, tire fora.

Na figura:

T1 - TRIAC TIC206 ou BR136 (ou algum outro equivalente)
BR1 - ponte retificadora 400V, ou então vc pode montar uma ponte com 4 1N4004 ou equivalentes. Dê um Google e vc acha como fazer uma, caso não ache a ponte pronta. Aqui tem algo sobre.


Agora, o código:

#define loadR 4    

volatile int power = 100;  

void zero_crosss_int()  
{
  // Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo)
  // (8333us - 8.33us) / 256 = 32 (aprox)
  int powertime = (32*(256-power));      
  // Mantém o circuito desligado por powertime microssegundos 
  delayMicroseconds(powertime);   
  // Envia sinal ao TRIAC para que ele passe a conduzir 
  digitalWrite(loadR, HIGH);  
  // Espera alguns microssegundos para que o TRIAC perceba o pulso
  delayMicroseconds(8.33);      
  // Desliga o pulso
  digitalWrite(loadR, LOW);   
}

void setup()
{
  Serial.begin(9600);
  pinMode(loadR, OUTPUT);
  // Inicializa interrupção. O número zero indica a porta 2 do Arduino,
  // zero_crosss_int é a função que será chamada toda vez que o pino 2
  // "subir" (RISING) de valor de 0 para 1.  
  attachInterrupt(0, zero_crosss_int, RISING);  
}

void loop()
{
  // Seta a potência para diferentes níveis. Se o sistema estiver conectado a uma lâmpada,
  // esta vai variar de brilho.
  power=10;
  delay(10000);
  power=60;
  delay(10000);
  power=120;
  delay(10000);
  power=180;
  delay(10000);
  power=240;
  delay(10000);
}




Abaixo, vídeo do circuito funcionando, onde vcs podem ver a variação da onda no osciloscópio, com a correspondente variação no brilho da lâmpada.




56 comentários:

  1. esse "Capacitor de 0,01uF" é eletrolitico? qual a tensão do mesmo?

    ResponderExcluir
    Respostas
    1. Cara, é de cerâmica. A tensão... não sei, porque comprei tem muito tempo, mas eu tenho impressão que uns 220V deve ser seguro. Vou tentar descobrir.

      Excluir
    2. apenas para constar, acredito que o capacitor seja poliester já que ceramica normalmente é baixa tensão (50 ou 100V) para segurança este capacitor deve ser de 400V para evitar problemas em 127/220V já que o projeto contempla as 2 cargas.

      Excluir
    3. Anônimo, esse foi de cerâmica mesmo. Mas vc tem toda razão, usar um capacitor de poliéster de 400V seria mais seguro.

      Excluir
  2. Ficou ótimo este "filminho" hein? Não tinha me mostrado.

    ResponderExcluir
    Respostas
    1. Pois é, curtinho e deu o recado. Gostei tb.

      Excluir
  3. Mauro, testei o seu sketch mas estou tendo um problema, fiz a seguinte alterações no loop principal:
    void loop()
    {
    for (int i=0; i < 100; i++){
    power=i;
    delay(50);
    }
    for (int i=100; i > 1; i--){
    power=i;
    delay(50);
    }
    }

    e na interrupção:
    int auxpower = map(power, 0, 100, 0, 255);
    int powertime = (32*(256-auxpower));
    ...

    O estranho é que a lampada vai aumentando o brilho começando com 0% até chegar no 100% ai ele apaga a lampada por +-1segundo e volta com 100% e começa a diminuir até 0%.... alguma dica?

    ResponderExcluir
    Respostas
    1. acredito que o problema seja alguma margem de erro na conta... alterei a linea:
      int auxpower = map(power, 0, 100, 0, 255);

      para:
      int auxpower = map(power, 0, 100, 0, 241);

      ficou funcionando legal

      Excluir
  4. Achei muito bom, quero montar esse projeto tem como voce disponibilizar caracteristicas dos componentes? Ficou muito bom quero acompanhar novos post.

    ResponderExcluir
    Respostas
    1. Anônimo, os componentes estão descritos acima. Você pode melhorar o capacitor para um de poliéster de 400 V, 0,01 uF.

      Excluir
  5. Duvuda: Nesse circuito, posso usar o 4N25 (Mesmo do post 2) para o sensor de 0... E o MOC3021 no lugar do 3020? Pergunto pois tenho dificuldade de comprar componentes aqui na regiao. E esses citados ja ta na mao...

    Abraços

    ResponderExcluir
    Respostas
    1. Tiago, desculpe-me pela demora na resposta: pode sim, usar o o MOC3021, sem problemas, assim como o 4N25.

      Excluir
  6. Desculpem pela duvida, mas sou iniciante em tudo.

    Eu estava estudando o codigo e nessa parte;

    power=240;

    aqui seria 240 volts? Ai no meu caso que a rede é 110 eu colocaria 110?

    Obrigado

    ResponderExcluir
    Respostas
    1. Eduardo,

      Não, o power aí não tem a ver com volts. É que eu resolvi que quando power = 0 a potência é mínima e quando power é 240 a potência é máxima. Esse valor foi arbitrado, e é condizente com os cálculos dentro da função zero_crosss_int(). Tem a ver com o tempo que o sistema "corta" da onda.

      Ou seja, para 110 V vc deve manter o valor em 240.

      E, como vc é iniciante, não custa recomendar: CUIDADO, monte o circuito com muita atenção, para evitar acidentes. Se possível, peça ajuda de alguém mais experiente.

      Excluir
  7. Ok, obrigado e lá vai mais uma duvida.

    No tutorial, diz que tem 2 circuitos dos dois circuitos, o de zero (esquerda) e o de controle (direita) terei que montar os dois com um ARDUINO para cada? OUTRA COISA, ( E JA QUE ESTOU AQUI, VAMOS RESOLVER TUDO NÉ.)

    O FRIZING ABRIU TODOS OS COMPONENTES estão fora da protoboard, e eu ate baixei a versão atual do Frizing, mas mesmo assim o problema persiste, você tem alguma ideia de como resolver ?

    ResponderExcluir
  8. POXA, QUE MANCADA, hoje que fui rever o codigo, vi que fiz uma pergunta besta pra ti,esta evidente ali a ordem crescente. Mas ontém eu estava devagar demais. Desculpa.

    ResponderExcluir
  9. Oi Mauro tudo bem?

    Tenho um projeto em que estou trabalhando com a ajuda de varios pessoas, pois o meu conhecimento deixa a desejar.

    E lendo sobre o PID pensei se eu não poderia implementa-lo o meu projeto.

    O PROJETO

    Preciso desenvolver um projeto. Em que um tecido seco é colocado num suporte, ai um sistema de uma balança registra esse peso, e quando esse mesmo tecido for colocado de novo, úmido, ou molhado, o programa identifica a diferença e aciona a secagem, que será feita através de resistências de fio crome de 350w. ate que o peso volte a ser do tecido seco.
    Não acho que o sistema irá conseguir levar a secagem aos mesmos números do tecido seco, acho que alguma parte ficará ao menos um pouco úmida, e ai o peso não será o mesmo, e os dados serão diferentes do inicio, dai acho que precisarei fazer ajustes no programa aqui e regrava-lo, em PIC ( ser for PIC, precisarei de um gravador ) ou no ARDUINO.

    JA TENHO UM PROGRAMA QUE UM AMIGO FE PRA MIM, MAS PERGUNTO A TI SE NÃO SERIA MAIS EFICIENTE, IMPLEMENTAR O PID.

    ABRAÇO

    ResponderExcluir
    Respostas
    1. Olha, se vc implementar o controle por fase, como descrito no blog, seu projeto vai ficar bem mais eficiente. Aí sim, vc ganhará muito com o PID. Se vc for fazer um controle somente liga/desliga aí o PID pode ser utilizado, mas o ganho é menor (e o controle do seu projeto também).
      Outra dica: vá de Arduino que é mais poderoso, mais fácil e mais barato.

      Excluir
  10. Oi Mauro, muito obrigado, me ajudando, você estará ajudando ao pais, pois a nossa empresa que surgirá, ira destinar metade do lucro para o bem, alem de nascer com a ideia da qualidade em primeiro lugar. E preços baixos em segundo.

    Aquele Código que foi colocado lá, funcionaria para o que eu quero?

    OU esse abaixo do Tiago Struck.

    NÃO QUERO ABUSAR DA SUA BOA VONTADE, mas sei pouco de programação também, estou estudando.

    Valeu Euclides, na verdade era outra coisa...
    depois que eu coloquei: digitalWrite(2, LOW); no setup passou a funcionar...
    Já fiz o dimmer funcionar... por questões de achar exagero 10 Dimmers, baixei o numero para 6, então meu código ficou assim:
    //Sliders
    #define S1 3
    #define S2 5
    #define S3 6
    #define S4 7
    #define S5 8
    #define S6 9
    volatile int valorS1 = 0; + inf INF 2 - IMPORTANTE
    volatile int valorS2 = 0;
    volatile int valorS3 = 0;
    volatile int valorS4 = 0;
    volatile int valorS5 = 0;
    volatile int valorS6 = 0;
    void setup(){
    //Seta como LOW Pino para AttachInterrupt Dimmer - Sensor de zero.

    digitalWrite(2, LOW);
    //Seta Pinos Sliders OUTPUT
    pinMode(S1, OUTPUT);
    pinMode(S2, OUTPUT);
    pinMode(S3, OUTPUT);
    pinMode(S4, OUTPUT);
    pinMode(S5, OUTPUT);
    pinMode(S6, OUTPUT);
    //Seta Pinos Sliders como LOW
    digitalWrite(S1, LOW);
    digitalWrite(S2, LOW);
    digitalWrite(S3, LOW);
    digitalWrite(S4, LOW);
    digitalWrite(S5, LOW);
    digitalWrite(S6, LOW);
    AttachInterrupt (0, zero_crosss_int, RISING);
    }
    void zero_crosss_int() {
    // Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo)
    // (8333us - 8.33us) / 256 = 32 (aprox)
    if (valorS1 > 0){
    int powertimeS1 = (32*(256-valorS1)); * (multiplicação)
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertimeS1);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(S1, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(S1, LOW);
    }

    if (valorS2 > 0){
    int powertimeS2 = (32*(256-valorS2));
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertimeS2);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(S2, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(S2, LOW);
    }

    if (valorS3 > 0){
    int powertimeS3 = (32*(256-valorS3));
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertimeS3);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(S3, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(S3, LOW);
    }

    if (valorS4 > 0){
    int powertimeS4 = (32*(256-valorS4));
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertimeS4);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(S4, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(S4, LOW);
    }

    if (valorS5 > 0){
    int powertimeS5 = (32*(256-valorS5));
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertimeS5);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(S5, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(S5, LOW);
    }

    if (valorS6 > 0){
    int powertimeS6 = (32*(256-valorS6));
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertimeS6);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(S6, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(S6, LOW);
    }
    }
    Daí no loop é só receber os valores para as variaveis valorS1, valorS2 e etc...

    ABRAÇO

    ResponderExcluir
    Respostas
    1. Eduardo, esse código não vai funcionar. Na verdade o que vc quer fazer é bem enrolado, eu andei pensando sobre isso. Acho que para fazer funcionar eu teria que montar o circuito e testar umas ideias.
      Posso fazer para vc, mas como um trabalho remunerado. Não cobro caro.

      Excluir
    2. Tenho um codigo aqui, mas não é para PID. a duvida é, será que com PID, será melhor que com esse codigo abaixo?

      NÃO FUI EU QUEM O FEZ. ABRAÇO

      peso= ModelagemDeDados(1); para peso= ModelagemDeDados(x);
      onde x vai ser a Ax
      float peso;
      float seca;
      int led = 13;// saida digital pra acionar resistência

      /*
      filtro de dados le 100 vezes o peso e faz a media para um maior precisão
      */
      float ModelagemDeDados(int x) // x= numero do pino analógico
      {
      int leituras[100],i,j,aux,a,q1,q3,TotalDeElementos=100;
      float MenorOutlier,MaiorOutlier,soma=0;
      for (i=0;i<100;i++) //um segundo de leituras
      {
      leituras[i]=analogRead(x);
      delay(10);
      }
      //Ordenação do vetor por bubble sort

      for(j=100-1;j>=1;j--)
      {
      for(i=0;ileituras[i+1])
      {
      aux=leituras[i];
      leituras[i]=leituras[i+1];
      leituras[i+1]=aux;
      }
      }
      }
      //Calculo de Amplitude e Outliers utilizando técnicas de modelagem de entrada de dados
      q1=leituras[24];
      q3=leituras[74];
      a=q3-q1;
      MenorOutlier=q1-1.5*a;
      MaiorOutlier=q3+1.5*a;
      //Retirando os outiliers (Leituras fora de padrão)
      for(i=0;i<100;i++)
      {

      if((float)leituras[i]MaiorOutlier)
      {
      leituras[i]=0;
      TotalDeElementos--;
      }
      }
      //Media das leituras retirando as leituras foda do padrão
      for(i=0;i<100;i++)
      {
      soma=soma+leituras[i];
      }
      return (soma/TotalDeElementos); //Valor ainda não convertido em ºC
      }

      void setup() {
      // initialize serial communications at 9600 bps:
      Serial.begin(9600);
      pinMode(led, OUTPUT);
      }
      void loop() {
      Serial.println("coloque a roupa SECA na balanca " );


      while(peso<2) { // monitora se tem algo na balança se sim vai em frente
      peso= ModelagemDeDados(1);
      delay(1000);
      }
      delay(2000);
      peso= ModelagemDeDados(1);
      if (peso>3){ // le o valor da roupa seca e memoriza em seca
      seca= peso;
      Serial.print("seca = " );
      Serial.println(seca );
      Serial.println("Retire a roupa da balanca " );
      }

      while (peso>3){// monitora se tem algo na balança se nao espera
      peso= ModelagemDeDados(1);
      delay(1000);
      }
      Serial.println("coloque a roupa umida na balanca " );
      while(peso<2) {// monitora se tem algo na balança se sim vai em frente
      peso= ModelagemDeDados(1);
      delay(1000);
      }
      while(pesoseca+2){// compara o valor da roupa umida com a seca mais uma tolerancia no caso 2
      digitalWrite(led,HIGH);
      peso= ModelagemDeDados(1);
      Serial.println("secando " );
      delay(1000);
      }

      digitalWrite(led,LOW);

      Serial.println("Roupa seca retire a roupa " );
      // Serial.print(peso);
      // Serial.println();
      delay(1000);
      while (peso>3){// monitora se tem algo na balança se nao vai em frente
      peso= ModelagemDeDados(1);
      delay(1000)

      Excluir
    3. Eduardo, esse seu código é de monitoramento, PID é controle, ou seja, PID não agrega ao seu algoritmo. O cara usa uns filtros (o código tá um pouco confuso), certamente dá para melhorar.

      Excluir
  11. Oi Mauro,

    Bom Dia, obrigado por responder-me.
    Fico feliz de saber que você pode fazer, e que cobra barato, mas eu tive a oportunidade de pagar para um engenheiro fazer isso pra mim, e deixar tudo prontinho, a uns 4 meses atrás, mas ai sonhei que eu poderia fazer. Como que quero apreender a fazer resolvi encarar o desafio.

    Mas quero sim guardar o seu fone para necessidades futuras, e talvez, lhe contrate, mas ai eu gostaria de apreender junto.
    Ou, você aceitaria me dar aulas particulares sobre PID? Faríamos o programa para esse meu projeto e ao mesmo tempo eu apreenderia a fazer?
    Você poderia cobrar por hora, ou pelo projeto todo.

    Poderíamos gravar a tela do PC a elaboração do programa e as suas explicações, + as minhas perguntas, eu ficaria com esse vídeo para rever, pois esqueço fácil.

    Você mora em sampa?

    Abraço

    Eduardo

    ResponderExcluir
    Respostas
    1. Eduardo,

      Eu moro em São José dos Campos, então tá fácil.
      Podemos combinar de vc vir para cá e fazemos o treinamento e ainda matamos o seu projeto.
      O ideal seria dia de semana ou num domingo.
      Meu e-mail é assismauro@hotmail.com. Podemos conversar por lá.

      Excluir
  12. Você aceita assinar um contrato de sigilo?

    Vou te enviar um e-mail, acho melhor.

    abraço

    ResponderExcluir
  13. Mauro,

    Este circuito consegue controlar até que potência?
    Como tu menciona o chuveiro elétrico, acredito que ele suporte tranquilo até uns 5000 W, não?

    Abraço!

    ResponderExcluir
  14. Boa noite.

    Meu caro, andei estudando todo seu projeto, ele sera de grande utilizado para o projeto que estou implementando.

    estava construindo o Zero Crossing de outra forma... e ... essa é bem mais simples e pratica.

    No meu caso não estou usando arduino,(isso não difere em nada).. mas a duvida é a seguinte, como filtro vc utilizou um capacitor no 1º Circuito utilizando um CIH1AA... para o segundo circuito (que é o que utilizarei) não tenho a certeza da necessidade de um filtro... sei que é possível mas não quero ir na tentativa e erro, preciso ser mais preciso.

    desde-ja obrigado.

    ResponderExcluir
    Respostas
    1. Rodrigo,

      Ótimo que esse post sirva para vc, assim como tem servido para muita gente.
      Eu temo que nesse caso do capacitor só experimentando, mas eu coloquei porque achei realmente necessário.

      Excluir
  15. Mauro,

    Meu nome é Gilberto, estou desenvolvendo um controle para controlar a potencia de um chuveiro 110V. estou usando como base esse artigo. Nao estou conseguindo fazer rodar. inicialmente ligamos uma lampada em vez do chuveiro para testar. Montamos o circuito de acordo como vc mostra no artigo. compilamos para o arduíno o código que vc mostrou acima. Nao esta funcionado. O led antes do moc nao acende. tem muito pouco tensão chegando nele. Poderia nos ajudar??
    outra coisa, o que essas linhas de programação deveriam fazer com a lampada???

    Fico aguardando seu retorno.
    Atenciosamente.
    Gilberto

    ResponderExcluir
    Respostas
    1. Gilberto,
      Vc terá que checar as tensões nos diversos pontos do circuito e comparar com os valores esperados (que vc pode determinar pelo entendimento do circuito).
      O programa desse post faz com que a lâmpada varie o brilho de 10 em 10 segundos.

      Excluir
    2. Mauro
      Depois de muito esforço funcionou. Queremos agradecer sua ajuda e te parabenizar pelo trabalho. Só uma observação, a primeira imagem esta faltando a ligação do pino 2 do moc, que é ligado no terra e a segunda imagem que é a que nós estávamos usando para ligar os componentes (aquele que tem a ponte retificadora) não funciona, ele está montado errado, foi por isso que patinamos mais de 2 meses ..rss..
      Vamos partir agora para a segunda parte do nosso projeto, sempre mais díficil..
      Abraço!!
      Gilberto.

      Excluir
    3. Gilberto,

      Por favor, me conta o que está errado, aí conserto e pronto.
      E que bom que resolveu, anyway,
      Abracadabraço,
      Mauro

      Excluir
    4. Olá, Mauro. Primeiramente parabéns pela iniciativa, me ajudando bastante =). Estou montando o segundo circuito e ele se apresenta do mesmo modo que o Gilberto falou. Já sabe o que está montado errado?

      Excluir
    5. Andouglas, atualizei o projeto do circuito colocando um desenho muito mais simples. Por favor, use esse novo esquema e, por favor, me atualize sobre os resultados.

      Abracadabraço,

      Mauro

      Excluir
    6. Olá Mauro, funcionou. Acredito que era a parte do LED mesmo, quando tirei e liguei direto foi que deu certo. =) Outra coisa. não sei se tem muito sentido, mas no outro desenho, a resistência que ligava a entrada 220/110, se eu não estou enganado, era de 90k e agora é de 30k. Obrigado mais uma vez =).

      Excluir
  16. Eu poderia usar um capacitor de 0,01 uf 630 V ?? O QUE MUDARIA?

    ResponderExcluir
    Respostas
    1. Desde que não seja eletrolítico, pode sim. A tensão indicada é a máxima suportada, então quanto maior melhor.

      Excluir
  17. kra, legal... mais um post seu q me serviu... vlws...

    ResponderExcluir
    Respostas
    1. Uai, Vincent, que bom... tomara que venham mais!

      Excluir
  18. Olá Mauro,
    Inicialmente te agradeço por ter compartilhado este projeto. Muito interessante.
    Tentei fazer este mesmo projeto, mas não funcionou. Queria tirar algumas dúvidas:

    1 - No circuito, fiquei com dúvida no contato direto que existe entre a carga e a rede. Como a corrente é alternada, no semiciclo positivo a corrente passa pelo circuito, já no negativo ela vai direto à carga. Tá correto isso?

    2 - Eu estou utilizando o Aruino Leonardo. A única alteração que fiz foi no código, na linha:
    attachInterrupt(0, zero_crosss_int, RISING);
    que substitui por:
    attachInterrupt(1, zero_crosss_int, RISING);
    Fiz isso baseado nessa tabela (http://arduino.cc/en/Reference/attachInterrupt). Será que é necessário fazer mais alguma alteração pra que funcione com o Leonardo?

    Abraço.

    ResponderExcluir
    Respostas
    1. Boa tarde Mauro,
      Funcionou!
      O meu circuito estava com uma ligação errada. Nada que uma boa revisão não corrija...hehe :-)
      Obrigado por ter compartilhado este projeto.
      Abraço.

      Excluir
    2. Michel,

      Que bom que funcionou. Eu ainda não tinha nem visto seu comentário...
      Só uma sugestão: da próxima confira bem antes de montar, pq esses circuitos "alta tensão" podem causar estrago...

      Divirta-se com seu brinquedo.

      Abracadabraço,

      Mauro

      Excluir
  19. Mauro estou com uma duvida. Para um sistema trifásico onde eu gostaria de controlar as três fases. Bastaria eu repetir o circuito para controle 3 vezes e na programação eu fazer a declaração dos pinos a mais? Estou querendo fazer um projeto para o meu TCC para controlar a partida de um motor AC trifásico. Obrigado!!

    ResponderExcluir
  20. Prezado Mauro,
    Fiz vários teste com este post, inclusive aquela ideia de colocar um sensor digital DHT22 (preciso mais demora 2 segundos para ler) com um contador... mas não ficou legal então voltei para o lm35 mesmo.
    O prejeto esta funcionando legal, porem quando o pid esta atuando em um valor de power > 10 e menor 240, ou seja, enquanto a lâmpada esta piscando (sendo ela no caso minha carga/resistência) o arduino parece que fica travado no processo, inclusive coloque no fim do loop o seguinte código:

    digitalWrite(led, HIGH); (porta 13) do arduino
    delay(200);
    digitalWrite(led, LOW);

    e percebi que o led não pisca ou pisca atrasado enquanto a lâmpada esta tentando aquecer o lm35. Então pergunto: Será que o pid esta consumindo todo o processo aponto de não ser possível fazer outra coisa? pois o lcd que implementei também atrasa para mostrar os valores.
    Tem alguma ideia ou sugestão para não interromper o processo enquanto o pid atual?

    Paulo

    ResponderExcluir
    Respostas
    1. Paulo,

      Vc deve "abandonar" o pedaço em que a lâmpada fica piscando. Nesse pedaço da onda o circuito não é funcional. Ou seja, vc só deve atuar quando os valores estiverem entre 10 e 240, mantendo a atuação como 0 e 255 quando os valores estiverem <=10 e >=240, respectivamente.

      Quanto ao atraso: ele realmente ocorre, mas sim por causa da função zero_cross_int. Durante a execução dela o Arduino literalmente para, ou seja, nem o contador de tempo é atualizado. Assim, se vc usar funções como delay elas vão sofrer distorções, ou seja, o tempo vai "passar mais devagar" dependendo do tempo que o programa estiver demorando dentro da zero_cross_int, que por sua vez é função do valor de power.

      A solução? Depende do que vc quiser faze. Se o problema for ter por exemplo uma contagem de tempo precisa, vc pode usar um relógio de tempo real. Nesse caso, vc "perguntaria" o intervalo de tempo prá ele e mostraria o valor correto.

      Excluir
  21. Não estou conseguindo fazer rodar o sketch do circuito com a ponte retificadora, o que devo fazer??

    ResponderExcluir
    Respostas
    1. Rogério,

      Por favor, seja mais específico, para que eu possa ajudá-lo.

      [],

      Mauro

      Excluir
    2. Bem, eu montei o circuito com a ponte retificadora, copiei o sketch acima e fiz o upload, até ai tudo ok. O problema é quando coloco no serial monitor e tento fazer com que o programa rode, não acontece nada. não liga e nem varia o brilho da lâmpada.

      Excluir
  22. Rogéiro,

    Qual dos dois circuitos vc montou?
    De toda forma, na realidade são dois circuitos, certo? O de detecção de zero e o de controle. O de detecção por zero tá funcionando? Para testá-lo rode o programa do post que fala do assunto.

    Se ele funcionar, me avise e eu bolo um jeito de analisar como verificar o circuito. Se não funcionar, aí vc tem que ver o que está errado, mas essa parte é muito simples de analisar.

    ResponderExcluir
  23. Estou usando o circuito com o 4N25 e a programação é:

    #define loadR 4

    volatile int power = 100;

    void zero_crosss_int()
    {
    // Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo)
    // (8333us - 8.33us) / 256 = 32 (aprox)
    int powertime = (32*(256-power));
    // Mantém o circuito desligado por powertime microssegundos
    delayMicroseconds(powertime);
    // Envia sinal ao TRIAC para que ele passe a conduzir
    digitalWrite(loadR, HIGH);
    // Espera alguns microssegundos para que o TRIAC perceba o pulso
    delayMicroseconds(8.33);
    // Desliga o pulso
    digitalWrite(loadR, LOW);
    }

    void setup()
    {
    Serial.begin(9600);
    pinMode(loadR, OUTPUT);
    // Inicializa interrupção. O número zero indica a porta 2 do Arduino,
    // zero_crosss_int é a função que será chamada toda vez que o pino 2
    // "subir" (RISING) de valor de 0 para 1.
    attachInterrupt(0, zero_crosss_int, RISING);
    }

    void loop()
    {
    // Seta a potência para diferentes níveis. Se o sistema estiver conectado a uma lâmpada,
    // esta vai variar de brilho.
    power=10;
    delay(10000);
    power=60;
    delay(10000);
    power=120;
    delay(10000);
    power=180;
    delay(10000);
    power=240;
    delay(10000);
    }

    ResponderExcluir
    Respostas
    1. Ok. Então rode o programa do post anterior e veja se funciona. Se não funcionar, o problema é nessa parte do circuito (detecção de zero). Se funcionar, o problema é no resto, aí a gente vê.

      Excluir
  24. Bem montei o circuito que usa o CI H11AA1, e rodei o sketch para contar os pulsos, só que o serial monitor só mostra o resultado 0 infinitamente.

    ResponderExcluir
    Respostas
    1. Rogério,

      Eu não sei o que pode estar errado. Esse circuito é bem simples, né?

      [],

      Mauro

      Excluir
  25. Sim, só que não esta registrando os 120 de pulso que deveria mostrar no serial monitor.

    ResponderExcluir