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

Nesse último artigo da nossa série sobre PID, vamos estudar um caso prático de uso dessa técnica em um sistema de controle. Os outros posts podem ser lidos em:

Controle de Pot. em CA - PID, Arduino e TRIAC - Parte I
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte II
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte III
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte IV
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte V

Como é comum nessa plataforma tão versátil que é o Arduino, existe uma biblioteca pronta para quem quer implementar controles baseados em PID. Essa biblioteca é a PID Library. Ela nos livra do trabalho de calcular a função PID, todo o cálculo já está implementado "dentro" do objeto PID definido. O cálculo não é complicado, quem tiver lido e entendido esses posts que fiz e quiser dar uma espiadinha no arquivo PID_v1.cpp vai entender perfeitamente a implementação. O jeito de usar é simples, tb. De posse dos valores de KpKi e Kd, vc tem que começar um fonte do Arduino assim:

#include "PID_v1.h"
 
// Carga (pino onde será aplicado o output)
#define loadR 3    
 
// Constantes do PID
#define kp 50
#define ki 10
#define kd  0
 
// Variáveis do PID: a nomenclatura é a mesma descrita no post III
double SetPoint, PresentValue, ManipulatedValue;
 
// O último parâmetro indica se o controle é inversa ou 
// diretamente proporcional, ou seja, se a uma alteração do PV
// deve corresponder uma alteração de mesmo sinal (DIRECT) ou 
// de sinal trocado (REVERSE).
PID pid(&PresentValue, &ManipulatedValue, &SetPoint, kp, ki, kd, DIRECT);
 
volatile int power = 100;  
 
long t;
 
void setup()
{
  Serial.begin(9600);
  pinMode(loadR, OUTPUT);
  attachInterrupt(0, zero_crosss_int, RISING); 
// Os valores 10 e 240 foram definidos empiricamente usando-se
// o osciloscópio para ver onde o controle da onda é estável.
  pid.SetOutputLimits(10, 240);
  pid.SetMode(AUTOMATIC); 
  SetPoint=60;
  t=millis();
}
 
void zero_crosss_int()  
{
// Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo)
// (8333us - 8.33us) / 256 = 32 (aprox).
// Ou seja, cada 1 unidade em power corresponde a 32 microssegundos
// na onda de meio ciclo.
  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);   
}
 
 
// Função que lê o PV. É uma função que lê a saída  
// de um LM35 cinco vezes e acumula, depois tirando a média das
// 5 leituras e calculando a temperatura em °C.
int GetTemp(int sensor)
{
  float temp = 0;
  for(int i=0; i< 5;i++)
  {
    temp += analogRead(sensor);
    delay(20);
  }
  temp = (temp * 0.48875855)/5;
  return (int)temp;
}
 
void loop()
{
  float temp = GetTemp(A0);
  PresentValue=temp;// Calcula o valor manipulado   
  pid.Compute();
// Valor de power, que vai ser usado em
// zero_crosss_int() para atuar no processo.
  power = ManipulatedValue;
// Exibe os valores usados de 1 em 1s.
  if ((millis()-t) > 1000)
  {
    Serial.print(millis()/1000);
    Serial.print(",");
    Serial.print(PresentValue);
    Serial.print(",");
    Serial.println(ManipulatedValue);
    t=millis();
  }
  delay(300);
}
Esse exemplo é bem simples, e mostra como, usando-se a biblioteca pid_v1.h, fica fácil a gente implementar esse tipo de controle nos nossos projetos, ou seja, o pulo do gato está em entender o que se quer do PID e escolher as constantes certas para obter o resultado desejado.

Um outro exemplo, combinando o controle por TRIAC e o PID, segue abaixo. Esse circuito "junta tudo": combina os primeiros posts de controle de potência com os post de PID, num circuito sofisticado e prático para controle em geral, indo de aplicações de controle de processo propriamente dito até robótica, por exemplo, um simples robozinho segue-faixa pode ser muito beneficiado pelo uso desse tipo de algoritmo.

Para terminar, resolvi escrever sobre esse assunto porque não achei na net bons textos práticos em português sobre ele. Aliás, nem em inglês eu vi algo que fosse simples mas ao mesmo tempo descrevesse com rigor os conceitos envolvidos, por isso resolvi dedicar um tempo a isso.

Espero que essa série posts, que tomou mais de um mês para ser feita, seja útil a vcs. Por favor, escrevam sobre o que acharam, para que eu tenha o feedback de como me saí nessa empreitada. Abracadabraço!

#include "PID_v1.h"

// Carga (pino onde será aplicado o output). Esse pino deve ser
// ligado ao MOC. No primeiro circuito do post III dessa série
// o MOC está ligado ao pino 4.
#define loadR 4    

// Constantes do PID
#define kp 50
#define ki 10
#define kd  0

// Variáveis do PID: a nomenclatura é a mesma descrita no post III
double SetPoint, PresentValue, ManipulatedValue;

// O último parâmetro indica se o controle é inversa ou 
// diretamente proporcional, ou seja, se a uma alteração do PV
// deve corresponder uma alteração de mesmo sinal (DIRECT) ou 
// de sinal trocado (REVERSE).
PID pid(&PresentValue, &ManipulatedValue, &SetPoint, kp, ki, kd, DIRECT);

volatile int power = 100;  

long t;

void setup()
{
  Serial.begin(9600);
  pinMode(loadR, OUTPUT);
attachInterrupt(0, zero_crosss_int, RISING); // Os valores 10 e 240 foram definidos empiricamente usando-se // o osciloscópio para ver onde o controle da onda é estável. pid.SetOutputLimits(10, 240); pid.SetMode(AUTOMATIC); SetPoint=60; t=millis(); } void zero_crosss_int() { // Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo) // (8333us - 8.33us) / 256 = 32 (aprox). // Ou seja, cada 1 unidade em power corresponde a 32 microssegundos // na onda de meio ciclo. 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); } // Função que lê o PV. É uma função que lê a saída // de um LM35 cinco vezes e acumula, depois tirando a média das // 5 leituras e calculando a temperatura em °C. int GetTemp(int sensor) { float temp = 0; for(int i=0; i< 5;i++) { temp += analogRead(sensor); delay(20); } temp = (temp * 0.48875855)/5; return (int)temp; } void loop() { float temp = GetTemp(A0); PresentValue=temp;// Calcula o valor manipulado pid.Compute(); // Valor de power, que vai ser usado em // zero_crosss_int() para atuar no processo. power = ManipulatedValue; // Exibe os valores usados de 1 em 1s. if ((millis()-t) > 1000) { Serial.print(millis()/1000); Serial.print(","); Serial.print(PresentValue); Serial.print(","); Serial.println(ManipulatedValue); t=millis(); } delay(300); }

Comentários

  1. Dr. Mauro,
    Li apenas o primeiro post por completo e já estou empolgado com o projeto!
    Sou bolsista no Laboratório de Ensaios Térmicos da UFRGS e estou trabalhando no desenvolvimento de um Túnel de Tratamento de Ar, onde controlarei a temperatura e umidade deste.
    Com esse projeto seu poderei fazer um controle excelente da resistência que aquecerá o ar assim como a resistência que evaporará a água para criar a umidade desejada.
    Nas próximas semanas estudarei este projeto seu e à medida do possível lhe passarei os feedback!!
    Desde já te agradeço muito pelas publicações! E os textos estão ótimos: diretos, simples e explicativos! Meus parabéns, Doutor.

    ResponderExcluir
    Respostas
    1. Mateus,

      Em primeiro lugar pode me tratar por Mauro. Sou um reles engenheiro atrevido o suficiente para escrever sobre engenharias: software, automação e controle, agrícola...

      O controle de potência por fase é o melhor que se consegue para controlar resistências ligadas em corrente alternada. E o PID, por sua vez, é o algoritmo de controle por malha fechada que melhor performance dá, em termos genéricos, quer dizer, pode haver alguma outra forma específica para determinado caso, mas no geral o PID é o canal.

      Ou seja, se vc for nesse caminho, no que concerne aos seus controles, o seu projeto será um sucesso absoluto! ;)

      Abracadabraço,

      Mauro

      Excluir
  2. Mauro, em poucas palavras esta tão bom que você deveria escrever um livro.

    ResponderExcluir
    Respostas
    1. Hmenom,

      Obrigado pelo incentivo! Sabe que ando pensando nisso?

      [],

      Mauro Assis

      Excluir
  3. Mario bom dia,
    Fiz a simulação do circuito no Proteus e agora estou montando o mesmo no protoboard usando o LM35.
    Fiz alguns testes recentemente com o sensor digital DHT22 (umidade e temperatura) e pelos resultados comparados com um termômetro profissional em Fahrenheit, fiquei muito satisfeito.

    Uma vez que eu preciso também de ler a umidade, pensei em usar o DHT22 (muito mais preciso que o DHT11) no lugar do LM35, porém a sua velocidade de leitura é de 2 segundos.
    Então vai a pergunta: será que vai funcionar com o PID sendo que o acumulo dos resultados das 5 temperaturas levaria 10 segundos, isto não seria muito tempo ? Tem alguma idéia de como eu poderia implementar?

    Paulo

    ResponderExcluir
    Respostas
    1. Paulo, bom dia. Meu nome é Mauro... :)

      Olha, pode ser que sim e pode ser que não. Depende da forma em que o analogRead está implementado em suas "entranhas". Se a interrupção de tempo continuar ocorrendo dentro do analogRead o sistema funcionará normalmente, agora se o analogRead travar tudo enquanto espera a leitura, aí não vai dar. É que, como vc deve ter visto pelo texto, a interrupção ocorre 120 vezes/segundo, então qualquer travamento maior que 8.33 milissegundos avacalha o algoritmo.

      Resumindo: só testando prá ver.

      Outra coisa: se o seu sensor é muito preciso e leva 2s para fazer uma leitura muito provavelmente não será necessário fazer mais de uma leitura. Vc pode então simplificar a rotina.

      Depois poste aqui a sua conclusão. Me interessei pelo seu projeto, então quem sabe vc se animava a fazer um post aqui no meu blog dizendo da sua experiência? Atualmente tenho em média 500 acessos dia, então seria uma forma legal de vc ter o seu trabalho divulgado, já que (claro!) vc teria o seu devido crédito pelo seu material.

      Excluir
    2. PS: prá dar um chute, eu acredito que funcione.

      Excluir
    3. Paulo preciso fazer um trabalho onde o meu setpoint é 37ºC. minha ideia inicial seria usar pelo sistema on off. o sistema é pra controlar umidade e temperatura de uma estufa.fiz a programação da seguinte forma:usando uma resistencia de 130watts, quando a temperatura for 36ºc, ligar a reistencia. e quando a temperatura atingir 38ºC a resistencia desliga.(resistencia ligada em um rele). gostaria de fazer essa programação usando PID.voce pode me ajudar ?

      Excluir
    4. Prezado Garcia favor me passar mais informações no meu email paulo@bancariosdivinopolis.org.br é um trabalho para escola ?
      Como dia os americanos "I will do my best"....

      Excluir
  4. Sim Dr. Mauro.

    Desculpa pelo Mario :)... foi a vontade de escrever....
    Sim pensei em deixar ler uma unica vez ai vai dar 2 segundos...
    Depois posto os resultados. Vou seguir seu conselho de criar um blog. Amo eletrônica e tenho alguns projetos em mente, fiz curso técnico e estou pensando em ingressar na faculdade tenho um filho de 4 anos e ele já ama triac diac, diodo rrs... um abraço...

    ResponderExcluir
  5. Vou criar um contador que conte até 240 (240 * 0,00833333 = 2 segundo) e só ai, dentro do loop, lê o sensor e zera o contador... desta forma acredito que ele não vai atrapalhar no processo da interrupção. Depois te conto.

    ResponderExcluir
  6. boa noite Mauro.

    Seu post é exatamente o que procurei há horas na net.
    Estou pesquisando sobre controle de temperatura por PID pra fazer meu tcc. Faço engenharia de controle e automação e meu projeto é um controle de secagem de grãos.
    Vou comprar os componentes e reproduzir seu post pra começar meu trabalho. Seu site estará nas minhas referencias rsrsrsrs
    Grata! ^-^

    ResponderExcluir
    Respostas
    1. Gedeane, que bom que esses posts estão sendo-lhe úteis! Realmente, são os campeões de audiência por aqui.
      Eu sou engenheiro agrícola, trabalhei numa instituição de pesquisa especializada em armazenamento e secagem de grãos, de modo que gostaria de saber mais detalhes do seu projeto, e também de ajudar caso necessário.

      Abracadabraço!

      Excluir
    2. Nossa, respondeu rápido! rsrsrs
      Sobre o projeto, ainda estou na fase de pesquisa. Eu estou responsável pela parte de programação e eletrônica do projeto.
      Gostaria de juntar o controle PID, que é algo muito usado na indústria, com o arduino, que é de fácil utilização (comecei pesquisando por curiosidade e acabou virando um hobby).
      Um sistema supervisório (Elipse E3) fará o monitoramento das variáveis, que serão a temperatura e a massa dos grãos (antes e após a secagem). Ainda não sei como será a planta, estamos em dúvida se faremos um silo ou um sistema tubular; e nem o grão que iremos secar (creio que será feijão ou arroz, pela facilidade de encontrar).
      O prof orientador me dá atividades semanais para pesquisa, e esta semana ele me pediu que pesquisasse sobre o uso de resistencias e sensores de temperatura. Não vi nada de resistencias com arduino, mas vi que será utilizado um circuito de potência, provavelmente TRIAC, como no seu post.
      Se tiver algumas ideias ou sugestões, serão todas bem-vindas!
      Grata ^-^

      Excluir
    3. Uma dica "agrícola": feijão é mais fácil de secar do que arroz. normalmente é mais fácil de achar feijão verde, que tem muita água para perder. Já arroz é mais fácil vc torrar do que secar...

      Se vc simular um secador, em que os grãos se movimentem, é melhor. O silo dá tb, mas vc tem que controlar a temperatura ao longo da camada, prá não cozinhar embaixo, nem a umidade que for retirada da parte inferior condensar na parte de cima. Por outro lado, não tem que mover os grãos.

      Enfim, é um desafio, vc vai se divertir bastante!

      Excluir
    4. É uma área nova pra mim, essa parte agrícola. Achei muito interessante e bem abrangente para pesquisa.
      Suas dicas "agrícolas" ou não já estão anotadas e serão passadas na minha próxima reunião com o grupo.
      Depois poderia me passar um e-mail para contato?
      Abraços :)

      Excluir
    5. Meu email: assismauro@hotmail.com.

      Excluir
    6. Obrigada mais uma vez, provavelmente vou mandar emails quando começar a fazer o circuito do post :)

      Excluir
  7. Este comentário foi removido pelo autor.

    ResponderExcluir
  8. Boa noite Mauro,

    que bênção seu post, parece miragem, ó. Deus tá ligado do tanto que caço algo sobre esse assunto sinistro, esse tal de controle PID. Mas vamos à vaca fria! Sou estudante (2º ano) do ensino médio-técnico Eletrônica/CEFET-MG, isto é, sei nada. Então.. como eu poderia fazer um controle PID para meu carrinho seguidor de linha? Eu só consegui fazer um controle proporcional. Ficou mais ou menos razoável pois a carrinho não ficou zigue-zaqueando tanto na borda da linha de referência, que é preta. Mas sabe como é né, a vida é bandida e eu sei que pode melhorar mas não sei exatamente o que fazer. Eu usava o MSP430, mas migrei para o Arduíno (#arduendodasso!)
    Agradeço por antecipação (vai que assim vosmecê não me dá um help?)!

    ResponderExcluir
    Respostas
    1. Patrícia,

      Dou sim, Patrícia.

      Ótimo que vc migrou pro Arduino, é mais poderoso e mais fácil de programar. Na net tem muita coisa, tb.

      Eu fiz COLTEC aí em BH... há mais de 30 anos atrás.

      Tem gente que faz PID prá controlar esses carrinhos mesmo. Eu pessoalmente nunca fiz.

      O que é que tá pegando? Se vc estudar os fontes que postei aí, principalmente o primeiro fonte desse post aqui, creio que vc não terá dificuldade em fazer o PID funcionar no seu carrinho.

      Se precisar de mais alguma coisa...

      [],

      Mauro

      Excluir
  9. Este comentário foi removido pelo autor.

    ResponderExcluir
  10. Mauro, muito bom o projeto! Estou querendo iniciar um projeto de aparelho de cocção por sous vide, onde preciso controlar a temperatura com certa precisão, e aquecer a água sempre que preciso. Apenas me tire uma dúvida pois ainda estou estudando qual método utilizar, qual a vantagem de usar controle de fase em A/C, ao invés de PWM por D/C?

    ResponderExcluir
    Respostas
    1. Dr Lecter,
      Só agora vi a sua mensagem.
      Não sei como comparar os dois circuitos, talvez sejam até equivalentes.

      Excluir
  11. Boa tarde Mauro, tudo bem?

    Reproduzi seu circuito da parte 3, e com alguns ajustes que vi nos comentários deu certo. Bem, tá faltando uma ligação no Fritizing no pino 2 do MOC, que deve ser aterrado, por isso não funcionou de primeira, rs.

    Quando fui reproduzir os circuitos da parte 6, tive um problema. Como a linha #define loadR 4 saiu, então dá erro nas linhas onde tem o loadR. Substitui pelo OutputPin mas não deu certo.

    Gostaria de medir a temperatura da lâmpada e ajustar o brilho, tem como fazer isso? Ou medir a luminosidade por um LDR?

    Estes são os primeiros passos pro meu tcc, comecei pela lâmpada e depois vou usar uma resistência.

    Att

    ResponderExcluir
    Respostas
    1. Tem jeito de fazer tanto medindo a temperatura quanto a luminosidade. Eu outro dia ajudei uns alunos a fazer medindo a temperatura da lâmpada e funcionou beleza.

      Excluir
    2. acho que o meu problema agora está no sketch...poderia me dar uma ajuda? O PID não funcionou junto com o circuito de potência... :(

      Excluir
  12. Bom dia Mauro!
    Seu projeto é excelente e de grande valia, Parabéns!
    Estou enfrentando uma dificuldade na compilação do código, é primeira vez que uso PID, e justamente nele que está o problema, vou postar o retorno do relatorio da compilação.

    sketch_oct02a:18: error: 'PID' does not name a type
    sketch_oct02a.ino: In function 'void setup()':
    sketch_oct02a:28: error: 'pid' was not declared in this scope
    sketch_oct02a:28: error: 'AUTOMATIC' was not declared in this scope
    sketch_oct02a.ino: In function 'void loop()':
    sketch_oct02a:54: error: 'pid' was not declared in this scope


    Isso me acontece nos dois codigos que estão aí acima, copiei e colei na IDE e acontece isso, sabe me dizer a possivel causa?
    Obrigado

    ResponderExcluir
    Respostas
    1. Obrigado pelos elogios.
      Com ceteza faltou vc instalar a biblioteca PID no seu micro (PID_v1.h). Faça o download e instale do diretório \libraries.
      Aí compilará.

      Abracadabraço!

      Mauro

      Excluir
  13. Valeu Mauro, cara problemas simples porem tao me dando trabalho rsrsr,
    Fiz a instalação da biblioteca, ela apareceu la na IDE, e carrego ela por la mesmo, porem quando adicionada no projeto não muda de cor do nome da biblioteca no projeto o , fica em preto, quando teria q ficar laranja né, sendo assim não reconhecida ainda. Desculpe fazer essas perguntas, mas to sem saída.
    O que será que está ocorrendo ainda? Estou usando a v1.0.5 da IDE do arduino, teria alguma relação a isso?

    ResponderExcluir
    Respostas
    1. Bom, Cristiano, o fato é que o programa não tá achando a lib. Vc saiu e entrou de novo? O nome do diretório está exatamente igual, incluindo mai/min? É por aí que vc deve investigar.

      Excluir
    2. Bom dia Mauro, Olha realmente to travado num problema besta rsrsrr
      Não tem jeito da IDE reconhecer a biblioteca, qual versao da IDE que vc usou?

      Excluir
    3. Cristiano, bom dia. Eu estou usando a 1.5. Mande pro meu email, assismauro_arroba_hotmail_ponto_com um print da tela do seu diretório libraries.

      Excluir
  14. Boa noite Mauro, achei seu projeto muito bom e estou pensando em usar seu projeto, seria possível me encaminhar o projeto todo incluindo seus esquemáticos e código?
    desde ja agradeço

    mekclaud@gmail.com

    ResponderExcluir
  15. Bom dia Mauro.

    Vou fazer um robo seguidor de linha, afim de transporte de material dentro de uma empresa para o meu tcc, gostaria de usar do controle PID para controle de velocidade do meu motor. Como eu poderia fazer esse processo para poder obter uma velocidade alta em retas e uma velocidade menor quando for curva. Queria saber se vocetem alguma dica ou sugestão de como eu poderia fazer isso.

    Desde ja muito obrigado


    Att.

    Vinicius

    viniciusmmartinez@ig.com.br

    ResponderExcluir
    Respostas
    1. Vinicius,

      Eu acho que o ganho do PID no segue-faixa é na aplicação da correção em curvas, e não no ajuste de velocidade entre curvas e retas. Ele faz com que a correção, quando há o desvio da rota devido à curva, seja a mais eficiente possível, evitando a oscilação que é comum nesse tipo de mecanismo: ele corrige, passa da faixa pro lado de dentro da curva, corrige de novo, aí sai fora etc.

      O jeito de fazer dá para vc ver aí pelos meus textos, não é difícil, a depender da sua experiência com programação.

      Abracadabraço,

      Mauro Assos

      Excluir
  16. Olá Mauro! Cara, não tenho palavras para lhe agradecer...
    Estive um bom tempo procurando aprender sobre PID para implementar em um controle de temperatura com arduino, que pretendo utilizar em uma adaptação que estou fazendo para transformar minha fresadora CNC (feita pro mim) em impressora 3D.
    Como eu faço tudo por pura "curiosidade" (na verdade eu trabalho com jardinagem, e o que aprendo sobre eletrônica/mecânica/programação é procurando pela net), acabei não compreendendo bulhufas do escasso material que fala sobre PID.
    Quando encontrei seu post no Lab. de Garagem que direcionava para cá, bastou uma olhada rápida para perceber que eu tinha encontrado o que procurava!
    Parabéns pela iniciativa de fazer e compartilhar esse excelente material, ficou tudo muito bem explicado!
    Bom, de qualquer forma MUUUITO OBRIGADO! =D

    Um abraço!

    Diego Henrique.

    ResponderExcluir
    Respostas
    1. Diego,

      Muito bom saber que esses posts lhe foram úteis. Deu um trabalhão danado para fazer mas são os posts mais visitados do blog, então valeu a pena.

      Se tiver alguma dúvida é só perguntar aqui.

      Abracadabraço!

      Mauro

      Excluir
  17. Post muito legal mesmo mauro,realmente n tem muito conteúdo entendível sobre esse assunto na net.Foi muito esclarecedora a sua analogia de controle da temperatura no chuveiro. Parabéns o post ficou muito bom mesmo.

    ResponderExcluir
    Respostas
    1. Obrigado, Pedro. Estes posts deram um trabalhão danado mas no fim a audiência compensou e muito. Tem servido a muita gente por aí afora...

      Abracadabraço!

      Mauro

      Excluir
  18. Fantástico esse post, mostra a teoria e a aplicação na prática, parabéns. Li com atenção para entender tudo, e percebi que é citado nos comentários um capacitor que não aparece em nenhum dos diagramas. Onde devo ligar esse capacitor?

    ResponderExcluir
    Respostas
    1. Giba, que bom que vc gostou. Aqui no autômatoBr é assim: a gente mata a cobra e mostra o mouse! Explicações, vídeos, diagramas e código fonte para que vc possa reproduzir o que quiser.

      Deixando o vitupério de lado: o capacitor aparece no primeiro diagrama da Parte III do texto, aqui: http://4.bp.blogspot.com/-L3oMF8-GA-k/UZffT62-WoI/AAAAAAAABdk/seXeFQoJtjs/s1600/Dimmer_TRIAC_bb.png. Eu até já corrigi o texto atendendo a sugestão da turma de trocar o capacitor de cerâmica por um de poliéster. Acontece que o diagrama que vem abaixo do que tem o capacitor é melhor de montar, pelas razões que lá estão explicadas, e não usa capacitor nenhum.

      Abracadabraço,

      Mauro Assis

      Excluir
  19. 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 coloquei 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. Olá Paulo, boa noite, ví sua postagem e compartilho do mesmo problema que vc está tendo, no meu caso o sistema faz o controle perfeito até atingir o setpoint, quando passa do setpoint é que por algum motivo o sistema trava completamente. Andei pesquisando e fazendo uns testes, e tudo indica que é por causa das interrupções, só não sei ainda como resolver esse impasse.

      Excluir
    2. O problema é o uso de delay() em função (zero_crosss_int()) ligada a interrupção.
      Tem que dar um jeito de eliminar esse delay. Lembre-se, o delay é seu inimigo.

      Excluir
  20. Para quem esta querendo melhorar a leitura do lm35 encontrei este código e adaptei ele para 50 leituras, meio segundo. Na verdade o mesmo faz um filtro descartando as medições discrepantes. (Segundo a teria seria legal 100 leituras para uma boa modelagem de dados, mas para o projeto fiz o teste com 50 amostras e ficou melhor) então fica ai para quem interessar:


    float ModelagemDeDados(int x) //x= numero do pino analógico
    {
    int leituras[50],i,j,aux,a,q1,q3,TotalDeElementos=50,soma=0;
    float MenorOutlier,MaiorOutlier;
    for (i=0;i<50;i++) //um segundo de leituras
    {
    leituras[i]=analogRead(x);
    delay(10);
    }

    //Ordenação do vetor por bubble sort
    for(j=50-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[12];
    q3=leituras[37];
    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<50;i++)
    {
    if((float)leituras[i]MaiorOutlier)
    {
    leituras[i]=0;
    TotalDeElementos--;
    }
    }
    //Media das leituras retirando as leituras foda do padrão
    for(i=0;i<50;i++)
    {
    soma=soma+leituras[i];
    }
    return (soma/TotalDeElementos); //Valor ainda não convertido em ºC
    }

    ResponderExcluir
  21. Olá Mauro, primeiramente parabéns pela iniciativa de compartilhar seus conhecimentos.
    Se tratando de programação estou apenas engatinhando, e como os bebes, só repito o que os adultos falam.
    Gostaria de usar seu código para uma aplicação. Preciso controlar o nível de um recipiente. A água não para de entrar nesse reservatório, por isso preciso de um PID para atuar em uma valvula, que será tocada por um motor com redução ou um motor de passo, ainda não sei. Essa válvula ficaria sendo controlada pelo PID, abrindo e fechando e ficando estática, dependendo do nível em fuunção do setpoint.
    Bom, esse é o problema, infelizmente não estou conseguindo adaptar projetos a essa minha necessidade.
    Se por acaso estiver procurando um desafio e quiser me ajudar, meu e-mail é marcusilv@gmail.com.

    Grande abraço e mais uma vez parabéns!!!

    ResponderExcluir
  22. Obrigado Mauro, seu projeto continua ajudando bastante. Estou usando ele como base para um controle de temperatura usando CLP ao invés de arduíno. Mais uma vez, obrigado pela iniciativa.

    ResponderExcluir
  23. Olá Mauro, eu estou tentando controlar uma temperatura de um equipamento através do acionamento de um IGBT via a saída PWM do Arduino. A parte de potência eu domino, mas necessito usar o PID para controlar a saída. Tentei o código básico descrito na página http://playground.arduino.cc/Code/PIDLibaryBasicExample mas não funcionou. Você teria um exemplo para me ajudar?

    ResponderExcluir
  24. Sugiro que vc vá por partes.

    Já conseguiu ligar e desligar o IGBT a partir do Arduino?

    Se sim, eu imagino que vc basicamente terá que escrever na porta digital com analoWrite(PORTA,valor), onde valor é algo entre 0 e 255.

    Nunca usei IGBT, nem sabia da existência do bicho, parece ser uma boa alternativa para esse tipo de controle.

    Aqui tem um material que achei. https://arduinodiy.wordpress.com/2015/07/25/1498/

    Se quiser, vá me dando notícia do seu progresso e eu acudo no que for possível.

    E, nunca é demais dizer, CUIDADO!

    ResponderExcluir
  25. Boa tarde, Mauro! O circuito utilizado no último exemplo é o mesmo dos posts anteriores?

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

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

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

Dividindo um programa (sketch) do Arduino em mais de um arquivo