ESP8266 - Sensor de velocidad óptico ranurado IR

Este tutorial te enseña cómo usar el ESP8266 NodeMCU con un sensor de velocidad óptico ranurado IR, para que la placa sepa cada vez que algo pasa por el espacio estrecho del sensor. Con esa sola señal, el NodeMCU puede contar objetos o saber a qué velocidad gira un motor. En detalle, aprenderemos:

Te sugerimos:

ESP8266 NodeMCU NodeMCU con sensor de velocidad óptico ranurado IR

Hardware Requerido

1×ESP8266 NodeMCU ESP-12F
1×Alternatively, ESP8266 D1 Mini NodeMCU ESP-12F
1×Alternatively, ESP8266 NodeMCU ESP-12E (Uno-form)
1×Micro USB Cable
1×Alternatively, ESP8266 NodeMCU ESP-12F (SMD-form)
1×Cable USB Tipo-A a Tipo-C (para PC USB-A)
1×Cable USB Tipo-C a Tipo-C (para PC USB-C)
1×IR Slotted Optical Speed Sensor
1×Cables Puente
1×(Opcional) Breadboard
1×(Recomendado) Placa de Expansión de Terminales de Tornillo para ESP8266

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Divulgación: Algunos de los enlaces proporcionados en esta sección son enlaces de afiliado de Amazon. Podemos recibir una comisión por las compras realizadas a través de estos enlaces sin costo adicional para usted. Apreciamos su apoyo.

Acerca del sensor de velocidad óptico ranurado IR

Imagina un marco de puerta diminuto hecho de plástico negro. Un haz invisible cruza el marco. Cuando algo sólido pasa por el marco, el haz se corta, y el sensor avisa al ESP8266 al instante. Eso es todo lo que hace este módulo, pero lo hace rápido y con una señal muy limpia. Por eso se usa como sensor de velocidad, contador de pulsos y tope de fin de carrera.

Dentro del cuerpo en forma de U

Cómo funciona el sensor de velocidad óptico ranurado IR

El módulo está formado por tres partes:

  1. Un LED infrarrojo en un brazo. Emite luz IR todo el tiempo.
  2. Un fototransistor NPN en el otro brazo. Está a 5,9 mm de distancia y mira al LED.
  3. Un disparador Schmitt en la placa pequeña. Convierte la señal del fototransistor en un nivel digital nítido.

El pin OUT sigue al haz:

  • El haz llega al fototransistor (la ranura está vacía): OUT está en HIGH.
  • El haz se corta por un objeto sólido (una tarjeta, un dedo, un diente de un disco codificador): OUT está en LOW.

Gracias al disparador Schmitt, los flancos no tienen rebotes. Tu código para ESP8266 puede usar el valor tal cual, sin paso de antirrebote.

Algunos consejos antes de probar:

  • Usa algo que no sea transparente. El plástico transparente puede dejar pasar la luz IR, y el sensor puede no notarlo.
  • Algunos módulos de otros fabricantes tienen la lógica inversa (LOW cuando está vacío). En ese caso, intercambia LOW y HIGH en el código de conteo. El código de rpm cuenta un flanco por cada ranura, así que sigue dando la velocidad correcta.

Especificaciones

Sensor de velocidad óptico ranurado IR
Tipo de sensor Fotoeléctrico de ranura (LED IR + fototransistor NPN)
Ancho de la ranura 5,9 mm
Tensión de funcionamiento 3,3V a 5V CC
Salida Digital (TTL), LOW cuando está bloqueado, HIGH cuando está libre
Acondicionamiento de señal Disparador Schmitt integrado
Montaje Orificios M3 en ambos extremos
Pines 3 (VCC, GND, OUT)

Los dos orificios M3 te permiten atornillar el módulo al chasis de un robot o a un soporte de motor, para que se quede en el mismo lugar mientras un disco gira a su lado. Usos típicos: un medidor de rpm para un motor pequeño, realimentación de velocidad de rueda para un coche robot, un contador de piezas en una cinta transportadora, un medidor de distancia que cuenta las vueltas de la rueda, y un interruptor de límite o posición sin contacto.

Pines del sensor de velocidad óptico ranurado IR

Pines del sensor de velocidad óptico ranurado IR
  • Pin VCC: debe conectarse al pin 3V3 del NodeMCU (no a 5V ni a VIN)
  • Pin GND: debe conectarse a un pin G (GND) del NodeMCU (0V)
  • Pin OUT: la salida digital; debe conectarse a un pin de entrada del NodeMCU (D5 en este tutorial)

※ Nota:

La disposición de los pines de un módulo puede variar de un fabricante a otro, y dos lotes del mismo producto también pueden ser distintos. Es esencial consultar siempre las etiquetas impresas en el módulo al usarlo. ¡Míralas con atención!

¿Por qué 3,3V y no 5V? El pin OUT sube hasta la tensión que hay en VCC. El ESP8266 es un chip de 3,3V. Si el sensor recibe 5V, OUT también daría 5V a un pin del NodeMCU. Cuando VCC viene del pin 3V3, OUT se mantiene entre 0V y 3,3V, lo cual es seguro para la placa.

Disco codificador: de pulsos a rpm

Un disco codificador es una rueda plana con un anillo de agujeros cerca del borde. Lo presionas sobre el eje del motor o la rueda, y colocas el sensor de modo que el borde del disco pase por la ranura. Al girar el disco, los agujeros y los dientes pasan por el haz uno tras otro. Cada diente hace que OUT pase a LOW una vez.

La mayoría de los kits de motorreductores TT incluyen un disco de 20 ranuras. Así convierte el ESP8266 los pulsos en velocidad:

  1. Cuenta los pulsos durante 1 segundo.
  2. Multiplica por 60 para obtener pulsos por minuto.
  3. Divide entre 20 (pulsos en una vuelta) para obtener vueltas por minuto, es decir, rpm.

Diagrama de Cableado

Usa tres cables puente: VCC del sensor al pin 3V3 del NodeMCU, GND del sensor a un pin G, y OUT del sensor a D5, como puedes ver en la imagen de abajo.

Diagrama de cableado del ESP8266 NodeMCU NodeMCU con sensor de velocidad óptico ranurado IR

This image is created using Fritzing. Click to enlarge image

Para obtener m\u00e1s informaci\u00f3n, consulte Pines del ESP8266 y c\u00f3mo alimentar ESP8266 y otros componentes.

¿Etiqueta D5 o GPIO14?

La serigrafía del NodeMCU muestra etiquetas como D1, D2 y D5. El chip ESP8266 usa números GPIO, y los dos no coinciden. D5 en la placa es GPIO14 en el chip. En el código escribimos D5, y el núcleo del ESP8266 para Arduino IDE lo cambia a GPIO14 por nosotros. Si escribes solo 5, el código usa GPIO5, que es el pin D1. Este es un error común, así que mantén siempre la "D" en el código.

Puedes mover el cable OUT a otro pin si D5 está ocupado. Usa esta lista para elegir:

Etiqueta del NodeMCU GPIO ¿Sirve para este sensor?
D1 GPIO5 Sí
D2 GPIO4 Sí
D5 GPIO14 Sí (usado en este tutorial)
D6 GPIO12 Sí
D7 GPIO13 Sí
D3 GPIO0 No, pin de arranque
D4 GPIO2 No, pin de arranque
D8 GPIO15 No, pin de arranque
D0 GPIO16 Sin soporte de interrupciones, así que no sirve para el código de rpm

El chip revisa D3, D4 y D8 cuando arranca. El sensor maneja OUT todo el tiempo. Si la ranura está libre, OUT está en HIGH, y en D8 ese HIGH puede impedir que la placa arranque. Si un diente del disco está justo en la ranura, OUT está en LOW, y en D3 o D4 ese LOW también puede impedir un arranque normal. Por eso mantén el sensor lejos de estos tres pines.

Cómo programar el sensor de velocidad óptico ranurado IR

No hay que instalar ninguna biblioteca. Todo viene del núcleo del ESP8266 que añadiste a Arduino IDE.

Pasos para el código de conteo

  • El primer paso es dar un nombre al pin conectado a OUT. Fíjate en la etiqueta "D":
const int SENSOR_PIN = D5;
  • Después, el pin se configura como entrada en setup(). El sensor lleva la línea a HIGH o LOW por sí mismo, así que no hace falta pull-up:
pinMode(SENSOR_PIN, INPUT);
  • Luego, el código lee el pin en cada pasada de loop(). LOW le dice al ESP8266 que el haz está cortado:
int state = digitalRead(SENSOR_PIN);
  • Por último, la nueva lectura se compara con la anterior (lastState). La cuenta sube solo cuando el valor ha cambiado a LOW. Así, una tarjeta que se queda en la ranura cinco segundos cuenta solo como una.

Pasos para el código de rpm

  • El primer paso es hacer el contador de pulsos volatile. La función de interrupción lo cambia en segundo plano, y la palabra volatile le dice al compilador que lea siempre el valor real:
volatile unsigned long pulseCount = 0;
  • Después, se escribe la función de interrupción. En el ESP8266, esta función debe llevar la palabra IRAM_ATTR delante. Esto coloca la función en la RAM interna rápida del chip. Sin ella, el ESP8266 puede fallar y reiniciarse cuando llega un pulso:
void IRAM_ATTR countPulse() { pulseCount++; }
  • Luego, la función se enlaza a D5 en setup(). FALLING significa que se ejecuta cuando OUT baja de HIGH a LOW, que es el momento en que un diente entra en la ranura:
attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), countPulse, FALLING);
  • Después, una vez por segundo (comprobado con millis()), el código copia el contador y lo pone a cero. El ESP8266 es un chip de 32 bits, así que lee el contador de 32 bits en un solo paso. Por eso esta versión no necesita el par noInterrupts() e interrupts() que usan las placas de 8 bits:
unsigned long pulses = pulseCount; pulseCount = 0;
  • Por último, la velocidad se calcula con la fórmula de la sección del disco codificador:
float rpm = pulses * 60.0 / SLOTS_PER_TURN;

Código ESP8266 NodeMCU para contar objetos en la ranura

Este código lee D5 todo el tiempo en loop(). Suma uno al contador cada vez que la ranura se bloquea, e imprime una línea solo cuando cambia el estado. Así el monitor serie no se llena con el mismo mensaje.

/* * Este código de ESP8266 NodeMCU fue desarrollado por es.newbiely.com * Este código de ESP8266 NodeMCU se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/esp8266/esp8266-ir-slotted-optical-speed-sensor */ const int SENSOR_PIN = D5; // ESP8266 pin D5 connected to the OUT pin of the speed sensor int lastState; // the previous state of the sensor int objectCount = 0; // how many times the slot was blocked void setup() { Serial.begin(9600); pinMode(SENSOR_PIN, INPUT); lastState = digitalRead(SENSOR_PIN); } void loop() { int state = digitalRead(SENSOR_PIN); if (state != lastState) { // the state has changed if (state == LOW) { // LOW = something is in the slot objectCount++; Serial.print("The slot is blocked - count: "); Serial.println(objectCount); } else { // HIGH = the slot is clear Serial.println("The slot is clear"); } lastState = state; } }

Pasos R\u00e1pidos

  • Consulta cómo configurar el entorno para ESP8266 en Arduino IDE si es la primera vez que usas ESP8266.
  • Cablea los componentes como se muestra en el diagrama.
  • Conecta la placa ESP8266 a tu computadora con un cable USB.
  • Abre Arduino IDE en tu computadora.
  • Selecciona la placa NodeMCU 1.0 (ESP-12E Module) y el puerto COM de tu NodeMCU.
  • Copia el código anterior y pégalo en Arduino IDE.
  • Haz clic en el botón Subir y espera a que termine la carga.
  • Abre el monitor serie y ponlo a 9600 baudios.
  • Mete una tira de cartulina en la ranura, y luego sácala. Repite tres veces.
  • Mira el resultado en el monitor serie.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
The slot is blocked - count: 1 The slot is clear The slot is blocked - count: 2 The slot is clear The slot is blocked - count: 3 The slot is clear
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2

¿La primera línea dice "blocked" aunque no hay nada en la ranura? Entonces tu módulo tiene la lógica inversa. Cambia LOW por HIGH en la sentencia if y sube el código de nuevo.

Código ESP8266 NodeMCU para medir la velocidad del motor (rpm)

Un disco de 20 ranuras en giro puede generar cientos de pulsos por segundo. Si loop() solo lee el pin, algunos pulsos se escaparán mientras el ESP8266 está ocupado, por ejemplo al imprimir texto. Una interrupción resuelve esto. El chip se detiene un momento, ejecuta countPulse() y vuelve a su trabajo, así que cada diente se cuenta.

Una vez por segundo, el código imprime la cuenta de pulsos y la velocidad. La constante SLOTS_PER_TURN vale 20. Si tu disco tiene otro número de agujeros, cuéntalos y cambia este número.

/* * Este código de ESP8266 NodeMCU fue desarrollado por es.newbiely.com * Este código de ESP8266 NodeMCU se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/esp8266/esp8266-ir-slotted-optical-speed-sensor */ const int SENSOR_PIN = D5; // ESP8266 pin D5 connected to the OUT pin of the speed sensor const int SLOTS_PER_TURN = 20; // number of slots (holes) in the encoder disc volatile unsigned long pulseCount = 0; // changed inside the interrupt unsigned long lastTime = 0; // runs every time a tooth of the disc blocks the slot void IRAM_ATTR countPulse() { pulseCount++; } void setup() { Serial.begin(9600); pinMode(SENSOR_PIN, INPUT); attachInterrupt(digitalPinToInterrupt(SENSOR_PIN), countPulse, FALLING); } void loop() { if (millis() - lastTime >= 1000) { // every 1 second lastTime = millis(); unsigned long pulses = pulseCount; // read and reset the counter pulseCount = 0; float rpm = pulses * 60.0 / SLOTS_PER_TURN; // pulses per second -> turns per minute Serial.print("Pulses: "); Serial.print(pulses); Serial.print(" | Speed: "); Serial.print(rpm); Serial.println(" RPM"); } }

Pasos R\u00e1pidos

  • Deja el cableado como está. OUT sigue en D5. Si lo mueves, elige D1, D2, D6 o D7 y cambia SENSOR_PIN en el código.
  • Presiona el disco codificador sobre el eje del motor o la rueda. Ajusta la altura del sensor para que los dientes pasen por el centro de la ranura y nunca toquen el plástico.
  • Pega el código de rpm en Arduino IDE y haz clic en Subir.
  • Abre el monitor serie a 9600 baudios.
  • Gira el disco con el dedo, o pon en marcha el motor. Para mover el motor desde el NodeMCU, consulta el tutorial ESP8266 - Motor de CC.
  • Mira la velocidad en el monitor serie.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
Pulses: 0 | Speed: 0.00 RPM Pulses: 98 | Speed: 294.00 RPM Pulses: 101 | Speed: 303.00 RPM Pulses: 100 | Speed: 300.00 RPM Pulses: 99 | Speed: 297.00 RPM Pulses: 0 | Speed: 0.00 RPM
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2

El motor de esta prueba gira a casi 300 rpm. Revisa la línea con 101 pulsos: 101 x 60 / 20 = 303 rpm. La primera línea se imprimió antes de que el motor arrancara, y la última después de que se detuviera.

※ Nota:

Si el NodeMCU se reinicia sin parar en cuanto gira el disco, mira primero la función de interrupción. En el ESP8266, debe estar marcada con IRAM_ATTR. Mantenla también muy corta: sin Serial.print(), sin delay(), solo el contador.

Conocimientos adicionales

Preguntas frecuentes

¿Puedo alimentar el sensor desde el pin VIN para hacerlo más fuerte?

No. VIN lleva 5V del cable USB, y entonces OUT enviaría 5V a un GPIO de 3,3V. El módulo funciona bien con 3,3V, así que el pin 3V3 es la elección correcta.

¿Por qué los valores de rpm cambian en pasos de 3?

El código cuenta pulsos enteros durante un segundo. Con 20 ranuras, un pulso extra suma 60 / 20 = 3 rpm. Un disco con más ranuras da pasos más pequeños. Un disco con menos ranuras da pasos más grandes. Uses el disco que uses, haz que SLOTS_PER_TURN coincida con él.

¿Por qué FALLING y no CHANGE?

FALLING ejecuta la función una vez por diente, en el momento en que el diente entra en la ranura. CHANGE también la ejecutaría cuando el diente sale, así que tendrías dos cuentas por diente y el doble de las rpm reales.

¿Puede un NodeMCU leer dos sensores de velocidad?

Sí. Pon el segundo sensor en otro pin seguro, como D6, y dale su propio contador volatile y su propia función IRAM_ATTR. Esto es útil para un coche robot con dos ruedas motrices.

¿Sensor ranurado, sensor de obstáculos o encoder rotativo?

El sensor ranurado quiere que el objetivo pase por su espacio de 5,9 mm, siempre en el mismo punto. Da un pulso limpio por cada paso y es la mejor herramienta para rpm y conteo.

El sensor de obstáculos mira el espacio abierto. Capta la luz que rebota en una pared, una mano o una caja frente a él, así que el objetivo no necesita caber en una ranura.

El encoder rotativo es una perilla. Tiene dos señales (CLK y DT) además de un botón, así que también puede indicar el sentido de giro.

Es evidente que el sensor óptico ranurado es el más preciso de los tres para medir el tiempo de una pieza en giro, porque el haz se corta en el mismo punto pequeño en cada vuelta. Sin embargo, no puede indicar el sentido. Si lo necesitas, el encoder rotativo es el que debes elegir.

De rpm a velocidad de la rueda

Cuando el disco está en la rueda de un robot, un paso más convierte las rpm en la velocidad a la que se mueve el robot:

  • Circunferencia de la rueda = π x diámetro de la rueda
  • Distancia en un segundo = (rpm / 60) x circunferencia de la rueda

Ejemplo: una rueda de 60 mm de diámetro tiene una circunferencia de unos 188,5 mm. A 300 rpm, da 5 vueltas por segundo, así que el robot avanza unos 942 mm, o 0,94 metros, cada segundo.

Video Tutorial

Estamos considerando crear tutoriales en video. Si considera que los tutoriales en video son importantes, suscríbase a nuestro canal de YouTube para motivarnos a crear los videos.

Referencias de funciones

Tutoriales Relacionados

※ NUESTROS MENSAJES

  • No dude en compartir el enlace de este tutorial. Sin embargo, por favor no use nuestro contenido en otros sitios web. Hemos invertido mucho esfuerzo y tiempo en crear el contenido, ¡por favor respete nuestro trabajo!