[Résolu] Problème compteur (passe en négatif à partir d'un moment)

Bonjour à toutes et tous.

Je fais face à un nouveau problème que je n'arrive pas à élucider...

J'ai un programme qui incrémente un compteur temps toutes les 100 ms et une autre variable qui s'incrémente via les données récupérer par mon codeur incrémental.

Premier problème rencontré et solutionné

  • le compteur de temps partait en négatif au bout de 32700ms => -32736 puis -32636, etc... jusqu'à 0 donc et repartait en positif : -36 puis 64 puis 164,...
    J'ai solutionné le problème en désignant ma variable temps en "unsigned int"

Deuxième problème qui est similaire au point précédent
Je mesure en µm une distance à l'aide de mon codeur incrémental.
Arrivé à -32343µm (signe moins en fonction de si on avance ou recule), la valeur suivante passe à 32518 puis 31955, ...
Je ne peux solutionner le problème comme précédemment en mettant un "unsigned int" car la fonction ne fonctionnerait plus pour incrémenter ou décrémenter la valeur.
J'ai "temporairement" solutionné le problème en passant les valeurs en dizaine de µm plutôt qu'en µm (en passant le diamètre de 21500 à 2150)

Mais pour être plus précis, il me faudrait cette distance en µm mais je ne comprends pas ce "bug" de passer en négatif quand le compteur avoisine les 32700....

Ci dessous le code de mon programme, en espérant que quelqu'un à déjà fait face à ce genre de problèmes.

Merci par avance.
Arduinonement.

//Pin 2 & 3 sont des pins spéciales, ne pas changer
int encoderPin1 = 2;
int encoderPin2 = 3;

unsigned int time1 = 0;
int Pi = PI;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

void setup()
{
  Serial.begin (9600);

  pinMode(encoderPin1, INPUT); //Broche 2 en sortie
  digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
    
  pinMode(encoderPin2, INPUT); //Broche 3 en sortie
  digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3) 
  attachInterrupt(0, updateEncoder, CHANGE); 
  attachInterrupt(1, updateEncoder, CHANGE);
}

void loop()
{ 
  while (!Serial.available() > 0)
  {
      int coeff = ((PI/180)*21500); //2150=rayon roue codeur (5 chiffres problèmes à partir de 32700)
      int ValueLength = ((encoderValue*0.15)*coeff); //Transformation bit en longueur 
      Serial.print("Temps (ms);");
      Serial.print(time1);
      Serial.print(";");
      Serial.print("Longueur parcourue (µm);");
      Serial.print(ValueLength);
      Serial.println(";");
    
      time1 = time1 + 100;
      delay(100); //mesures toutes les 100ms
  }
}


void updateEncoder()
{
  int MSB = digitalRead(encoderPin1); //MSB = most significant bit
  int LSB = digitalRead(encoderPin2); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded; //store this value for next time
}

Bonjour,

Il faut que tu déclares ValueLength en long.

Bonjour

Premier problème' : aucun bug la dedans mais le 'quotidien' des nombres binaires formés d'un nombre de bits fixé et deont le bit de poids dans lequel les bit de poids fort représente le signe.
-> Chercher des infos sur le code 'binaire complémenté à 2'

Pour éviter ce mécanisme définir les variables comme des nombres non signés: unsigned int par exemple
ça permettra de monter jusqu'à 65535 avec 16 bits et non passer en négatif à mi chemin

S'il ya 'bug' c'est celui du programmeur qui n'a pas encore pris en compte la représentation des entiers négatifs en binaire et ses 'effets de bord' !!

Mais bien sur !!!

Comme vous le dites si bien, une erreur de débutant !
Mais quand on est tête bêche dans le programme depuis des heures, il arrive qu'on ne vois plus les simples erreurs qui sont sous notre nez...

Encore merci et désolé pour cette erreur bête...