Boa noite pessoal, estou fazendo um limitador de giro bem simples, ideia e achar a frequência que o Arduíno vai ler do distribuidor na rotação desejada e limitar (ligar um rele para o corte) cortando, ele automaticamente vai diminuir a frequência e voltar ao loop... ler a frequência foi fácil porem a regra if não esta a funcionar.. segue o codigo

volatile uint32_t rpm;//Váriavel que armazena as rotações.


void setup()
{
pinMode(5,OUTPUT);
pinMode(1,INPUT_PULLUP);
Serial.begin(115200);//Inicia a Serial.
attachInterrupt(1, ctt, RISING);//Habilita a interrupção 0 no pino 2.
}

void loop()
{
delay(1000);//Aguarda um segundo.
Serial.println(rpm * 30);//Mostra o RPM.
rpm = 0;//Reseta a váriavel para proxima leitura.

//Como estamos lendo a cada UM segundo, usariamos RPM*60 para determinar as rotações por minuto,
//porém, como foi dito na explicação, é preciso dividir o valor por 2, por isto 30!

if ( rpm >= 1200){
digitalWrite(5, HIGH);
}

else {
digitalWrite (5, LOW);
}

}

void ctt()
{
rpm++;//Incrementa a váriavel.
}

Se alguém poder me dar uma luz agradeço. 

Exibições: 777

Responder esta

Respostas a este tópico

bom dia Mauricio.

    Embora seu programa seja muito simples, ele tem alguns problemas conceituais. Você declarou   a variável usada dentro da ISR (a variável que vc chamou de "rpm") usando o qualificador "volatile", o que está correto. Porém a forma como você usa esta variável fora da ISR, está inadequada. Observe que esta variável "rpm" está sendo constantemente atualizada dentro da ISR, e é por isso que usamos o qualificador "volatile", pois isto força o compilador agerar um código que sempre "lê" esta variável quando ela é acessada fora da ISR.

       Então, você não pode acessar a variável "rpm" a qualquer instante, e esperar que o valor dela seja mantido. Isto não vai acontecer, já que a ISR está sendo executada na mesma taxa dos pulsos que provocam a Interrupção.

       Logo, o que você precisa fazer, é uma amostragem do valor da variável "rpm", e usar esta amostra no restante do processamento (neste caso o cálculo da rotação em RPM e liga/desliga do Relé).

       Após processar a amostra atual, você pode então zerar a variável "rpm", e iniciar a contagem do período de tempo para a próxima amostragem (neste caso vc está usando 1 segundo). Não há problema o fato da ISR continuar sendo executada (no "background")  enquanto vc faz qualquer outro processamento, já que quando vc zerar a variável "rpm", causará um sincronismo automático entre o processamento normal e a própria ISR.

      Assim, alterei seu código de forma a adequar o mesmo para a amostragem da variável  "rpm". Apenas mudei o nome da variável para "counter", pois de fato esta não possui o valor do giro em RPM, e sim a contagem de giro no período que vc determinou (neste caso 1 segundo).

     No anexo deste post, vc encontrará duas versões do código: uma usa a função "delay" para gerar a temporização de 1 segundo. A outra versão usa a função "Millis" para fazer esta temporização. Você vai observar que a versão usando o "Millis" tem uma precisão melhor que usar o "delay". Isto ocorre porque a função "delay" pode ter o tempo ligeiramente "dilatado" por código executando no background do Arduino (inclusive a sua própria ISR). É possível impedir essa dilatação, mas é totalmente desaconselhável fazer isso (pois vc paraliza o "background", o que pode causar problemas muito maiores). Assim caso vc necessite de uma precisão maior, aconselho usar a versão baseada no Millis.

     Para uma visualização rápida, estou incluindo "prints" das duas versões nas duas figuras seguintes.

     Veja o print para a versão usando "delay":

     E agora o print para a versão usando o "Millis":

     Procure atentar para a sequência em que os statements (as linhas de código em C) são executados, pois esta sequencia faz toda a diferença para que o código funcione corretamente.

     Detalhe: após ter reescrito os códigos, testei ambos antes de disponibilizar aqui, e funcionaram perfeitamente.

     E para quem quiser testar de forma rápida, vai uma dica:  mude o tipo da entrada digital na função "setup", de "INPUT_PULLUP" para apenas "INPUT", e então "encaixe" um fio de uns 10 cm no pino 2 do Arduino (o pino usado para gerar as Interrupções no código). Essa mudança tornará a entrada no pino 2, extremamente sensível a ruídos externos, e o fio encaixado funcionará como uma "antena". Com isso o pino 2 captará facilmente o sinal de 60 Hz induzido pela rede elétrica, disparando assim IRQs exatamente na taxa de 60 pulsos por segundo. Com esta taxa de IRQs, o Arduino indicará uma rotação de 1800 RPM (resultado de 30x60, já que seu fator de cálculo é 30).

      Note que o código "ajustado", está escrito usando alguns "#defines", ao invés de fixar valores numéricos dentro do corpo do programa. Procure usar esta prática, pois simplifica o entendimento e a manutenção do seu código, já que em código, nomes são normalmente mais esclarecedores que números.

      Caso vc tenha quaisquer dúvidas em relação ao funcionamento do código, fique à vontade pra perguntar.

      Abrçs,

      Elcids

Anexos

Boa noite, primeiramente muito obrigado me ajudou muito, fiz um teste pratico em um cooler aqui em casa funcionou muito bem gostei de como colocou as variáveis, estarei testando no veiculo amanha e ver se fica bom.

ok Maurício.

     Gostaria de lembrar de um aspecto prático:  se seu motor for à combustão, e as explosões forem comandadas por velas automotivas (caso dos motores à álcool e gasolina), fique atento aos ruídos eletromagnéticos gerados por este Sistema. As ignições por este processo costumam gerar ruídos eletromagnéticos muito fortes, as quais quase sempre interferem no funcionamento dos circuitos eletrônicos. Isto ocorre porque normalmente os circuitos digitais trabalham com tensões baixas (de 5V para menos), o que os tornam "alvos" fáceis dos ruídos eletromagnéticos originados na ignição dos motores a combustão. E estes ruídos podem facilmente atingir picos instantâneos de várias dezenas de Volts, ou seja, são fortes.

       Não sei como vc está gerando os pulsos correspondentes aos giros do Motor: se é um sensor elétrico, ótico, ou magnético. Cada um destes sensores tem uma imunidade diferente em relação aos ruídos eletromagnéticos). Mas pode ocorrer de que os pulsos que vc está gerando sofram interferências provenientes do sistema de ignição. Se isto ocorre, então seu sistema de medição com o Arduino vai indicar valores errados ou imprecisos, já que a quantidade e qualidade dos pulsos pode estar prejudicada.

      Caso vc tenha este problema, uma solução simples é filtrar os pulsos através de um "Filtro Passa-Baixas", e em seguida garantir que sejam pulsos digitais (através de circuitos "Schmitt Trigger"). São circuitos muito simples e baratos. Caso vc precise de orientação de como fazer isso, me avise que posso te orientar.

      Por hora, desejo boa sorte com seus testes, e grandes resultados!!!

      Ah, fiquei com uma curiosidade: qual método vc resolveu usar? usou o método baseado no "delay", ou o método baseado no "Millis"?

      Abrçs

      Elcids

Olá, na questão ruídos não tive problema aparente de imediato, fiz um teste bem breve e funcionou, usei o sinal do sensor hall direto do distribuidor vindo com um cabo coaxial aterrado junto ao chassis do veículo e do Arduíno. Usei Millis mesmo e tive que diminuir o valor pra acionar mas rápido, o carro está em fase de montagem e acerto ainda, parte de suspensão e outras coisas... Porém assim q ele estiver livre para testes farei um vídeo mostrando como ficou.

Bom dia , 

Como já disse anteriormente, não espere muita precisão com Tacômetro (medidor de RPM) com Arduino.

Devido à construção dos registradores internos do Micro-controlador, sempre haverá um erro significativo. 

Já fiz alguma experiências com o NodeMCU ESP32 e achei incrível o uso dos registradores para gerar pulsos. 

E o Clock do ESP32 é ultra-rapido.

Não testei tacômetro ainda com ele, mas tenho certeza que será expressivamente muito melhor ! 

Bom dia, poise estou com um projeto que até vi q VC se familiarizou em roda fônica em um artigo. 

Quero fazer uma ignição com roda fonica, inclusive acabei de comprar o esp32, já tinha visto e comparado.

Abri um tópico aqui no grupo (rodafonica, substituir distribuído.) se quiser da uma olhada lá agradeço.

Chegando o nodemcu vou testar a entrada de sinal pra ver, tenho uma noção boa mas não sei desenvolver muito na programação... Vamos ver 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço