ESP8266 - Sensor Óptico de Velocidade IR com Fenda
Este tutorial ensina você a usar o ESP8266 NodeMCU com um sensor óptico de velocidade IR com fenda, para que a placa saiba cada vez que algo passa pela fenda estreita do sensor. Com esse único sinal, o NodeMCU pode contar coisas ou dizer a que velocidade um motor gira. Em detalhes, vamos aprender:
- Como a barreira de luz dentro do sensor (também vendido como opto interruptor ou foto interruptor) dá um sinal HIGH ou LOW
- Como ligar o sensor ao pino 3.3V e ao pino D5 (GPIO14) do NodeMCU, e quais pinos manter livres
- Como escrever um código ESP8266 que conta cada objeto que bloqueia a fenda
- Como escrever um código ESP8266 que mede a velocidade do motor em RPM com um disco encoder e uma função de interrupção marcada com IRAM_ATTR
Nós sugerimos:
- Usar um encoder rotativo se uma pessoa gira um botão com a mão e o código precisa saber se ele vai para a esquerda ou para a direita.
- Usar um sensor infravermelho de obstáculo se a coisa que você quer encontrar está na frente do sensor, a alguns centímetros de distância, e não consegue passar por uma fenda pequena.

Hardware Necessário
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Sobre o Sensor Óptico de Velocidade IR com Fenda
Imagine uma pequena moldura de porta feita de plástico preto. Um feixe invisível atravessa a moldura. Quando qualquer coisa sólida passa pela moldura, o feixe é cortado, e o sensor avisa o ESP8266 na mesma hora. É só isso que este módulo faz, mas ele faz rápido e com um sinal muito limpo. Por isso os makers o usam como sensor de velocidade, contador de pulsos e fim de curso.
Dentro do Corpo em Forma de U

O módulo é construído em torno de três partes:
- Um LED infravermelho em um dos braços. Ele emite luz IR o tempo todo.
- Um fototransistor NPN no outro braço. Ele fica a 5.9 mm de distância e de frente para o LED.
- Um Schmitt trigger na pequena placa. Ele transforma o sinal do fototransistor em um nível digital nítido.
O pino OUT segue o feixe:
- O feixe chega ao fototransistor (a fenda está vazia): OUT fica HIGH.
- O feixe é cortado por um objeto sólido (um cartão, um dedo, um dente de um disco encoder): OUT fica LOW.
Graças ao Schmitt trigger, as bordas não têm jitter. O seu código ESP8266 pode usar o valor como está, sem etapa de debounce.
Algumas dicas antes de testar:
- Use algo através do qual você não consiga ver. O plástico transparente pode deixar a luz IR passar, e o sensor pode não perceber.
- Alguns módulos vendidos por outros fabricantes têm a lógica inversa (LOW quando vazio). Nesse caso, troque LOW e HIGH no código de contagem. O código de RPM conta uma borda para cada fenda, então ele ainda dá a velocidade correta.
Especificações
| Sensor Óptico de Velocidade IR com Fenda | |
|---|---|
| Tipo de sensor | Fotoelétrico tipo fenda (LED IR + fototransistor NPN) |
| Largura da fenda | 5.9 mm |
| Tensão de operação | 3.3V a 5V DC |
| Saída | Digital (TTL), LOW quando bloqueado, HIGH quando livre |
| Condicionamento de sinal | Schmitt trigger embutido |
| Montagem | Furos para parafuso M3 nas duas pontas |
| Pinos | 3 (VCC, GND, OUT) |
Os dois furos M3 permitem que você parafuse o módulo no chassi de um robô ou no suporte de um motor, para que ele fique no mesmo lugar enquanto um disco gira ao lado. Usos típicos: um medidor de RPM para um motor pequeno, retorno de velocidade da roda para um carrinho robô, um contador de itens em uma esteira, um medidor de distância que conta voltas da roda, e uma chave de limite ou de posição sem contato.
Pinagem do Sensor Óptico de Velocidade IR com Fenda

- Pino VCC: deve ser conectado ao pino 3V3 do NodeMCU (não ao 5V nem ao VIN)
- Pino GND: deve ser conectado a um pino G (GND) do NodeMCU (0V)
- Pino OUT: a saída digital; deve ser conectado a um pino de entrada do NodeMCU (D5 neste tutorial)
※ Nota:
A disposição dos pinos em um módulo pode variar de um fabricante para outro, e dois lotes do mesmo produto também podem ser diferentes. É essencial sempre consultar as etiquetas impressas no módulo ao usá-lo. Olhe com atenção!
Por que 3.3V e não 5V? O pino OUT chega até a tensão que está no VCC. O ESP8266 é um chip de 3.3V. Se o sensor receber 5V, o OUT também daria 5V a um pino do NodeMCU. Quando o VCC vem do pino 3V3, o OUT fica entre 0V e 3.3V, o que é seguro para a placa.
Disco Encoder: Dos Pulsos ao RPM
Um disco encoder é uma roda plana com um anel de furos perto da borda. Você o prende no eixo do motor ou na roda, e posiciona o sensor de modo que a borda do disco passe pela fenda. Conforme o disco gira, furos e dentes passam pelo feixe um após o outro. Cada dente faz o OUT ir para LOW uma vez.
A maioria dos kits de motor de redução TT vem com um disco de 20 fendas. Veja como o ESP8266 transforma pulsos em velocidade:
- Conte os pulsos durante 1 segundo.
- Multiplique por 60 para obter pulsos por minuto.
- Divida por 20 (pulsos em uma volta) para obter voltas por minuto, que é o RPM.
Diagrama de Ligação
Use três fios jumper: VCC do sensor no pino 3V3 do NodeMCU, GND do sensor em um pino G, e OUT do sensor no D5, como você pode ver na imagem abaixo.

This image is created using Fritzing. Click to enlarge image
Para mais informações, veja Pinagem do ESP8266 e como alimentar o ESP8266 e outros componentes.
Etiqueta D5 ou GPIO14?
A serigrafia do NodeMCU mostra etiquetas como D1, D2 e D5. O chip ESP8266 em si usa números GPIO, e os dois não são iguais. O D5 da placa é o GPIO14 no chip. No código nós escrevemos D5, e o core do ESP8266 para o Arduino IDE troca para GPIO14 para nós. Se você escrever apenas 5, o código usa o GPIO5, que é o pino D1. Este é um erro comum, então sempre mantenha o "D" no código.
Você pode mover o fio OUT para outro pino se o D5 estiver ocupado. Use esta lista para escolher:
| Etiqueta do NodeMCU | GPIO | Bom para este sensor? |
|---|---|---|
| D1 | GPIO5 | Sim |
| D2 | GPIO4 | Sim |
| D5 | GPIO14 | Sim (usado neste tutorial) |
| D6 | GPIO12 | Sim |
| D7 | GPIO13 | Sim |
| D3 | GPIO0 | Não, pino de boot |
| D4 | GPIO2 | Não, pino de boot |
| D8 | GPIO15 | Não, pino de boot |
| D0 | GPIO16 | Sem suporte a interrupção, então não serve para o código de RPM |
O chip verifica D3, D4 e D8 quando liga. O sensor controla o OUT o tempo todo. Se a fenda estiver livre, o OUT fica HIGH, e no D8 esse HIGH pode impedir a placa de iniciar. Se um dente do disco estiver na fenda, o OUT fica LOW, e no D3 ou D4 esse LOW também pode impedir uma inicialização normal. Portanto, mantenha o sensor longe desses três pinos.
Como Programar o Sensor Óptico de Velocidade IR com Fenda
Não há biblioteca para instalar. Tudo vem do core do ESP8266 que você adicionou ao Arduino IDE.
Passos para o código de contagem
- O primeiro passo é dar um nome ao pino que está ligado ao OUT. Note a etiqueta "D":
- Em seguida, o pino é configurado como entrada no setup(). O sensor puxa a linha para HIGH ou LOW por conta própria, então não é preciso pull-up:
- Depois, o código lê o pino a cada passagem do loop(). LOW diz ao ESP8266 que o feixe está cortado:
- Por fim, a nova leitura é comparada com a anterior (lastState). A contagem sobe apenas quando o valor mudou para LOW. Assim, um cartão que fica na fenda por cinco segundos ainda conta como um.
Passos para o código de RPM
- O primeiro passo é tornar o contador de pulsos volatile. A função de interrupção o altera em segundo plano, e a palavra-chave volatile diz ao compilador para sempre ler o valor real:
- Em seguida, a função de interrupção é escrita. No ESP8266, esta função precisa ter a palavra IRAM_ATTR na frente. Isso coloca a função na RAM interna rápida do chip. Sem ela, o ESP8266 pode travar e reiniciar quando chega um pulso:
- Depois, a função é ligada ao D5 no setup(). FALLING significa que ela roda quando o OUT cai de HIGH para LOW, que é o momento em que um dente entra na fenda:
- Depois disso, uma vez por segundo (verificado com millis()), o código copia o contador e o zera. O ESP8266 é um chip de 32 bits, então ele lê o contador de 32 bits em um único passo. Por isso esta versão não precisa do par noInterrupts() e interrupts() que as placas de 8 bits usam:
- Por fim, a velocidade é calculada com a fórmula da seção do disco encoder:
Código ESP8266 NodeMCU para Contar Objetos na Fenda
Este código fica lendo o D5 no loop(). Ele soma um ao contador cada vez que a fenda é bloqueada, e imprime uma linha apenas quando o estado muda. Assim, o Serial Monitor não se enche com a mesma mensagem.
Passos Rápidos
- Se esta é a primeira vez que você usa o ESP8266, veja como configurar o ambiente para o ESP8266 no Arduino IDE.
- Ligue os componentes como mostrado no diagrama.
- Conecte a placa ESP8266 ao seu computador usando um cabo USB.
- Abra o Arduino IDE no seu computador.
- Selecione a placa NodeMCU 1.0 (ESP-12E Module) e a porta COM do seu NodeMCU.
- Copie o código acima e cole-o no Arduino IDE.
- Clique no botão Upload e espere até o upload terminar.
- Abra o Serial Monitor e configure-o para 9600 baud.
- Empurre uma tira de cartão para dentro da fenda e depois puxe-a para fora. Repita três vezes.
- Veja o resultado no Serial Monitor.
A primeira linha diz "blocked" enquanto não há nada na fenda? Então o seu módulo tem a lógica inversa. Troque LOW por HIGH na instrução if e faça o upload de novo.
Código ESP8266 NodeMCU para Medir a Velocidade do Motor (RPM)
Um disco de 20 fendas girando pode gerar centenas de pulsos por segundo. Se o loop() apenas lê o pino, alguns pulsos vão escapar enquanto o ESP8266 está ocupado, por exemplo enquanto imprime texto. Uma interrupção resolve isso. O chip para por um momento, executa countPulse() e volta ao seu trabalho, de modo que cada dente é contado.
Uma vez por segundo, o código imprime a contagem de pulsos e a velocidade. A constante SLOTS_PER_TURN é 20. Se o seu disco tem um número diferente de furos, conte-os e mude este número.
Passos Rápidos
- Deixe a ligação como está. O OUT continua no D5. Se você o mover, escolha D1, D2, D6 ou D7 e mude SENSOR_PIN no código.
- Prenda o disco encoder no eixo do motor ou na roda. Ajuste a altura do sensor para que os dentes passem pelo meio da fenda e nunca toquem o plástico.
- Cole o código de RPM no Arduino IDE e clique em Upload.
- Abra o Serial Monitor a 9600 baud.
- Gire o disco com o dedo, ou ligue o motor. Para acionar o motor com o NodeMCU, veja o tutorial ESP8266 - Motor DC.
- Observe a velocidade no Serial Monitor.
O motor neste teste gira a quase 300 RPM. Confira a linha com 101 pulsos: 101 x 60 / 20 = 303 RPM. A primeira linha foi impressa antes de o motor começar, e a última depois de ele parar.
※ Nota:
Se o NodeMCU reinicia assim que o disco gira, olhe primeiro para a função de interrupção. No ESP8266, ela deve ser marcada com IRAM_ATTR. Mantenha-a também bem curta: sem Serial.print(), sem delay(), apenas o contador.
Conhecimento Adicional
Perguntas Frequentes
Posso alimentar o sensor pelo pino VIN para deixá-lo mais forte?
Não. O VIN leva 5V do cabo USB, e o OUT então enviaria 5V para um GPIO de 3.3V. O módulo funciona bem com 3.3V, então o pino 3V3 é a escolha certa.
Por que os valores de RPM mudam em passos de 3?
O código conta pulsos inteiros durante um segundo. Com 20 fendas, um pulso extra soma 60 / 20 = 3 RPM. Um disco com mais fendas dá passos menores. Um disco com menos fendas dá passos maiores. Seja qual for o disco que você usar, faça o SLOTS_PER_TURN corresponder a ele.
Por que FALLING e não CHANGE?
FALLING executa a função uma vez por dente, no momento em que o dente entra na fenda. CHANGE a executaria também quando o dente sai, então você teria duas contagens por dente e o dobro do RPM real.
Um NodeMCU consegue ler dois sensores de velocidade?
Sim. Coloque o segundo sensor em outro pino seguro, como o D6, e dê a ele o seu próprio contador volatile e a sua própria função IRAM_ATTR. Isso é útil para um carrinho robô com duas rodas motrizes.
Sensor de Fenda, Sensor de Obstáculo ou Encoder Rotativo?
O sensor de fenda quer que o alvo passe pela sua abertura de 5.9 mm, sempre no mesmo ponto. Ele dá um pulso limpo por passagem e é a melhor ferramenta para RPM e contagem.
O sensor de obstáculo olha para o espaço aberto. Ele capta a luz que volta de uma parede, de uma mão ou de uma caixa na frente dele, então o alvo não precisa caber em uma fenda.
O encoder rotativo é um botão. Ele tem dois sinais (CLK e DT) mais um botão de pressão, então também consegue dizer o sentido da rotação.
É evidente que o sensor óptico de fenda é o mais preciso dos três para medir o tempo de uma peça girando, porque o feixe é cortado no mesmo pequeno ponto a cada volta. Mas ele não consegue dizer o sentido. Se você precisa disso, o encoder rotativo é o que deve escolher.
Do RPM à Velocidade da Roda
Quando o disco está em uma roda de robô, mais um passo transforma o RPM em quão rápido o robô se move:
- Circunferência da roda = π x diâmetro da roda
- Distância em um segundo = (RPM / 60) x circunferência da roda
Exemplo: uma roda com 60 mm de diâmetro tem uma circunferência de cerca de 188.5 mm. A 300 RPM, ela dá 5 voltas por segundo, então o robô anda cerca de 942 mm, ou 0.94 metro, a cada segundo.