Accueil > La technologie > Arduino > Manœuvre des aiguilles avec des servo-moteurs > Clavier de réglage des butées

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

Clavier de réglage des butées

samedi 30 novembre 2013, par Jean-Luc

Essayant de ne pas faire de trop gros articles indigestes, je saucissonne un peu plus les sujets. Voici le 2e sur le réglage des butées. Il porte sur la transformation du programme que nous avions écrit pour le clavier analogique afin que le même programme puisse servir pour le clavier de réglage et en fait pour n’importe quel clavier analogique. En informatique on appelle ça la généricité.

Poussoirs de réglage de la position

Les poussoirs de réglage de la position sont mis en œuvre avec un clavier analogique de la même manière que les poussoirs de commande mais nous allons employer 4 poussoirs au lieu de 8 et les connecter sur l’entrée analogique A1. Nous allons voir plus tard pourquoi 4 et pas 2.

Pour avoir les valeurs des résistances, il suffit de faire sauter un poussoir sur deux dans le tableau de « Plusieurs boutons poussoir sur une entrée analogique » et d’additionner les deux résistances de part et d’autre des poussoirs supprimés. Les valeurs des résistances peuvent être moins précises car les plages de valeurs sont deux fois plus larges. Nous avons donc :

  Tension Résistance Résistance approchée Tension approchée Erreur
R1 1,25V 110Ω 120Ω 1,33V 6,4%
R2 2,5V 212Ω 220Ω 2,61V 4,4%
R3 3,75V 650Ω 560Ω 3,65V 1,78%

Le logiciel

Nous avons maintenant deux clavier analogiques, l’un pour les 8 poussoirs de changement de positions des servomoteurs et l’autre avec 4 pour le réglage. Nous allons bien entendu utiliser les mêmes fonctions pour les deux claviers et en profiter pour les passer en C++ comme nous l’avons fait pour les servomoteurs car maintenant que nous avons 2 claviers, il est logique d’avoir des objets. Un clavier analogique est jusqu’à présent représenté par 2 variables.

byte etatAutomate = NON_PRESSE;
int etatPoussoir = -1;

Mais les fonctions lirePoussoirs() et lireEvenement() que nous avons écrites ont en dur dans le code le fait qu’il y ait 8 poussoirs. Il en est de même pour la broche de connexion. Par conséquent, pour que les fonctions puissent être génériques, nous allons en plus avoir besoin de la broche de connexion, du nombre de poussoirs et de ce nombre de poussoirs, nous allons déduire la taille d’une plage de valeurs. Voici le début de notre classe DescripteurClavierAnalogique.

class DescripteurClavierAnalogique {
    byte etatAutomate;
    int  etatPoussoir;
    int  taillePlage;
    int  nbPoussoirs;
    int  pin;
};

Nous allons ajouter le constructeur qui contient les initialisations indépendantes du nombre de poussoirs et de la broche et une fonction de connexion qui va contenir les initialisations qui en sont dépendantes.

  public:
  
    DescripteurClavierAnalogique()
    {
        etatAutomate = NON_PRESSE;
        etatPoussoir = -1;
    }
    
    void connecte(int pinDeConnexion, int nombreDePoussoirs)
    {
        pin = pinDeConnexion;
        nbPoussoirs = nombreDePoussoirs;
        /* 
         * calcule la taille d'une plage
         * le convertisseur a 1024 valeurs, Le taille de plage
         * est égal à 1024/nombreDePoussoirs.
         */
        taillePlage = 1024 / nombreDePoussoirs;
    }

Enfin, nous allons modifier lirePoussoirs() afin de remplacer les valeur en dur par la plage de valeurs ou le nombre de poussoirs. lirePoussoirs() est placé dans la partie privée de la classe car il n’est appelé que part la fonction lireEvenement()

    int lirePoussoirs()
    {
        int resultat;
        int numPoussoir = (analogRead(pin) + taillePlage / 2) /taillePlage;
        
        int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */
     
        switch (etatAutomate) {
            case NON_PRESSE:
                if (numPoussoir < nbPoussoirs)
                    etatAutomate = ENFONCE;
                break;
            case ENFONCE:
                if (numPoussoir < nbPoussoirs) {
                    etatAutomate = PRESSE;
                    nouvelEtatPoussoir = numPoussoir;
                }
                else {
                    etatAutomate = NON_PRESSE;
                }
                break;
            case PRESSE:
                if (numPoussoir == nbPoussoirs) {
                    etatAutomate = NON_PRESSE;
                    nouvelEtatPoussoir = -1;
                }
                break;
        }
    
        return nouvelEtatPoussoir;
    }

Nous pouvons maintenant créer nos deux objets clavierOrdreServo et clavierReglage.

DescripteurClavierAnalogique clavierOrdreServo;
DescripteurClavierAnalogique clavierReglage;

et à appeler la fonction connect(...) dans setup()

    clavierOrdreServo.connecte(0,8); /* pin A0, 8 poussoirs */
    clavierReglage.connecte(1,4);    /* pin A1, 4 poussoirs */

Pour finir, la classe complète de gestion de clavier analogique avec l’ajout de lireEvenement(...). Cette classe est réutilisable sans modification dans n’importe quel montage comportant un clavier analogique.

class DescripteurClavierAnalogique {
    byte etatAutomate;
    int  etatPoussoir;
    int  taillePlage;
    int  nbPoussoirs;
    int  pin;
 
    int lirePoussoirs()
    {
        int resultat;
        int numPoussoir = (analogRead(pin) + taillePlage / 2) /taillePlage;
        
        int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */
     
        switch (etatAutomate) {
            case NON_PRESSE:
                if (numPoussoir < nbPoussoirs)
                    etatAutomate = ENFONCE;
                break;
            case ENFONCE:
                if (numPoussoir < nbPoussoirs) {
                    etatAutomate = PRESSE;
                    nouvelEtatPoussoir = numPoussoir;
                }
                else {
                    etatAutomate = NON_PRESSE;
                }
                break;
            case PRESSE:
                if (numPoussoir == nbPoussoirs) {
                    etatAutomate = NON_PRESSE;
                    nouvelEtatPoussoir = -1;
                }
                break;
        }
    
        return nouvelEtatPoussoir;
    }
 
  public:
  
    DescripteurClavierAnalogique()
    {
        etatAutomate = NON_PRESSE;
        etatPoussoir = -1;
    }
    
    void connecte(int pinDeConnexion, int nombreDePoussoirs)
    {
        pin = pinDeConnexion;
        nbPoussoirs = nombreDePoussoirs;
        /* 
         * calcule la taille d'une plage
         * le convertisseur a 1024 valeurs, Le taille de plage
         * est égal à 1024/nombreDePoussoirs. Le décalage est 
         * la taille de la plage sur 2
         */
        taillePlage = 1024 / nombreDePoussoirs;
    }

    /*
     * 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;
     
        etatPoussoir = nouvelEtatPoussoir;
        *numPoussoir = etatPoussoir;
        
        return evenement;
    }
};

Maintenant que les deux commandes nécessaires au réglage sont mises en place, nous allons pouvoir nous concentrer sur le réglage en lui-même.

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.)