Aller au contenu


Photo
- - - - -

driver pwm : gros problème


  • Veuillez vous connecter pour répondre
16 réponses à ce sujet

#1 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 01 avril 2016 - 11:06

Bonjour,

 

Je me permets de me tourner vers vous pour essayer de trouver une solution à mon problème.

 

J'essaie désespérément de faire fonctionner mon driver pwm (16 servos) achetez sur le web.

 

Je précise que ce dernier est une copie du modèle adafruit….mais bon ….

 

Bref, voici ma config :

 

Pc sous windows 7

Genuino mega 2560 rev3 (original)

Servo towerpro MG996R

 

J’ai effectué la recherche pulsemin et pulsemax avec un petit soft en envoyant des largeurs d’impulsion pour trouver les bornes min et max, soit pulsemin = 650 et pulsemax 2400.

 

J’ai ensuite utilisé un autre petit programme arduino pour faire bouger mes servo de 0 à 180° par pas de 1°, puis de 180 à 0° et aucun problème.

 

Enfin j’ai essayé de mettre en œuvre le driver pwm sur un servo connecté à la pin9 du driver (pin0, 3, 5, ....cela ne change rien) !!

 

Et c’est là que les problèmes commencent : deux servo de MORT déjà…..

 

Après moultes recherches sur le web, je ne trouve toujours pas de solution à mon problème qui est le suivant : les servos vont en butée 180° à une vitesse phénoménale d’où la destruction de deux servos.

 

Faut dire que j’ai essayé beaucoup de solutions…..Apparemment je suis complétement à côté de la plaque !!

 

Le soft maintenant…Baaaaaaaa voici ci-dessous :

 /***************************************************
 test driver pwm
 ****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Utilisation de l'adresse par défaut 0x40 du Breakout.
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver( 0x40 );


#define SERVOMIN  650 // La longueur d'impulsion 'minimale' (valeur du compteur, max 4096)
#define SERVOMAX  2400 // La longueur d'impulsion 'maximale' (valeur du compteur, max 4096)

// Servos Commandés - Numéro de sorties sur le breakout
uint8_t servo9 = 9;

void setup() {
  Serial.begin(9600);
  Serial.println("Controle du Servo Moteur 9");

  pwm.begin();
 
  pwm.setPWMFreq(60);  // Les servo sont mis-à-jour à ~60 Hz
  Serial.println("Fin de setup");
}

void loop() {
 
  delay(5000);
 
  //--- Controle du Deuxieme Servo (no 9) ---
  Serial.println("Servo 9 a 30 degres");
  int pulseLen = map( 30, 0, 180, SERVOMIN, SERVOMAX );
  Serial.println( pulseLen);
  pwm.setPWM(servo9, 0, pulseLen);
 
  delay(5000);

   //--- Controle du Deuxieme Servo (no 9) ---
  Serial.println("Servo 9 a 150 degres");
  pulseLen = map( 150, 0, 180, SERVOMIN, SERVOMAX );
  Serial.println( pulseLen);
  pwm.setPWM(servo9, 0, pulseLen);
 
  delay(5000);
 
  //--- Les deux servo à 0 ---
  Serial.println("Servo 9 a 0 degres");
  pulseLen = map( 0, 0, 180, SERVOMIN, SERVOMAX );
  Serial.println( pulseLen);
  pwm.setPWM(servo9, 0, pulseLen);
 
  delay(5000);
}

Franchement je ne vois pas.....Je passe à côté de quoi ....B...de ......

 

Merci par avance pour vos conseils, pistes, solutions miracles ou bonnes grosses gifles pour me faire ouvrir les yeux !!!

 

A bientôt.



#2 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 01 avril 2016 - 12:36

Punaise !!

 

je viens de trouver une solution !!! par contre je ne comprends pas pourquoi !!

 

il fallait mettre :

#define SERVOMIN  145
#define SERVOMAX  560

Ha?!! Ok alors et pourquoi???

 

Ensuite j'ai essayé ceci :

  for (a=0; a<=180; a++)
  {
    delay(100);
    //Serial.println(a);
    pulselen = map( a, 0, 180, SERVOMIN, SERVOMAX);
    pwm.setPWM(servo1, 0, pulselen);
//delay(15); //plusieurs valeurs essayé sans succés !!
    pwm.setPWM(servo9, 0, pulselen);

  }
 
  delay(2000);
 
  for (b=180; b>=0; b--)
  {
    delay(100);
    //Serial.println(a);
    pulselen = map( b, 0, 180, SERVOMIN, SERVOMAX);
    pwm.setPWM(servo1, 0, pulselen);
//delay(15); //plusieurs valeurs essayé sans succés !!
    pwm.setPWM(servo9, 0, pulselen);

  }
  delay(500);

Parfois les deux servo arrivent à tourner ensemble dans le même sens et des fois il se mettent tous les deux à battre la mesure d'une manière hérétique......Comme si il revenaient à la position 0° pour repartir sur le nouvel angle a ou b selon la boucle..........

 

Et je n'ai pas le problème lorsque je n'utilise qu'un seul servo.................

 

Punaise....Je ne suis pas sorti de l'auberge moi !!!



#3 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 01 avril 2016 - 07:56

Bonjour,

 

Heu flûte alors je n'aurais pas dû poster ce topic ici mais plutôt dans : programmation !! Aie !!

 

y aurait t'il un modo pour ré-aiguiller mon post??

 

Merci par avance....

 

++



#4 levend

levend

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 5 572 messages
  • Gender:Male
  • Location:Vendée

Posté 01 avril 2016 - 08:04

J'ai déplacé ton sujet ..

 

 

C'est marrant le nombre de personnes, moi compris :D, qui trouve la solution après avoir posté dans un forum.

Bon courage pour la suite.


Imprimante 3D : Prusa i3 (MK1) + CR-10S + CR-10 S5 + Artillery Sidewinder X2 + CR-30 + Elegoo Mars + Anycubic Wash & cure 2 + Phrozen Sonic Mega 8K + Phrozen Cure Mega

#5 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 01 avril 2016 - 08:21

Oui, il faut dure qu'en relisant mon message et en regardant encore et encore les exemples, la seul différence était sur  :

#define SERVOMIN  145
#define SERVOMAX  560

Par contre je n'ai toujours pas trouvé d'explication, une idée peut être avec la fréquence et le temps pour atteindre 180 °. Dans mon cas 0.14 s/60º (6 V) soit 0.42s (420 ms) pour atteindre 180°

 

Un cylce de 20 ms pour un compteur de 4096...Soit 20/4096 = 0,0048828125 par unité cycle.

 

Ensuite la largeur d'impulsion étant de 2400 pour 180° .....2400/0.00488 = 491803,29 ...........???!! 2400*0.00488 = 11.712 ???!! Bon .....

 

Sinon ce bout de code ne me donne toujours pas satisfaction :

for (a=0; a<=180; a++)
  {
    delay(100);
    //Serial.println(a);
    pulselen = map( a, 0, 180, SERVOMIN, SERVOMAX);
    pwm.setPWM(servo1, 0, pulselen);
//delay(15); //plusieurs valeurs essayé sans succés !!
    pwm.setPWM(servo9, 0, pulselen);
  }

Parfois les deux servo arrivent à tourner ensemble dans le même sens et des fois il se mettent tous les deux à battre la mesure d'une manière hérétique......Comme si il revenaient à la position 0° pour repartir sur l'angle a ..........Je ferrai une vidéo si mes explications ne sont pas assez claires.

 

Si j'utilise qu'un seul servo, je n'ai pas de problème ....C'est quoi encore le tracassin ???

for (a=0; a<=180; a++)
  {
    delay(100);
    //Serial.println(a);
    pulselen = map( a, 0, 180, SERVOMIN, SERVOMAX);
    pwm.setPWM(servo1, 0, pulselen);
  }

++



#6 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 01 avril 2016 - 08:34

 

C'est marrant le nombre de personnes, moi compris  :D, qui trouve la solution après avoir posté dans un forum.

Ho oui moi aussi. Ecrire a cette vertu.



#7 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 01 avril 2016 - 10:25

for (a=0; a<=180; a++)
  {
    for ( long i =0; i <100000 ; i++)
    {
      On fait rien on attend  juste sans utiliser la fonction delay 
    }
    pulselen = map( a, 0, 180, SERVOMIN, SERVOMAX);
    pwm.setPWM(servo1, 0, pulselen);
    pwm.setPWM(servo9, 0, pulselen);
  }

Si tu utilises le code ci dessus ça donne quoi ?


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#8 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 01 avril 2016 - 10:54

Merci.

 

Je vais essayer ça ce soir (il est 11h48 ici : Tahiti - Papeete).

 

Ce serait donc la fonction delay qui poserait problème??

 

Bon je vous tiens au courant...



#9 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 02 avril 2016 - 10:33

Ok alors :
 
Sous condition de placer ces valeurs pour pulsmin et pulsemax :

double pulselen;//Et non pas en unint8...

#define SERVOMIN  145
#define SERVOMAX  560

J'ai toujours pas compris pourquoi ces valeurs alors que mes tests avec la librairie servo j'ai trouvé 640 et 2400 donc il y à un rapport avec le temps de cycle (20ms) et le compteur 4095 soit 0,00488 (20/4905) par unité de cycle et ensuite et bien ....Quelqu'un une idée peut être?

 

Bref, le code ci dessous fonctionne très bien :

void loop() {

  for (a=0; a <= 180; a++) 
  {
              pulselen = map( a, 0, 180, SERVOMIN, SERVOMAX);
              pwm.setPWM(servo1, 0, pulselen);
              //delay(5);//avec deux délais de 5ms, le mouvement est très légèrement saccadé, plus fluide avec uniquement délais en fin de boucle
              pwm.setPWM(servo9, 0, pulselen);
              delay(10);//Il faut au minimum un délais de 5ms en fin de boucle sinon trop rapide
  }
//*********************************************   
delay(5000);//pour test
  for (a=180; a >= 0; a--) 
  {            
              pulselen = map( a, 0, 180, SERVOMIN, SERVOMAX);
              pwm.setPWM(servo1, 0, pulselen);
              //delay(5);//avec deux délais de 5 ms, le mouvement est très légerement saccadé, plus fluide avec uniquement délais en fin de boucle
              pwm.setPWM(servo9, 0, pulselen);
              delay(10);//Il faut au minimum un délais de 5ms en fin de boucle sinon trop rapide
  }
//*********************************************
delay(5000);//pour test
  
}


#10 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 02 avril 2016 - 11:45

Salut Telson,

Je débute aussi. Le sujet m'intéresse car je suis aussi en train de travailler sur 2 servo avec un UNO et je voudrais bien comprendre ton problème.

 

Tu fais des mesures du min et du max avec servo.h. C'est bien ça ? Donc avec tes servo branché directement sur le arduino.

 

 

Quand ça fonctionne, tu as essayé avec 50Hz (pwm.setPWMFreq(50); ) et les min, max obtenus avec servo.h ?



#11 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 03 avril 2016 - 01:48

C'est grosso modo ça, il est intéressant de piloter le servomoteur par le port série afin d'envoyer des largeurs d'impulsions différentes et ainsi trouver pulsemin et pulsemax.

 

http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieDepuisPCPositionServomoteur

 

Cinématique inverse :

 

http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoMecatroniqueBrasLong5ServosPrehensionBalleTrackingBallxy

 

Explications :

 

http://www.mon-club-elec.fr/mes_docs/math/bras_5_servos/math_bras_5_servos.pdf



#12 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 03 avril 2016 - 10:12

Et merci encore pour les personnes qui ont pris de leur temps pour me répondre.

 

Il reste toutefois une question en suspend et j'arrive pas à trouver le pourquoi du comment et cela me saoule ....

 

Sous condition de placer ces valeurs pour pulsmin et pulsemax :

double pulselen; //Et non pas en unint8...

#define SERVOMIN 145
#define SERVOMAX 560

J'ai toujours pas compris pourquoi ces valeurs alors que mes tests avec la librairie servo j'ai trouvé 640 et 2400 donc il y à un rapport avec le temps de cycle (20ms) et le compteur 4095 soit 0,00488 (20/4905) par unité de cycle et ensuite et bien ....Quelqu'un une idée peut être?



#13 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 03 avril 2016 - 11:33

tu as bien mis 50 Hz comme path te l'a suggéré ? 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#14 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 04 avril 2016 - 06:28

J'attends de comprendre pourquoi il existe une telle différence entre les valeurs des deux librairies :

 

  • servo.h -> pulsemin = 640 et pulsemax = 2400
  • adafruit -> pulsemin = 145 et pulsemax = 560

 

Passer de 50 Hz à 60 Hz expliquerait en quoi la différence entre ces valeurs???

 

C'est le pourquoi du comment qui m'intéresse.....le fameux pourquoi?? Ha!! oui mais c'est bien sûr !!

 

Merci par avance.



#15 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 04 avril 2016 - 11:31

Tes servo sont sant doutes  fait pour fonctionner en 50 Hz 
La librairie servo.h fourni un pwm en 50 Hz . 

Si ton code fait un pwm en 60 Hz ça peut expliquer le changement des valeurs
 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#16 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 04 avril 2016 - 07:53

Je sais pas non plus. C'est justement pour savoir ^^

http://www.datasheet4u.com/pdf/MG996R-pdf/942981

On y voit surtout que ces servos ont 120° d'amplitude et non 180° comme on peut voir un peu partout.

Si tu les envois à 180, comme c'est dans les exemples ... C'est peut -être ça le pb.



#17 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 04 avril 2016 - 10:11

Ho ?? !! Tiens c'est étonnant ce datasheet.

 

En ce qui me concerne mes servos effectuent bien une rotation de 0°-> 180° ++

 

En voici un lien sur lequel nous pouvons constater qu'il existe ce même modèle avec une rotation de 180° ou 360° .....  : http://www.servodatabase.com/servo/towerpro/mg996r

 

La fréquence 50Hz ou 60 Hz modifierait telle d'autant les valeurs de pulsemin/pulsemax de 640->2400 contre 145->560 ??

 

Nous avons un rapport de +/- 0.23 : 0.23*2400 = +/-560 et 0.23*640 = 147.....Bon .....Et alors....

 

Fréquence de 50 hz = période de 20 ms. Fréquence de 60 hz = période de disons 17 ms....

 

Spécialement je pencherais plus pour regarder du côté des librairies avec des compteurs de 1024 ou 4096.....Car 1024/4096 = 0.25.....Le rapport est déjà plus proche.

 

Donc :

 

  • avec la librairie servo et une période de 50 Hz, soit 20 ms, codé sur 1024 bits,
  • avec la librairie adafruit et une période de 60 Hz, soit 17 ms, codé sur 4096 bits.

Je pense que le facteur important ici c'est la taille du compteur pour coder la largeur d'impulsion et peut être pas spécialement la fréquence de rafraichissement.

 

Nous aurions donc un rapport de 0.25.....pour cause de taille de compteur différent? ça ma plaît bien moi comme justif?

 

Suis'je dans le juste ou complétement à côté de la plaque là ???

 

N'y aurait t'il pas un expert ici qui pourrait nous aiguiller, j'aimerais bien comprendre ?

 

Merci?






0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users