0verflow sur type de variables

salut tous le monde,

j'ai un souci d'overflow sur type de variables qui se produit dans mon programme.

j'effectue des opérations simples ( Addition, division ) sur des valeurs stockées dans un tableau de char ( 8bits sur arduino)

le résultat de ces "petites" opérations devrait être compris entre 0 et 15, mais la science n'ayant rien d'exacte je reçois parfois des valeurs négatives entre -1 et -3 . Vue que j'utilise des variables de types non signées, je reçois des 255, 254 etc.

Ma question: Comment faire pour avoir des 0 à la place de valeurs négatives ? ou à la limite des valeurs correspondant a la valeur absolu ?

j'ai tester des masques, pour récupérer les 4 bits de poids faibles mais sa pose un problème dans certains ( et ces cas sont fréquents).

j'ai aussi tester la fonction "Abs" mais sa na pas l'aire de vraiment fonctionner ( voir pire).

cordialement.

Bonjour,

Ben, il faut faire le calculs intermédiaires sur des long ou unsigned long

j'ai tester pas mal de type de variable avec le même résultat.

j'ai un timer en mode Input capture, dont la valeur renvoyer par le timer via ICR5 ( 16bit) a chaque front descendant, est stokée dans un tableau de int ( 16bits sur arduino ) :

ISR(TIMER5_CAPT_vect)
{

Buffer[ buff_index ] = ((ICR5 )/ 44)-15); 
}

et je reçois des quelques valeurs négatives.

Là il n'y a pas de débordement.
Ca veut simplement dire que ICR5 est inférieur à 44*15
D'où vient ta formule?

Pour décoder le capteur, il faut mesurer le temps entre deux fronts descendant de plusieurs impulsions.

le timer tourne à 16Mhz, soit 16cycles/µs ==>> le temps en microseconde Tµs = ICR5/16. (oui ?).

Ensuite l'information que je recherche est codée dans le temps, C.a.d :

la durée de chaque impulsion est un multiple d'une "Unité de temps(UT)" qui 2,8µs et d'apres la datasheet du capteur une impulsions dure entre 12 UT et 27 UT.

Ce qui veut dire que chaque impulsions referme une information sur 4 bits. ( 12UT = B0000 et 27UT = B1111)

donc le temps en UT vaut : T_ut = (ICR5/ 16*2,8) (oui ?)

Pour finir, pour savoir combien valent mes 4 bits, je fait -11 (- 15 normalement, mais les temps mesurés via le programmeur fourni ne sont pas exactement les meme que par l'Arduino, Je suppose que les niveaux de détections High, Low ne sont pas les même)

voila pour la formule.

Moi, je serais de toi je mettrais dans buffer, la valeur lue dans ICR5 et je ferais les calculs lors de l'exploitation de buffer ce qui permettrait d'afficher les valeurs mesurées et le valeurs calculées.
Sauf erreur de ma part, le timer n'est pas remis à zéro lors de l'interruption capture, est ce qu'il ne faudrait pas le remettre à zéro: TCNT5=0;

OUI il est remis a zero a chaque fois.

{
 TCNT5 = 0;
  Buffer[ buff_index ] = (((ICR5) / 44) - 11); //& B00001111; //(48 = 3*16) 3 = prédiv capteur, et 16 clock/µs
  buff_index ++;
  if (buff_index == size_buff)
  {
    buff_index = 0;
  }

je vais essayer de traiter les valeurs hors de l'interruption.

Salut,

ICR5 est un word (16 bits), donc s'il dépasse (255+15)*44, soit 11880, alors il y aura débordement et la valeur de retour sera erronée...

Peut-être effectuer un test

if (ICR5 < 11880) {
// faire le calcul
} // sous entendu qu'au-dessus, on ne traite pas l'info puisqu'on déborde...

Oui faites les maths en dehors de l'ISR c'est mieux. Est-ce que Buffer (et buff_index) est bien déclaré en volatile ?

Comment savez vous que le buffer a été rempli quand l'index revient à zéro versus pendant qu'il le rempli? Traitez vous tout le tableau en dehors ? (attention aux ISR si vous travaillez sur 16 bits ou à l'atomicité des maths)

il est vrai que le compilateur traite toutes les constantes comme INT par défaut, donc quoiqu'il arrive, ce sera du 16 signé partout...

un tableau en 16 bits sera peut-être une alternative. d'ailleurs, le tableau, c'est pour faire une moyenne? un filtrage?