Lecture des roues codeuses

by bigey — on

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 cours N
    • previous: u16 - Position de la codeuse lue à l’itération N - 1
  • constantes
    • min: u16 = 0x0 - Valeur minimale fournie par la roue codeuse
    • max: u16 = pow(2, 16) - 1 - Valeur maximale fournie par la codeuse
    • half: 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() :

Partager: