Alternative à digitalRead(buttonXpin)?

Bonjour,
La fonction ci-dessous fait un défilement du texte vers la bas. En appuyant sur un bouton (ici B), le défilement doit s'arrêter et une fonction a( ) démarre:

void defilementBas()
{
do { 
  
  matrix.fillScreen(0);if (digitalRead(buttonBpin) == LOW) { a();}

 matrix.setCursor(1, y);
 if(y++ >= 9) y = 0;if (digitalRead(buttonBpin) == LOW) { a();}
 temp = dht.readTemperature();
    matrix.setTextColor(colors[2]);if (digitalRead(buttonBpin) == LOW) { a();}
     matrix.print((temp),1); matrix.write ((char)248);
    matrix.show();if (digitalRead(buttonBpin) == LOW) { a();}
    delay(50);if (digitalRead(buttonBpin) == LOW) { a();}
    } while (y <= 8);
    if (digitalRead(buttonBpin) == LOW) { a();}
  
}

Je n'ai trouvé d'autre alternative que de placer un "if (digitalRead(buttonBpin) == LOW) { a();}" après chaque ligne pour que ça fonctionne. Il y a des ratés, car parfois il faut appuyer 2 fois, voire garder brièvement le bouton appuyé. Et le code n'est pas élégant.
Il y a-t-il une autre façon de faire?
Merci

Tu pourrais envisager une interruption créée par l'appui sur le bouton, si ta fonction a n'est pas trop longue.
Tu la déclares dans ton setup :

attachInterrupt(digitalPinToInterrupt(buttonBpin), a, LOW);

le souci sans doute vient de la structure du code.

Par exemple temp = dht.readTemperature();, qu'est-ce qu'il fait là au milieu de la boucle ? (c'est un appel qui est très lent)

pourquoi avez vous un delay(50); aussi ?

C'est vrai qu'elle est bizarre cette fonction, on a l'impression qu'on ne peut pas sortir du while. La condition de sortie serait y>8 mais à l'intérieur tu mets y = 0 s'il vaut 9.
Donc la condition de sortie n'est jamais réalisée.

Au passage, ceci

if (y++ >= 9) y = 0;

peut s'écrire (% est la fonction modulo)

y = (y + 1) % 8;

Merci pour vos commentaires,

  • Il y a une sonde T° attachée à l'Arduino (DHT11): avec temp = dht.readTemperature(); la température est mise à jour à chaque loop.
  • le delay (50) c'est la vitesse de défilement, je comprends que l'idéal est de n'avoir aucun delay pour que les boutons deviennent réactifs.
    Mais s'il n'y a pas de delay, le défilement est tellement rapide, qu'il ne sert à rien.

@lesept
tu as raison, je vais corriger. Le défilement fonctionne quand même parce que le 9 n'est jamais atteint mais le 8 oui, ce qui provoque la sortie du loop.
mais y n'est jamais remis à 0.

Je vais essayer ta proposition :
attachInterrupt(digitalPinToInterrupt(buttonBpin), a, LOW);

if (y++ >= 9) y = 0;

peut s'écrire (% est la fonction modulo)

y = (y + 1) % 8;

Je ne crois pas, c'est

y = (y + 1) % 10;

Si y vaut 8, le test est faux et on incrémente y après, ce qui fait qu'il va jusqu'à 9.
Et on peut aussi écrire

y = ++y % 10;

Si l'interruption ne fonctionne pas, l'autre solution est de mesurer le temps et de ne faire des mesures de température que toutes les cinquante millisecondes avec millis. On peut alors se passer du delay et scanner le bouton plus souvent.

Il faut restructurer le code et utiliser millis

Avez vous besoin de lire la température si souvent ? Un appel à dht.readTemperature() prend au moins 250ms... ça rend la lecture des boutons très peu ergonomique

Merci beaucoup pour vos précieux conseils.
Je vais essayer de séparer les actions, par exemple l'appel température est réalisé dans une fonction X et l'affichage du résultat dans une autre fonction Y, avec l'appel boutons. Au lieu d'avoir tout sous une même fonction.

J'ai pas encore eu le temps d'essayer attachInterrup, ça a l'air intéressant.

Il faut lire la température à un rythme raisonnable par rapport à la vitesse d’évolution de la température. Si c’est juste dans une pièce de la maison, lire toutes les 10 ou 15 minutes sera sans doute suffisant, pas la peine de lire toutes les 500ms...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.