Bonjour,
Après examen rapide il y a deux problèmes :
L'absence de volatile sur une variable partagée entre le programme principal et l'ISR alors que le programme principal (loop) effectue un while (...) sur cette variable comme le souligne Rob1. Rien ne dit que le compilateur la relit de la mémoire et prend donc connaissance de la valeur mise à jour par l'ISR
Un problème plus subtil de concurrence sur l'accès à la variable. En effet, l'Arduino AVR est une machine 8 bits, donc qui effectue les calculs sur un octet alors qu'un int occupe deux octets. De plus l'AVR 8 bits est une machine RISC : les calculs et comparaisons se font dans des registres internes du microcontrôleur. Par conséquent, additionner 1 à une variable globale se fait en plusieurs instructions : copie de la mémoire vers un registre, ajout de 1 au registre, copie du registre vers la mémoire. Pour un int, on a : copie du premier octet dans un premier registre, copie du 2e octet dans un second registre, ajout de 1 avec retenue sur les deux registres, copie du premier registre dans le premier octet de la mémoire, copie du second registre dans le second octet de la mémoire. Maintenant que se passe-il si l'interruption survient alors que dans le programme principal, le premier octet a été copié mais pas encore le second ? Et bien la valeur lue dans le programme principal sera formée de la moitié de la donnée avant l'ajout de 1 et de la moitié de la donnée après l'ajout de 1. La donnée aura donc une valeur non prévue.
Il faut donc copier cette variable globale dans une variable locale avec les interruptions désactivées :
while(1)
{
noInterrupts();
int localCopy = cpt_M220V;
interrupts();
if (localCopy >= 105) break;
monter();
}
De cette manière la copie locale est une copie correcte.