[Résolu] "Lags" Arduino Mega 2560

Bonjour à tous,

Voila mon problème: Je suis en train de coder un programme sur mon Arduino Mega 2560, ce programme gère beaucoup d'entrées et sorties (presque toutes les broches sont prises). Pour l'instant, les entrées sont connectées à de simples boutons et les sorties à des leds (c'est plus simple pour les tests). Cependant, j'ai une impression de "lag": quand j'appuie sur le bouton, la led correspondante s'allume une fois sur deux, comme s'il fallait appuyer sur le bouton pile quand l'arduino est en train de lire la partie correspondante du programme.

C'est très pénible et j'aimerais bien m'en débarrasser. Il n'y a pas de delay dans void loop, il y en a un dans void setup (je pense pas que cela vienne de là).
J'ai entendu parler des "interruptions" qui évitent ce genre de problème, mais étant débutant, je ne sait pas trop comment les utiliser.
Pouvez-vous m'aider à trouver une solution?

Merci d'avance! :smiley:

P.S: Je souhaite par la suite rajouter un écran LCD monochrome de 4x20 ou 2X16. Pensez-vous que ce sera possible sans trop surcharger l'aruino? (j'ai vérifié, je peux le brancher)

https://www.arduino.cc/en/Reference/Interrupts

D'acc merci :wink:
En gros j'aurais tout mon code dans la partie noInterrupts et rien dans la partie Interruption puisque tout mon code (mes 20 boutons avec leurs sorties) à besoin de réagir rapidement.
Mais dans ce cas cette fonction est toujours utile?

Il y a peu de chances pour qu'un programme bien organisé soit trop occupé pour arriver à suivre correctement l'évolution des entrées.

Gérer 20 boutons est plus que très largement à la portée du nono, même sans interruptions.

Comment est structuré ton programme?

  • Quelle méthode de debouncing utilise-tu ?

  • Tu peux lire tous les pins d'un même port en une seule opération, ce qui est bien plus rapide que de lire les entrées une à une (bien que ce ne soit probablement pas la cause de ton problème). Voir ici et .

  • Il existe des librairies pour gérer des boutons, une que j'aime bien est celle-ci.

Impossible de t'aider sans voir ton code.

Si on voyait le programme ce serait pas mal.

bonjour,

fdufnews:
Si on voyait le programme ce serait pas mal.

+1

Il y a des pullups sur les entrées boutons?

Il faut que tu détectes les goulots d'étranglement dans ton code et que tu les suprimes.

Ensuite si ce n'est pas suffisant pour augmenter la vélocité il y a deux moyens qui t'ont été indiqué :

  • Éviter les fonctions Wiring/Arduino digitalRead() et digitalWrite() qui sont très lentes.
    Pour cela il faut lire directement les registres PINx, avec x = A,B,C,D etc dépendant du micro utilisé --> voir le nom des ports dans la datasheet du micro (chez Atmel ).
    Autre point : interruption :
    Sur les micros "avr" il existe deux types d'interruption : sur un nombre limité de pins spéciales, c'est celle que tu utilises avec la fonction Wiring/Arduino attachInterupt().
    Il existe un autre type qui n'est pas géré par les fonctions Wiring/Arduino et qui peut être utilisé à partir de toutes les pins : c'est les interruptions sur les PORTs.
    Dans les deux cas la lecture de la datasheet du micro-contrôleur s'impose.

fdufnews:
Si on voyait le programme ce serait pas mal.

Et le schéma électrique aussi !

Résistance de tirage au plus ou à la masse ?
Capa anti-rebonds ou anti- rebonds logiciel ?
Si anti-rebonds logiciel utilisation de delay() ?

C'est vrai que les fonctions digitalRead() et digitalWrite() sont lentes, mais comparé au temps d'appui sur le bouton (disons supérieur à 100 ms) que ça prenne 1 ou 100 µs ça ne change pas grand chose.
Je suis de l'avis de Bricoleau ça dépend grandement de la structure du programme.

Déjà, merci à tous!

-Oui, j'utilise des pullup
-Il n'y a pas de fonctions delay

  • Le système anti-rebons est fait avec un simple condensateur en parallèle du bouton

Voici le code (il n'est pas fini, ne faites pas attention au texte, c'est pour m'y retrouver plus facilement)

#include <Servo.h>
//Initialisation des conditions
boolean etatBouton1;
boolean etatBouton2;
boolean etatBouton3;
boolean etatBouton4;
boolean etatBouton5;
boolean etatBouton6;
boolean etatBouton7;
boolean etatBouton8;
boolean etatBouton9;
boolean etatBouton10;
boolean etatBouton11;
boolean etatBouton12;
boolean etatBouton13;
boolean etatBouton14;
boolean etatBouton15;
boolean etatBouton16;
boolean etatBouton17;
boolean etatBouton18;
boolean etatBouton19;
boolean etatBouton20;


//Initialisation des différents noms des pins

const int led_test = 53;
const int led_security = 52;
const int led_class_1 = 51;
const int led_class_2 = 50;
const int arduino_nano_check = 49;
const int buzzer = 48;
const int relai_1 = 47; //Contrôle du relai 1 qui gère la ligne 1
const int relai_2 = 46; //  -
const int relai_3 = 45; //  -
const int relai_4 = 44; //  -
const int relai_5 = 43; //  -
const int relai_6 = 42; //  -
const int relai_7 = 41; //  -
const int relai_8 = 40; //  -
const int relai_9 = 39; //  -
const int relai_10 = 38; 
const int relai_11 = 37; 
const int relai_12 = 36;
const int relai_13 = 35; 
const int relai_14 = 34; 
const int relai_15 = 33;
const int relai_16 = 32; 
const int relai_17 = 31; 
const int relai_18 = 30; 
const int relai_19 = 29; 
const int relai_20 = 28; 
const int bouton_1 = 27; //gestion de l'option #1
const int bouton_2 = 26; //gestion de l'option #2
const int bouton_3 = 25; //gestion du relai 1
const int bouton_4 = 24; //gestion du relai 2 
const int bouton_5 = 23; //gestion du relai 3
const int bouton_6 = 22; //gestion du relai 4
const int bouton_7 = 0; //gestion du relai 5
const int bouton_8 = 1; //gestion du relai 6
const int bouton_9 = 2; //gestion du relai 7
const int bouton_10 = 3; //gestion du relai 8
const int bouton_11 = 4; //gestion du relai 9
const int bouton_12 = 5; //gestion du relai 10
const int bouton_13 = 6; //gestion du relai 11
const int bouton_14 = 7; //gestion du relai 12
const int bouton_15 = 8; //gestion du relai 13 
const int bouton_16 = 9; //gestion du relai 14
const int bouton_17 = 10; //gestion du relai 15
const int bouton_18 = 11; //gestion du relai 17
const int bouton_19 = 12; //gestion du relai 18
const int bouton_20 = 13; //gestion du relai 19

//partie écran


//Initialisation des différentes sorties et entrées
void setup() 
{
//Sorties
pinMode (led_test, OUTPUT);
pinMode (led_security, OUTPUT);
pinMode (led_class_1, OUTPUT);
pinMode (led_class_2, OUTPUT);
pinMode (arduino_nano_check, OUTPUT);
pinMode (buzzer, OUTPUT);
pinMode (relai_1, OUTPUT);
pinMode (relai_2, OUTPUT);
pinMode (relai_3, OUTPUT);
pinMode (relai_4, OUTPUT);
pinMode (relai_5, OUTPUT);
pinMode (relai_6, OUTPUT);
pinMode (relai_7, OUTPUT);
pinMode (relai_8, OUTPUT);
pinMode (relai_9, OUTPUT);
pinMode (relai_10, OUTPUT);
pinMode (relai_11, OUTPUT);
pinMode (relai_12, OUTPUT);
pinMode (relai_13, OUTPUT);
pinMode (relai_14, OUTPUT);
pinMode (relai_15, OUTPUT);
pinMode (relai_16, OUTPUT); 
pinMode (relai_17, OUTPUT);
pinMode (relai_18, OUTPUT);
pinMode (relai_19, OUTPUT);
pinMode (relai_20, OUTPUT);

//Entrées
pinMode (bouton_1, INPUT_PULLUP);
pinMode (bouton_2, INPUT_PULLUP);
pinMode (bouton_3, INPUT_PULLUP);
pinMode (bouton_4, INPUT_PULLUP);
pinMode (bouton_5, INPUT_PULLUP);
pinMode (bouton_6, INPUT_PULLUP);
pinMode (bouton_7, INPUT_PULLUP);
pinMode (bouton_8, INPUT_PULLUP);
pinMode (bouton_9, INPUT_PULLUP);
pinMode (bouton_10, INPUT_PULLUP);
pinMode (bouton_11, INPUT_PULLUP);
pinMode (bouton_12, INPUT_PULLUP);
pinMode (bouton_13, INPUT_PULLUP);
pinMode (bouton_14, INPUT_PULLUP);
pinMode (bouton_15, INPUT_PULLUP);
pinMode (bouton_16, INPUT_PULLUP);
pinMode (bouton_16, INPUT_PULLUP);
pinMode (bouton_17, INPUT_PULLUP);
pinMode (bouton_19, INPUT_PULLUP);
pinMode (bouton_20, INPUT_PULLUP);

//Mise par défaut des entrées bouton_XX sur HIGH (=1)
etatBouton1 = HIGH;
etatBouton2 = HIGH;
etatBouton3 = HIGH;
etatBouton4 = HIGH;
etatBouton5 = HIGH;
etatBouton6 = HIGH;
etatBouton7 = HIGH;
etatBouton8 = HIGH;
etatBouton9 = HIGH;
etatBouton10 = HIGH;
etatBouton11 = HIGH;
etatBouton12 = HIGH;
etatBouton13 = HIGH;
etatBouton14 = HIGH;
etatBouton15 = HIGH;
etatBouton16 = HIGH;
etatBouton17 = HIGH;
etatBouton18 = HIGH;
etatBouton19 = HIGH;
etatBouton20 = HIGH; 

//code pour écran

}


void loop() 
{
//Programme pour bouton_1
etatBouton1 = digitalRead(bouton_1);
if(etatBouton1 == HIGH)
{
digitalWrite(relai_1,LOW);
}
else
{
digitalWrite(relai_1,HIGH);
delay (500);
}



//Programme pour bouton_2
etatBouton2 = digitalRead(bouton_2);
if(etatBouton2 == HIGH)
{
digitalWrite(relai_2,LOW);
}
else
{
digitalWrite(relai_2,HIGH);
delay (500);
}



//Programme pour bouton_3
etatBouton3 = digitalRead(bouton_3);
if(etatBouton3 == HIGH)
{
digitalWrite(relai_3,LOW);
}
else
{
digitalWrite(relai_3,HIGH);
delay (500);
}



//Programme pour bouton_4
etatBouton4 = digitalRead(bouton_4);
if(etatBouton4 == HIGH)
{
digitalWrite(relai_4,LOW);
}
else
{
digitalWrite(relai_4,HIGH);
delay (500);
}



//Programme pour bouton_5
etatBouton5 = digitalRead(bouton_5);
if(etatBouton5 == HIGH)
{
digitalWrite(relai_5,LOW);
}
else
{
digitalWrite(relai_5,HIGH);
delay (500);
}



//Programme pour bouton_6
etatBouton6 = digitalRead(bouton_6);
if(etatBouton6 == HIGH)
{
digitalWrite(relai_6,LOW);
}
else
{
digitalWrite(relai_6,HIGH);
delay (500);
}



//Programme pour bouton_7
etatBouton7 = digitalRead(bouton_7);
if(etatBouton7 == HIGH)
{
digitalWrite(relai_7,LOW);
}
else
{
digitalWrite(relai_7,HIGH);
delay (500);
}



//Programme pour bouton_8
etatBouton8 = digitalRead(bouton_8);
if(etatBouton8 == HIGH)
{
digitalWrite(relai_8,LOW);
}
else
{
digitalWrite(relai_8,HIGH);
delay (500);
}



//Programme pour bouton_9
etatBouton9 = digitalRead(bouton_9);
if(etatBouton9 == HIGH)
{
digitalWrite(relai_9,LOW);
}
else
{
digitalWrite(relai_9,HIGH);
delay (500);
}



//Programme pour bouton_10
etatBouton10 = digitalRead(bouton_10);
if(etatBouton10 == HIGH)
{
digitalWrite(relai_10,LOW);
}
else
{
digitalWrite(relai_10,HIGH);
delay (500);
}



//Programme pour bouton_11
etatBouton11 = digitalRead(bouton_11);
if(etatBouton11 == HIGH)
{
digitalWrite(relai_11,LOW);
}
else
{
digitalWrite(relai_11,HIGH);
delay (500);
}



//Programme pour bouton_12
etatBouton12 = digitalRead(bouton_12);
if(etatBouton12 == HIGH)
{
digitalWrite(relai_12,LOW);
}
else
{
digitalWrite(relai_12,HIGH);
delay (500);
}



//Programme pour bouton_13
etatBouton13 = digitalRead(bouton_13);
if(etatBouton13 == HIGH)
{
digitalWrite(relai_13,LOW);
}
else
{
digitalWrite(relai_13,HIGH);
delay (500);
}



//Programme pour bouton_14
etatBouton14 = digitalRead(bouton_14);
if(etatBouton14 == HIGH)
{
digitalWrite(relai_14,LOW);
}
else
{
digitalWrite(relai_14,HIGH);
delay (500);
}



//Programme pour bouton_15
etatBouton15 = digitalRead(bouton_15);
if(etatBouton15 == HIGH)
{
digitalWrite(relai_15,LOW);
}
else
{
digitalWrite(relai_15,HIGH);
delay (500);
}



//Programme pour bouton_16
etatBouton16 = digitalRead(bouton_16);
if(etatBouton16 == HIGH)
{
digitalWrite(relai_16,LOW);
}
else
{
digitalWrite(relai_16,HIGH);
delay (500);
}



//Programme pour bouton_17
etatBouton17 = digitalRead(bouton_17);
if(etatBouton17 == HIGH)
{
digitalWrite(relai_17,LOW);
}
else
{
digitalWrite(relai_17,HIGH);
delay (500);
}



//Programme pour bouton_18
etatBouton18 = digitalRead(bouton_18);
if(etatBouton18 == HIGH)
{
digitalWrite(relai_18,LOW);
}
else
{
digitalWrite(relai_18,HIGH);
delay (500);
}



//Programme pour bouton_19
etatBouton19 = digitalRead(bouton_19);
if(etatBouton19 == HIGH)
{
digitalWrite(relai_19,LOW);
}
else
{
digitalWrite(relai_19,HIGH);
delay (500);
}



//Programme pour bouton_20
etatBouton20 = digitalRead(bouton_20);
if(etatBouton20 == HIGH)
{
digitalWrite(relai_20,LOW);
}
else
{
digitalWrite(relai_20,HIGH);
delay (500);
}


}

Je suis débutant, donc le code n'est peut-être pas très optimisé

Bonjour,

Zyaxi:
-Il n'y a pas de fonctions delay

??? j'en compte 20 !!!

oui effectivement x) mais elles ne sont prises en compte que si le bouton est activé. Et le "lag" n'est pas de 500ms mais plus d'environ 100/300ms.

100 à 300 ms ça me parait énorme pour exécuter loop()

Je te conseille d'afficher le temps d'exécution sur le terminal

Pour cela:
Dans setup tu initialises la liaison série

 Serial.begin(9600);

Au début de loop tu mémorises le temps

 unsigned long debut=millis();

A la fin de loop tu affiches le temps

  unsigned long duree=millis()-debut;
  Serial.print("Duree: ");
  Serial.println(duree);

Tu lances le moniteur série dans l'ide arduino et tu verras combien dure la boucle

merci :smiley:

voila le résultat http://puu.sh/kSnIg/06775f4857.png

oula! ça parait énorme

Cela signifie que tu as alternativement 1 et 2 boutons détectés comme enfoncés, ce qui déclenche une pause de 500 ms ou 1000 ms.

Tes boutons 7 et 8 utilisent les pin 0 et 1 => ce sont les Serial.print ajoutés qui génèrent des appuis parasites

Mais sans Serial.print, difficile de diagnostiquer quoi que ce soit => Branche tes boutons 7 et 8 ailleurs

Au passage, il serait grand temps d'apprendre les tableaux :smiley:

Voici la version strictement équivalente au programme que tu as posté :

#include <Servo.h>

const int nb_boutons = 20;

//Initialisation des conditions
boolean etatBouton[nb_boutons];

//Initialisation des différents noms des pins

const int led_test = 53;
const int led_security = 52;
const int led_class_1 = 51;
const int led_class_2 = 50;
const int arduino_nano_check = 49;
const int buzzer = 48;
const int relai[nb_boutons]  = {47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28};
const int bouton[nb_boutons] = {27, 26, 25, 24, 23, 22,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13}; 

//partie écran

//Initialisation des différentes sorties et entrées
void setup() 
{
//Sorties
pinMode (led_test, OUTPUT);
pinMode (led_security, OUTPUT);
pinMode (led_class_1, OUTPUT);
pinMode (led_class_2, OUTPUT);
pinMode (arduino_nano_check, OUTPUT);
pinMode (buzzer, OUTPUT);
for (int i=0; i<nb_boutons; i++) pinMode (relai[i], OUTPUT);

//Entrées
for (int i=0; i<nb_boutons; i++) pinMode (bouton[i], INPUT_PULLUP);

//Mise par défaut des entrées bouton_XX sur HIGH (=1)
for (int i=0; i<nb_boutons; i++) etatBouton[i] = HIGH;

//code pour écran

}


void loop() 
{
//Programme pour bouton i
  for (int i=0; i<nb_boutons; i++) {
    etatBouton[i] = digitalRead(bouton[i]);
    if(etatBouton[i] == HIGH)
    {
    digitalWrite(relai[i],LOW);
    }
    else
    {
    digitalWrite(relai[i],HIGH);
    delay (500);
    }
  }
}

Bricoleau à raison, il y a des boutons lus comme enfoncés. Je viens de faire un essai en déclarant tous les boutons sur la pin 27 et la durée de la boucle est de l'ordre de 1 ms.