Bonjour,
Je débute sur Arduino et ja cale sur le besoin que je cherche à satisfaire sur un servomoteur:
En fait je veux donner à une plaque tournante (modélisme ferroviaire) 3 positions, avec une vitesse de rotation très lente.
L'idée est qu'avec un interrupteur 3 positions, le servo atteigne l'une des trois positions programmées à une vitesse lente programmée et s'arrête une fois la position atteinte.
Je ne m'en sors pas après avoir essayé des quantité de programmes:
Au mieux, j'ai tout mais ça tourne en boucle !!
Merci par avance à celui qui voudra perdre du temps à me répondre
Daniel
Bonjour
un servo va se positionner TRES rapidement à la valeur de consigne. Par exemple si vous êtes à 20° et lui dites d'aller à 60°, ça va se faire en quelques dixièmes de secondes.
Si vous voulez qu'il y aille lentement, il faut intégrer une pause et lui demander de faire des "petits pas". Dans l'exemple ci dessus ça se traduirait par
aller à 21°, puis attendre un peu,
aller à 22°, puis attendre un peu,
aller à 23°, puis attendre un peu,
aller à 24°, puis attendre un peu,
...
aller à 59°, puis attendre un peu,
aller à 60°
si le code n'a rien d'autre à faire, vous pouvez mettre cela dans une fonction bloquante qui comportera une boucle entre la position courante (20° ici) et la destination (60° ici) et pour "attendre un peu" vous pouvez utiliser la fonction delay()
Pour vous aider il faudra poster votre code, prenez le temps de lire les règles du forum pour voir comment bien poster.
+1
La rapidité est un paramètre primordial dans un servo, pas de chance.
Avec des pauses, si c'est "très lent", du fait du principe le mouvement sera saccadé.
Est-ce gênant ? Pas sur, il faut faire un essai pour le dire.
En fait je veux donner à une plaque tournante (modélisme ferroviaire) 3 positions, avec une vitesse de rotation très lente.
Les servos dit 360° sont des moteurs classiques sans asservissement de position et qui se programment avec les mêmes signaux qu'un vrai servo.
Il est possible de régler leur vitesse mais pour le positionnement il faudra des contacts type fin de course ou un système qui fait la même fonction.
Conseil : "LE" site pour un passionné des petits trains : https://www.locoduino.org/
Alors, voilà mon code qui ne fonctionne pas comme je veux, le servo va bien de 45 degrés à 135 degrés à vitesse lente, mais il retourne en vitesse rapide à X degrés et tourne en boucle.
Suivant l'état du bouton la boucle tourne de 45 à 135 ou de 135 à 45.
(J'essaye de joindre le fichier.ino)
servo6.ino (856 Bytes)
Postez le code directement dans le forum, en utilisant les balises de code
[code]`` [color=blue]// votre code ici[/color] ``[/code].
ça doit ressembler à cela:// votre code ici
(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l’IDE avant de copier le code pour qu’il soit indenté correctement)
Merci, j'essaye ça, est ce bon ?
// NOK
// Deux positions programables au bouton, vitesse lente programmable
//Ca marche mais en boucle !!!Grrrr
#include<Servo.h>//Bibliothèque servo
Servo myServo; // désigne mon servo
int pos = 0; //
int switchState = 0;
#define PAUSE 50 // Avec 100 on a la mini recherchée
#define MIN 450 // pour angle 0 degré
#define MAX 750 // pour angle 180 degrés
void setup()
{
myServo.attach (9, MIN, MAX);
pinMode (2, INPUT); // pin du bouton
}
void loop()
{
switchState = digitalRead (2); // lire l'état du bouton
if (switchState == LOW)
{
for (pos = 45; pos <= 135; pos++) // de la position 45° à 135° par degré
{
myServo.write (pos);
delay (PAUSE);
}
}
else
{
for (pos = 135; pos >= 45; pos--)
{
myServo.write (pos);
delay (PAUSE);
}
}
}
Votre bouton n’est pas en INPUT_PULLUP
Comment est il câblé ?
(Ensuite le fonctionnement est bloquant donc le bouton ne sera pas réactif mais c’est un autre problème)
Salut
Bon ça fait un moment que j'ai pas mis le nez là-dedans... mais ... Quoiqu'il arrive on demande au servo de bouger. Le pauvre.
Si on appuie sur un bouton, le servo va en position A
Si on n'appuie pas il va en B
Donc dès qu'il est allé sur A, il revient en B?
C'est un aiguillage? C'est pas sensé rester en position?
Si c'est bien ça, il te faut un bouton A et un bouton B.
Tant que tu n'indiques ni A ni B, il peut faire une sieste (tu peux même couper l'alimentation du servo si les contraintes mécaniques sont moindres)
EN espérant ne pas ire de bêtises...
Ah oui, si jamais tu te poses la question, si tu veux que ton programme soit capable de lire la position de ton servo avant de décider s'il faut le bouger, j'avais fait un petit tuto sur un SG90
Alors, pour être clair :
Ce n'est pas un bouton poussoir mais un interrupteur 2 positions stables.
Je parviens très bien à faire aller le servo sur les deux positions de mon interrupteur, à l'angle que je veux, ça marche très bien. C'est quand j'essaye inclure le paramétrage de la vitesse lente, vitesse lente que j'obtiens bien, mais là le programme tourne en boucle:
Si l'interrupteur est en position A, Il passe en vitesse rapide à la position A, puis rejoint en vitesse lente la position B, et recommence en boucle.
Si l'interrupteur est en postion B, il passe en vitesse rapide à la position B puis rejoint en vitesse lente la position A , et recommence en boucle.
Ça marche donc presque bien sauf que ça tourne en boucle
mais là le programme tourne en boucle:
Si l'interrupteur est en position A, Il passe en vitesse rapide à la position A, puis rejoint en vitesse lente la position B, et recommence en boucle.
C’est exactement ce que le code dit de faire....puisque la loop boucle. Si vous ne voulez le faire qu’une seule fois, Il faut une variable qui se souviendra que l’opération a été réalisée. Il faut bien sûr gérer cette variable pour pouvoir passer d’un état à l’ autre
Je l'ai bien compris mais c'est exactement ce que je ne parviens pas à faire par manque de compétence en la mat!ère, j'ai essayé en vain avec une bouche "do"... "while"..., sans succès.
vous bouclez déjà avec la loop, pourquoi rajouter un do-while ?
c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)
dans le setup()
- vous lisez la position actuelle de l'interrupteur (DROITE ou GAUCHE) - disons DROITE
- donc vous êtes à l'état DROITE
dans la loop()
- si l'interrupteur change d'état vous effectuez le mouvement associé à ce changement (DROITE -> GAUCHE ou GAUCHE -> DROITE)
- vous mémoriser le nouvel état
Si vous voulez forcer un mouvement lors de l'allumage, lisez l'état et dans le SETUP dites que vous êtes dans l'état contraire. Comme cela à l'entrée de la loop() il voit un état différent et effectue le mouvement
une fois que cela fonctionne vous pourrez faire évoluer ce code avec des états supplémentaires pour définir les états transitoires, lorsque vous êtes en mouvement, afin de ne plus mettre de delay() dans le code et avoir quelque chose qui réagit instantanément au changement de position de l'interrupteur.
Solution d'un neuneu de base (juste un peu dégrossi) :
Tu créé une variable booléenne appellée flag, non comme c'est le forum francophone on l'appelera drapeau.
Dans setup tu initialise drapeau à "true" (-> VRAI)
Dans loop tu mets ce que tu veux faire dans un if
if (drapeau )
{
taratata
drapeau = false;
}
Comme cela au premier passage dans la fonction loop le code taratata s'exécutera, une fois exécuté drapeau sera mis à false et au prochain tour de loop le code ne sera pas exécuté.
Ca c'est pour le principe, il reste à adapter à ton besoin exact.
Note :
J'ai réduis l'écriture de la condition dans le if a sa plus simple expression car je suis feignant.
Le résultat de la condition dans un if ou un while est un booléen, ce résultat ne peut être que true ou false -> c'est exactement la nature de la variable drapeau.
if(drapeau) est totalement équivalent à if(drapeau==true) puisque le résultat du contrôle de l'égalité est un boolean.
Si tu trouves la deuxième écriture plus claire à comprendre tu l'utilises, si cela ne te gènes pas tu utilise la première.
L'important est de comprendre que le résultat d'une condition if ou while est un booléen.
J'ai réduit l'écriture de la condition dans le if a sa plus simple expression car je suis feignant.
Non, ce n'est pas de la fainéantise, c'est la bonne écriture qui montre que l'on a compris ce qu'est un type "valeur de vérité".
Pour mettre cela en français, une affirmation du genre "tu es malade" a une valeur de vérité. C'est une affirmation. quand vous parlez vous ne dites pas
Si tu es malade est vrai alors tu iras chez le docteur
mais on dit
Si tu es malade alors tu iras chez le docteur
il en va de même en programmation. écrire if(drapeau==true) c'est comme mal parler français.
L'important est de se comprendre.
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.