Ir ao conteúdo

Leitura de corrente e dimmer com Arduino.


Ir à solução Resolvido por .if,

Posts recomendados

Postado

Fala aí pessoal.

 

Estou montando um projeto com um arduino nano, achei que seria simples mas estou tendo problemas em trazer essa ideia para o mundo real.

A ideia do projeto é usar um arduino para dimmerizar uma carga resistiva (Não posso usar os módulos prontos pois é uma carga de 30A) e diminuir a potencia dela ao longo do tempo, dou o start no timer assim que a carga é acionada, para isso uso um sensor de corrente não invasivo de 100A e saida 50mA (montei uma interface para mandar esse sinal para o arduino).

 

O problema é que não consigo fazer essas 3 variáveis (Dimmer, contagem do tempo e leitura da corrente) funcionar ao mesmo tempo, individualmente cada uma delas funciona perfeitamente. Se utilizo interrupções para fazer o dimmer, a contagem de tempo fica com um erro absurdo, se tiro o dimmer da rotina de interrupção, o timer funciona, mas no momento em que o programa executa a rotina de leitura da corrente, a carga desliga (Vai ler 0A) pois a leitura leva um tempo considerável (tempo o suficiente para parar o dimmer).

 

Pensei em montar outra interface para o sensor de corrente, para transformar o sinal analógico em continuo, assim saberia se a carga está ligada ou não, mas quero dar um upgrade nesse projeto futuramente e saber o valor da corrente vai ser necessário.

Só consigo pensar em trocar o arduino por um ESP32 que possui 2 núcleos, acho que não teria esse problema, ou existe alguma saida com o arduino?

 

Algumas partes do meu código.

 

Leitura da corrente:

bool cargaLigada(){ //Retorna se a carga está ligada
  double Irms = SCT013.calcIrms(1480);   // Calcula o valor da Corrente e armazena na variavel Irms

  if (Irms > 30){
    potencia -= 10; //Se a corrente estiver muito alta diminui a potencia da carga
  }
  
  if (Irms > 1){
    Serial.println("Carga ligada");
    return true;
  }

  else{
    Serial.println("Carga desligada");
    return false;
  }
}

 

Rotina de interrupção do zero cross:

void zeroCross(){
  if (potencia>100) potencia=100;
  if (potencia<0) potencia=0;
  t1 = 8200 * (100 - potencia) / 100; //Calcula o tempo de disparo do TRIAC
  disparo = true;  
}

 

Rotina que dispara o triac, está fora da interrupção por causa do problema descrito acima.

  if (disparo){ //dispara o triac
    delayMicroseconds(t1);
    digitalWrite(PINO_DIM, HIGH);  
    delayMicroseconds(6);      // t2
    digitalWrite(PINO_DIM, LOW);
    disparo = false;
  }

 

Até pensei em fazer um sistema de contagem assim:

if ((nowMillis - lastExec) >= delay){
	//disparo
}

Mas a leitura da corrente ainda impediria dessa "função" ser executada.

  • Membro VIP
  • Solução
Postado

A princípio dá pra fazer isso até com um pic10fxxx. O que você precisa é entender melhor seu próprio sistema e suas necessidades. Como deu detalhes superficiais, vou dar dicas na mesma proporção baseando-me só em ...

1 hora atrás, RRod disse:

fazer essas 3 variáveis (Dimmer, contagem do tempo e leitura da corrente) funcionar ao mesmo tempo

-dimerizar:suponho que é por ângulo da fase, sincronize com a rede ac fazendo uma detecção pela passagem por zero e comece a contar uma variável. Dispare assim que atingir um valor determinado

-corrente: leia a corrente i+=read_adc() varias vezes (x) a cada passagem - ou melhor, em várias passadas -determinado tempo após o disparo. Faça a média i/x e terás a corrente

-tempo: a cada passagem, some uma variável de tempo (t). Sabendo-se a freq da rede 60Hz cada incremento de t vai ser 16.666 (ou 8.333 no caso de disparo a cada semiciclo) mili segundos. Use este valor como base de tempo pra compor seus segundos, minutos, horas e etc.

 

O uso do hw do mc (timers, interrupções e etc) tornam o sistema mais elegante e perfumado, claro. Mas na dica minimalista acima sequer é necessário onde se encaixaria o pic10f. Não me debruçarei sobre a questão do uso de hw do mc pra você ok?

 

obs... não vi seu fonte antes de digitar isso acima. Numa passada rápida de olhos meio que parece que meio que estamos meio que sincronizados...

Postado
42 minutos atrás, .if disse:

-dimerizar:suponho que é por ângulo da fase, sincronize com a rede ac fazendo uma detecção pela passagem por zero e comece a contar uma variável. Dispare assim que atingir um valor determinado

Já tenho um circuito que detecta a passagem por 0 e a cada semi ciclo ele manda um sinal, uso esse sinal para contar um tempo e disparar o triac, através de uma interrupção.

 

44 minutos atrás, .if disse:

-tempo: a cada passagem, some uma variável de tempo (t). Sabendo-se a freq da rede 60Hz cada incremento de t vai ser 16.666 (ou 8.333 no caso de disparo a cada semiciclo) mili segundos. Use este valor como base de tempo pra compor seus segundos, minutos, horas e etc.

Uma boa ideia, não havia pensado nisso. Estou utilizando a função millis() pra contar o tempo, mas usar esse método vai simplificar muito o meu código.

 

46 minutos atrás, .if disse:

-corrente: leia a corrente i+=read_adc() varias vezes (x) a cada passagem - ou melhor, em várias passadas -determinado tempo após o disparo. Faça a média i/x e terás a corrente

O maior problema está aqui, esse sensor que uso possui um biblioteca própria, só crio um objeto e chamo a função 'calcIrms(1480)', que retorna a corrente em ampere, só que essa função demora a ser concluída e atrasa todo o programa. Tentei ir incrementado a leitura a cada ciclo e tirar uma média, mas sem sucesso.

Vou abrir essa biblioteca e ver como ela funciona e tentar implementar de outra maneira.

 

50 minutos atrás, .if disse:

Não me debruçarei sobre a questão do uso de hw do mc pra você ok?

Não precisa. Não tenho muito conhecimento de microcontroladores, se aprofundar demais eu não vou entender nada. kkk

  • Membro VIP
Postado

Que bacana que reconheceu parte de minha dica não inútil. Assim sendo debrucemos então sobre isso...

38 minutos atrás, RRod disse:

a função 'calcIrms(1480)', que retorna a corrente em ampere, só que essa função demora a ser concluída e atrasa todo o programa

Apesar de desconhecer detalhes de seu projeto, penso que você não precisa chamar a função a cada lida da corrente. Indo até mais longe nem precisa da função. Mande os dados brutos pra onde vai ser usado e o sistema se vira pra tornar humano. Mas digamos que seja o próprio mc a mostrar num display ou enviando pra serial. Considerando que só o fato de imprimir na tela ja come um tempão, faça as continhas p.ex. a cada 1 segundo.

E tem + ... algo me diz que a função não retorna o dado exatamente em ampere. Pra isso ela deve supor que o argumento é coerente com o que ela quer. No seu caso como está capturando pedaços meio que em pontos aleatórios da corrente, talvez o valor não seja exatamente o que você ou a função quer. A dica prática que dou é:

-tenha um amperímetro padrão e anote o valor da corrente correspondente ao valor ao resultado do conversor ad e faça algo como uma regra de três. A princípio nem precisaria daquela função

 

38 minutos atrás, RRod disse:

tentar implementar de outra maneira.

 


😁

Postado

 

 

1 hora atrás, .if disse:

Apesar de desconhecer detalhes de seu projeto, penso que você não precisa chamar a função a cada lida da corrente.

...faça as continhas p.ex. a cada 1 segundo.

Só preciso desse valor de tempos em tempos, 1 segundo deve ser o suficiente.

 

1 hora atrás, .if disse:

... algo me diz que a função não retorna o dado exatamente em ampere. Pra isso ela deve supor que o argumento é coerente com o que ela quer.

Na minha função de setup eu passo os parâmetros para o objeto para que ele possa fazer os cálculos. Comparei os resultados que essa função me retorna com os valores lidos de um alicate amperímetro e são praticamente iguais.

 

Usei essa biblioteca e função ('calcIrms(1480)') por recomendação de outros projetos que achei na internet com esse sensor, dei uma olhada na biblioteca para ver o funcionamento e descobri que esse valor '1480' é o numero de vezes que ele lê o valor na porta analógica, faz uma série de cálculos e no final tira a média, como você disse.

 

2 horas atrás, .if disse:

-corrente: leia a corrente i+=read_adc() varias vezes (x) a cada passagem - ou melhor, em várias passadas -determinado tempo após o disparo. Faça a média i/x e terás a corrente

Esse quantidade de vezes executada é que deixa tudo lento.

 

Sendo assim, vou voltar ao que era, quando dimmerizava pela interrupção, o millis() pausava gerando os erros na contagem de tempo, usando o método que você citou, a cada passagem por 0 incrementar 8,33ms a uma variável, posso descartar o millis(), essa função que calcula a corrente pode demorar o tempo que for, pois sempre que a rede passar por 0, o calculo da corrente vai ser interrompido para poder dimmerizar.

 

Acredito que assim deva funcionar, vou testar e depois volto aqui, mas já agradeço a força!👍😁

 

Postado

@RRod ,

 

Poderia postar o seu circuito detetor de passagem por zero para eu calcular o erro dele ?

 

E poste também qual o

sensor que você está usando porque nunca ví ter de usar biblioteca específica …..


Lembre que você tem 3 timers no seu Arduino ….. um deles será sua base de tempo, assim você não se perde no programa principal…. E uma interrupção qualquer deve ser acionada pelo detetor de passagem por zero.

 

Assim fica melhor para

você acertar o programa.

 

Paulo

 

 

 

Paulo

  • Membro VIP
Postado
3 horas atrás, RRod disse:

Esse quantidade de vezes executada é que deixa tudo lento.

É nada. Perceba que a leitura e simples soma com a anterior é feita uma (01) vez só a cada passada o que não leva tempo considerável. Se em 64 passadas pelo loop você lê uma vez, ao final basta dividir a soma por 64... (64=2^6=base 2: a preferida para os mc's) ~8mS cada leitura... a cada ~0.5 terás a soma fará a conta apenas neste período de 0.5 em 0.5 seg.  .. de novo: não faça ou evite fazer conta complexa principalmente com fracionários no mc 8 bits... é muito pra cabecinha dele

 

Mas meu lado psicotécnico me diz que quando alguém menciona a função arduína milis() é que esta pessoa está contaminada pelos mastigados desta plataforma o que limita um pouco a margem de ajustes técnicos baseado no hw do mc.. p.ex. teça algum comentário sobre...

2 horas atrás, aphawk disse:

Lembre que você tem 3 timers no seu Arduino ….. um deles será sua base de tempo, assim você não se perde no programa principal…. E uma interrupção qualquer deve ser acionada pelo detetor de passagem por zero.

e mostre que meu psicologismo falhou kk

🤪

Brinc...  Tudo bem...

5 horas atrás, RRod disse:

Não tenho muito conhecimento de microcontroladores, se aprofundar demais eu não vou entender nada. kkk

tmj... desde o ano passado 😁

Postado
Em 31/12/2021 às 22:29, aphawk disse:

 

Poderia postar o seu circuito detetor de passagem por zero para eu calcular o erro dele ?

É um módulo que comprei pela internet, um resistor de 33K, uma ponte retificadora, e um opto 4N25. Do lado do arduino tem um resistor pull-down de 1K. Mas o erro acontecia na hora de contar o tempo pra decrementar a potencia da carga. Ex. deveria decrementar a cada 2 minutos, mas por conta do erro isso só acontecia a cada 3,5min e o erro só ia aumentando. O dimmer está OK.

 

Em 31/12/2021 às 22:29, aphawk disse:

E poste também qual o

sensor que você está usando porque nunca ví ter de usar biblioteca específica …..

O sensor é um SCT013. Ele não tem uma biblioteca especifica, usei uma biblioteca que recomendaram em projetos com esse mesmo sensor. Como ela dá um resultado preciso e é fácil implementar, resolvi ficar com ela mesmo.

 

Em 01/01/2022 às 01:14, .if disse:

Mas meu lado psicotécnico me diz que quando alguém menciona a função arduína milis() é que esta pessoa está contaminada pelos mastigados desta plataforma

O seu lado psicotécnico está correto, escolhi o arduino por já ter tudo meio pronto. Tive contato com PIC e assembly em um dos cursos que fiz e achei muito ruim de usar, kkk, sei que quando for fazer algo mais complexo, vou ter que recorrer a isso, mas por enquanto vou ficar com o simples.

 

Em 01/01/2022 às 01:14, .if disse:

p.ex. teça algum comentário sobre...

O que eu posso dizer é que já pesquisei sobre esses Timers... kkk

Mas começou a ficar complexo, ai dei uns passos pra trás e fui tentar fazer de outro jeito.

 

 

A dica de incrementar 8.33ms a cada pulso do zero cross resolveu todos os problemas, agora a carga não desliga no momento em que mede a corrente, a contagem do tempo não tem erros e descartei o millis(). Agora vou testar com a carga real, só me falta um opto-diac para isolar o triac do arduino, alguma recomendação? A tensão do circuito é 220V.

 

Postado

@RRod ,

 

Bom, jâ dá para fazer alguns cálculos :

 

Seu sistema de passagem por zero tem um erro aproximado de 9 graus, ou seja, ele lhe indica zero quando na verdade você tem cerca de 30V na carga. E o seu resistor de 33K deve estar dissipando 1,4 Watts de calor ligado no 220V.

 

A potência máxima entregue à carga será de 90% em relação à que você teria ligando ela direto na rede.

 

Agora, seu sensor de corrente é um simples TC …. prá quê usar uma biblioteca ???? Dá para fazer seu cálculo diretamente , por exemplo amostrando o ADC 32 vezes durante o semiciclo de 60 Hz ( lembra dos timers ??? Servem para isso kkk ), com isso você tem a corrente média ( eu já fiz um post aqui no CDH mostrando o calculo e o processo todo, sò muda o sensor que no meu caso era um ACS712 , com um TC igual ao seu é ainda mais simples  ) e consegue calcular certinho a potência . 
 

Por último, para isolar, use um optoacoplador tipo MOC e pronto.

 

Paulo

 

 

 

  • Curtir 1
Postado
7 horas atrás, aphawk disse:

A potência máxima entregue à carga será de 90% em relação à que você teria ligando ela direto na rede.

Este erro não chega a ser um problema.

 

7 horas atrás, aphawk disse:

...prá quê usar uma biblioteca ????

Quando comecei o projeto não sabia como converter a corrente do secundário do TC para um sinal de tensão, aí usei a biblioteca por ser o mais fácil (Descobri que não tem haver com o código e que precisava montar uma interface só depois). 

Dei uma fuçada nela e vi como funciona os cálculos, vou tentar implementar direto no meu código e eliminar essa lib.

 

Quanto ao seu post mostrando os calculos, o que encontrei foi isso aqui:

Em 29/10/2017 às 11:26, aphawk disse:

Eu já descrevi algumas vezes o processo matemático para o cálculo da corrente RMS medida por um sensor ACS, usando amostragens no período da senoide aqui neste mesmo Fórum..... mas já fazem alguns anos e não me lembro onde está isso kkkk sugiro uma boa pesquisa !

Se já faziam alguns anos em 2017... Não sei se encontro esse post kkkk.

 

Obrigado @aphawk@.if , agora esse projeto sai! 😁

  • Membro VIP
Postado
8 horas atrás, RRod disse:

o processo matemático para o cálculo da corrente RMS medida por um sensor

Certa feita precisei disso dai pra medir corrente. Mas era (e ainda é) muito pra minha cabecinha. A solução que usei foi um simples filtro rc na saída amplificada por um retificador ideal ou de precisão com ampop e filtrada com o rc. O dc que saía era proporcional à corrente e contas mínimas foram necessárias pro mc. E sim, coincidentemente a tensão/corrente era despedaçada por um par de scr. Usando um amperímetro padrão consegui calibrar com 99,9% de precisão. Algo como...

um+filtro+passa+baixo+de+primeira+ordem.

removendo a parte dos cálculos obviamente😁

  • Haha 1
Postado

@RRod ,

 

Realmente tem coisas meio antigas né , mas tem muito conhecimento distribuido aqui no CDH ao longo de muitos anos .... segue o link do meu post original ( 2012 kkkk ) , nesse tempo a @.if  usava o "nome verdadeiro"  ainda... :

 

 

 

Não tem segredo, eu usei 72 amostragens no período de uma senóide inteira a 60 Hz.

 

Paulo

  • Curtir 2
  • Membro VIP
Postado

... na época usava pic16f676 mc 8 bits 1k flash 128bytes que e ele não daria conta das contas principalmente da raiz quadrada em tempo real.. poderia dar mas ia perder tempo pra bolar o algoritmo otimizado em c e principalmente pro próprio mc calcular. No (meu) caso o rc fazia a conta analogicamente pra ele... mais uma faceta do poder do capacitor que nem coloquei naquela lista maluca 🤪

Em 03/08/2013 às 22:36, aphawk disse:

depois tirar a raiz quadrada,

Hoje em dia com os mastigados e velocidade dos mc's pode ser uma boa pedida 😉

Postado

@.if ,

 

Realmente trabalhar com Pic antigo era uma encrenca …. Mas os Avrs já tinham multiplicação por hardware, e como quase tudo é apenas um ciclo de clock sempre consegui fazer operações matemáticas com Word em baixo tempo, dentro das interrupções….

 

Mas a sua solução com os amp ops também resolveu e simplificou muito o software.

 

Paulo

Postado
Em 03/01/2022 às 07:36, .if disse:

A solução que usei foi um simples filtro rc na saída amplificada por um retificador ideal ou de precisão com ampop e filtrada com o rc.

Acho que está na hora de partir para o Eletronica vol. 2 do Malvino, porque não entendi nada desse circuito 😅

 

Em 03/01/2022 às 10:46, aphawk disse:

nesse tempo a @.if  usava o "nome verdadeiro"  ainda...

Nesse tempo eu não sabia a diferença entre tensão e corrente. 😂

  • Haha 1
  • Membro VIP
Postado
8 horas atrás, RRod disse:

Acho que está na hora de partir para o Eletronica vol. 2

... mas não sem antes começar pelo excelente marco 0...

No mínimo vai entender um pouco mais que 0

8 horas atrás, RRod disse:

porque não entendi nada desse circuito

😜

  • Curtir 1
Postado
11 horas atrás, RRod disse:

Acho que está na hora de partir para o Eletronica vol. 2 do Malvino, porque não entendi nada desse circuito 😅

 

KKKK na verdade são dois circuitos juntos : o primeiro é um retificador de onda completa  de precisão , ou seja, aplicando em sua entrada um sinal senoidal AC ( cujo valor médio é ZERO cero ?) , em sua saída ele apresenta esse sinal senoidal "retificado" , ou seja, ele sempre terá valor positivo, cujo valor médio será proporcional ao valor médio do sinal AC na sua entrada.

 

Veja como sai o sinal , é o que está representado pela letra C :

 

image.png.551e644b5f1ccb4dc7c865e4d93411d8.png

 

Se tiver outros sinais juntos com o sinal de 60 Hz, o que é bastante comum, eles tem de ser filtrados , portanto é aí que entra o segundo circuito, que é o filtro passa baixas, que deve ser calculado para deixar passar apenas o sinal de 60 Hz , cortando os sinais de frequência acima dessa.

 

Paulo

 

 

 

 

  • Curtir 3
Postado
Em 05/01/2022 às 07:49, .if disse:

... mas não sem antes começar pelo excelente marco 0...

valeu pela dica, vou tentar encontrar na versão física.

 

Em 05/01/2022 às 10:20, aphawk disse:

na verdade são dois circuitos juntos...

Agora eu entendi! Não é tão complicado quanto parece. Caso essas interrupções e cálculos fritem o arduino, vou por essa opção.

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...