Accueil > La technologie > Arduino > Manœuvre des aiguilles avec des servo-moteurs > Plusieurs boutons poussoir sur une entrée analogique

Manœuvre des aiguilles en analogique avec des servo-moteurs

Plusieurs boutons poussoir sur une entrée analogique

samedi 16 novembre 2013, par Jean-Luc

Dans « Commande du servo-moteur par bouton poussoir », nous avons vu comment connecter un bouton poussoir à une entrée analogique. Dans celui-ci nous allons voir comment en connecter plusieurs et lire lequel est enfoncé.

Cette idée de connecter plusieurs poussoirs sur une entrée analogique n’est pas nouvelle. Une Application Note de Freescale existe et l’idée m’a été soufflée par Marc-Henri que je remercie au passage.

Marc-Henri vient de publier un article sur son blog qui décrit précisément le calcul des résistances ainsi qu’une feuille de calcul (format Excel) le mettant en œuvre pour un nombre quelconque de poussoirs

Principe de fonctionnement

Avec un seul poussoir, nous avons vu que l’entrée analogique de l’Arduino était tirée à la masse via une résistance de 10kΩ. L’appui sur le poussoir amenait cette entrée à 5V. Pour la suite, on va inverser la connexion. L’entrée analogique esr tirée à +5V et l’appui sur le poussoir amène cette entrée à la masse. En effet, avec plusieurs poussoirs, cette façon de faire est plus commode car, sur le réseau, la masse est distribuée partout alors que ce n’est pas le cas pour le +5V.

Connexion d’un poussoir à l’entrée analogique de l’Arduino Uno, état de repos à +5V

Imaginons maintenant que nous ajoutions un second poussoir en parallèle du premier et qu’il soit connecté entre l’entrée analogique de l’Arduino et la masse via une résistance, également de 10kΩ, comme ceci.

Connexion de deux poussoirs à une entrée analogique

Lorsque B0 est pressé, nous avons le même comportement, l’entrée analogique est à 0V. Lorsque B1 est pressé, les deux résistances sont en série entre 5V et 0V et l’entrée analogique est à la tension qui existe entre les deux résistances. On voit qu’il s’agit d’un diviseur de tension, et donc l’entrée analogique est à 2,5V. Evidemment, on ne peut pas presser 2 poussoirs en même temps, l’Arduino ne verra que le poussoir de rang le plus bas.

On peut continuer à ajouter des poussoirs en parallèle avec la résistance adéquate pour que le diviseur de tension donne une tension précise pour chaque poussoir. Pour nos 8 boutons-poussoir, nous allons procéder de cette manière.

Connexion de 8 poussoirs à une entrée analogique

Avec 8 poussoirs, il faut diviser les 1024 valeurs possibles en 8 intervalles de 1024 ÷ 8 = 128 valeurs. Plus on ajoute des poussoirs et plus cet intervalle devient petit. Plus cet intervalle devient petit et plus il est nécessaire d’avoir des résistances précises. Or, les résistances standards ont des valeurs déterminées et sont précises à 5%. Si les intervalles sont trop petits, il devient impossible de distinguer deux valeurs voisines de façon fiable. Cela limite le nombre de poussoirs que l’on peut connecter mais 8 poussoirs ne devraient pas poser de problème.

Sur la figure précédente, la plage de valeurs analogiques a été découpée en 8 intervalles. En (a) le poussoir pressé, en (b) la tension correspondante, en (c) la valeur numérique, en (d) cette même valeur numérique en binaire. Il faut donc déterminer les résistances R1 à R7 de manière à obtenir plus ou moins la tension voulue. On va voir que ça se fait assez bien.

Une fois une valeur analogique numérisée, il faut déterminer par programme de quel poussoir il s’agit. On peut le faire par une succession de if ... else ... en testant la valeur lue par rapport au milieu des intervalles : entre 0 et 63, aucun poussoir n’est pressé, entre 63 et 191, B0 est pressé, entre 192 et 319, B1 est pressé, etc. Mais c’est un peu long. On peut écrire cela de manière plus concise, un programmeur est un fainéant, moins il écrit de code, mieux il se porte.

Pour cela, nous allons diviser la valeur lue par la taille de l’intervalle (128).
Il s’agit évidemment d’une division entière, le résultat donnerait le numéro du poussoir pressé, il s’agit des 3 bits de poids fort dans la colonne (d), ceux qui sont séparés des autres. Malheureusement, on peut voir que ce résultat change au voisinage de la valeur lue. Par exemple au voisinage de 127, le résultat peut être 0 ou 1 et au voisinage de 255, le résultat peut être 1 ou 2. Par conséquent on peut confondre les deux poussoirs !

Pour malgré tout procéder de cette manière, il suffit de décaler l’intervalle. En ajoutant la moitié de la taille de l’intervalle à la valeur lue, 64 donc, le résultat donné pas la division entière est directement le numéro du poussoir (de 0 à 7), ou bien 8 si aucun poussoir n’est pressé, et ce numéro est stable et centré au voisinage des valeurs lues, comme montré à la colonne (d). La détermination du poussoir pressé se fait alors en une ligne de code.

int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;

Cette concision ne peut que réjouir le programmeur ^_^

Immunité au bruit et détermination des résistances

Les essais avec un seul poussoir ont employé une résistance de 10kΩ traversée par une courant de 0,5mA quand le poussoir est pressé. Avec de longs fils entre les poussoirs et l’Arduino, le bruit électrique dû aux ondes électromagnétiques qui nous environnent peut être important. Il est préférable d’utiliser des résistances de plus faible valeur afin que le courant circulant dans le circuit quand un poussoir est pressé soit plus élevé et que le bruit puisse être absorbé par l’alimentation. Nous allons donc choisir un courant maximum d’environ 15mA, soit une résistance de 330Ω à la place de la résistance de 10kΩ utilisée jusqu’à présent.

Il faut maintenant déterminer les valeurs des résistances R1 à R7 pour obtenir les tensions que nous avons déterminées. Les diviseurs de tension pour chacun des poussoirs sont les suivants.

Les diviseurs de tension pour chacun des poussoirs.

Par calcul on détermine les valeurs des résistances pour chaque poussoir. La colonne Résistance donne la résistance qui serait nécessaire, la colonne Résistance approchée donne la valeur standard employée et la colonne Tension approchée donne la tension effectivement obtenue en supposant évidemment que la résistance est juste.

  Tension Résistance Résistance approchée Tension approchée Erreur
R1 0,625V 47,14Ω 47Ω 0,634V 0,04%
R2 1,25V 62,85Ω 62Ω 1,27V 0,23%
R3 1,875V 88Ω 82Ω 1,89V 1,34%
R4 2,5V 132Ω 130Ω 2,53V 1,38%
R5 3,125V 220Ω 220Ω 3,17V 1,03%
R6 3,75V 440Ω 430Ω 3,76V 1,46%
R7 4,375V 1320Ω 1300Ω 4,377V 1,50%

Le retour du rebond

Il ne s’agit pas tout à fait d’un rebond mais il va falloir prendre en compte ce que l’on appelle une transitoire.

Quand l’un des poussoirs est pressé, l’entrée analogique passe de 5V à la tension correspondante telle qu’elle a été réglée par les résistances. Mais elle ne le fait pas instantanément. Cela prend un certain temps.

Imaginons maintenant que le convertisseur analogique-numérique de l’Arduino capture la tension alors que celle-ci est en train de descendre. Le résultat va être que le logiciel croit voir une pression sur un poussoir de rang supérieur à celui véritablement pressé. De même quand le poussoir va être relâché, la capture de la tension peut avoir lieu alors qu’elle est en train de monter et retourner également un numéro de poussoir de rang supérieur. Il faut donc filtrer ces transitoires et n’accepter la valeur brute calculée dans numPoussoir que sous certaines conditions.

Avec un seul poussoir ce phénomène n’existait pas car il n’y avait pas d’autre poussoir.

Pour filtrer les valeurs non voulues, nous allons mettre en œuvre ce que l’on appelle un système séquentiel. On représente ce genre de système par un graphe, appelé automate. Un ovale est un état, une flèche est une transition qui permet de passer d’un état à l’autre. Les textes en vert sont des conditions qui permettent ou empêchent une transition et les textes en rouge des actions qui sont effectuées lors d’une transition. L’ovale à double bordure est l’état initial. La flèche qui vient de nulle part et qui pointe sur l’état initial correspond aux actions d’initialisation.

Voici l’automate de notre système.

Automate de lecture de l’état des poussoirs
Entre chaque transition, le temps nécessaire à l’exécution de loop(), s’écoule.
Le passage par l’état ENFONCE permet de laisser passer du temps entre la détection de la pression sur un poussoir et la lecture du numéro correspondant. Ce numéro n’est pas réactualisé dans l’état PRESSE, ce qui permet de filtrer les valeurs non désirées lors du relâchement du poussoir.

À partir de l’état initial, NON_PRESSE, qui correspond à aucun poussoir enfoncé, on peut :

  • rester dans cet état (aucun poussoir enfoncé correspond à un numéro de poussoir égal à 8) ;
  • passer dans l’état ENFONCE (l’un des poussoir enfoncé correspond à un numéro de poussoir inférieur à 8).

Une fois dans l’état ENFONCE :

  • soit le poussoir est relâché immédiatement (c’est à dire en quelques millisecondes, il s’agissait d’un rebond ou d’un parasite), le numéro de poussoir est égal à 8 ;
  • soit il est toujours enfoncé, numéro de poussoir inférieur à 8 et on confirme en passant dans l’état PRESSE et en mémorisant dans etatBouton le numéro du poussoir enfoncé.

Dans l’état PRESSE :

  • soit le poussoir est maintenu enfoncé (numPoussoir < 8) et on attend en restant dans l’état PRESSE ;
  • soit le poussoir est relâché (numPoussoir == 8) et on repasse dans l’état NON_PRESSE en remettant etatBouton à -1.

Le passage de l’automate à un programme C est direct. On va avoir besoin d’une variable pour stocker l’état dans lequel se trouve l’automate ainsi que des variables employées par l’automate. Comme il est impossible de détecter plusieurs poussoirs enfoncés, il est inutile d’avoir une variable d’état par poussoir. Une seule variable suffit mais elle a autant d’états que de poussoirs plus une pour représenter le fait qu’aucun poussoir n’est enfoncé.

const byte NON_PRESSE = 0;
const byte ENFONCE = 1;
const byte PRESSE = 2;
 
byte etatAutomate = NON_PRESSE;
int etatPoussoir = -1; /* aucun poussoir n'est pressé au début */
 
const int pinPoussoirs = 0;

int lirePoussoirs()
{
    int resultat;
    int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;
    
    int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */

    switch (etatAutomate) {
        case NON_PRESSE:
            if (numPoussoir < 8)
                etatAutomate = ENFONCE;
            break;
        case ENFONCE:
            if (numPoussoir < 8) {
                etatAutomate = PRESSE;
                nouvelEtatPoussoir = numPoussoir;
            }
            else {
                etatAutomate = NON_PRESSE;
            }
            break;
        case PRESSE:
            if (numPoussoir == 8) {
                etatAutomate = NON_PRESSE;
                nouvelEtatPoussoir = -1;
            }
            break;
    }
    
    return nouvelEtatPoussoir;
}

Il reste à modifier lireEvenement(...) pour l’adapter à lirePoussoirs(). En effet, en plus de l’information de présence d’événement, il est nécessaire d’obtenir le numéro du poussoir qui a déclenché l’événement. Or une fonction C ne retourne qu’une seule valeur. Il faut donc trouver un moyen pour obtenir la seconde valeur, le numéro du poussoir.

Nous allons employer un argument. En C les arguments sont passés aux fonctions par valeur. C’est à dire que la valeur contenue dans la variable que l’on passe à la fonction est recopiée dans une variable locale de la fonction. Si la fonction change le contenu de cette variable, seule sa copie est changée. Il faut donc employer un autre moyen pour que la fonction puisse modifier la variable qui lui est passée. Ce moyen, ce sont les pointeurs.

Une variable est placée dans la mémoire RAM du micro-contrôleur. On peut voir la RAM comme un tableau de cases. Chaque case a un numéro, on dit une adresse. Il est possible d’obtenir l’adresse d’une variable via l’opérateur &, de définir une variable qui soit un pointeur vers un type, via la notation * et il est possible d’écrire ou de lire dans une variable par l’intermédiaire de son adresse via l’opérateur *. Ainsi :

int *p;

définit un pointeur vers une variable de type int. Ce pointeur est pour l’instant non initialisé, il ne pointe sur rien. Essayer d’accéder à ce qu’il pointe est une erreur.

int a;
int *p = &a;

définit un pointeur p vers une variable de type int qui pointe sur a. &a retourne l’adresse de a.

*p = 3;

met la valeur 3 dans la variable a.

Pour définir la fonction lireEvenement(...) qui retourne un byte et prend pour argument un pointeur vers un int, et qui modifie la variable pointée, on écrira.

byte lireEvenement(int *numPoussoir)
{
    byte evenement;
    int nouvelEtatPoussoir = lirePoussoirs();
    
    if (nouvelEtatPoussoir == etatPoussoir)
        evenement = AUCUN_EVENEMENT;
    if (nouvelEtatPoussoir >= 0 && etatPoussoir == -1) 
        evenement = EVENEMENT_PRESSE;
    if (nouvelEtatPoussoir == -1 && etatPoussoir >= 0) 
        evenement = EVENEMENT_RELACHE;

    etatPoussoir = nouvelEtatPoussoir;
    *numPoussoir = etatPoussoir;
    
    return evenement;
}

L’argument int *numPoussoir définit numPoussoir qui est un pointeur sur un int. À l’avant dernière ligne de la fonction, l’état du poussoir est écrit dans la variable pointée par numPoussoir, il s’agit de la ligne *numPoussoir = etatPoussoir;

Il faut donc que numPoussoir pointe sur la variable dans laquelle on désire récupérer le numéro de poussoir. Donc, pour appeler cette fonction, on écrira.

    int numeroPoussoir;
    byte evenement = lireEvenement(&numeroPoussoir);

ce qui a pour effet de passer à la fonction l’adresse, opérateur &, de numeroPoussoir afin d’obtenir la valeur désirée dans cette variable.

Essai du système

La première étape consiste à câbler sur la breadboard les poussoirs est les résistances comme ceci.

Placement des composants sur le breadboard

Voici le programme complet de test du système. Les messages d’appui ou de relâchement des poussoirs sont affichés sur le moniteur série avec le numéro de poussoir enfoncé.

    const byte NON_PRESSE = 0;
    const byte ENFONCE = 1;
    const byte PRESSE = 2;
     
    byte etatAutomate = NON_PRESSE;
    int etatPoussoir = -1;
     
    const byte AUCUN_EVENEMENT = 0;
    const byte EVENEMENT_PRESSE = 1;
    const byte EVENEMENT_RELACHE = 2;
     
    const int pinPoussoirs = 0;
     
    int lirePoussoirs()
    {
        int resultat;
        int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;
       
        int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */
     
        switch (etatAutomate) {
            case NON_PRESSE:
                if (numPoussoir < 8)
                    etatAutomate = ENFONCE;
                break;
            case ENFONCE:
                if (numPoussoir < 8) {
                    etatAutomate = PRESSE;
                    nouvelEtatPoussoir = numPoussoir;
                }
                else {
                    etatAutomate = NON_PRESSE;
                }
                break;
            case PRESSE:
                if (numPoussoir == 8) {
                    etatAutomate = NON_PRESSE;
                    nouvelEtatPoussoir = -1;
                }
                break;
        }
       
        return nouvelEtatPoussoir;
    }
     
    /*
     * construction d'un événement en comparant
     * le nouvel état des poussoirs avec l'état précédent.
     */
    byte lireEvenement(int *numPoussoir)
    {
        byte evenement;
        int nouvelEtatPoussoir = lirePoussoirs();
       
        if (nouvelEtatPoussoir == etatPoussoir)
            evenement = AUCUN_EVENEMENT;
        if (nouvelEtatPoussoir >= 0 && etatPoussoir == -1)
            evenement = EVENEMENT_PRESSE;
        if (nouvelEtatPoussoir == -1 && etatPoussoir >= 0)
            evenement = EVENEMENT_RELACHE;
     
        if (evenement == EVENEMENT_PRESSE) {
          *numPoussoir = nouvelEtatPoussoir;
        }
        else if (evenement == EVENEMENT_RELACHE) {
          *numPoussoir = etatPoussoir;
        }

        etatPoussoir = nouvelEtatPoussoir;
        
        return evenement;
    }
     
    void setup()
    {
        Serial.begin(9600);
    }
     
    void loop()
    {
        int numPoussoir;
        byte evenement = lireEvenement(&numPoussoir);
     
        switch (evenement) {
            case EVENEMENT_PRESSE:
                Serial.print("Presse : ");
                Serial.println(numPoussoir);
                break;
            case EVENEMENT_RELACHE:
                Serial.print("Relache : ");
                Serial.println(numPoussoir);
                break;
        }
       
        delay(3);
    }

Une petite vidéo montrant la mise en œuvre du programme.

Le système de commande à 8 boutons sur une entrée analogique est opérationnel.

Nous avons vu quelques éléments supplémentaires de langage C comme les pointeurs et leur emploi pour retourner plusieurs valeurs à partir d’une fonction. Nous avons vu rapidement les automates et comment les mettre en œuvre avec un switch ... case. La prochaine fois nous ajouterons nos 8 servo-moteurs.

Messages

  • Merci. Un grand merci. Je suis un minuscule débutant mais apprécie votre aptitude à présenter clairement des notions complexes tel ce système séquentiel et son automate. Je suis depuis des semaines sur votre contribution mais j’avance. Encore merci.
    J-P G.

    Voir en ligne : Plusieurs boutons poussoirs sur une entrée analogique

    • Je suis moi même un peu bidouilleur en tout genre et j’ai regardé avec grand intérêt votre tutoriel. Je l’ai trouve remarquable de clarté et de concision, merci beaucoup de partager ce travail. Le programme tel quel fonctionne très bien chez moi, avec seulement 4 boutons (j’ai juste légèrement adapté les valeurs de seuil pour discriminer mes 4 boutons). Plus de phénomènes de rebonds et l’Arduino (Nano) ne semble pas du tout ralenti par les processus. Toutefois, je bute sur L’utilisation de la même routine plus avant dans le programme. Je m’explique : je souhaite intégrer votre programme pour gérer un petit moteur pas à pas destiner a faire tourner un appareil photo pour des time-lapse.
      un BP fait tourner le moteur dans un sens, un 2eme BP le fait tourner dans l’autre sens, en vitesse rapide, pour positionner l’appareil, et un 3eme BP démarre un cycle de rotation avec des paramètres pré-définis(temps de rotation et sens de rotation). Jusque là, tout va bien, les taches sont parfaitement effectuées. Mais je souhaite que le 4eme bouton me permettre d’entrer dans un sous menu pour modifier éventuellement le temps de rotation et le sens. Il semble que dans ce sous menu, je ne puisse plus utiliser la fonction lireEvenement(&numPoussoir) pour entrer dans un nouveau switch(numpoussoir) ; Le compilateur s’arrete sur un case —> error : case label ’1’ not within a switch statement Je ne vois pas ce que j’ai loupé....?? Je dois dire que je galère lamentablement avec l’utilisation des pointeurs...et je soupçonne que mes difficultés tournent autour de cette question
      Merci de m’éclairer si vous pouvez

  • Sans la formule nécessaire au calcul des tensions dans un pont de résistance, cet article est inutilisable pour le néophite que je suis...
    Comment adapter ceci à 4 boutons poussoirs sans savoir calculer ces fameuses valeurs de résistances ?
    Mystère....

    • Bonjour,

      le le blog n’ayant pas comme finalité l’électronique, il ne m’a pas semblé nécessaire de développer ce point. De plus, les articles sur le diviseur de tension ne manquent pas sur le web. Une recherche renvoie en première place l’article Wikipedia qui y est consacré.

      Par ailleurs, passer de 8 à 4 boutons est trivial, il suffit de supprimer les boutons ayant des numéros impair et de sommer les résistances 2 à 2 : R1+R2, R3+R4, etc.

    • J’ai touvé la réponse à ma question en fouinant sur le net alors je partage ma découverte.
      C’est un tableau excel qui permet d’effectuer les calculs automatiquement.

      Voir en ligne : Tableau de calcul de resistances

    • Hem.

      Le le lien vers cette feuille Excel est donné en haut de la page où nous sommes, dans l’encadré gris juste au dessus du premier intertitre.

    • Et non ce n’est pas trivial pour le néophyte que je suis et aller de site en site pour glaner des informations nous fait souvent perdre le fil d’une réflexion entamée sur un sujet précis.
      Ce n’est pas un reproche mais une remarque constructive.
      Je persiste à penser qu’il serait judicieux de préciser l’intégralité de la démarche au niveau des calculs, je ne m’en suis pas sorti seul avec les quelques souvenirs que j’avais de la loi d’ohm et j’ai perdu une ou deux heures avant de me lancer dans de nouvelles recherches...

      Merci tout de même pour avoir partagé toutes ces informations sur internet, elles m’ont été très utiles dans ma tentative de dompter un arduino récalcitrant ;-)

    • Quand je vous dis qu’on finit par perdre le fil à force de partir dans toutes les directions...

      Je n’avais pas remarqué que ce lien que j’avais ouvert dans un onglet en attente de lecture provenait de votre site :-)

  • Bonjour
    Quelques mois sont passés depuis ma dernière question.
    Mes 25 actionneurs d’aiguillages sont maintenant assemblés. Merci encore pour toutes ces sources d’inspiration très précieuses.
    Je me permets de vous demander un petit éclaircissement sur la valeur d’une résistance sur le clavier 8 boutons :
    Sur le troisième dessin du module ARDUINO avec le schéma 8 boutons, la première résistance reliée au +5V à une valeur de 10kΩ.
    Par la suite vous mentionnez une résistance d’une valeur de 330Ω (voir placement des composants sur le breadboard) en bas de page.
    Mes connaissances en ce domaine étant limitées, je préfère demander confirmation.
    Encore merci
    Yvon - B

    • Bonjour Yvon,

      C’est sympa de donner des nouvelles de l’avancement des travaux. L’explication est dans le paragraphe intitulé « Immunité au bruit et détermination des résistances » plus haut dans le texte.

      Je vous signale également un nouveau site que nous avons lancé avec plusieurs autres Arduinistes du ferroviaire :) : LOCODUINO

      Bien cordialement.

  • Le lien du fichier excel est expiré, prière de le charger sur un autre serveur ou bien de me répondre à propos la méthode de calcul des résistance, pour la première résistance application directe du diviseur de tension (simple) mais les autres tensions on peut pas les calculer en utilisant la formule du diviseur tout court. Merci bien

    • Bonjour,

      je n’ai pas le fichier excel car je n’en suis pas l’auteur. Ce n’est pas compliqué avec la formule du diviseur. Une fois déterminé R1, on calcule le diviseur qui donne R1 + R2. Comme on connaît R1 on en déduit R2. Et on recommence à l’étape suivante pou R3.

    • Si je veux utiliser 16 boutons poussoirs quelles sont les modifications sur le code ? (j’ai déjà calculé les nouvelles valeurs des résistances)

  • Bonjour,

    pour calculer les valeurs des resistances (pour 5 boutons avec des pas de 1 volts) :

    Pas de bouton pressé = 5v
    Bp1 = 0v
    Bp2 = 1v
    Bp3 = 2v
    Bp4 = 3v
    Bp5 = 4v

    Pour obtenir R2 dans un pont diviseur de tension :

    R2 = R1(ve/vs) - R1

    avec ve = tension entrée et vs = tension de sortie

    donc avec r0 = 330 ohms on obtient :

    R1 = R0(5/4)-R0 = 82,5 ohms
    R1+R2 = R0(5/3)-R0 et on soustrait R1 = 137,5 ohms

    etc....

    cordialement.

    Cyril

  • Bonjour , voici le projet de 16 boutons en isis avec le code arduino ; bon j’ai divisé l’intervalle 0 .. 2047 en 16 intervalles équidistante de longueur 128, c’est pourquoi je multiplie la valeur retournée par "analogread" par 2 .
    le calcul des résistances est fait à l’aide de la formule Req=(Vin/V)/(1-(Vin/V)).R
    avec : V : 5v
    Vin la valeur de tension d’entrée à la carte
    _R : 330 ohm
    _Req : R équivalente , à chaque fois on retranche la somme des résistances précedentes
    le lien du projet et code :

    https://drive.google.com/open?id=0B_XaAqFY961JbUVEV0JQVlByX2s

  • Il y a quelque chose que je ne comprends pas ??!!
    Si on met 5 résistances de x Ohms en série (en pratique 220 Ohms mais ce pourrait être une autre valeur pourvu qu’elles soient identiques, il n’y a que l’intensité qui change) on a exactement 1, 2, 3, 4 et 5 Volts entre la masse et les points de jonction des résistances.
    Si on en met 10 le pas est de 0,5 V
    Alors pourquoi tous ces calculs ?
    Si on veut moins de valeurs, on choisi le nombre de points et pour 3 valeurs on peut prendre 1, 2 et 3 Volts et laisser 4 et 5.
    Désolé je ne sais pas comment faire pour laisser un schéma et j’espère avoir été clair...

    • Bonjour,
      il y a une subtilité dans le montage dont le schéma figure en tête d’article :
      on court-circuite des résistances pour obtenir une tension (alors que vous pensez qu’on prélève une tension pour l’appliquer à une entrée). L’intérêt est qu’en cas d’appuis multiples, il y a une priorité et donc absence d’ambiguïté. Les résistances en aval sont court-circuitées donc non prises en compte.
      Cordialement

    • Pardon, je recopie mon message en fin de fil, je l’avais probablement mal placé

      Je suis moi même un peu bidouilleur en tout genre et j’ai regardé avec grand intérêt votre tutoriel. Je l’ai trouve remarquable de clarté et de concision, merci beaucoup de partager ce travail. Le programme tel quel fonctionne très bien chez moi, avec seulement 4 boutons (j’ai juste légèrement adapté les valeurs de seuil pour discriminer mes 4 boutons). Plus de phénomènes de rebonds et l’Arduino (Nano) ne semble pas du tout ralenti par les processus. Toutefois, je bute sur L’utilisation de la même routine plus avant dans le programme. Je m’explique : je souhaite intégrer votre programme pour gérer un petit moteur pas à pas destiner a faire tourner un appareil photo pour des time-lapse.
      un BP fait tourner le moteur dans un sens, un 2eme BP le fait tourner dans l’autre sens, en vitesse rapide, pour positionner l’appareil, et un 3eme BP démarre un cycle de rotation avec des paramètres pré-définis(temps de rotation et sens de rotation). Jusque là, tout va bien, les taches sont parfaitement effectuées. Mais je souhaite que le 4eme bouton me permettre d’entrer dans un sous menu pour modifier éventuellement le temps de rotation et le sens. Il semble que dans ce sous menu, je ne puisse plus utiliser la fonction lireEvenement(&numPoussoir) pour entrer dans un nouveau switch(numpoussoir) ; Le compilateur s’arrete sur un case —> error : case label ’1’ not within a switch statement Je ne vois pas ce que j’ai loupé....?? Je dois dire que je galère lamentablement avec l’utilisation des pointeurs...et je soupçonne que mes difficultés tournent autour de cette question
      Merci de m’éclairer si vous pouvez

    • Bonjour,

      Vous avez probablement une erreur de syntaxe dans votre programme. Pouvez vous me l’envoyer ? Prenez contact via le formulaire

    • Il aurait peut etre été préférable que je vous envois le programme sous forme de fichier.ino, mais je ne sais pas comment faire ! excusez moi
      Cordialement Michel

  • Bonjour,
    Article très bien fait et très formateur pour l’arduiniste débutant que je suis.
    Je cherche à réaliser les commandes d’éclairage par poussoirs en utilisant un ou plusieurs ports analogiques, mais mes tests sur breadboard me surprennent :
    le résultat de la commande analogRead renvoie régulièrement des valeurs complètement décalées (plusieurs à la suite - donc état:Pressé).
    Exemple : valeur 250 plus de 50 fois de suite(poussoir 2 validé) puis en maintenant le poussoir la valeur passe à 750 au moins 4 fois de suite (poussoir 6 validé à tort).
    J’ai essayé sur autre port analogique : Idem, Un condo entre GND et port anlogique : Idem
    Je pense que le phénomène risque de s’amplifier avec les effets magnétique et capacitif du cablage entre les poussoirs et l’arduino.
    Donc l’appui sur un poussoir d’une chambre risque d’éclairer la chambre voisine.
    J’ai prévu d’utiliser des registres à décalage (74HC595) avec des cartes à relais commandés par optocoupleurs pour la commande (cette partie fonctionne en test sur des leds)
    Si vous avez une idée et peut être une solution sur ce problème merci de me répondre
    Cordialement, Louis

  • bonjour,

    Merci beaucoup de cet article, qui permet d’augmenter le nombre de poussoirs à volonté, ou presque selon les calculs,
    pour mon projet j’ai besoin de plusieurs poussoirs préssés au même moment, dans ce cas le pont diviseur ne fonctionne pas ?
    je voulais que ce soit en parallèle mais possible de changer/repenser le dispositif...

    Auriez vous des conseils à me donner ? j’ai du mal à finir ce projet,

    bonne journée,
    Charlotte

  • Bonjour à tous, je ne suis pas encore débutant…. Désolé si ma question est debile, ce programme permet il de faire tourner un moteur pas à pas de x pas avec le bouton 1, y pas avec le bouton 2 etc…en sachant qu’il me faudra 13 boutons au total. Merci d’avance pour vos éclaircissements et bonne journée

    • Bonjour,

      Ce programme permet de lire 8 boutons. Une fois ceci fait, on récupère un nombre, de 0 à 7. Ensuite on en fait ce qu’on veut et pourquoi pas faire tourner un moteur pas-à-pas.

      Bonne journée.

Un message, un commentaire ?

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)