Conception compteur de points

Bonjour,

Je souhaite produire un compteur de points pour un match de tennis de table.

Il est important de préciser que j'ai un niveau 0 en électronique :sweat_smile:.
Ce compteur devra donc affiche les points, le nombre de set, le temps mort pour les 2 jours.

Donc dans ma conception j'avais imaginer :

  • 6 afficheurs (2 par joueurs pour le nombre de points, 1 par joueur pour le nombre de set)
  • 9 boutons (3 par joueurs "+/-/temps mort", 1 bouton reset, 1 bouton switch lorsque les joueurs changent de côté, 1 bouton on/off)

J'avais préparé une documentation et tout, je découvre Tinkercad donc je commence à m'amuser avec, j'ai réussi à faire un compteur de points/set pour un joueur.

Seulement là j'arrive au moment où je me pose la question : comment vais-je faire pour compter pour le second joueur ?
J'ai trop d'éléments à brancher sur un seul arduino !
Ma conception est-elle mauvaise ? Ou alors c'est mon manque de connaissance ?
Dois je utiliser 2 arduino ? Si oui je dois les faire communiquer entre eux pour qu'ils connaissent le score de chaque joueur ?

Voici ce que j'ai réussi à faire pour le moment pour ceux que ça intéresse:
1 bouton -, un bouton +, un bouton reset.
Quand le score arrive à 11, le nombre de set augmente.

N'oubliez pas que les broches analogiques peuvent également être utilisées comme broches numériques (même si je pense qu'elles ne suffiraient pas de toute façon), mais il n'est pas nécessaire d'utiliser deux Arduinos; vous pouvez utiliser un Mega, qui possède de nombreuses broches, ce qui vous permet de connecter les deux écrans au même Arduino.

Bien sûr, le code devra également être révisé pour prendre en charge le Mega et étendu pour en utiliser deux, mais vous comprendrez cela après l'achat d'un Mega.

Super merci :wink:.
Je ne trouve pas le mega sur Tinkercad, je vais voir si il existe une autre solution car j'aimerai tout faire fonctionner avant de commander les pièces :sweat_smile:

Tinkercad a empiré depuis qu'Autodesk l'a repris. J'utilise souvent Wokwi, qui inclut également Mega (et plus), et je le trouve plus pratique à gérer et à utiliser.

Son seul défaut est que la compilation du code est parfois très lente (il existe une option payante offrant une priorité supérieure à celle du compte gratuit).

Yep je viens de tester sur wokwi et j'ai trouvé le mega, merci :wink:.
Tant que tous les composants sont là ça ira :laughing:

Une âme charitable pourrait jeter un coup d'oeil ici ?

J'essaie de reproduire ce que j'ai fait sur Tinkercad mais pour une raison qui m'échappe le simple clique du bouton semble ne pas fonctionner...

Plusieurs raisons.

  • Vous avez mal connecté le bouton sur la breadboard; vous devez le faire pivoter:
  • Toutes les variables modifiables dans un ISR doivent être marquées comme "volatiles"
  • Si vous souhaitez utiliser Serial, vous devez ajouter "Serial.begin(9600)" (ou supérieur) dans setup().
  • Vous ne devez pas utiliser Serial dans un ISR, car les timer sont tous arrêtés; pour cette raison, les ISR doivent être aussi courts que possible.
  • Dans plus_player_A(), l'indentation est étrange ; il semble qu'il manque une parenthèse "{".
  • Par convention, les numéros de broches doivent être écrits sous forme de constantes (par exemple, "byte" est suffisant, car ils ne seront jamais supérieurs à 255) et les noms doivent être en majuscules (ceci est nécessaire pour distinguer visuellement les variables des constantes). Donc, pas "const int btn_plus = 9;" mais "const int BTN_PLUS = 9;". Ce n’est pas obligatoire, c’est juste une convention, mais c’est utile comme norme.

De plus, je n'ai pas compris l'utilisation de "set_over" mais je vais le laisser de côté pour le moment.

Mais pourquoi utiliser OneButton, géré via ISR, pour les boutons plutôt que de les gérer directement? Voir cette version:

(le simulateur ne réagit pas très vite à la pression, je ne sais pas si c'est à cause de la "lenteur" du simulateur ou de quelque chose dans le reste du code, ou les deux, mais ça marche quand même)

Enfin, une fois que cela fonctionne, il reste quelques optimisations à effectuer, car, par exemple, les fonctions gérant les boutons "+" et "-" des deux joueurs seront très similaires ; il est inutile de reproduire des lignes de code quasi identiques. Nous verrons cela plus tard.

Wow merci pour toutes ces explications, bon malgré tout ces conseils je n'arrive pas à faire fonctionner le bouton avec OneButton mais cela fonctionne sans :sweat_smile: (est-ce que cela pourrait venir du fait que sur tinkercad j'utilise uno et sur wokwi j'utilise mega ?)

set_over servira à savoir si le set est terminé, pas vraiment une grande utilité hormis le fait d'empêcher l'arbitre d'augmenter les points indéfiniment.

J'ai utilisé OneButton car initialement ça ne fonctionnait pas quand je mettais le bouton sur une broche différente de 2 il me semble.
J'avais lu quelque part que les interruptions ne fonctionnaient que sur les broches 2 et 3, mais avec la librairie OneButton je pouvais palier à ce problème et je vois que dans votre exemple vous n'utilisez d'interruption.

N'est-ce pas mieux d'utiliser une interruption plutôt que de toujours lire le bouton ?

En tout cas encore merci maintenant cela fonctionne et j'ai appris des choses :wink:.

Et oui je vais essayer de ne pas dupliquer le code par rapport aux joueurs :grin:

Cela dépend de ce que le programme doit faire, car l'utilisation d'interrupt est pratique si vous avez des événements "asynchrones" à gérer pendant que vous effectuez d'autres tâches.

Dans votre cas, vous ne faites que cela, les interrupt ne sont donc pas nécessaires pour plusieurs raisons : elles vous obligent à utiliser des variables "volatiles", vous ne pouvez pas utiliser d'autres interruptions, donc millis() ne fonctionne pas, ni la communication série, et comme les autres interruptions ne sont pas déclenchées lorsqu'une ISR est active, celle-ci doit être aussi courte et rapide que possible. Je recommande d'utiliser l'approche du code que je vous ai montré.

En bref, utiliser une library dans ce cas est une complication inutile. J'ai créé un projet pour gérer un panneau Flight Simulator comprenant 14 interrupteurs et deux interrupteurs à bascule à 3 et 4 positions : le tout a été géré avec un seul Arduino Nano, et sans interrupt…

Si vous voulez le vérifier: :wink:

Parce que pour un débutant, cela simplifie largement le développement et que l'on peut espérer que l'auteur fournisse un code de meilleur qualité, avec par exemple l'anti-rebond.
Donc même si cela peut paraitre relativement simple à gérer soit même, le débutant pourra galérer et faire l'erreur d'utiliser de multiple delay qui bloquerons la détection de l'appuis sur le bouton faute de ISR.

D'ailleurs dans ton code il me semble que tu bloque le µC pendant 5100 + 1001 ms entre deux tentatives de détections d'appuis sur le bouton.
Ce qui ce traduit par devoir appuyer sur le bouton pendant plus de 600ms, relativement assez souvent :slight_smile:
Tu aurais fait un ISR, tu n'aurais pas ce soucis.

Bien sûr, apprendre à gérer les ISR, pourquoi utiliser des variables "volatile", pourquoi millis() ne fonctionne pas dans les ISR, etc., rend certainement les choses plus faciles pour un débutant, n'est-ce pas?

Simplifier les choses pour un débutant est une chose, mais lui proposer des solutions apparemment simples mais incompréhensibles en est une autre. L'absence de ces concepts de base compliquera de toute façon la compréhension du reste du processus. Apprendre à gérer un bouton et son anti-rebond n'est pas difficile, et cela permet de mieux comprendre le fonctionnement d'Arduino et la gestion du hardware.

Ca peut te paraitre paradoxale, mais oui, l'utilisation d'une librairie est plus facile pour un débutant.
Et si tu regarde la partie que tu n'a pas cité, j'ai bien indiqué que l'on peut espérer avoir du code de meilleur qualité, mais on trouve des librairies de qualité très inégales.
Après il faut aussi te mettre à la place d'un débutant qui ne sait pas ce qu'est un ISR, entre un code avec 4 lignes et devoir écrire toute la gestion d'un bouton(action, anti-rebond, ...), il n'y a pas photo ?

Ba oui, c'est bien le problème du débutant, l'absence des concepts lié au µC, complique de toute façon les choses, avec ou sans librairie.
Mais sans cela veut dire que tu affrontes tout d'un coup. N'est-il alors pas mieux d'apprendre par petit morceaux, dans un premier temps en utilisant une librairie, puis dans un second temps sans?

Je ne connais pas ton niveau, mais regarde la solution que tu as mis en œuvre, contient des delay qui gène la réactivité de ton bouton.
Du coup peut ton dire que c'est réellement plus simple pour @apocalypse67 de suivre cette approche.
comme le dirais @J-M-L cela ce prête bien l'utilisation d'une machine à état :slight_smile:
Mais on en revient, cela est-il plus simple pour un débutant que d'utiliser OneButton?

Mais attention personnellement je conseillerais toujours à quelqu'un qui veut apprendre, de ne pas utiliser trop de librairie ou du moins de s'en passer des que possible sur de petit projet.

Je pense avoir suivi tous vos conseils.
J'ai cependant retiré le delay(1O) et remplacé par le réaffichage, qu'en pensez-vous ?

N'hésitez pas à me dire si quelque chose ne va pas ou si c'est perfectible au niveau de la gestion des évènements du bouton

Je vois que vous avez introduit le timing avec millis(), et c'est très bien, car ce sont des concepts très utiles en général. Dans votre cas, vous actualisez l'affichage toutes les 10 millisecondes (100 fois par seconde? Êtes-vous sûr que c'est nécessaire?) et vérifiez l'état des boutons toutes les 50 millisecondes.

Puisque votre code n'a rien d'autre à faire que de vérifier si un bouton a été appuyé et d'agir en conséquence, je ne suis pas sûr que ce soit particulièrement utile, mais c'est OK.

Comme je le disais à l'auteur de l'article, le code (du moins dans sa version actuelle…) vérifie simplement si un bouton a été enfoncé et agit en conséquence, utiliser delay() ne présente donc aucun inconvénient.
À mon avis, utiliser des libraries, puis écrire et gérer des IRS, c'est tout, n'a aucun sens.
Si l'utilisateur est inexpérimenté, je pense qu'il est préférable de lui enseigner les bases plutôt que de lui faire utiliser du code d'autres personnes qu'il ne peut pas analyser pour comprendre son fonctionnement.

Mais ce sont des philosophies différentes, je ne dis pas que l'utilisation de bibliothèques est "interdite" ou "contre-indiquée", mais que d'un point de vue pédagogique, c'est moins utile.
Je laisserais à l'auteur le soin de décider ce qu'il préfère faire. :smiling_face_with_sunglasses:

PS: Oui, j'ai une certaine expérience, car j'utilise Arduino depuis plus de 10 ans et je suis analyste senior, je programme depuis 1982 et j'ai 65 ans... :wink:

Pour l'affichage si je mets plus de 50 ça clignote :sweat_smile:.

Et pour les boutons je passe à 500

Si cela présente un gros inconvénient, puisque tu ne regardes pas l'état du bouton, pendant ce temps là, donc tu loupe des appuis, c'est ce qu'il ce passe dans le woki qui tu as donné.

C'est simplement l'emplois d'un delay au lieu d'un code à base de millis(machine à état).

Je ne dis pas non plus le contraire, c'est pour ça que l'on est plusieurs à préconiser de se former au C et au spécificité des µC.
Mais je pense qu'il faut aussi ne pas décourager le débutant, ce qui n'a aucun sens non plus?
Je dis simplement que dans un premier temps lui faire utiliser des librairies, permet de rester dans le domaine du ludique.

Tu sembles indiqué que c'est noir ou blanc, mais je pense qu'il y a du gris.

Je ne suis pas tout a fait d'accord, la preuve OneButton, te fais aborder des notions importantes des µC.
Le plus gros problème est surtout la documentation minimaliste des librairies Arduino.
Par exemple, je crois que dans celle de OneButton, il soit indiquer de ne pas se fier à millis et que la fonction soit la plus courte possible.

D'ailleurs je ne crois pas que dans ce fil de discutions, on a rappelé que le site d'eskimon regorge d'information utiles ?

Personne n'est parfait :slight_smile:

non, l'un n'est pas mieux que l'autre :slight_smile:
Moi j'aime bien les interruptions, mais tu peux parfaitement t'en passer.

Ce n'est pas normal, tu peux utiliser un bouton sur n'importe quelle broche configuré en numérique(je met de coté l'analogique volontairement :slight_smile: ).

Oui, c'est normal, je crois que comme tu multiplexes, tu es obligé de rafraichir en permanence avec une fréquence suffisante pour notre oeil.

la boucle suivante a quelle but ?
un seul segoutput par afficheur suffit non ?

for(int i=0; i<100; i++)
  {
    segOutput(1, hex, 1);
    segOutput(0, dec, 1);
  }

Oui mais j'avais lu quelque part que sur arduino uno on ne pouvait utilisé que les broches 2 et 3 pour les ISR :
"Sur la carte Arduino UNO, il y a deux broches qui supportent les interruptions: les broches 2 et 3. Nous allons donc relier la sortie du bouton à la broche 2 de l’Arduino."

Pour les segOutput je ne sais pas du tout, pour le moment j'ai repris quelque chose d'un tuto qui fonctionne et une fois que j'arriverai à faire fonctionnerai j'essaierai de comprendre/d'optimiser.
Il y avait un delay(50) dans la boucle que j'ai retiré.
Au début j'avais repris le fonctionnement double segment de eskimon puis j'ai découvert qu'on pouvait avoir directement un afficheur 7 segment 2 digit :laughing:.

Ba disons que du coup tu risques de faire des choses qui ne permette pas un bon fonctonnement.
Optimiser ne sert à rien pour l'intant, mais pas contre faire fonctionner quelque chose sans comprendre, risque de prendre plus de temps que d'essayer de comprendre.
Après c'est toi qui choisi la stratégie et le temps que tu veux perdre à tatoner.

Disons que je comprends dans les grandes lignes vu que j'avais lu le mode de fonctionnement des afficheurs 7 segment, mais ce code utilisé pour le 2 digit me paraît plus complexe que celui qu'avais proposé eskimon avec le décodeur et les segments pour unité et dizaine.

Donc je m'étais dis que je verrai les détails de ce qu'il fait plus tard.

Bonjour apocalypse67

Je ne comprends pas pourquoi?
Cette bibliothèque te simplifierai nettement le traitement de tes boutons.
Si tu veux un exemple de ton programme modifié avec OneButton, c'est volontier :wink:

Tu pourrais nettement te simplifier le programme et la câblage en utilisant des modules tels que ceux-ci à base de TM1637:
image
, il n'utilisent que 2 fils et il y a plein des bibliothèques tel que tm1637.h:

Avec tout ça tu pourrais utiliser un UNO ou un Nano pour faire ton compteur, tu aurai assez de broches.

A+
Cordialement
jpbbricole