Como medir a rotação de um motor com o sensor de velocidade LM393
Medir a velocidade de um motor pode ser muito útil em projetos de robótica, e você pode fazer isso utilizando o sensor de velocidade encoder LM393. Com ele você pode medir a rotação de motores, calcular a velocidade de robôs, definir limites de deslocamento, entre outras aplicações.
Esse módulo pode também ser utilizado para contagem de pulsos ou como chave de fim de curso. Ele utiliza o chip comparador LM393 (datasheet), e na sua extremidade tem um optointerruptor com um vão de 5 mm no qual você pode utilizar um disco encoder ou algum outro dispositivo para interromper o feixe de luz.
Módulo sensor de velocidade LM393
O módulo possui 4 pinos, sendo dois de alimentação (3 à 5V e GND), uma saída digital (DO) e uma analógica (A0).
O optointerruptor MOCH22A tem de um lado um led infravermelho, e no outro lado um fototransistor. Quando o feixe de luz infravermelha é interrompido, a saída digital D0 envia o sinal 1, caso contrário, o saída permanece em nível 0.
Vamos testar esse sensor utilizando dois programas: um para medir a velocidade de um motor, e outro como uma chave de fim de curso. Nesses dois exemplos vamos usar apenas a saída digital D0 do módulo.
Medindo a rotação de um motor
Para medir a rotação de um motor, ligue o sensor de velocidade no Arduino com o pino D0 ligado à porta digital 2:
Para testar o circuito, usamos um disco encoder ligado ao motor. O disco possui várias “aberturas” por onde o feixe de luz vai passar e gerar um pulso na saída digital.
O disco que estamos usando tem 20 aberturas, e esse número deve ser colocado no programa (linha 11), que vai usar essa informação para calcular a rotação do motor.
//Programa: Sensor de velocidade Arduino LM393 //Autor: Arduino e Cia //Pino ligado ao pino D0 do sensor int pino_D0 = 2; int rpm; volatile byte pulsos; unsigned long timeold; //Altere o numero abaixo de acordo com o seu disco encoder unsigned int pulsos_por_volta = 20; void contador() { //Incrementa contador pulsos++; } void setup() { Serial.begin(9600); //Pino do sensor como entrada pinMode(pino_D0, INPUT); //Interrupcao 0 - pino digital 2 //Aciona o contador a cada pulso attachInterrupt(0, contador, FALLING); pulsos = 0; rpm = 0; timeold = 0; } void loop() { //Atualiza contador a cada segundo if (millis() - timeold >= 1000) { //Desabilita interrupcao durante o calculo detachInterrupt(0); rpm = (60 * 1000 / pulsos_por_volta ) / (millis() - timeold) * pulsos; timeold = millis(); pulsos = 0; //Mostra o valor de RPM no serial monitor Serial.print("RPM = "); Serial.println(rpm, DEC); //Habilita interrupcao attachInterrupt(0, contador, FALLING); } }
Carregue o programa no Arduino e utilize o serial monitor para visualizar a velocidade de rotação do motor.
Utilizando o módulo como chave de fim de curso
Você pode utilizar esse módulo também como chave de fim de curso, para indicar o correto posicionamento de um motor ou alguma estrutura, como por exemplo uma porta, janela, uma guia linear ou outra estrutura móvel.
Nesse caso, o sensor de velocidade funciona como se fosse uma chave liga/desliga, fazendo com que o programa execute uma rotina específica caso o feixe de luz do optointerruptor seja bloqueado.
Testamos essa configuração acrescentando no circuito anterior um motor de passo 28BYJ-48:
O programa usa a biblioteca Customstepper (download), que já usei anteriormente no post Controlando motor de passo 28BYJ-48 utilizando CustomStepper.
É feita uma monitoração simples da porta digital 2, e cada vez que é recebido o valor 1, a variável sentido tem o seu valor invertido.
//Programa: Sensor de velocidade LM393 - Chave de fim de curso //Autor: Arduino e Cia #include <CustomStepper.h> //Pino ligado ao pino D0 do sensor int pino_D0 = 2; //Define os parametros de ligacao do motor de passo CustomStepper stepper(8, 9, 10, 11, (byte[]) { 8, B1000, B1100, B0100, B0110, B0010, B0011, B0001, B1001 }, 4075.7728395, 12, CW); int sentido = 0; void setup() { Serial.begin(9600); //Pino do sensor como entrada pinMode(pino_D0, INPUT); //Define a velocidade do motor stepper.setRPM(12); //Define o numero de passos por rotacao stepper.setSPR(4075.7728395); } void loop() { int valor = digitalRead(pino_D0); if (valor != 0) { while (digitalRead(pino_D0) != 0) { delay(100); } //Inverte o sentido de rotacao sentido = !sentido; } delay(1); if (sentido == 0) { //Gira motor no sentido horario stepper.setDirection(CW); stepper.rotate(); } if (sentido == 1) { //Gira motor no sentido anti-horario stepper.setDirection(CCW); stepper.rotate(); } stepper.run(); }
Usando o programa acima, à cada vez que o feixe de luz do sensor é interrompido, o sentido de rotação do motor é alterado.
Gostou? Confira outros posts usando encoder aqui mesmo no Arduino e Cia!
Eu tenho o Sensor de Velocidade (não o módulo completo); 1) o que teria de ser mudado no circuito para eu poder ligá-lo no Arduino?
2) Era possível fazer um circuito com esse Sensor e um LCD para mostrar os dados? Obrigado
Boa noite,
Não fiz nenhum teste ainda apenas com o sensor, mas olhando o módulo, são poucos componentes que você vai precisar.
Quanto ao LCD, atualmente eu recomendo um módulo I2C para display LCD, assim você economiza várias portas do Arduino.
Abraço!
Olá estou fazendo o diagrama do meu projeto no Fritzing. Estou utilizando este sensor, porém não consegui ele no Fritzing, poderia me ajudar ?
Oi Alvanir,
Eu também não consegui achar esse componente no Fritzing, então pedi para desenharem separadamente…
Abraço!
me pudes pasar el diagrama del sensor
me pudes pasar el modulo del sensor para fritzing gracias
boa noite, onde acho os discos para acoplar nos motores?
Oi Arthur,
No Mercado Livre tem algumas opções de disco. Faça uma procura por "disco encoder".
Abraço!
boa noite. amigo gostei muito da sua explicação, porém gostaria de saber se você pode me ajudar a tirar uma dúvida. estou com um projeto aqui em que tenho que usar esse sensor para registrar a velocidade de um carro. minha pergunta é: se este disco ficar na roda do carro o sensor consegue fazer a leitura?
Boa tarde,
Isso depende de testes, mas pela velocidade do sensor, creio que funcionaria sem problemas.
Abraço!
Ola. Teria como utilizar este sensor como um anemometro?
Boa tarde,
Sim, sem problemas.
Abraço!
Como ficaria o programa para Arduino Mega 2560?
Oi Ricardo,
Você pode usar o mesmo programa.
Abraço!
Obrigadão
Valeu!!!! 🙂
Abraço.
Olá, vi apenas exemplos usando a saída digital que seria apenas o pulso do sensor… Porém no caso da saída analógica a saída seria o que? Possuo um projeto que necessita da leitura da velocidade de forma analógica (0-X Volts)
Boa noite,
Gostaria de saber que tipo de sensor poderia utilizar para medir a velocidade de um carrinho sem motor.
ola, uma duvida, eu tendo um sensor hall, tres fios na roda de um carro com sistema de airbag, o que teria que mudar no projeto acima para conseguir captar a velocidade da roda. Desde já obrigado 🙂
Onde posso obter o arquivo (Fritzing encoder FC-03)?
Olá. Primeiro muito obrigado pelo seu trabalho, ajuda muito.
Sabe se é possível ligar dois sensores em um memso arduino? estou tendo algumas dificuldades com a programação para ligar o segundo sensor…
valeu.
opa… passando para deixa um alô e dizer que o tutorial foi de grande serventia…
Opa.. bom saber…. 🙂
Abraço e obrigado!
Adilson
Parabéns pelo tutorial! Muito bom!
Gostaria de saber se é possível identificar a direção em que o motor está girando com esse sensor, ou seja, fazer leituras de velocidades tanto negativas quanto positivas.
Agradeço desde já.
Bom dia!
Para determinar a direção, vc precisaria de pelo menos dois sensores desse.
Abraço e obrigado!
Adilson
Bom dia, meu nome é Italo,
gostaria de saber se posso delimitar um número de rotações de um motor dc, que não seja o de passo, para abrir e fechar uma janela ou abri um portão por exemplo. Obrigado!
Oi Italo,
Pode sim, você pode usar um sensor de velocidade como esse do post e contar os pulsos enviados pelo módulo, determinando assim o quanto ele girou.
Abraço!
Boas podes me explicar melhor essa parte toda?
//Atualiza contador a cada segundo
if (millis() – timeold >= 1000)
{
//Desabilita interrupcao durante o calculo
detachInterrupt(0);
rpm = (60 * 1000 / pulsos_por_volta ) / (millis() – timeold) * pulsos;
timeold = millis();
pulsos = 0;
Olá!
Sou Jefferson, estou precisando do módulo LM393 para concluir o diagrama elétrico do meu TCC – Especialização Eng. Automação, Controle e Robótica, meu projeto é um robô seguidor de linha com braço robótico, com sistema de controle PID para velocidade.
Agradeço pelo apoio técnico das informações contidas no site, para conclusão das informações de meus estudos ao longo do curso.
Oi Jefferson,
Tudo bem? O que você precisa exatamente? Do componente do Fritzing ?
Abraço e obrigado por visitar o Arduino e Cia! 🙂
Adilson
Boa noite montei o tacômetro, a a rotação não esta confiável sendo que estou medindo a rotação de um motor de passo, no lcd que controla o motor está em 24rmp, com o teste que fiz fica variando muito, até de 15rmp a 45 rpm
Olá,qual a velocidade máxima para leitura?
Boa tarde ele suporta umidade e agua?
Não recomendo. 🙂
Abraço!
Adilson
Olá, boa noite! Estou fazendo um projeto de TCC, meu objetivo é diminuir colisão traseira entre carros, eu quero fazer com que o carro que estiver a trás consiga saber a velocidade do carro da frente (CASO O CARRO A FRENTE FAZER UMA FREADA BRUSCA), com a utilização de sensor ultrassônico (que vai fazer a função de informar quando o carro estiver muito perto do permitido pela legislação). ENFIM! PESQUISEI EM VÁRIOS SITES E O MAIS PRÓXIMO FOI O SEU, GOSTARIA DE SABER SE TEM ALGUM SENSOR OU COMPONENTE ELETRÔNICO QUE EU CONSIGA PROGRAMAR E SABER A VELOCIDADE DO CARRO A FRENTE? DESDE JÁ AGRADEÇO 🙂
Seria interessante avisar que as portas com interrupção sao especificas
https://www.arduino.cc/reference/pt/language/functions/external-interrupts/attachinterrupt/
Como funciona a saída analógica desse sensor? Qual a escala de saída? É em volts ou mA?
Agradeço se alguém tiver alguma informação.
A saída analógica (A0) recebe a informação real e direta do optointerruptor, ou seja, quando algum objeto começa passar na frente dele, vai enfraquecendo a captação da luz infravermelho do optointerruptor assim dando um efeito linear. É esse sinal linear que a saída analógica é capaz de captar. Diferente da saída digital (D0), que passa pelo comparador (LM393) fazendo com que só saia o sinal se o objeto estiver tampando totalmente o optointerruptor.
Oi amigo. Gostei muito do seu post. Tenho esse sensor de velocidade e gostaria que pudesse me ajudar. Queria utilizar ele como um contador de voltas ao invés de calcular o rpm. Como eu poderia fazer isso?
Oi David,
Depende do projeto e do tipo de equipamento que você vai usar, mas é relativamente simples. Usando o programa de exemplo do post, que tem 20 pulsos por volta, basta você criar um contador que a cada 20 pulsos, conta 1 volta.
Abraço!
Adilson
Bom dia estou a pensar num projecto de alterar um sistema de tracção cuja a velocidade é regulada em frequência só não sei se é possível, e penso ajuda nessa modificação é um trabalho académica.
Boa tarde. Comprei esse encoder, um disco com 20 furos, um motor cc 3V a 6V (https://www.makerhero.com/produto/motor-dc-3-6v-com-caixa-de-reducao-e-eixo-duplo/), que diz que a velocidade é de 200rpm a 6V. Estou utilizando uma alimentação de fonte externa de 5V. Logo, é de se esperar uma velocidade pouco abaixo dos 200rpm. Utilizei desse programa para testar o encoder e quando mede a velocidade do motor cc citado mostra na serial um valor em torno de 520rpm. Segue abaixo o código:
//Programa: Sensor de velocidade Arduino LM393
//Autor: Arduino e Cia
//Pino ligado ao pino D0 do sensor
int pino_D0 = 2;
int rpm;
volatile byte pulsos;
unsigned long timeold;
//Altere o numero abaixo de acordo com o seu disco encoder
unsigned int pulsos_por_volta = 20;
int IN3 = 6;
int IN4 = 7;
void contador()
{
//Incrementa contador
pulsos++;
}
void setup()
{
Serial.begin(9600);
//Pino do sensor como entrada
pinMode(pino_D0, INPUT);
//Interrupcao 0 – pino digital 2
//Aciona o contador a cada pulso
attachInterrupt(0, contador, FALLING);
pulsos = 0;
rpm = 0;
timeold = 0;
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop()
{
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
//Atualiza contador a cada segundo
if (millis() – timeold >= 1000)
{
//Desabilita interrupcao durante o calculo
detachInterrupt(0);
rpm = ((60 * 1000 / pulsos_por_volta ) / (millis() – timeold)) * pulsos;
timeold = millis();
pulsos = 0;
//Mostra o valor de RPM no serial monitor
Serial.print("RPM = ");
Serial.println(rpm, DEC);
//Habilita interrupcao
attachInterrupt(0, contador, FALLING);
}
}
O que há de errado?
Boa tarde,
Na interrupção o que é o comando FALLING?
Obrigado
Oi Guilherme,
O FALLING quer dizer que o microcontrolador vai detectar a interrupção na descida do sinal, ou seja, quando ele estiver 1 e passar para 0.
Abraço!
Adilson
Eu consigo utilizar ele juntamente com aquelas fitas listradas de impressora (do carrinho de impressão)?
Oi Alexandro,
Boa pergunta e ótima sugestão. Nunca tentei, vou ver se arrumo alguma para testar.
Abraço!
Adilson
ola bom dia gostaria de saber se e possível usar um sensor indutivo NPN 6-36V usando em um disco de ferro vasado, usando como contador de rpm?
Oi Mauricio,
Teoricamente sim, teria que ver o tipo de instalação, mas com o sensor indutivo também é possível.
Abraço!
Adilson
Gostaria de saber se existe alguma forma de saber o sentido da rotação, já que o disco encoder tem os "furos" na mesma sequencia, independente do sentido. Existe algum outro sensor que me dê o sentido da rotação? Na verdade gostaria de saber o sentido de rotação de uma catraca, se foi para frente ou para trás. Agradeço a ajuda.
Oi Márcio,
Sugiro usar dois sensores. Aí fica fácil. 🙂
Abraço!
Adilson
queria usar este encoder para controlar um led qual seria a descrição do programa
Como ficaria para controle de led limitando para no máximo 100 rpm
Bom dia, você sabe quantos DPI´s esse MOCH22A consegue detectar? E outra pergunta, já que ele só possui um fototransistor, ele não consegue detectar direção correto?
Oi Bruno,
Sobre os DPI´s, não tenho essa informação. Sobre a direção, eu recomendaria utilizar dois sensores de velocidade.
Abraço!
Adilson
Porque você está interrompendo o pino ‘0’ se é o pino ‘2’ que está sendo utilizado?
Boa tarde,
Sim, é o pino 2 que está sendo utilizado. No programa coloquei o nome desse pino como Pino_D0, por que o pino 2 será ligado à saída D0 do sensor.
Abraço!
Adilson
Olá! Sou novo na eletrônica e estou procurando toda informação possível!
Fiz um projeto de “bicicleta” estacionária e adquiri alguns itens para a parte eletrônica…
-um arduino mega 2560
-sensor encoder de velocidade
-um display tft de 3.5″ shield https://www.makerhero.com/produto/display-lcd-tft-shield-3-5-para-arduino/
Minha dúvida é como eu alimento o sensor e qual pino eu posso usar, uma vez que o display ocupa todos os pinos, deixando os pinos 22 ao 53 livres.
Ligo a energia nesse pino de 5v e o gnd disponível na protoboard? e posso usar qualquer pino, ajustando o código depois?
e difere muito se eu uso digital ou analógico para fazer isso? digo o resultado da velocidade
precisaria de mais algum componente para isso?
Muitíssimo obrigado pela atenção!
Oi Henrique,
Uma opção é vc alimentar o sensor com uma fonte externa, e interligar o GND com o GND do Arduino. Quanto ao uso do pino analógico ou digital, eu testaria os dois, mas a princípio vc não teria muita diferença nos resultados.
Sobre os componentes, eu recomendo vc usar uma fonte externa (9V – 1A) para alimentação do Arduino.
Abraço!
Adilson
Obrigado Adilson!
Eu segui esse exemplo e agora apareceu outro problema.
como estou usando o shield display, eu liguei o sensor na porta 22.
troquei a linha 5 (int pino_D0 = 2;) por 22… e nada acontece…
tentei na porta 31, troquei o codigo e tambem nada acontece..
tirei o display, conectei a porta 2, troquei o codigo e funcionou….
como utiliza as portas 22 ao 53?
obrigado novamente
Oi Henrique,
Que estranho. Essas portas estão funcionando corretamente? Tente com um led e também sem o display, apesar que eu acho muito difícil que ele esteja interferindo em algo.
Abraço!
Adilson
Olá Adilson!!
obrigado pela resposta!
Eu fiz isso e segui o exemplo do código acima!
Conectei ao pino 31 e mudei o código na linha
//Pino ligado ao pino D0 do sensor
int pino_D0 = 2;
para int pino_Do = 31;
mas ele não funciona! Tentei outras portas e nada…. o que teria de errado em funcionar esses pinos?
obrigado
Bom dia eu estou fazendo um projeto no curso de mecatrônica gostaria de saber como seria a programação desse mesmo sensor para o ESP32 e também gostaria de saber se existe algum pino específico para a montagem.
Oi Gustavo,
Eu não cheguei a usar esse código com o ESP32, você tentou alguma coisa?
Abraço!
Adilson