Olá pessoal.

Estou utilizando algumas funções como o micros() (4 a 1024) e millis() (1 a 100), em loop, para gerar contadores para situações específicas. Estes valores são um pouco pequenos e ao utilizar a interrupção, está gerando problemas para mim.

Vocês conhecem alguma forma de realizar a leitura de RPM no arduino, para 4000+ RPM, sem utilizar a interrupção? Talvez algum recurso externo? (de preferência simples e barato hahaha)

Exibições: 465

Responder esta

Respostas a este tópico

Bom dia TM,

1. A função micros() com valores inferiores a 10 me parece um pouco instável, devido ao tempo de processamento

       das outras instruções envolvidas no processo.

2.  Porque você recomenda que a medida de \RPM não pode usar interrupções?

RV

eu utilizo um contador com millis para algumas situações. 

Sem interrupção, o contador me retorna um valor (50....100...200...300...). Com interrupção, ele me retorna "1".

Não li a função da interrupção, mas tendo em vista o fenômeno, acredito que ele gere uma "pausa" no sistema para realizar a contagem dos pulsos. Quando a interrupção finaliza, o valor do millis() já passou a variável comparativa.

Minha solução, até o momento foi fazer um contador "no braço":

#define rpm_porta 8

int rpm_intervalo = 100;
int rpm_contador = 0 ;
uint32_t rpm_millis_anterior ;
int Pre;

void rpm_setup() {
Serial.begin(9600);
pinMode(rpm_porta, INPUT);
Pre = digitalRead(rpm_porta);
rpm_millis_anterior = millis() ;
}

void rpm_loop() {

if ( millis() - rpm_millis_anterior > rpm_intervalo ) {
Serial.print("RPM: ");
Serial.println(rpm_contador * 600/4);
rpm_millis_anterior = millis() ;
rpm_contador = 0;
}
if (digitalRead(rpm_porta) != Pre) {
rpm_contador = rpm_contador + 1;
Pre = digitalRead(rpm_porta);
}
}

Estou realizando testes ainda, o código atual é meio grosseiro e não apresenta muita precisão mas, aparentemente, na casa das centenas e milhares, ele apresenta um valor correto.

Vou melhora-lo até surgir outra opção.

Boa tarde, 

Você tem vários meios de medir RPM. 

Você pode medir com uma taxa de leitura mais rápida ou mais lenta.

Exemplo = 4000 RPM 

a) Se for medir RPM através da frequência dos pulsos

    RPM = 60 x RPS    RPS = 4000 / 60 = 66,66 Hz

    Essa frequencia é baixa! Esta tendo dificuldade em medi-la com interrupções? 

b) Pode medir RPM, contando a quantidade de pulsos durante um intervalo de um minuto ou até menos. 

    Para um minuto = 4000 pulsos

    Para meio minuto = 2000 pulsos 

   Muito lento para o Arduino. Qual seria a sua dificuldade? 

Com sua perspectiva, acredito que minha dificuldade seja conhecimento do hardware ou de programação. hahaha.

No arduino, eu estava utilizando um pwm por software referenciando um registrador, na ideia de obter uma boa frequência e realizar um ajuste fino de duty com micros() (como é feito, normalmente, com millis()). Para obter um valor de referência de ciclos, eu adicionava um contador num "if millis()". (Com led. Funcionou)

Ao utilizar a interrupção, para obter o valor de uma RPM, a variável sempre retornava igual a "1". Sem a interrupção, retornava 8mil~115mil (dependendo das funções adicionadas).

Isso me fez pensar em desistir da interrupção pois, num mero palpite, imagino que teria perda na frequência.

O problema agora, é que, ainda que funcione o código que escrevi acima, mas a PWM por software está gerando um problema num dos motores. A cada 1+- seg, ele da um "chute" (como um aumento rápido de torque, que só é sentido ao tocar o motor). Motivo? não sei. Freqüência? talvez. meu multímetro é simples, não tenho como ver frequências.

Utilizar o analogWrite não é um bom recurso, pois a frequência é baixa, obrigando a iniciar em quase 170/255 nos pinos 3, 9, 10, 11, e 90/255 nos pinos 5 e 6 (que já não é tããão ruim), além do mais, eu fico limitado a 6 pwm (preciso de 8)

Também vi que existem umas bibliotecas que ajustam a frequencia de PWM, principalmente direcionado aos 25khz, mas fica refém de apenas 2 á 3 portas com essa frequência pré-definidas. Com 3, altera o timer0.

Pessoalmente, a forma que encontrei, para obter a rpm sem gerar nenhum "gargalo" foi o código que citei, mas tenho 99% de certeza que você tem uma forma melhor, mais rápido, que não trava o sistema de forma alguma hehehe (reconheço a diferença de conhecimento entre mim e uma boa parcela dos membros do fórum).

Pàra o PWM, imagino que terei que fazer um circuito por fora (link do post que criei sobre 555, arduino e pwm  obs- Ainda estou pesquisando sobre os CI's citados no post), o problema do 555 é que preciso de um "potenciômetro digital", vi uma referência no WrKits sobre o 4066 (que não vende aqui na cidade).

Final das contas, to meio travadão, caçando qualquer informação para tentar pegar a direção certa.

Uma coisa é certa. Concluindo isso, vou fazer uma postagem dando o passo-a-passo, pois sei que não sou o primeiro e provavelmente não serei o ultimo a ter essa dificuldade hahahaha.

Adicionando uma nova informação.

o "chute" nos motores acontece SEMPRE que um Serial.print é chamado e o pwm é por código.

Nova informação:

o limite de informação é de 53 caracteres pela serial, dentro de 1 segundo. Mais que isso, o motor volta a aplicar "chutes".

obs- até o momento, teste com apenas 1 motor.

olá Tiago.

      Uma dica:   como sua Serial  está a 9600 bps,  o tempo para receber estes tais 53 caracteres,  será próximo a 10 x 53 / 9600 = 0.0552 segundos,  ou seja,  próximo a 55 mili-segundos.  O resultado deste cálculo te diz algo?  Pense bem.

      Veja:  medir a RPM através de IRQs (Interrupções),  é a forma mais confiável e precisa de se fazer isso no Arduino.  Então porque não está funcionando para vc?  A resposta também me parece clara:  vc não está usando a técnica correta para tratamento das IRQs.  E para usar da forma correta,  há algumas coisas que precisam ser feitas no seu código (e eventualmente no seu Hardware),  mas todas estas coisas são bem simples. Logo é apenas preciso conhecer a técnica.

      Então mais uma dica:   dê uma vasculhada nos tópicos onde participei aqui no LDG, pois que eu me lembre há pelo menos uns 5 tópicos onde eu implementei medições da RPM de Motores (inclusive automotivos). E sempre usei técnicas clássicas e confiáveis. E em todos os casos,  as medições alcançaram seus objetivos.

      Para procurar,  vá ao meu perfil aqui no LDG, e a partir de lá dê uma vasculhada na listagem de tópicos.  Há tópicos com implementações da medição de RPMs  desde 2018 até bem recentemente.

      Aqui tem dois deste ano:   "RPM Server"   e   "RPM vento"

      No entanto estes dois links,  são implementações um pouco mais complexas devido aos assuntos dos tópicos correspondentes.  Mas procurando conforme te disse, vc irá encontrar alguns com códigos extremamente mais simples e muito didáticos (pode acreditar).

      Abrçs

      Elcids

Como sempre, eu não entendo do assunto e demoro um pouco para poder responder (pois preciso ler alguma coisa, ver algum vídeo ou alguma outra postagem para chegar menos ignorante).

Vi suas postagens e não vou mentir, tive dificuldade para entender. A do WebServer, tem BASTANTE coisa (que foi a que mais olhei), por vezes, fiquei confuso.

No final da vida, buscando comparativos, "adaptei" 2 códigos em 1. O primeiro utilizando o pulseIn, o segundo utilizando a interrupção, e tentei criar um "atraso" para parecer menos "injusto" o comparativo.

O que percebi, é que com o pulse in, obtive um valor de APRESENTAÇÃO talvez "melhor", entretanto, com a interrupção, aparentemente, tive maior folga no processador.

Anexos

Olá. Desde já, agradecendo a resposta de todos.

Acredito que minha ideia inicial (gerar pwm por software para todos os canais e ter uma frequencia de 1~35khz nos canais) não tenha sido uma das mais inteligentes, pois ao adicionar uma tonelada de rotinas, ela ficou impraticável (motivo pelo qual evitava interrupções e uma série de coisas, pois um "delay(1)" já atrapalhava tudo, o millis() eu tinha descartado, pois achei lento, e o micro() estava sendo usado).

A solução que encontrei foi utilizar um circuito com o 555 (disponibilidade) e um potenciômetro, para gerar o sinal pwm, 

O potenciômetro utilizado, para testes, foi o mecânico de 10k, mas terei que adquirir um digital.

Com relação a contagem da RPM, com a condição citada, utilizar a interrupção ou o pulseIN, certamente serão as melhores e mais precisas formas. Já tinha usado as duas em outras situações, e responderam bem. Resta agora fazer o teste com os circuitos externos. hehehe

Com relação ao potenciômetro digital (aqui eu tive dificuldade), sofri um pouco para achar (leigo é brabo) até o momento, o alvo é o x9c103, Qual a opinião de vocês? tem alguma outra sugestão?

obs- após a conclusão do projeto, devo fazer um modelo e postar aqui no site, pois não fui o primeiro e, certamente, não serei o ultimo leigo a ficar perdido hehehe.

Bom dia Tiago,

Se quer gerar pulsos com controle do duty cycle (PWM), tem mais essa opção:

Gerador de sinais digitais com o ESP32 (3,3V). 

Frequencia de 1 Hz a 40 MHz (com algumas limitações). 

http://labdegaragem.com/forum/topics/frequenc-metro-1?commentId=622...

olá José Gustavo Abreu Murta . Vi a postagem e achei bastante interessante. 

Se eu entendi direito, na sua postagem, a ideia é transformar o uno/esp em um frequencímetro (inicialmente) e posteriormente num gerador de frequências (com limitações). 

Por não ter um frequencímetro em mãos (normalmente tenho que ir até alguém que tenha, para realizar o teste), acredito que este recurso vá ser bastante útil nas minhas atividades. Assim que os novos materiais chegarem, farei um teste.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço