Capteur inductif sans fil pour compteur d’eau avec « cyble » – Partie 2 : améliorations du prototype
Dans la première partie, on avait un circuit dont le principe de base était opérationnel mais où il restait des choses à améliorer ou à concevoir :
- L’alimentation se fait via un accu et les tensions de bias et de référence vont baisser avec la décharge alors qu’elle doivent rester constantes.
- Faire baisser au maximum la consommation du circuit (pouvoir couper le bias et la référence quand il n’y a pas de mesures en cours)
Améliorations du circuit
Pour poursuivre le circuit, on va donc ajouter une référence de tension de 2.5V qui sera activée par une sortie de l’atmega durant les mesures.
Le schéma de la partie 1 représentant une seule boucle de mesure, ce qui permet de compter le nombre de tour en supposant qu’elle tourne toujours dans le même sens. Il en faudra 2 ou 3 si on désire également détecter le sens de rotation de la cyble. Pour tester, on va donc doubler ce circuit pour obtenir le schéma suivant :
Et là c’est le drame, ce qui était prévisible se produit, bien que les oscillateurs soient déclenchés l’un après l’autre, il y a un couplage inductif entre les deux inductances qui déforme complètement le signal. L’effet est diminué en éloignant les bobines, mais elle doivent néanmoins êtres placées assez près l’une de l’autre pour entrer dans le diamètre de la cyble.
Pour limiter le phénomène, on va mettre les entrées de l’atmega où sont connectés les PULSE_IN_X en sortie et à l’état bas durant la mesure de la boucle active, et ça a quand même une meilleure tête.
Détection de la position et comptage des tours
Selon la présence de métal ou non sous chaque bobine, on peut déduire la position de la partie métallique, puis à l’aide d’une machine à états, en déduire quand un tour a été effectué.
On peut utiliser une, deux ou les trois bobines selon la précision désirée et le fait de détecter ou non le sens de rotation :
- une bobine : il y a 2 états possibles, avec ou sans métal (0 et 1), à chaque changement d’état le disque a fait un demi-tour mais on ne peut pas connaître le sens de rotation
- deux bobines : il y a 4 états possibles (00, 10, 11 et 01) , on peut détecter le sens de rotation
- trois bobines : il y a 6 états possibles (011, 001, 101, 100, 110 et 010, les états 000 et 111 étant théoriquement impossibles)
En prenant la configuration à deux bobines, il va falloir gérer les transitions suivantes :
Etat N | Etat N+1 | Evènement |
00 | 01 | NbTours– |
00 | 10 | ok |
00 | 11 | erreur |
01 | 00 | NbTours++ |
01 | 10 | erreur |
01 | 11 | ok |
10 | 00 | ok |
10 | 01 | erreur |
10 | 11 | ok |
11 | 00 | erreur |
11 | 01 | ok |
11 | 10 | ok |
Test sur breadboard
Pour éviter d’éventrer mon compteur d’eau pour récupérer la cyble et qu’il m’arrive des bricoles, j’en ai fait un prototype maison à partir de ce qui trainait dans le coin. Le mandrin de la visseuse fera l’affaire pour que ça tourne.
A chaque mesure des deux oscillateurs, on détecte s’il y a presénce de métal ou non en fonction du nombre d’oscillations. Par la suite il sera nécéssaire d’ajouter une fonction de calibration pour détecter le maximum et éventuellement se recalibrer périodiquement.
On regarde ensuite dans quel cas de transition on est, si elle est valide et s’il est nécessaire d’incrémenter le nombre de tour. On passe en veille profonde entre deux mesures pour limiter au maximum la consommation de la batterie.
La prochaine étape sera d’ajouter le module radio et de réaliser un circuit au propre…
19:41:13.560 -> A:32, B:42, rotationState:1011, index:0, error:1
19:41:13.891 -> A:36, B:40, rotationState:1111, index:0, error:1
19:41:14.174 -> A:48, B:36, rotationState:1111, index:0, error:1
19:41:14.452 -> A:62, B:36, rotationState:1101, index:0, error:1
19:41:14.779 -> A:66, B:35, rotationState:101, index:0, error:1
19:41:15.102 -> A:66, B:35, rotationState:101, index:0, error:1
19:41:15.382 -> A:68, B:51, rotationState:100, index:1, error:1
19:41:15.663 -> A:70, B:63, rotationState:0, index:1, error:1
19:41:15.991 -> A:58, B:62, rotationState:0, index:1, error:1
19:41:16.273 -> A:30, B:54, rotationState:10, index:1, error:1
19:41:16.557 -> A:30, B:26, rotationState:1011, index:1, error:1
19:41:16.892 -> A:58, B:24, rotationState:1101, index:1, error:1
19:41:17.178 -> A:64, B:28, rotationState:101, index:1, error:1
19:41:17.466 -> A:68, B:60, rotationState:100, index:2, error:1
19:41:17.754 -> A:60, B:64, rotationState:0, index:2, error:1
19:41:18.083 -> A:41, B:60, rotationState:10, index:2, error:1
19:41:18.363 -> A:36, B:57, rotationState:1010, index:2, error:1
19:41:18.697 -> A:36, B:56, rotationState:1010, index:2, error:1
19:41:18.986 -> A:32, B:42, rotationState:1011, index:2, error:1
19:41:19.270 -> A:44, B:34, rotationState:1111, index:2, error:1
19:41:19.556 -> A:62, B:36, rotationState:1101, index:2, error:1
19:41:19.892 -> A:64, B:36, rotationState:101, index:2, error:1
19:41:20.173 -> A:62, B:48, rotationState:101, index:2, error:1
19:41:20.502 -> A:62, B:64, rotationState:100, index:3, error:1
19:41:20.784 -> A:42, B:62, rotationState:10, index:3, error:1
19:41:21.066 -> A:37, B:58, rotationState:1010, index:3, error:1
19:41:21.391 -> A:34, B:56, rotationState:1010, index:3, error:1
19:41:21.669 -> A:30, B:44, rotationState:1011, index:3, error:1
19:41:21.996 -> A:34, B:30, rotationState:1111, index:3, error:1
19:41:22.281 -> A:52, B:34, rotationState:1111, index:3, error:1
19:41:22.565 -> A:66, B:35, rotationState:1101, index:3, error:1
19:41:22.889 -> A:66, B:41, rotationState:101, index:3, error:1
19:41:23.170 -> A:70, B:63, rotationState:100, index:4, error:1
19:41:23.450 -> A:52, B:60, rotationState:10, index:4, error:1
19:41:23.776 -> A:38, B:56, rotationState:1010, index:4, error:1
19:41:24.056 -> A:36, B:56, rotationState:1010, index:4, error:1
19:41:24.384 -> A:36, B:48, rotationState:1011, index:4, error:1
19:41:24.663 -> A:42, B:36, rotationState:1111, index:4, error:1
19:41:24.991 -> A:54, B:36, rotationState:1101, index:4, error:1
19:41:25.274 -> A:64, B:36, rotationState:101, index:4, error:1
19:41:25.554 -> A:66, B:42, rotationState:101, index:4, error:1
19:41:25.880 -> A:65, B:64, rotationState:100, index:5, error:1
19:41:26.162 -> A:48, B:62, rotationState:10, index:5, error:1
19:41:26.446 -> A:38, B:58, rotationState:1010, index:5, error:1
19:41:26.772 -> A:36, B:58, rotationState:1010, index:5, error:1
19:41:27.055 -> A:38, B:46, rotationState:1011, index:5, error:1
19:41:27.384 -> A:48, B:36, rotationState:1111, index:5, error:1
19:41:27.663 -> A:64, B:36, rotationState:1101, index:5, error:1
19:41:27.940 -> A:66, B:36, rotationState:101, index:5, error:1
19:41:28.266 -> A:64, B:48, rotationState:101, index:5, error:1
19:41:28.545 -> A:60, B:64, rotationState:100, index:6, error:1
19:41:28.871 -> A:42, B:62, rotationState:10, index:6, error:1
19:41:29.192 -> A:38, B:60, rotationState:1010, index:6, error:1
19:41:29.473 -> A:36, B:58, rotationState:1010, index:6, error:1
19:41:29.751 -> A:36, B:44, rotationState:1011, index:6, error:1
19:41:30.076 -> A:46, B:36, rotationState:1111, index:6, error:1
19:41:30.354 -> A:62, B:36, rotationState:1101, index:6, error:1
19:41:30.681 -> A:64, B:36, rotationState:101, index:6, error:1
19:41:30.960 -> A:70, B:62, rotationState:100, index:7, error:1
19:41:31.241 -> A:60, B:64, rotationState:0, index:7, error:1
19:41:31.569 -> A:44, B:62, rotationState:10, index:7, error:1
19:41:31.851 -> A:42, B:62, rotationState:1010, index:7, error:1
19:41:32.180 -> A:44, B:60, rotationState:1010, index:7, error:1
19:41:32.464 -> A:46, B:48, rotationState:1011, index:7, error:1
19:41:32.786 -> A:50, B:46, rotationState:1111, index:7, error:1
19:41:33.065 -> A:65, B:38, rotationState:1101, index:7, error:1
19:41:33.344 -> A:64, B:48, rotationState:101, index:7, error:1
19:41:33.673 -> A:70, B:64, rotationState:100, index:8, error:1
19:41:33.955 -> A:58, B:64, rotationState:0, index:8, error:1
19:41:34.280 -> A:42, B:59, rotationState:10, index:8, error:1
19:41:34.558 -> A:38, B:58, rotationState:1010, index:8, error:1
19:41:34.840 -> A:38, B:47, rotationState:1011, index:8, error:1
19:41:35.171 -> A:39, B:38, rotationState:1111, index:8, error:1
19:41:35.452 -> A:52, B:36, rotationState:1111, index:8, error:1
19:41:35.782 -> A:66, B:36, rotationState:1101, index:8, error:1
19:41:36.065 -> A:64, B:50, rotationState:100, index:9, error:1
19:41:36.348 -> A:70, B:65, rotationState:0, index:9, error:1
19:41:36.673 -> A:52, B:62, rotationState:10, index:9, error:1
19:41:36.952 -> A:38, B:60, rotationState:1010, index:9, error:1
19:41:37.279 -> A:36, B:56, rotationState:1010, index:9, error:1
19:41:37.558 -> A:32, B:38, rotationState:1011, index:9, error:1
19:41:37.886 -> A:46, B:34, rotationState:1111, index:9, error:1
19:41:38.169 -> A:64, B:36, rotationState:1101, index:9, error:1
19:41:38.448 -> A:66, B:36, rotationState:101, index:9, error:1
19:41:38.776 -> A:70, B:64, rotationState:100, index:10, error:1
19:41:39.054 -> A:38, B:58, rotationState:10, index:10, error:1