ESP8266 - Capteur de vitesse optique à fente IR
Ce tutoriel vous explique comment utiliser l'ESP8266 NodeMCU avec un capteur de vitesse optique à fente IR, afin que la carte sache chaque fois que quelque chose passe dans l'espace étroit du capteur. Avec ce seul signal, le NodeMCU peut compter des objets ou mesurer la vitesse de rotation d'un moteur. En détail, nous allons apprendre :
- Comment la barrière lumineuse à l'intérieur du capteur (aussi vendue sous le nom de fourche optique) donne un signal HAUT ou BAS
- Comment câbler le capteur à la broche 3,3V et à la broche D5 (GPIO14) du NodeMCU, et quelles broches laisser libres
- Comment écrire un code ESP8266 qui compte chaque objet qui bloque la fente
- Comment écrire un code ESP8266 qui mesure la vitesse d'un moteur en tr/min (RPM) avec un disque codeur et une fonction d'interruption marquée IRAM_ATTR
Nous suggérons :
- D'utiliser un ESP8266 - Encodeur rotatif. si une personne tourne un bouton à la main et que le code doit savoir s'il va à gauche ou à droite.
- D'utiliser un ESP8266 - Capteur d'obstacles. si l'objet à détecter est devant le capteur, à quelques centimètres, et ne peut pas passer dans une petite fente.

Matériel Requis
Ou vous pouvez acheter les kits suivants:
| 1 | × | Kit de Capteurs DIYables (18 capteurs/écrans) |
À Propos du Capteur de Vitesse Optique à Fente IR
Imaginez un petit cadre de porte en plastique noir. Un faisceau invisible traverse le cadre. Quand un objet solide passe dans le cadre, le faisceau est coupé, et le capteur le signale tout de suite à l'ESP8266. C'est tout ce que fait ce module, mais il le fait vite et avec un signal très propre. C'est pourquoi les makers l'utilisent comme capteur de vitesse, compteur d'impulsions et fin de course.
À l'Intérieur du Boîtier en U

Le module est construit autour de trois éléments :
- Une LED infrarouge dans un bras. Elle émet de la lumière IR en permanence.
- Un phototransistor NPN dans l'autre bras. Il est à 5,9 mm de distance et fait face à la LED.
- Un trigger de Schmitt sur la petite carte. Il transforme le signal du phototransistor en un niveau numérique net.
La broche OUT suit le faisceau :
- Le faisceau atteint le phototransistor (la fente est vide) : OUT est HAUT.
- Le faisceau est coupé par un objet solide (une carte, un doigt, une dent d'un disque codeur) : OUT est BAS.
Grâce au trigger de Schmitt, les fronts n'ont pas de rebond. Votre code ESP8266 peut utiliser la valeur telle quelle, sans étape d'anti-rebond.
Quelques conseils avant de tester :
- Utilisez un objet à travers lequel on ne voit pas. Un plastique transparent peut laisser passer la lumière IR, et le capteur peut ne pas le remarquer.
- Quelques modules vendus par d'autres fabricants ont la logique inverse (BAS quand la fente est vide). Dans ce cas, échangez LOW et HIGH dans le code de comptage. Le code des tr/min compte un front par fente, il donne donc toujours la bonne vitesse.
Spécifications
| Capteur de vitesse optique à fente IR | |
|---|---|
| Type de capteur | Photoélectrique à fente (LED IR + phototransistor NPN) |
| Largeur de la fente | 5,9 mm |
| Tension de fonctionnement | 3,3V à 5V DC |
| Sortie | Numérique (TTL), BAS quand bloqué, HAUT quand dégagé |
| Conditionnement du signal | Trigger de Schmitt intégré |
| Fixation | Trous de vis M3 aux deux extrémités |
| Broches | 3 (VCC, GND, OUT) |
Les deux trous M3 vous permettent de visser le module sur un châssis de robot ou un support de moteur, pour qu'il reste au même endroit pendant qu'un disque tourne à côté. Usages typiques : un compteur de tr/min pour un petit moteur, un retour de vitesse de roue pour une voiture robot, un compteur d'objets sur un tapis roulant, un compteur de distance qui compte les tours de roue, et un interrupteur de limite ou de position sans contact.
Le Brochage du Capteur de Vitesse Optique à Fente IR

- Broche VCC : doit être connectée à la broche 3V3 du NodeMCU (pas à 5V ni à VIN)
- Broche GND : doit être connectée à une broche G (GND) du NodeMCU (0V)
- Broche OUT : la sortie numérique ; elle doit être connectée à une broche d'entrée du NodeMCU (D5 dans ce tutoriel)
※ Note:
La disposition des broches d'un module peut différer d'un fabricant à l'autre, et deux lots du même produit peuvent aussi être différents. Il est essentiel de toujours se référer aux étiquettes imprimées sur le module lorsque vous l'utilisez. Regardez bien !
Pourquoi 3,3V et pas 5V ? La broche OUT monte aussi haut que la tension sur VCC. L'ESP8266 est une puce 3,3V. Si le capteur reçoit 5V, OUT enverrait aussi 5V à une broche du NodeMCU. Quand VCC vient de la broche 3V3, OUT reste entre 0V et 3,3V, ce qui est sans danger pour la carte.
Disque Codeur : des Impulsions aux Tr/min
Un disque codeur est une roue plate avec une couronne de trous près de son bord. Vous l'enfoncez sur l'arbre du moteur ou sur la roue, et vous placez le capteur pour que le bord du disque passe dans la fente. Quand le disque tourne, les trous et les dents passent le faisceau l'un après l'autre. Chaque dent fait passer OUT à BAS une fois.
La plupart des kits de moteurs à engrenages TT sont fournis avec un disque de 20 fentes. Voici comment l'ESP8266 transforme les impulsions en vitesse :
- Comptez les impulsions pendant 1 seconde.
- Multipliez par 60 pour obtenir les impulsions par minute.
- Divisez par 20 (impulsions par tour) pour obtenir les tours par minute, c'est-à-dire les tr/min (RPM).
Schéma de Câblage
Utilisez trois fils de liaison : VCC du capteur vers la broche 3V3 du NodeMCU, GND du capteur vers une broche G, et OUT du capteur vers D5, comme vous pouvez le voir sur l'image ci-dessous.

Cette image a été créée avec Fritzing. Cliquez pour agrandir l'image.
Pour plus d'informations, consultez Brochage ESP8266. et Comment alimenter l'ESP8266..
Étiquette D5 ou GPIO14 ?
La sérigraphie du NodeMCU montre des étiquettes comme D1, D2 et D5. La puce ESP8266 elle-même utilise des numéros GPIO, et les deux ne correspondent pas. D5 sur la carte est GPIO14 dans la puce. Dans le code, nous écrivons D5, et le core ESP8266 pour Arduino IDE le change en GPIO14 pour nous. Si vous écrivez seulement 5, le code utilise GPIO5, qui est la broche D1. C'est une erreur courante, gardez donc toujours le « D » dans le code.
Vous pouvez déplacer le fil OUT sur une autre broche si D5 est occupée. Utilisez cette liste pour choisir :
| Étiquette NodeMCU | GPIO | Convient à ce capteur ? |
|---|---|---|
| D1 | GPIO5 | Oui |
| D2 | GPIO4 | Oui |
| D5 | GPIO14 | Oui (utilisée dans ce tutoriel) |
| D6 | GPIO12 | Oui |
| D7 | GPIO13 | Oui |
| D3 | GPIO0 | Non, broche de démarrage |
| D4 | GPIO2 | Non, broche de démarrage |
| D8 | GPIO15 | Non, broche de démarrage |
| D0 | GPIO16 | Pas de support des interruptions, donc pas pour le code des tr/min |
La puce vérifie D3, D4 et D8 quand elle démarre. Le capteur pilote OUT en permanence. Si la fente est dégagée, OUT est HAUT, et sur D8 ce HAUT peut empêcher la carte de démarrer. Si une dent du disque se trouve dans la fente, OUT est BAS, et sur D3 ou D4 ce BAS peut aussi empêcher un démarrage normal. Gardez donc le capteur loin de ces trois broches.
Comment Programmer pour le Capteur de Vitesse Optique à Fente IR
Il n'y a aucune bibliothèque à installer. Tout vient du core ESP8266 que vous avez ajouté à Arduino IDE.
Étapes pour le code de comptage
- La première étape est de donner un nom à la broche câblée à OUT. Notez l'étiquette « D » :
- Ensuite, la broche est configurée en entrée dans setup(). Le capteur met la ligne à HAUT ou BAS lui-même, donc aucune résistance de pull-up n'est nécessaire :
- Puis, le code lit la broche à chaque passage de loop(). BAS indique à l'ESP8266 que le faisceau est coupé :
- Enfin, la nouvelle lecture est comparée à la précédente (lastState). Le compteur augmente seulement quand la valeur est passée à BAS. Ainsi, une carte qui reste cinq secondes dans la fente ne compte que pour un.
Étapes pour le code des tr/min
- La première étape est de rendre le compteur d'impulsions volatile. La fonction d'interruption le modifie en arrière-plan, et le mot-clé volatile dit au compilateur de toujours lire la vraie valeur :
- Ensuite, la fonction d'interruption est écrite. Sur l'ESP8266, cette fonction doit avoir le mot IRAM_ATTR devant elle. Cela place la fonction dans la RAM interne rapide de la puce. Sans lui, l'ESP8266 peut planter et redémarrer quand une impulsion arrive :
- Puis, la fonction est liée à D5 dans setup(). FALLING signifie qu'elle s'exécute quand OUT passe de HAUT à BAS, c'est-à-dire au moment où une dent entre dans la fente :
- Ensuite, une fois par seconde (vérifié avec millis()), le code copie le compteur et le remet à zéro. L'ESP8266 est une puce 32 bits, il lit donc le compteur 32 bits en une seule étape. C'est pourquoi cette version n'a pas besoin de la paire noInterrupts() et interrupts() que les cartes 8 bits utilisent :
- Enfin, la vitesse est calculée avec la formule de la section sur le disque codeur :
Code ESP8266 NodeMCU pour Compter des Objets dans la Fente
Ce code lit D5 en continu dans loop(). Il ajoute un au compteur chaque fois que la fente est bloquée, et il affiche une ligne seulement quand l'état change. Ainsi, le Moniteur Série ne se remplit pas du même message.
Étapes Rapides
- Si c'est la première fois que vous utilisez l'ESP8266, consultez Installation du logiciel ESP8266..
- Câblez les composants comme indiqué sur le schéma.
- Connectez la carte ESP8266 à votre ordinateur avec un câble USB.
- Ouvrez Arduino IDE sur votre ordinateur.
- Sélectionnez la carte NodeMCU 1.0 (ESP-12E Module) et le port COM de votre NodeMCU.
- Copiez le code ci-dessus et collez-le dans Arduino IDE.
- Cliquez sur le bouton Téléverser et attendez la fin du téléversement.
- Ouvrez le Moniteur Série et réglez-le sur 9600 bauds.
- Enfoncez une bande de carte dans la fente, puis retirez-la. Répétez trois fois.
- Voyez le résultat sur le Moniteur Série.
La première ligne dit-elle « blocked » alors que rien n'est dans la fente ? Alors votre module a la logique inverse. Changez LOW en HIGH dans l'instruction if et téléversez à nouveau.
Code ESP8266 NodeMCU pour Mesurer la Vitesse du Moteur (RPM)
Un disque de 20 fentes en rotation peut produire des centaines d'impulsions chaque seconde. Si loop() ne fait que lire la broche, certaines impulsions seront manquées pendant que l'ESP8266 est occupé, par exemple quand il affiche du texte. Une interruption résout ce problème. La puce s'arrête un instant, exécute countPulse(), et reprend son travail, donc chaque dent est comptée.
Une fois par seconde, le code affiche le nombre d'impulsions et la vitesse. La constante SLOTS_PER_TURN vaut 20. Si votre disque a un nombre de trous différent, comptez-les et changez ce nombre.
Étapes Rapides
- Laissez le câblage tel quel. OUT reste sur D5. Si vous le déplacez, choisissez D1, D2, D6 ou D7 et changez SENSOR_PIN dans le code.
- Enfoncez le disque codeur sur l'arbre du moteur ou sur la roue. Réglez la hauteur du capteur pour que les dents passent au milieu de la fente sans jamais toucher le plastique.
- Collez le code des tr/min dans Arduino IDE et cliquez sur Téléverser.
- Ouvrez le Moniteur Série à 9600 bauds.
- Tournez le disque avec votre doigt, ou faites tourner le moteur. Pour faire tourner le moteur depuis le NodeMCU, consultez le tutoriel ESP8266 - Moteur à courant continu..
- Regardez la vitesse sur le Moniteur Série.
Le moteur de ce test tourne à près de 300 tr/min. Vérifiez la ligne avec 101 impulsions : 101 x 60 / 20 = 303 tr/min. La première ligne a été affichée avant le démarrage du moteur, et la dernière après son arrêt.
※ Note:
Si le NodeMCU redémarre dès que le disque tourne, regardez d'abord la fonction d'interruption. Sur l'ESP8266, elle doit être marquée avec IRAM_ATTR. Gardez-la aussi très courte : pas de Serial.print(), pas de delay(), juste le compteur.
Connaissances Supplémentaires
Foire Aux Questions
Puis-je alimenter le capteur depuis la broche VIN pour le rendre plus fort ?
Non. VIN fournit 5V depuis le câble USB, et OUT enverrait alors 5V dans un GPIO 3,3V. Le module fonctionne bien en 3,3V, la broche 3V3 est donc le bon choix.
Pourquoi les valeurs de tr/min varient-elles par pas de 3 ?
Le code compte des impulsions entières pendant une seconde. Avec 20 fentes, une impulsion de plus ajoute 60 / 20 = 3 tr/min. Un disque avec plus de fentes donne des pas plus petits. Un disque avec moins de fentes donne des pas plus grands. Quel que soit le disque, faites correspondre SLOTS_PER_TURN à celui-ci.
Pourquoi FALLING et pas CHANGE ?
FALLING exécute la fonction une fois par dent, au moment où la dent entre dans la fente. CHANGE l'exécuterait aussi quand la dent sort, vous auriez donc deux comptages par dent et le double des vrais tr/min.
Un NodeMCU peut-il lire deux capteurs de vitesse ?
Oui. Mettez le deuxième capteur sur une autre broche sûre, comme D6, et donnez-lui son propre compteur volatile et sa propre fonction IRAM_ATTR. C'est pratique pour une voiture robot avec deux roues motrices.
Capteur à Fente, Capteur d'Obstacles ou Encodeur Rotatif ?
Le capteur à fente veut que la cible passe dans son espace de 5,9 mm, toujours au même endroit. Il donne une impulsion propre par passage et c'est le meilleur outil pour les tr/min et le comptage.
Le ESP8266 - Capteur d'obstacles. regarde l'espace libre. Il capte la lumière qui rebondit sur un mur, une main ou une boîte devant lui, la cible n'a donc pas besoin d'entrer dans une fente.
L'ESP8266 - Encodeur rotatif. est un bouton. Il a deux signaux (CLK et DT) plus un bouton poussoir, il peut donc aussi indiquer le sens de rotation.
Il est évident que le capteur optique à fente est le plus précis des trois pour chronométrer une pièce en rotation, car le faisceau est coupé au même petit endroit à chaque tour. Il ne peut cependant pas indiquer le sens. Si vous en avez besoin, l'encodeur rotatif est le bon choix.
Des Tr/min à la Vitesse de la Roue
Quand le disque est sur une roue de robot, une étape de plus transforme les tr/min en vitesse de déplacement du robot :
- Circonférence de la roue = π x diamètre de la roue
- Distance en une seconde = (RPM / 60) x circonférence de la roue
Exemple : une roue de 60 mm de diamètre a une circonférence d'environ 188,5 mm. À 300 tr/min, elle fait 5 tours par seconde, donc le robot avance d'environ 942 mm, soit 0,94 mètre, chaque seconde.