Parlons Arduino > Débuter

commande servo par inter

(1/4) > >>

philippe 31:
Bonjour ,
comme indiqué dans ma présentation, je cherche à piloter des servos . J'ai honteusement copié les fichiers de jlb ( que je remercie et félicite pour la qualité de son travail )
J'ai 2 options :
soit piloter par attiny 45, 1 servo par 1 inter suivant le programme de jlb que j'ai trouvé sur le site de LR
soit piloter par carte NANO , 4 servos par 4 inters suivant le programme ( 8 servos 8 inters )
dans les 2 cas je n'y arrive pas
pour le pilotage par NANO , je ne veux pas 8 inters sur une entrée mais 1 entrée pour chaque inter . J'ai essayé de modifié sur le programme  la structure(Lire poussoir) par un semblant de descripteur clavier . Malgré le nombre d'heures à chercher  (je ne suis pas programmeur ) ,je ne vous dit pas le résultat . Vous avez compris .
Pour le pilotage par attiny , j'arrive à transférer le programme cité ci dessus en modifiant la bibliothèque servo par servo8Bit 2 Mais le servo ne répond pas à la commande de l'inter. Sur la carte NANO j'utilise les bornes AO pour l'inter et 2 pour le servo( comme le logiciel ) . Quand je le transpose sur attiny ,j'utilise la pin 3 soit la patte 2 pour l'inter et la pin 2 soit la patte 7
Dans les 2 cas , j'aimerai de l'aide de votre part
Cordialement
Philippe


DDEFF:
Bonjour,
C'est bien de se lancer... ;)

Sur ATTiny, je ne comprends pas ce que tu entends par "modifier la bibliothèque".
Normalement, une bibliothèque, ça ne se modifie pas.
D'autre part, le nom "servoBit 2" est étrange : on ne met pas de blanc dans un nom. A minima, l'appeler "servo8bits_2".

Sur NANO, tu t'attaques à un programme assez costaud pour un débutant.
Dans ce programme, on entre sur une entrée analogique et on divise les 5V en 1024/8 parties.
C'est très bien expliqué par Jean-Luc http://modelleisenbahn.triskell.org/spip.php?article59
Si tu veux 4 poussoirs, il faut diviser par 4 (et plus par 8 ) puis adapter les résistances.

Ma question est : pour quelle raison voudrais-tu 4 poussoirs distincts ?
Une spécificité de ton clavier ?

Denis

philippe 31:
Merci pour ta réponse
Sur Attiny
La bibliothèque Servo ne marche quà 16 MHZ. Les Attiny fonctionnent à 8MHZ. Donc si on veut commander un servo par un Attiny , il faut une autre bibliothèque qui est Servo8Bit2  . A priori , j'ai réglé le problème , je commande un servo par un inter avec recopie sur TCO par Led avec la commande writMicroseconds .
J'ai utilisé le sketch  de jlb (un servo par un inter )
Sur Nano
Le blog de jlb est mon livre de chevet ( je suis impressionné par la pédagogie de ce monsieur et sa compétence en programmation ).Mon but est d'utilisé le sketch " 8 servos par 8 inters écrit en C et non en c++( je ne souhaite pas le réglage des butées , je le fais directement sur le réseau avec une carte uno et un afficheur ). Le programme de jlb est 8 inters sur une seule entrée , il utilise un pont diviseur  . Je le cite
"""""""""""""""""""""
int lirePoussoirs()
{
    int resultat;
    int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;
   
    int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */
"""""""""""""""""""""""
De cette manière , on ne peut lire qu'un seul inter à la fois
Mon but est d'avoir 4 inters sur les bornes par ex  (AO , A3 ). Je souhaite modifier la fonction"LirePoussoirs() " pour savoir quel inter est activé . Et la je bloque
La raison est que je pilote les commandes aiguilles ou accessoire  par RRTC et des décodeurs LTD TYPE SA DEC 4 (4 sorties bistable C R T ) . Si j'avais cette fonction , je pourrai utilisé le T( contact travail)  du décodeur sur la borne AO, A3 et avoir un mouvement lent des aiguilles PECO code 55 ( je fais du N)et tout cela un moindre coût par rapport à d'autres commandes  moteur (type tortoi... , etc....)
Le logiciel de jlb est parfait pour mes besoins , reste à modifier cette ""maudite"" fonction
D'ou mon appel à l'aide
Cordialement
Philippe

DDEFF:
Bonjour Philippe,

Pour NANO, il te faut définir les 4 entrées A0 à A3 comme digitales et en entrées dans le setup().
Sur un NANO, pour A0 à A3, c'est faisable.
Note que ce ne serait pas faisable pour A6 et A7 qui ne peuvent être qu'analogiques.

On va donc avoir dans le setup :

--- Code: ---    pinMode(A0, INPUT_PULLUP);    //  BP 0
    pinMode(A1, INPUT_PULLUP);    //  BP 1
    pinMode(A2, INPUT_PULLUP);    //  BP 2
    pinMode(A3, INPUT_PULLUP);    //  BP 3

--- Fin du code ---

On utilise la résistance interne de l'Arduino pour tirer la tension vers le +5V (d'où le terme "pull_up").
Ton BP ou ton inter sera donc entre la masse (GND = ground) et la broche A0, A1...A3.

Jusque là, je pense que je ne t'apprends rien, mais on ne sait jamais.

Passons maintenant à la modification du programme lui-même.

La ligne

--- Code: ---int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;
--- Fin du code ---
n'a maintenant plus de raison d'être.

A quoi servait-elle ?

C'est là qu'on voit un programme bien fait :
Le nom de la variable donne la solution : elle donne le numéro du poussoir.

Les numéros vont de 0 à 7 et quand le numéro vaut 8, c'est qu'aucun bouton n'est appuyé.
C'est très bien expliqué dans l'article cité précédemment.

Deux choses restent à faire :
1°) trouver numPoussoir quand on appuie sur un bouton
2°) passer à 4 au lieu de 8 puisque tu n'as que 4 boutons. A plusieurs endroits.

Le module "lirePoussoirs" est au pluriel parce qu'il cherche quel est le bouton appuyé dans la chaîne de poussoirs.
Mais il ne lit qu'un bouton.

En fait, c'est dans le loop() qu'on balaye les boutons, dans la boucle :

--- Code: ---for (numServo = 0; numServo < 8; numServo++) gereServo(numServo);

--- Fin du code ---
Et donc, là aussi, il faudra mettre 4 au lieu de 8.

Donc, reste à lire tes 4 boutons.
Voyons quelles sont les difficultés (outre le problème des rebonds) :

La première idée qui vient serait d'écrire :

--- Code: ---numPoussoir = 4;
if (digitalRead(A0) == LOW)
{
  numPoussoir = 0;
}
if (digitalRead(A1) == LOW)
{
  numPoussoir = 1;
}
if (digitalRead(A2) == LOW)
{
  numPoussoir = 2;
}
if (digitalRead(A3) == LOW)
{
  numPoussoir = 3;
}
--- Fin du code ---

On note qu'on cherche un LOW et pas un HIGH, puisqu'on à par défaut un HIGH (pull_up) et qu'on met à LOW en appuyant sur le bouton.

Si on n'appuie sur rien, il sort bien numPoussoir = 4. OK.
Si on n'appuie que sur un seul bouton, numPoussoir va bien donner 0, 1, 2 ou 3 suivant le bouton appuyé. OK.

Mais si on appuie sur plusieurs boutons, le programme ne va retenir que le dernier appuyé.

Par exemple 2 et 3 :
numPoussoir va passer successivement par 4 (au départ), puis 2, puis 3, effaçant 2... complètement oublié dans l'histoire.

Si on imbriquait les if(...) {...} avec des if(...){...}else{...}, ça ne changerait pas grand chose : on obtiendrait le premier bouton appuyé et on sortirait des tests.
Cette fois, ce serait 3 qui serait oublié et numPoussoir vaudrait 2.

--- Code: ---numPoussoir = 4;
if (digitalRead(A0) == LOW)
{
    numPoussoir = 0;
}
else
{
    if (digitalRead(A1) == LOW)
    {
         numPoussoir = 1;
    }
    else
    {
        if (digitalRead(A2) == LOW)
        {
            numPoussoir = 2;
        }
        else
        {
            if (digitalRead(A3) == LOW)
            {
                numPoussoir = 3;
            }
        }
    }
}
--- Fin du code ---

On gagne juste un peu de temps : on ne fait en moyenne que 2 tests alors qu'avant on en faisait forcément 4.
Gain quasi nul et sans intérêt : le problème n'est pas là.

Ce qu'il faudrait, c'est mémoriser la position des 4 boutons et de ne retenir pour numPoussoir que pour le bouton qui a changé d'état.
Même si deux ont changé d'état en même temps, on traitera le premier, puis le deuxième au tour suivant.

Il faut donc 8 variables supplémentaires : ancienA0, nouveauA0, ancienA1, nouveauA1 ... nouveauA3.

Je n'ai pas la solution tout de suite, mais je te la donne dès que j'ai vérifié. Je ne voudrais pas écrire des bêtises.  ;)








DDEFF:
Suite

On commence par déclarer les variables (avant le setup() )


--- Code: ---boolean ancienA0  = HIGH;
boolean nouveauA0 = HIGH;
boolean ancienA1  = HIGH;
boolean nouveauA1 = HIGH;
boolean ancienA2  = HIGH;
boolean nouveauA2 = HIGH;
boolean ancienA3  = HIGH;
boolean nouveauA3 = HIGH;

--- Fin du code ---

Puis, en replacement de la ligne de lecture des 8 boutons :


--- Code: ---    numPoussoir = 4;

    nouveauA0 = digitalRead(A0);   
    if (ancienA0 != nouveauA0)
    {
        ancienA0 = nouveauA0;
        numPoussoir = 0;
    }
    else
    {
        nouveauA1 = digitalRead(A1);
        if  (ancienA1 != nouveauA1)
        {
            ancienA1 = nouveauA1;
            numPoussoir = 1;
        }
        else
        {
            nouveauA2 = digitalRead(A2);
            if  (ancienA2 != nouveauA2)
            {
                ancienA2 = nouveauA2;
                numPoussoir = 2;
            }
            else
            {
                nouveauA3 = digitalRead(A3);
                if  (ancienA3 != nouveauA3)
                {
                    ancienA3 = nouveauA3;
                    numPoussoir = 3;
                }                                 
            }
        }
    }

--- Fin du code ---

Le but est toujours d'avoir le numéro de bouton sur lequel on a appuyé.

Au début, tous les poussoirs sont à HIGH.
Quand on lit les nouveaux poussoirs, on retrouve évidemment HIGH puisqu'on n'a appuyé sur rien.
Tous les tests sont négatifs et donc numPoussoir reste à 4.

Si on appuie, par exemple, sur 2, on passe les tests A0 et A1 par la négative, mais pas A2 parce que ancienA2 est à HIGH et que le nouveauA2 vient d'être à LOW.

On sort des boucles avec numPoussoir à 2, mais on a mis ancienA2 à LOW.
Et il y reste.
Au prochain passage, si le poussoir est toujours activé, on ignorera le test en A2 car ancienA2 = nouveauA2 = LOW.
Et donc, on retrouvera numPoussoir = 4.

Mais on aura traité le cas A2 car on traite dans la foulée. Et traité le cas du troisième Servo (hé oui, 3ème, puisqu'on démarre à 0...)

Donc, tout va bien pour un seul poussoir qu'on détecte bien.
On avait déjà atteint ce point avec le tout premier programme. C'était bien la peine ... :D

Mais là où ça change complètement, c'est si on appuie sur plusieurs boutons.
Mettons qu'on appuie sur tous les boutons en même temps.

Premier test (A0) : on trouve ancienA0 = HIGH et nouveauA0 = LOW et donc on sort des tests directement avec numPoussoir à 0.
Mais on a mis ancienA0 à LOW.

Ce qui fait que quand on passe au tour suivant, on saute le test A0 et en testant A1, on trouve ancienA1 = HIGH et nouveauA1 = LOW et donc on sort des tests directement avec numPoussoir à 1.

Au passage d'après, on a 2 et au passage d'après on aura 3.
Chaque passage a donné son numPoussoir.
Puis retour à numPoussoir = 4 tant que les boutons n'ont pas évolué.

Il reste un problème, que j'ai laissé exprès. Je te laisse le découvrir.
Mais tu va pouvoir le contourner facilement.

C'est toujours plus agréable d'avoir cherché et trouvé soi-même la solution. C'est comme ça qu'on progresse.
Mais si tu ne trouves pas, je suis toujours là.

Navigation

[0] Index des messages

[#] Page suivante

Utiliser la version classique