IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Mouvements anormaux de servomoteurs après téléversement


Sujet :

Arduino

  1. #1
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Octobre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Mouvements anormaux de servomoteurs après téléversement
    Bonjour à tous,

    Je viens de fabriquer un petit bras robotisé que vous pourrez voir dans la vidéo ci-dessous.
    J'utilise une UNO pour le piloter et la programmation se fait avec Ardublock Education.
    Les servomoteurs sont des MG90S qui consomment très peu de courant.

    La vidéo montre le problème que je rencontre :
    La compilation et le téléversement s'effectuent pendant la première partie où il ne se passe rien.
    Lorsque le téléversement est terminé, les servomoteurs font des mouvements très brusques pour finalement revenir à leurs positions d'initialisation soit 90 degrés.
    Sur cette vidéo, aucun des mouvements effectué par le robot n'est souhaité.
    Je précise également que ces mouvements ne se font pas à chaque téléversement, peuvent être différents, et je n'ai pas réussi à trouver de lien de cause à effet.
    Parfois, il y a des mouvements plus ou moins importants comme ceux de la vidéo et à d'autres moments, il y a juste un petit bruit qui indique leur initialisation.



    Dans l'état actuel des choses, je crains la casse tôt ou tard.

    Pensez-vous que ce problème puisse se régler logiciellement ou faut-il que j'envisage de retarder la mise sous tension des servomoteurs matériellement ?

    Je vous remercie par avance de l'aide que vous pourrez m'apporter.

  2. #2
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Bonjour,

    peux-tu nous donner ton code ?
    Egalement peux-tu faire un schéma de ton montage ? Nous indiquer sur quelles broches sont connectés tes servomoteurs.
    Utilises-tu un shield et si oui lequel ?

  3. #3
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Octobre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    J'apporte donc les renseignements demandés :

    Dans le fichier ZIP en pièce jointe, il y a le programme ainsi qu'une bibliothèque à laquelle il fait appel.

    En ce qui concerne le montage, je n'utilise pas de shield :
    Les commandes des servomoteurs sont câblées les broches PWM : 3,5,9 et 11.
    Un interrupteur poussoir pour le départ de cycle est câblé sur la broche 8 avec une résistance de 10k.
    Tous les + des servomoteurs sont communs et sont câblés sur le +5V.
    Tous les - des servomoteurs sont communs et sont câblés sur le GND.
    Fichiers attachés Fichiers attachés

  4. #4
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoit Pat60

    GROS, GROS problème, j'ai essayé ton programme et j'ai constaté la même chose.
    Cela provient du fait que, au départ du programme, lorsque le PWM se met en marche, la compensation de la position physique du servo par rapport à la "position PWM" du programme est compensée immédiatement par le servo lui-même et cela sans contrôle de vitesse de la part du programme, d'où la vitesse excessive. Les fois ou il n'y a pas eu ou peu de déplacements, c'est parce-que tes servos étaient physiquement proches de la "position PWM" du programme.
    Difficile à résoudre, tu peux atténuer en supprimer cette ligne:
    Servos_90_deg();
    dans void setup()

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  5. #5
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Octobre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci pour cette réponse mais je ne comprends pas très bien.

    Servos_90_deg() appelle un sous programme qui demande aux servos de se mettre en position centrale ; donc au neutre.

    Lorsque le PWM se met en marche, les servos ne doivent pas se positionner en position centrale ?

    Auquel cas, les positions seraient identiques et ne devrait pas générer de mouvements.

  6. #6
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Pat60

    La suppression de cette ligne, au départ, n'est pas la solution, mais j'ai constaté moins mouvements au démarrage, ça n'arien de rigoureux.
    Ces mouvements brusques, sont, pour moi, des mouvements parasites, donc hors programme donc difficiles à contrôler.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 830
    Points
    4 830
    Par défaut
    Bonsoir

    Le problème est simple. La fonction write avec 4 arguments c'est le déplacement depuis la position actuelle jusqu'à la position demandée. Au démarrage la position par défaut c'est le 0 (voir pire cela n'est pas initialisé d'où la constatation que ce n'est pas toujours la même chose). Donc chaque servo va très vite à 0 puis revient à la vitesse demandée à 90°. Et cela de manière séquentielle. Un problème hardware aurait produit un mouvement synchronisé et bien plus rapide.

    Au démarrage il faut juste initialiser la position effective des servo (à 90°, avant de faire mieux et d'enregistrer les 4 valeurs dans l'EEPROM à l'arrêt), c'est éventuellement la fonction write à 2 arguments, mais j'ai été incapable de trouver la doc de la bibliothèque TSServo... (la 4 arguments est compréhensible par les noms des arguments et surtout par l'analyse de la vidéo. Je n'ai pas été plus loin).

    Bonne suite

    Delias

  8. #8
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Pat60

    J'ai repris les essais mais avec un oscilloscope et ai surtout relu le titre du message qui disait, après téléversement...
    C'est difficile à dire si après, pendant ou à la fin mais voici le phénomène constaté sur une des sorties PWM:
    Nom : Pat60_ServoOscillo.png
Affichages : 1303
Taille : 480,8 Ko
    L'impulsion de commande devient toute petite (position de droite) pendant ~2 secondes, ce qui envoie le servo dans les extrêmes et à vitesse maximum puis revient à la position de gauche à la même vitesse. Cela ne se produit pas à tout les coups.

    A mon avis, la seule façon d'éviter ce problème est de couper l'alimentation des servo pendant le téléchargement.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  9. #9
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 189
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 189
    Points : 11 571
    Points
    11 571
    Par défaut
    Salut,
    Tu vois ce phénomène juste après un téléchargement ? Peu importe le programme ? Il se passe quoi si tu télécharges un programme qui n'utilise pas le PWM ?

    Merci
    A+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  10. #10
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Vincent

    Oui, en fait, vu avec une sonde logique, pendant ce laps de temps il n'y a "plus d'état", ni 1 ni 0.
    La même chose se passe avec une une pin en pinMode(7, OUTPUT);

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  11. #11
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Bonsoir,

    juste un détail : les commandes de ces servomoteurs ne sont pas en PWM mais en PPM. La bibliothèque servo.h n'utilise pas les fonctions analogWrite() que l'on connaît car on ne pourrait pas obtenir des impulsions si brèves en modifiant seulement le rapport cyclique.


    Que se passe-t-il si tu enlèves le contenu du loop() (tu laisses uniquement ce qu'il y a dans la fonction setup() ) ?
    Code arduino : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void setup()
    {
      servo_pin_11.attach(11);
      servo_pin_5.attach(5);
      servo_pin_9.attach(9);
      servo_pin_3.attach(3);
      Servos_90_deg();
    }
     
    void loop()
    {
     
    }

  12. #12
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Auteur
    Citation Envoyé par Auteur Voir le message
    juste un détail : les commandes de ces servomoteurs ne sont pas en PWM mais en PPM. La bibliothèque servo.h n'utilise pas les fonctions analogWrite() que l'on connaît car on ne pourrait pas obtenir des impulsions si brèves en modifiant seulement le rapport cyclique.
    Excellente info, merci.

    Citation Envoyé par Auteur Voir le message
    Que se passe-t-il si tu enlèves le contenu du loop() (tu laisses uniquement ce qu'il y a dans la fonction setup() ) ?
    C'est la même chose.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  13. #13
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 830
    Points
    4 830
    Par défaut
    Bonsoir à tous

    J'ai reçu un mais j'ai l'impression que personne n'a vraiment essayer de comprendre mon précédent message

    Alors pour reprendre:
    - Lors d'un téléversement, le micro subit en premier un reset qui mets toutes ses E/S en mode entrée / haute impédance, cet état est conservé jusqu'à ce que le programme qui démarre par la suite modifie DDRx ou PORTx (ou en Arduino par pinMode()).
    - Avant l'introduction d'une valeur d'une impulsion, l'E/S reste à 0.
    - Ces deux états sont représentatif d'une absence de signal pour le servo-moteur. En l'absence de signal un (bon) servo reste en place.

    Donc le problème n'est pas le téléversement mais le démarrage du programme après le téléversement, après un enclenchement de la tension ou après un reset. Cela est d'ailleurs confirmé par la vidéo. Si le problème était l'absence de signal, les 4 servos bougeraient en simultanés et non l'un après l'autre qui est le signe d'une commande effectivement donnée par le déroulement d'un programme...

    La réponse est dans la classe TSServo et son unique fichier .h
    La fonction write à 4 arguments
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
      void write(int value, int speed, int min, int max)
    	{
     
        min = map(min, 0, 180, 0, 180);
        max = map(max, 0, 180, 0, 180);
    		int finalValue = map(constrain(value, min, max), 0, 180, 544, 2400);
    		int currentValue = Servo::readMicroseconds();
    		int	delta	= finalValue - currentValue;
        float increment = (float)speed/1000;
        //Synchronous move
    		if(delta>0)
        {
    			for(float i=0; i<=delta;i+=increment)
          {
    					Servo::writeMicroseconds(currentValue+i);
    			}
        }
        else
        {
    			for(float i=0; i>=delta;i-=increment)
          {
    					Servo::writeMicroseconds(currentValue+i);
    			}
    		}
        Servo::writeMicroseconds(finalValue);
      }
    Cette fonction prend la position actuelle (enregistrée en miroir dans une variable du micro) puis applique une succession de commande pour déplacer progressivement le servo jusqu'à la position désirée.
    Hors au démarrage, la position enregistrée dans la variable miroir n'est pas la position effective du servo (il y a une discordance) donc quand la fonction est appelée le servo est envoyé brutalement à la position enregistrée dans la variable (qui après un reset est généralement 0, alors que après une mise en tension c'est aléatoire), puis se déplace à nouveau vers le 90°.

    Idéalement il faudrait avoir un constructeur la fonction attach(); avec les 2 arguments (la pin et la position de départ) qui n'existe pas. A défaut il faudrait faire comme dans la référence de la bibliothèque de base Arduino.cc: ServoWrite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void setup() 
    { 
      myservo.attach(9);
      myservo.write(90);  // set servo to mid-point
    }
    normalement cela (write avec un seul argument) devrait être accepté également avec TSServo car c'est une classe fille, sauf que je n'ai pas l'IDE Arduino installé pour essayer.

    Bonne suite

    Delias

  14. #14
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Delias
    Citation Envoyé par Delias Voir le message
    J'ai reçu un mais j'ai l'impression que personne n'a vraiment essayer de comprendre mon précédent message
    Non, non! J'ai lu et apprécié ton explication, le pouce en l'air ce n'était pas Jules César, mais moi .
    Ton post explique une grande partie des mouvements incriminés.

    Ce que je voulais montrer dans mon post #8, image de droite, c'était cette impulsion très étroite qui fait "sursauter" le servo. Elle ne se produit pas tout les coups, elle arrive à la fin du téléchargement, au moment où s'affiche le texte avrdude done Thank you.. et environ 1 sec. après, il y a les premières manifestations du programme.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  15. #15
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Je présume qu'appeler la fonction write() juste après attach() et donner à cette fonction des valeurs nulles pour les arguments value et speed, ne donnerait rien de mieux ?

  16. #16
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 830
    Points
    4 830
    Par défaut
    Bonsoir Auteur

    Non le problème subsistera autant longtemps que l'on appellera servo_pin_X.write( 90, 15, 0, 180 ); après l'attach(yy);.

    Après relecture, la fonction setup devrait être la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void setup()
    {
      servo_pin_11.attach(11);
      servo_pin_11.write(90);
      servo_pin_5.attach(5);
      servo_pin_5.write(90);
      servo_pin_9.attach(9);
      servo_pin_9.write(90);
      servo_pin_3.attach(3);
      servo_pin_3.write(90);
    }
    pour autant que cette écriture soit valide

    Bonne suite

    Delias

  17. #17
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Delias

    Il y a une erreur à chaque ligne .write, les paramètres (4)

    ARDFR_ProgRobot.ino: 33:24: error: no matching function for call to 'TSServo::write(int)
       servo_pin_11.write(90)
     
    ARDFR_ProgRobot.ino:1: In file included from
    TSServo.h:18: note  candidate  void TSServo  write(int, int, int, int)
       void write(int value, int speed, int min, int max)
    TSServo.h:18: note    candidate expects 4 arguments, 1 provided
    TSServo.h:45: note  candidate  void TSServo  write(int, bool)
       void write(int value, bool inverse)
    TSServo.h:45: note    candidate expects 2 arguments, 1 provided
    ne sont pas optionnels.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  18. #18
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 830
    Points
    4 830
    Par défaut
    Bonsoir

    Ouille, je n'ai plus fait de C++ depuis mes études terminées il y a 12ans. (Depuis je suis resté en ASM et C sur microcontrôleur ainsi que Delphi et VBA sur PC)
    Le but c'est d'appeler la fonction write (int angle) de la classe mère Servo avec comme signature un seul int en paramètre. C'est quoi déjà la bonne syntaxe pour cela?
    Est-ce que servo_pin_X.Servo::write(90); fonctionnerait?
    Une autre solution serait: servo_pin_X.writeMicroseconds(1500);, mais ce n'est pas dans l'esprit d'une bonne programmation.
    Sinon servo_pin_X.Servo::write(90, false); mais le supplément de calcul, inutile dans ce cas, sera préjudiciable (car pendant ce calcul il peut y avoir la génération d'un pulse de 1ms et une réaction non voulue du servo).

    Delias

Discussions similaires

  1. Réponses: 183
    Dernier message: 31/01/2024, 14h56
  2. Réponses: 16
    Dernier message: 27/08/2022, 00h50
  3. Mise a jour de la position d'une div apres mouvement
    Par Floflo18 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 16/01/2018, 13h05
  4. Réponses: 67
    Dernier message: 28/05/2015, 15h22
  5. [Lazarus] Position d'une fiche après mouvement à la souris
    Par Invité dans le forum Lazarus
    Réponses: 1
    Dernier message: 17/03/2012, 12h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo