Ir ao conteúdo
  • Cadastre-se

Circuito Limitador de RPM (arduino)


Posts recomendados

1 hora atrás, ComandateGustavo disse:

mas estou olhando bastante e não consegui descobrir porque não está lendo o pino 4 em LOW, vou aguardar o @Thiago Miotto responder pra gente ver se ele consegue encontrar o erro porque não estou conseguindo, o código é esse:

Dei uma  olhada rapidona e não vi nada errado. Mas o que tu diz sobre não ler o pino 4 em Low?
Antes não tinha funcionado? Como foi tua montagem?
Dica, tu pode ligar o pino 4 no botão e só em gnd e declarar a variável como INPUT_PULLUP
 

 pinMode(inbotao,INPUT_PULLUP);

 

Link para o comentário
Compartilhar em outros sites

11 minutos atrás, Thiago Miotto disse:

Dei uma  olhada rapidona e não vi nada errado. Mas o que tu diz sobre não ler o pino 4 em Low?

dei uma vacilada mandei o código antigo, aqui está o atual que não está funcionando:

 

Citação

// --- Bibliotecas Auxiliares ---
#include <LiquidCrystal_I2C.h> //inclui biblioteca lcd
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

// --- Mapeamento de Hardware ---
#define inFreq   2  //entrada para medir a frequência no pino digital 2
#define outrele  7
#define inbotao  4


// --- Variáveis Globais ---
const int rele=7;
long freq, counter;
int pulseCount;
boolean pulse;


// --- Configurações Iniciais ---
void setup() 
{
  
  pinMode(inFreq,INPUT);    //Configura como entrada
  pinMode(inbotao,INPUT);
  pinMode(rele, OUTPUT);
  
  lcd.init();
  lcd.setCursor(2,0);      //Posiciona cursor na coluna 3, linha 1
  
  pulse = 0x01;             //Seta variável de controle
  
} //end setup


// --- Loop Infinito ---
void loop() 
{
  
  counter = millis();      //counter recebe o valor do tempo em ms
  
  if(digitalRead(inFreq))  //Entrada de frequência em nível alto?
  {                        //Sim...
  
    if(pulse) pulseCount++;  //incrementa pulseCount se variável de controle for verdadeira
     
    pulse = 0x00;            //limpa variável de controle

  }
  else                     //Não...
  {
    pulse = 0x01;          //Seta variável de controle
  }


  if(counter%500 == 0x00)  //Passaram-se 200 ms?
  {                        //Sim...
    freq = pulseCount*2;   //Atualiza frequência (200 x 5 = 1000ms)
    lcd.setBacklight(HIGH);
    lcd.setCursor(5,1);   //Posiciona cursor na coluna 6, linha 2
    lcd.print(freq);      //Imprime valor atual da frequência
    lcd.print("Hz");      //Imprime "Hz"
        
    
    pulseCount = 0x00;     //Reinicia contador
  }
  
if ((freq > 120)||(digitalRead(inbotao == LOW))) {

  if (((counter / 500) % 2) == 1) {
    digitalWrite(rele, HIGH); //liga por 500 milisgundos o led se freq maior que 120
  }
  else
  {
    digitalWrite(rele, LOW); //desliga por 500 milisgundos o led se freq maior que 120
  }
}
 else
{
  digitalWrite(rele, LOW); //desliga o led se freq menor que 120

}
}
  

dessa forma o led fica sempre piscando não importa se está em nivel alto ou baixo

@Thiago Miotto  é estranho porque se deixar assim não funciona:

 

Citação

if ((freq > 120)||(digitalRead(inbotao == LOW))) {

 

 

 

da forma antiga funciona quando está em nível alto:

 

Citação

if ((freq > 120)||(digitalRead(inbotao))) {

 

Link para o comentário
Compartilhar em outros sites

2 horas atrás, ComandateGustavo disse:

if ((freq > 120)||(digitalRead(inbotao == LOW))) {

O erro está Aqui
Como expliquei, o Arduino compila isso mesmo tendo a sintaxe errada.
Você pode usar:
if ((freq > 120)||(digitalRead(inbotao) == LOW)) {

ou
if ((freq > 120)||(!(digitalRead(inbotao)))) { 
Eu uso a 1ª, mas creio que a 2ª tb funcione

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
8 horas atrás, ComandateGustavo disse:

o rele é uma carga indutiva desligar e ligar a bobina dessa forma rápida pode prejudicar a porta do arduino, ou estou enganado?

Sim está enganado. A porta num tá nem aí pra bobina do relé pois ela apenas manda o transistor acionar e este se vira mas pede o tal diodo. O opto isola ainda mais mas claro há de se ter  fontes separadas como sua 2ª figura. Na 1ª ele está lá pra jogar dinheiro fora.

 

 

8 horas atrás, ComandateGustavo disse:

o rele vai ser ligado e desligado rapidamente 


O quão rapidamente? Se for muito rápido cogite um mosfet ou transistor de potência dependo do que ele vai acionar.

 

4 horas atrás, Thiago Miotto disse:

if ((freq > 120)||(digitalRead(inbotao) == LOW)) {

Eu (eu) prefiro algo como

if ((freq > 120) || !PORTA.Bit0) //PORTA.0, RA0, P0.0, GPIO0 e afins

É a lesma lerda mas é só questão de princípios 😁...

 

Link para o comentário
Compartilhar em outros sites

16 horas atrás, .if disse:

 

O ruído da ignição é bem estreito se comparado ao do de rotação (acho). Neste caso um capacitor em paralelo com a entrada do mc ligeiramente bem calculado (testado) pode dar um bom resultado

O desacoplamento entre 1 e 100nf é obrigatorio mas não suficiente para eliminar as transientes.  Uma ignicao antiga cdi tem uma faísca de 50/100 micros segundos e uma TCI atualmente entre 100/1000us (até 1ms).

 

Via software eu anulo qualquer interrupção externa acima de uma frequência que já considero ruido.

 

Outra coisa, o sensor hall ou relutor (bobina) soltará seu pulso antes da faísca, é possível ler o pulso e desabilitar a interrupção por x tempo e depois habilitar de novo etc.

 

Nesse projeto nosso amigo não terá que usar todo esse cuidado, um bom filtro na entrada e uma boa fonte de alimentação já resolve!

 

@ComandateGustavo seu código está ok mas você deve trabalhar com interrupção, seja ela por hardware ou software. Uma interrupcao faz o código parar para processa-la e depois o código continua de onde parou.

 

Um exemplo lúdico: você está na estrada e acende a luz de reserva de gasolina, imediatamente você procura um posto ou se concentra em resolver aquilo para depois concluir a viagem.

 

Sem interrupção, você terminaria de ouvir suas músicas, toma uma água, ajeita o banco do carro, olha a paisagem etc, mas nesse tempo pode acabar a gasolina pois você não priorizou aquilo, o sinal de rpm é curto e deve ser contabilizado no seu caso imediatamente.

 

Esse código https://www.google.com/amp/s/duino4projects.com/arduino-rpm-counter-tachometer-code/ trabalha com interrupção e já lhe dá o display que precisa, cada vez que o pino 2 cai de 5v para 0v ele dispara.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
11 minutos atrás, mlegnari disse:

O desacoplamento entre 1 e 100nf é obrigatorio mas não suficiente para eliminar as transientes.  Uma ignicao antiga cdi tem uma faísca de 50/100 micros segundos e uma TCI atualmente entre 100/1000us (até 1ms).

Se você diz.. então tá. No entanto penso que o autor pode personalizar e focar o filtro pro seu propósito. Neste caso, caso a diferença entre sinal e ruído for algo como o sinal é 3x mais largo, um RC simples numa entrada shimith trigger pode dar uma boa confiabilidade.

Fale qual a largura do sinal de rotação só de curiosisdade... O autor não tem osciloscópio.

Link para o comentário
Compartilhar em outros sites

15 horas atrás, Thiago Miotto disse:

Você pode usar:
if ((freq > 120)||(digitalRead(inbotao) == LOW)) {

ou
if ((freq > 120)||(!(digitalRead(inbotao)))) { 
Eu uso a 1ª, mas creio que a 2ª tb funcione

Testei as duas e as duas funcionaram, mas dessa vez se o fio do pino 4 não estiver conectado ao GND o led continua piscando,  se ele estiver em 5v ou se estiver "solto" o led pisca da mesma forma, é o mesmo erro que acontecia antes mas invertido, mas funciona funciona, só que realmente terei que usar resistor de pull-up ou pull-down por causa das flutuações.

 

6 horas atrás, .if disse:

Fale qual a largura do sinal de rotação só de curiosisdade... O autor não tem osciloscópio.

Boa observação @.if mas imagino que a largura do pulso fica menor quanto mais elevada for a RPM porque o distribuidor vai girar mais rápido, mas posso estar enganado...

 

6 horas atrás, .if disse:

um RC simples numa entrada shimith trigger pode dar uma boa confiabilidade.

taí mais coisas pra eu pesquisar e aprender rsrs

 

 

7 horas atrás, mlegnari disse:

Esse código https://www.google.com/amp/s/duino4projects.com/arduino-rpm-counter-tachometer-code/ trabalha com interrupção e já lhe dá o display que precisa, cada vez que o pino 2 cai de 5v para 0v ele dispara.

esse código trabalha com led IR e fototransistor, teria que alterar o código pra pegar o sinal do hall né?

 

7 horas atrás, mlegnari disse:

 seu código está ok mas você deve trabalhar com interrupção, seja ela por hardware ou software. Uma interrupcao faz o código parar para processa-la e depois o código continua de onde parou.

a função da interrupção seria para o arduino contar os pulsos parar para saber o que fazer com ela e depois executar a ação, mas se não trabalhar com interrupção como isso pode afetar o funcionamento? Seria no caso ao invés de limitar a rotação o arduino iria dar erro e congelar?

Link para o comentário
Compartilhar em outros sites

10 horas atrás, .if disse:

Se você diz.. então tá. No entanto penso que o autor pode personalizar e focar o filtro pro seu propósito. Neste caso, caso a diferença entre sinal e ruído for algo como o sinal é 3x mais largo, um RC simples numa entrada shimith trigger pode dar uma boa confiabilidade.

Fale qual a largura do sinal de rotação só de curiosisdade... O autor não tem osciloscópio.

O sinal do módulo q sai para o painel dos que medi aqui tem 5% de dutycycle, basta assumir que qualquer sinal com largura inferior a 4% do período anterior é ruido.

 

@ComandateGustavo se o micro estiver fazendo uma tarefa qualquer  pra exemplo contando de 1 a 100 trilhões e você tiver um pulso sem usar a interrupção ele ignora o pulso. A interrupção é para o micro disparar uma ação quando vier o sinal, depois ele volta a fazer coisas menos importantes.

 

O código que postei você pode declarar como input pullup igual nosso amigo citou acima, e cada vez que o opto chavear o coletor com o terra esses 5v do pino viram 0v e dispara  a interrupção.

 

Vou lhe dar uma dica show de bola: use simuladores! você vai precisar de depurar seu código linha a linha futuramente, é legal você pula linha a linha e vê o que acontece.

 

Proteus é muito bom mas complexo, comece pelo Thinkercad é gratuito!

 

Link para o comentário
Compartilhar em outros sites

3 horas atrás, Thiago Miotto disse:

No código postado, a entrada está como INPUT o correto para ligar direto no gnd seria:


  pinMode(inbotao,INPUT_PULLUP);

 

@Thiago Miotto  ahn agora simm, mesmo com o fio solto no ar o led permanece apagado, isso não elimina o esqueminha com resistor, mas deixa o cicuito melhor, este esquema que fizemos falta testar na prática mas já deve funcionar bem, para aprender mais a programação vou tentar colocar um potênciometro para selecionar a frequência que faz o led piscar, atualmente está configurado para 120Hz mas quero ver se consigo alterar isso pelo potenciometro vamos ver como fica.

 

vou tentar adaptar também o código que o @mlegnari  citou para aprender mais e também porque parece que terá um resultado melhor, na verdade cada vez mais estou tendo mais ideias para aplicar o arduino nos projetos aqui. Amanhã vou ter que ir a loja de eletronica comprar terminais porque estou dando uma geral na parte elétrica do carro, tinha fio desencapado fios que não vão pra lugar nenhum então estou melhorando isso, já vou aproveitar e comprar alguns componentes.

 

15 horas atrás, .if disse:

O quão rapidamente? Se for muito rápido cogite um mosfet ou transistor de potência dependo do que ele vai acionar.

@.if Ainda não sei a velocidade que precisa acionar isso vou ver na prática, mas tenho um 2N3055 dando sopa aqui será que vale usar ele no lugar do rele?

 

15 horas atrás, .if disse:

Eu (eu) prefiro algo como

if ((freq > 120) || !PORTA.Bit0) //PORTA.0, RA0, P0.0, GPIO0 e afins

É a lesma lerda mas é só questão de princípios 😁...

tu sabe que eu entendi só até o sinal de II né? kkkkkk

Link para o comentário
Compartilhar em outros sites

@mlegnari tentando alterar o código que me passou está dando erro na hora de compilar: stray '\342' in program

 

O erro acontece nessa linha: lcd.print(“RPM=”); o que será isso?

 

Citação

volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

// include the library code:
#include <LiquidCrystal_I2C.h> //inclui biblioteca lcd
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

void rpm_fun()
{
//Each rotation, this interrupt function is run twice, so take that into consideration for
//calculating RPM
//Update count
rpmcount++;
}

void setup()
{lcd.init();

//Interrupt 0 is digital pin 2, so that is where the IR detector is connected
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(0, rpm_fun, FALLING);


rpmcount = 0;
rpm = 0;
timeold = 0;
}

void loop()
{
//Update RPM every second
delay(1000);
//Don’t process interrupts during calculations
detachInterrupt(0);
//Note that this would be 60*1000/(millis() – timeold)*rpmcount if the interrupt
//happened once per revolution instead of twice. Other multiples could be used
//for multi-bladed propellers or fans
rpm = 30*1000/(millis() – timeold)*rpmcount;
timeold = millis();
rpmcount = 0;

//Print out result to lcd
lcd.clear();
lcd.print(“RPM=”);
lcd.print(rpm);

//Restart the interrupt processing
attachInterrupt(0, rpm_fun, FALLING);
}

 

Link para o comentário
Compartilhar em outros sites

Estou curioso para ver se o ruído da ignição consegue passar pelo opto....

 

Sobre o relé.... a porta que vai acionar o transistor que por sua vez vai acionar a bobina do relé não vai correr nenhum risco. Mas a fonte que alimenta o relé... o ruído induzido pelo acionamento do relé pode sim se propagar pela fonte podendo inclusive travar o Atmega; esse mesmo ruído pode se acoplar capacitivamente a outros circuitos que estejam perto e pode atrapalhar outras entradas, principalmente aquelas que sejam de alta impedância.

Uma dica:  Se puder colocar o relé longe, faça isso....

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
6 horas atrás, aphawk disse:

a fonte que alimenta o relé...

geralmente é a bateria e esta tem impedância baixa d+ pra deixar a linha se influenciar pelo ruidinho mixuruca do relé. E este teria ainda que passar pelo regulador do mc e tal. De fato o projeto tem que ter um certo grau de profissionalismo pra evitar tal problema (melhorei a frase). E s sim o relé não deve ficar colado no mc nem mesmo alimentado por fios soldados na pci dele. Portanto a dica é tentar não usar relé 5V e na mesma alimentação do mc. E sim 'distanciamento social' sempre fez bem pra relação controle/potência.

 

8 horas atrás, ComandateGustavo disse:

um 2N3055

daí 'varêia'. Ele precisa de alta corrente de base pra acionar altíssima corrente de coletor. Caso esta não seja tão alta, talvez um tip31 dê conta.

 

Nota... está virando muitas páginas... e sim isso me (me) incomoda 😑😁

6 horas atrás, aphawk disse:

o ruído induzido pelo acionamento do relé

Ah sim... Paulão se refere ao ruído dos contatos do relé. Corrente ou tensão altas sim zoam o barraco das proximidades. Penso que eu e ele temos experiência com isso😁

  • Haha 1
Link para o comentário
Compartilhar em outros sites

Fala pessoal, estou a um tempo lendo o tópico inteiro, estou atrás de um projeto de 3step com o arduíno, quero montar em minha moto injetada com bobina de pulso.
Sou bem iniciante em programação, minha moto ja tem conta giros, queria montar somente o corte com o botão. 
Alguém poderia me ajudar com o código e o esquema elétrico ? 
Tenho um Arduino Uno 

Link para o comentário
Compartilhar em outros sites

12 minutos atrás, Ricardo Bariquelo disse:

3step com o arduíno

E aí @Ricardo Bariquelo Beleza?

3step com Arduino era exatamente o que eu queria fazer desde o início, mas como não achei nenhum projeto resolvi botar a mão na massa e fazer, lógico que com muita ajuda do  pessoal aqui Clube do Hardware, 

Já está programado aqui, vou testar até o fim de semana, estou bem corrido com serviço aqui, se quiser algo meio preciso pode usar um esqueminha com NE555, mas aconcelhou você aguardar eu postar os resultados.

E sua moto é com carburador ou injeção?

Link para o comentário
Compartilhar em outros sites

@ComandateGustavo Eu li tudo, foi sensacional a trajetória desse projeto, por isso vou esperar o resultado sim!! E se possível quero montar um também ! Não sou muito bom com programação, mas consigo ler entender o código.
Minha moto é uma CG 150 injetada, atualmente se encontra com um modulo piggyback FuelController, possui o sistema de corte de ignição , mas o corte desse modulo não me agrada muito, então foi ai que pensei em montar o famoso 3Step com o arduino, seguindo a função do botão para o 'burnout', ai comecei as pesquisas pela internet e parei aqui, com muita coisa para aprender. 
Espero conseguir montar o meu também e postar o resultado aqui. 

Link para o comentário
Compartilhar em outros sites

Em 21/04/2021 às 15:51, Ricardo Bariquelo disse:

Espero conseguir montar o meu também e postar o resultado aqui.

Vai conseguir sim! E eu fui ver o preço de um 3step e é bem caro, então resolvi pesquisar e não achei nenhum circuito  que tivesse um resultado legal assim estou aqui, dá bastante trabalho mas vale a pena, assim aprendemos bastante e abre oportunidades para desenvolver bem mais coisas, além de ficar mais barato kkkkk vou testar amanhã o limitador.

 

 

Hoje a noite tive um tempinho e quis alterar o código para ver se conseguia alterar a frequência de 120 para um valor que pode ser alterado na hora com um potenciometro, compilei montei e testei, meio que funciona meio que não...

 

Citação

// --- Bibliotecas Auxiliares ---
#include <LiquidCrystal_I2C.h> //inclui biblioteca lcd
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

// --- Mapeamento de Hardware ---
#define inFreq   2  //entrada para medir a frequência no pino digital 2
#define outrele  7
#define inbotao  4
#define pot     A0   

// --- Variáveis Globais ---
const int rele=7;
long freq, counter;
int pulseCount;
boolean pulse;


// --- Configurações Iniciais ---
void setup() 
{
  pinMode(pot,INPUT);
  pinMode(inFreq,INPUT);    //Configura como entrada
  pinMode(inbotao,INPUT_PULLUP);
  pinMode(rele, OUTPUT);
  lcd.init();
  lcd.setCursor(2,0);      //Posiciona cursor na coluna 3, linha 1
  
  pulse = 0x01;             //Seta variável de controle
  
} //end setup


// --- Loop Infinito ---
void loop() 
{
  int x = analogRead(pot);
  int y = map(x,0,1023,0,200);
  lcd.setCursor(5,0);  
  lcd.print(y); 
  counter = millis();      //counter recebe o valor do tempo em ms
  
  if(digitalRead(inFreq))  //Entrada de frequência em nível alto?
  {                        //Sim...
  
    if(pulse) pulseCount++;  //incrementa pulseCount se variável de controle for verdadeira
     
    pulse = 0x00;            //limpa variável de controle

  }
  else                     //Não...
  {
    pulse = 0x01;          //Seta variável de controle
  }


  if(counter%500 == 0x00)  //Passaram-se 200 ms?
  {                        //Sim...
    freq = pulseCount*2;   //Atualiza frequência (200 x 5 = 1000ms)
    lcd.setBacklight(HIGH);
    lcd.setCursor(5,1);   //Posiciona cursor na coluna 6, linha 2
    lcd.print(freq);      //Imprime valor atual da frequência
    lcd.print("Hz");      //Imprime "Hz"
        
    
    pulseCount = 0x00;     //Reinicia contador
  }
  
if ((freq > y)||(!(digitalRead(inbotao)))) { 

  if (((counter / 250) % 2) == 1) {
    digitalWrite(rele, HIGH); //liga por 500 milisgundos o led se freq maior que 120
  }
  else
  {
    digitalWrite(rele, LOW); //desliga por 500 milisgundos o led se freq maior que 120
  }
}
 else
{
  digitalWrite(rele, LOW); //desliga o led se freq menor que 120

}
}
  
 

Dessa forma meio que funciona, mas a leitura de frequência ficou toda zuada, está variando uns 300Hz 😳 curiosamente se eu tirar as linhas: 

 

Citação

lcd.setCursor(5,0);  
  lcd.print(y); 

aí a medição de frequência funciona normalmente sem problema nenhum e o potênciometro também,  será que o código está errado @Thiago Miotto ?

 

Ou será que esse problema está sendo causado pelo que o @.if e o @aphawk disseram anteriormente, pode ser limitação ou alguma coisa causada pelo uso de bibliotecas do arduino?

  • Triste 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
6 horas atrás, ComandateGustavo disse:

curiosamente se eu tirar as linhas: 

Funções  e mais ainda as perfumadas, maqueadas, lindas e maravilhosas e nada otimizadas da plataforma arduína tomam tempo o que compromete o sistema quando a correta temporização é o quesito mais importante. Enquanto imprime no display, o tempo e contador estão fazendo a festa. Isso corrobora ainda mais o que dissemos sobre o domínio do hw e claro do sistema/desafio em si.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

12 horas atrás, ComandateGustavo disse:

curiosamente se eu tirar as linhas: 

 

Citação

lcd.setCursor(5,0);  
  lcd.print(y); 

aí a medição de frequência funciona normalmente sem problema nenhum e o potênciometro também,  será que o código está errado @Thiago Miotto ?

 

Ou será que esse problema está sendo causado pelo que o @.if e o @aphawk disseram anteriormente, pode ser limitação ou alguma coisa causada pelo uso de bibliotecas do arduino?

 

Bom, vou dar uma dica ... essas duas instruções demoram entre 20 e 25 milisegundos para serem feitas ( medí o tempo do Bascom para fazer a mesma coisa ) ..... já devem dar uma boa diferença no seu próximo comando que pega a temporização em milisegundos .

 

Nesse caso a biblioteca não tem nada a ver com o problema..... é a maneira que seu programa está funcionando, ele não aceita essa "demora"  extra causada pelo uso do display ....

 

É o problema de não se usar uma verdadeira base de tempo via interrupt de hardware .... ou uma contagem de pulsos precisa idealmente também feita por hardware.

 

Deixar tudo para o software ... teria de reescrever o jeitão de seu programa, enquanto os pulsos sejam contados por exatos 500 mseg nada pode ser feito, quando você terminar esse tempo e tiver o resultado da contagem dos pulsos aí sim você pode apresentar no display e fazer as suas outras funções.

 

Paulo

 

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@aphawk @.if @Thiago Miotto  Oi pessoal, hoje iria testar no carro do jeito que está pra ver se funciona e não deu tempo, fiquei o dia todo trocando fios organizando tudo em baixo do painel do carro, estava bem bagunçado, fios que não vão pra lugar nenhum, nem imaginava que em baixo do painel tinha tanto fio, se for medir tudo em linha reta deve passar de 1km...

 

Voltando ao circuito tentei usar a função interrupt RISING e na hora de compilar não deu erro, mas depois que carreguei pro arduino travou ele liga e já congela... Podem ver onde estou errando por favor? Fiz meio baseando no código que o @mlegnari  passou.

 

Citação

// --- Bibliotecas Auxiliares ---
#include <LiquidCrystal_I2C.h> //inclui biblioteca lcd
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

// --- Mapeamento de Hardware ---

#define outrele  7
#define inbotao  4
#define pot     A0   

// --- Variáveis Globais ---
const int rele=7;
long freq, counter;
int pulseCount;
boolean pulse;
unsigned int inFreq;

// --- Configurações Iniciais ---
void setup() 
{
  attachInterrupt(0, inFreq, RISING);
  pinMode(pot,INPUT);
  pinMode(inFreq,INPUT);    //Configura como entrada
  pinMode(inbotao,INPUT_PULLUP);
  pinMode(rele, OUTPUT);
  lcd.init();
  lcd.setCursor(2,0);      //Posiciona cursor na coluna 3, linha 1
  
  pulse = 0;             //Seta variável de controle
  
} //end setup


// --- Loop Infinito ---
void loop() 
{
  delay(1000);
  detachInterrupt(0);
  int x = analogRead(pot);
  int y = map(x,0,1023,0,200);
  counter = millis();      //counter recebe o valor do tempo em ms
  
  if(digitalRead(inFreq))  //Entrada de frequência em nível alto?
  {                        //Sim...
  
    if(pulse) pulseCount++;  //incrementa pulseCount se variável de controle for verdadeira
     
    pulse = 0x00;            //limpa variável de controle

  }
  else                     //Não...
  {
    pulse = 0x01;          //Seta variável de controle
  }


  if(counter%500 == 0x00)  
  {                        //Sim...
    freq = pulseCount*2;   //Atualiza frequência (500 x 2 = 1000ms)
    lcd.setBacklight(HIGH);
    lcd.setCursor(5,1);   //Posiciona cursor na coluna 6, linha 2
    lcd.print(freq);      //Imprime valor atual da frequência
    lcd.print("Hz");      //Imprime "Hz"
        
    
    pulseCount = 0x00;     //Reinicia contador
  }
  
if ((freq > y)||(!(digitalRead(inbotao)))) { 

  if (((counter / 250) % 2) == 1) {
    digitalWrite(rele, HIGH); //liga por 500 milisgundos o led se freq maior que 120
  }
  else
  {
    digitalWrite(rele, LOW); //desliga por 500 milisgundos o led se freq maior que 120
  }
}
 else
{
  digitalWrite(rele, LOW); //desliga o led se freq menor que 120

}
attachInterrupt(0, inFreq, RISING);
}
  
 

 

Link para o comentário
Compartilhar em outros sites

@mlegnari realmente me enganei nessa parte, corrigi algumas coisas e dessa vez o display acendeu mas não sai de 0Hz o que será que fiz errado agora? Não deu nenhum erro na hora de compilar. Hoje também consegui os componentes para montar o filtro do circuito que você passou.

 

Citação

// --- Bibliotecas Auxiliares ---
#include <LiquidCrystal_I2C.h> //inclui biblioteca lcd
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

// --- Mapeamento de Hardware ---

#define outrele  7
#define inbotao  4
#define pot     A0   

// --- Variáveis Globais ---
const int rele=7;
long freq, counter;
int pulseCount;
boolean pulse;
unsigned int inFreq;


// --- Configurações Iniciais ---
void setup() 
{
  attachInterrupt(0, inFreq, RISING);
  pinMode(pot,INPUT);
  pinMode(inFreq,INPUT);    //Configura como entrada
  pinMode(inbotao,INPUT_PULLUP);
  pinMode(rele, OUTPUT);
  lcd.init();
  lcd.setCursor(2,0);      //Posiciona cursor na coluna 3, linha 1
  
  pulse = 0;             //Seta variável de controle
  
} //end setup


// --- Loop Infinito ---
void loop() 
{
  detachInterrupt(0);
  int x = analogRead(pot);
  int y = map(x,0,1023,0,200);
  counter = millis();      //counter recebe o valor do tempo em ms
  
  if(digitalRead(inFreq))  //Entrada de frequência em nível alto?
  {                        //Sim...
  
    if(pulse) pulseCount++;  //incrementa pulseCount se variável de controle for verdadeira
     
    pulse = 0x00;            //limpa variável de controle

  }
  else                     //Não...
  {
    pulse = 0x01;          //Seta variável de controle
  }


  if(counter%500 == 0x00)  
  {                        //Sim...
    freq = pulseCount*2;   //Atualiza frequência (500 x 2 = 1000ms)
    lcd.setBacklight(HIGH);
    lcd.setCursor(5,1);   //Posiciona cursor na coluna 6, linha 2
    lcd.print(freq);      //Imprime valor atual da frequência
    lcd.print("Hz");      //Imprime "Hz"
        
    
    pulseCount = 0x00;     //Reinicia contador
  }
  
if ((freq > y)||(!(digitalRead(inbotao)))) { 

  if (((counter / 250) % 2) == 1) {
    digitalWrite(rele, HIGH); //liga por 500 milisgundos o led se freq maior que 120
  }
  else
  {
    digitalWrite(rele, LOW); //desliga por 500 milisgundos o led se freq maior que 120
  }
}
 else
{
  digitalWrite(rele, LOW); //desliga o led se freq menor que 120

}
attachInterrupt(0, inFreq, RISING);
}
  
 

 

Link para o comentário
Compartilhar em outros sites

Você está usando a interrupção errada

 

https://www.arduino.cc/reference/pt/language/functions/external-interrupts/attachinterrupt/

Ela chama um void que você não escreveu
Além disso, com interrupção, é possível utilizar o delay, justamente pois a interrupção funciona enquanto está ocorrendo o delay, na verdade ela serve justamente pra isso, pois durante o 1 segundo de delay o arduino vai se focar só em contar os pulsos do pino que você declarar.
Claro, se você quer uma atualização maior, use delay(300), delay(200) e assim por diante.

Link para o comentário
Compartilhar em outros sites

12 minutos atrás, Thiago Miotto disse:

eu tinha lido essa parte, mas não consegui compreender totalmente, a função interrupt é bem mais complexa do que as outras funções do arduino.

 

Citação

#define outrele  7
#define inbotao  4
#define pot     A0   


// --- Variáveis Globais ---
const int rele=7;
const byte interruptPin = 2;
long freq, counter;
int pulseCount;
boolean pulse;
unsigned int inFreq;


// --- Configurações Iniciais ---
void setup() 
{
  attachInterrupt(0, inFreq, RISING);
  pinMode(pot,INPUT);
  pinMode(inFreq,INPUT);    //Configura como entrada
  pinMode(inbotao,INPUT_PULLUP);
  pinMode(rele, OUTPUT);
  lcd.init();
  lcd.setCursor(2,0);      //Posiciona cursor na coluna 3, linha 1
  
  pulse = 0;             //Seta variável de controle
  
} //end setup


// --- Loop Infinito ---
void loop() 
{
  detachInterrupt(0);
  int x = analogRead(pot);
  int y = map(x,0,1023,0,200);
  counter = millis();      //counter recebe o valor do tempo em ms
  
  if(digitalRead(inFreq))  //Entrada de frequência em nível alto?
  {                        //Sim...
  
    if(pulse) pulseCount++;  //incrementa pulseCount se variável de controle for verdadeira
     
    pulse = 0x00;            //limpa variável de controle

  }
  else                     //Não...
  {
    pulse = 0x01;          //Seta variável de controle
  }


  if(counter%500 == 0x00)  
  {                        //Sim...
    freq = pulseCount*2;   //Atualiza frequência (500 x 2 = 1000ms)
    lcd.setBacklight(HIGH);
    lcd.setCursor(5,1);   //Posiciona cursor na coluna 6, linha 2
    lcd.print(freq);      //Imprime valor atual da frequência
    lcd.print("Hz");      //Imprime "Hz"
        
    
    pulseCount = 0x00;     //Reinicia contador
  }
  
if ((freq > y)||(!(digitalRead(inbotao)))) { 

  if (((counter / 250) % 2) == 1) {
    digitalWrite(rele, HIGH); //liga por 500 milisgundos o led se freq maior que 120
  }
  else
  {
    digitalWrite(rele, LOW); //desliga por 500 milisgundos o led se freq maior que 120
  }
}
 else
{
  digitalWrite(rele, LOW); //desliga o led se freq menor que 120

}
attachInterrupt(0, inFreq, RISING);
}
  
 

eu fiz mais correções mas mesmo assim não sai de 0Hz. Com certeza fiz algo errado mas não sei o que, eu li várias vezes aquela documentação do arduino e também já alterei o código várias vezes umas vezes dava erro na hora de compilar, outras vezes travava outras congelava e agora fica travado em 0

Link para o comentário
Compartilhar em outros sites

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...