[resolu]version arduino et comportement du sketch

Bonsoir

Alors voila, j'ai besoin d'utiliser un codeur comme interface pour un projet en cours. J'essaye donc plusieurs trucs, et finalement un bout de code à base de PCINT me semble le plus approprié dans mon cas. Ce code est une adaptation d'un code tiré du livre de Clemens Valens"maitrisez les microcontroleurs à l'aide d'arduino".

Voici donc ce code :

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

int pin_sw = 10;
int pin_a = 11;
int pin_b = 12;
int pin_out = 6;
int state = 0;
int state_sub = 0;
volatile int counter = 0;
volatile boolean flag = false;
volatile boolean flagbtn = false;
int valeur = 0;

LiquidCrystal_I2C lcd(0x20,20,4); 

void encoder_read(void)
{
  uint8_t pin_states = PINB & PCMSK0;
  
  // Push button press.
  if ((pin_states&0x04)==0)
  {
    flagbtn += 1;
  }  
  pin_states = (pin_states>>3)&0x03;
  // state is now 0, 1, 2 or 3.
  if (pin_states!=state)
  {
    // Exor the old & new states to determine the rotation direction.
    int inc = ((pin_states>>1)^state)&0x01;
    if (inc==0) inc = -1;
    state = pin_states;
    
    // Reset on change of direction.
    if ((inc<0 && state_sub>0) || (inc>0 && state_sub<0)) state_sub = 0;
    
    state_sub += inc;
    if (state_sub<=-4 || state_sub>=4)
    {
      state_sub -= (inc<<2);
      counter += inc;
      flag = true;
    }
  }
}

ISR(TIMER2_COMPA_vect)
{
  bitClear(TIMSK2,OCIE2A); // Disable timer2 interrupts.
  encoder_read();
  bitSet(PCIFR,PCIF0); // Clear pending interrupts.
  bitSet(PCICR,PCIE0); // Enable PCINT0-7.
}

ISR(PCINT0_vect)
{
  bitClear(PCICR,PCIE0); // Disable PCINT0-7.
  bitSet(TCCR2A,WGM21); // CTC mode.
  bitSet(TCCR2B,CS20);
  bitSet(TCCR2B,CS22); // Clk div by 128.
  OCR2A = 250; // 2 ms.
  TCNT2 = 0; // Clear counter.
  bitSet(TIFR2,OCF2A);
  bitSet(TIMSK2,OCIE2A);
}

void setup(void)
{
  lcd.init();
  lcd.backlight();
  lcd.print("Essai codeur");
  delay(500);

  pinMode(pin_sw,INPUT_PULLUP);
  pinMode(pin_a,INPUT_PULLUP);
  pinMode(pin_b,INPUT_PULLUP);
  state = 0;
  state_sub = 0;
  counter = 0;
  flag = false;
  PCMSK0 = 0x1c; 
  bitSet(PCIFR,PCIF0); // Clear pending interrupts.
  bitSet(PCICR,PCIE0); // Enable PCINT0-7.
  
  lcd.clear();
  lcd.print("Valeur : ");
}

void loop()
{
  if (flagbtn & 1)
  {
    lcd.blink();
    if (counter)
    {
		valeur += counter*5;
		counter = 0;
		if (valeur>255) valeur=255;
		if (valeur<0) valeur=0;
		lcd.setCursor(9,0);
		lcd.print("    ");
		lcd.setCursor(9,0);
		lcd.print(valeur);
    }
  }
  else 
  {
    counter = 0;
    lcd.noBlink();
  }  
  
  analogWrite(pin_out,valeur);
}

Ce code, compilé avec une version inférieure à 1.6.0 fonctionne comme attendu, à savoir quand j'appuie sur le bouton du codeur, le curseur clignote sur le LCD et je peux modifier la valeur affichée, et quand je re-appuie à nouveau sur le bouton, je quitte l'édition et donc tourner le codeur ne change plus ma variable. Parfait.
La sortie en PWM fonctionne également, tout va bien.

Maintenant je compile ce code avec la version 1.6.0... et je ne comprends plus. Le début semble fonctionner pareil, mais une fois dans l'édition de la valeur, impossible d'en sortir, les appuis suivants sur le bouton ne sont plus pris en compte (alors que la rotation du codeur fonctionne ! )

Mon problème étant que je suis obligé d'utiliser la version 1.6.0 car avec une version antérieure, ma librairies YASM pour les machines à états à base de pointeurs de fonction ne fonctionne pas à cause d'options différentes lors de l'appel du compilateur (du moins si j'ai bien compris). Et je ne peux pas non plus utiliser une version plus récente car alors c'est la librairie pour piloter mon LCD en I2C qui ne fonctionne plus...

Bon en fait avec la 1.0.5 ça fonctionne, y compris ma librairie YASM. C'est avec la série des 1.5.x que YASM ne compile pas.
D'autre part avec la dernière version 1.8.2 j'ai le même comportement qu'avec 1.6.x : seul le premier appui sur le bouton est pris en compte. Mais en plus la librairie liquicristal-I2C ne fonctionne plus (seul les premiers caractères des envois sont affichés, dans mon cas seul le V de "Valeur :" et seul le premier chiffre de la valeur).

Autant dans le cas de mon code, je comprendrais tout à fait que ce que j'ai codé ne soit pas correct, autant pour la librairie... j'ai des doutes.
Qui a une idée ?

Autant dans le cas de mon code, je comprendrais tout à fait que ce que j'ai codé ne soit pas correct, autant pour la librairie... j'ai des doutes.

Les macros bitSet, bitClear etc sont-elle toujours définies dans les nouvelles version de l'IDE ?
Car se sont des macro, elles ne font pas partie du langage C ou C++.

Idem pour la bibliothèque, n'utilise t-elle pas des vielles macros arduino ou des vielles macros Atmel qu'Atmel aurait déclarées "deprecated" depuis plus de 10 ans et qu'il aurait fini par supprimer dans les nouvelles versions de l'avr-libc ?

ben si les macros n'étaient pas définies, ça ne compilerait pas, non ? j'aurais une erreur du genre "undefined identifier" ou un truc du genre

Autre truc étrange : compilé avec 1.8.2 le sketch fait 3960o, avec 1.0.5 il fait 4916o... soit l'optimisation à beaucoup évolué, soit il manque des trucs dans le binaire final...
Avec 1.6.0 j'avais une taille encore différente entre ces deux là.

Problème résolu grace aux réponse sur le forum en anglais : mon erreur est d'avoir incrémenté un boolean pour changer sa valeur. Le comportement de l'IDE à changé et toute valeur supérieur à 1 est désormais considérée comme 1 alors que précédemment le booléan était incrémenté comme toute autre variable (donc son premier bit, soit le seul pris en compte, passait alternativement de 0 à 1) . J'ai remplacé par un uint8 et plus de soucis, j'ai bien le premier bit qui change d'état à chaque incrémentation et ça fonctionne.

et pour la librairie LiquidCrystal_I2C qui merdoie, c'est car sa fonction write() renvoie 0 au lieu de 1 du coup la nouvelle version de print() de l'IDE>1.6.0 considère ça comme une erreur et n'envoie pas la suite. En lui faisant renvoyer 1 ça fonctionne.

Donc je peux profiter de l'IDE 1.8.2 et des optimisations lors de la compilation (plus 20% quand même !!)

L'IDE n'y est pour rien c'est le comportement du compilateur avr-gcc qui a changé (->Atlmel).
Effectivement entre la version embarquée dans l'IDE 1.0.x et celle de maintenant le compilateur a bien progressé.
Il a progressé coté optimisation et coté rigueur, ce que tu constates est cohérant.
Personnellement je reste méfiant vis à vis des "deprecated" comme SIGNAL, maro qui a été remplacée par ISR depuis....le plus loin que j'ai réussi à remonter 2002 et que certains utilisent toujours au risque de ne pas comprendre pourquoi plus rien ne fonctionne après une mise à jour.