Lecture des roues codeuses
Le problème ici est de trouver un moyen de connaître l’état d’une roue codeuse capable de compter sur 16 bits.
À chaque rotation complète de la roue, ce capteur émets une interruption d’overflow, mais le but de l’algorithme présenté ici est de connaître en permanence la position de la roue codeuse (5 tours et 10 crans atteints depuis le début, par exemple) sans prendre en compte ces overflows.
Données initiales
- Le capteur nous fournit une position codée sur un
u16
- la roue codeuse est un compteur allant de
min = 0
àmax = pow(2, 16) - 1 = 65535
Résolution
On se donne les libertés suivantes :
- on a le droit d’avoir une variable
counter: i64
globale à l’algo - on peut utiliser autant de variables que l’on veut dans le programme
- on peut imposer des contraintes physiques sur la vitesse de rotation de la roue codeuse
Contraintes
La roue tourne strictement moins d’un demi-tour entre deux prises d’échantillon
Cette contrainte impose une vitesse de rotation v
maximale, mais elle permets que le sens de rotation de la roue codeuse soit décisable entre deux échantillons consécutifs.
Variables utilisées
La position globale de la roue codeuse est décidée pour chaque couple d’échantillons consécutifs, donc on utilise les variables suivantes :
- variables
counter: i64
- Compteur global correspondant à l’état de la roue codeuse. Utiliser 64 bits permets un déplacement sur plus de 2000km dans la même direction sans overflow pour une roue codeuse de diamètre 6cm.current: u16
- Position de la roue codeuse lue dans l’itération en coursN
previous: u16
- Position de la codeuse lue à l’itérationN - 1
- constantes
min: u16 = 0x0
- Valeur minimale fournie par la roue codeusemax: u16 = pow(2, 16) - 1
- Valeur maximale fournie par la codeusehalf: u16 = pow(2, 15)
- Valeur moyenne fournie par la codeuse et utilisée pour décider du sens de rotation
Traitement des cas possibles
Le code doit être capable de gérer les overflows et les underflows pour mettre à jour le counter
.
Il doit prendre en compte 4 cas différents : (2 sens de rotation différents) * (overflow ou non).
Rotation trigonométrique | Rotation horaire | |
---|---|---|
over/under flow | représentation : min--C---------P--max décision : (C < P) && (P - C > half) impact : counter += (max - P + C + 1) |
représentation : min--P---------C--max décision : (P < C) && (C - P > half) impact : counter -= (max - C + P + 1) |
comptage normal | représentation : min------C--P------max décision : (P < C) && (C - P < half) impact : counter += C - P |
représentation : min------P--C------max décision : (C < P) && (P - C < half) impact : counter -= P - C |
Implémentation possible
Finalement, voici une implémentation en considérant que la lecture se fait depuis read_captor()
: