[Résolu] Problème avec analogwrite sur un hexacopter

Bonsoir à tous !

Je suis nouveau sur le forum. J'ai depuis quelques mois entrepris la construction d'un hexacopter. J'ai réalisé le châssis et une grande partie du programme sur Arduino.
La stabilisation se fait via un filtre de Kalman à l'aide de deux gyroscopes à un axe et d'un accéléromètre trois axes.

Le programme calcule les pwms à partir des commandes, reçues par la télécommande, et aussi à partir du PID et des données de la centrale inertielle. Jusque là tout va bien ! Le problème intervient au moment d'envoyer les pwms calculés sur les moteurs via la fonction "analogWrite". L'ensemble fonctionne une dizaine de secondes avant de se bloquer, et je suis obligé de redémarrer la carte (MEGA 2560). Lorsque je supprime la fonction "analogWrite", le programme tourne sans aucun problème et aussi longtemps qu'il est allumé.

Je n'ai pas trouvé d'autres posts traitant de ce problème.

Est ce que quelqu'un a une idée ??

Merci pour votre aide !

Sans plus de détails sur le programme cela va être difficile de répondre.

Pour rester dans le fil de la discussion : http://arduino.cc/forum/index.php/topic,110692.0.html
quelle sont les sorties pwm que tu utilises ?
Utilises-tu aussi des timers dans des fonctions de ton programme ?
(attention des fonctions "arduino" peuvent utiliser des timers sans te le dire).

En tout état de cause publie ton programme entre les balises # sans oublier de le commenter

Merci pour ta réponse.

Voici une partie du code :

// PWM_5 à PWM_10 : pwm de chaque moteur
// les PWM_CMD_X sont calculés à partir de la télécommande 
// les PWM_CI sont calculés à partir du PID et de la "centrale inertielle"

// MIN = 140
// maximum = 210

  PWM_5 = constrain(PWM_CMD_MONTER + PWM_CMD_RECULER + PWM_CMD_ROT_DROITE + PWM_CI_ARRIERE, MIN, maximum);
  PWM_6 = constrain(PWM_CMD_MONTER + PWM_CMD_GAUCHE + PWM_CMD_ROT_GAUCHE + PWM_CI_DROITE, MIN, maximum);
  PWM_7 = constrain(PWM_CMD_MONTER + PWM_CMD_GAUCHE + PWM_CMD_ROT_DROITE + PWM_CI_DROITE, MIN, maximum);
  PWM_8 = constrain(PWM_CMD_MONTER + PWM_CMD_AVANCER + PWM_CMD_ROT_GAUCHE + PWM_CI_AVANT, MIN, maximum);
  PWM_9 = constrain(PWM_CMD_MONTER + PWM_CMD_DROITE + PWM_CMD_ROT_DROITE + PWM_CI_GAUCHE, MIN, maximum);
  PWM_10 = constrain(PWM_CMD_MONTER + PWM_CMD_DROITE + PWM_CMD_ROT_GAUCHE + PWM_CI_GAUCHE, MIN, maximum);

  // ENVOI DES PWMs AUX MOTEURS
  analogWrite(5, PWM_5);
  analogWrite(6, PWM_6);
  analogWrite(7, PWM_7);
  analogWrite(8, PWM_8);
  analogWrite(9, PWM_9);
  analogWrite(10, PWM_10);

Je vais me renseigner sur les timers.

Les timers ce n'est qu'une hypothèse, de plus je n'ai jamais utilisé de servo.
A priori avec les sorties 5,6,7,8,9,10 tu utiliserais les timers :
5 -> timer 3
6,7,8 -> timer 4
9,10 -> timer 2

Question : as-tu affiché dans un terminal [fonctions Serial.begin(), Serial.print() ] la valeur de tes différentes variables PWM_5 à PMW_10 pour vérifier que le contenu est conforme a tes attentes ?

oui j'affiche dans le terminal tous les PWMs et ils correspondent bien à ce que j'attend, c'est à dire qu'ils varient entre 140 et 210 selon les commandes et l'orientation.

Salut,
Juste une hypothèse : Utilises-tu, pour contrôler tes moteurs, des ESC (Electronic Speed Controller) de modélisme ? Si c'est le cas, je pense que tu devrais essayer de les contrôler avec la bibliothèque Servo de l'arduino plutôt qu'avec la fonction analogWrite() :

En effet le PWM utlisé par les récepteurs de modélisme pour contrôler les servo-moteurs par exemple n'est pas le même que celui généré par analogWrite() : le PWM "normal" est un signal dont le rapport cyclique varie en fonction de la valeur qui lui est attribuée (exemple : signal PWM 50% : pour une période donnée le signal sera au niveau logique 1 pendant 50% de la période, et au niveau logique 0 pendant l'autre moitié. Ainsi, un signal PWM 0% reste au niveau logique 0 tout le temps, et un signal PWM 100% reste au niveau logique 1 tout le temps. :stuck_out_tongue: ).
Tandis qu'un signal PWM de servo-moteur, par exemple, est un signal qui dure 20ms au total (obligatoirement), et dont l'information est transmise durant les 2 premières millisecondes de ce signal : signal 0% : une implusion au niveau logique 1 de 1ms puis 19ms au niveau 0 ; signal 50% : une implusion de 1.5ms puis 18.5ms au niveau 0 ; et un signal 100% : une impulsion de 2ms puis 18ms au niveau 0.
Voilà, j'espère avoir été clair mais sinon tu peux aller voir ici : Fribotte : Base de données technique - pic et servo-moteur pour un complément.

Pour la bibliothèque Servo, tu peux aller voir ici ; elle est très simple à utiliser : http://arduino.cc/fr/Main/LibrairieServo

Et voilà, j'espère que cela suffira pour faire marcher, que dis-je,faire voler ton projet ; et bonne chance pour la suite !

Oui j'utilise des ESCs. En désactivant le PID et la "centrale inertielle", le programme réagit très bien aux commandes avec la fonction analogWrite.

Je vais essayer avec la librairie Servo et je vous tiendrais au courant.

voici la fonction que j'ai écrite en utilisant la librairie Servo

// "valeur" est calculée à partir des commandes et du PID via la "centrale inertielle"
void pwm_2(int moteur, int valeur)
{
  pwm = map(valeur, 0, 255, 0, 180);
  pwm = constrain(pwm, 0, 180);
  
  myservo.attach(moteur);
  myservo.write(pwm);
  myservo.detach();
}

// appels des fonctions
  pwm_2(5, PWM_5);
  pwm_2(6, PWM_6);
  pwm_2(7, PWM_7);
  pwm_2(8, PWM_8);
  pwm_2(9, PWM_9);
  pwm_2(10, PWM_10);

Lorsque je lance mon programme, les moteurs bip et ne s'initialisent pas.

Bonjour,

nicolas34:
voici la fonction que j'ai écrite en utilisant la librairie Servo
(...)
Lorsque je lance mon programme, les moteurs bip et ne s'initialisent pas.

Ton code ne marche pas car tu utilise toujours le même objet Servo.
Si tu attach() write() detach() cela ne fait que générer une impulsion mais pas un signal continu sur la broche !

Tu doit créer plusieurs objet Servo, puis dans setup() faire TOUT les attach() de chaque objet Servo.
Exemple : principialabs.com - This website is for sale! - principialabs Resources and Information.

Mais c'est logique en plus ! Merci du conseil !

Je teste ça de suite

Bon MACMan8, la solution que tu m'as proposé marche parfaitement !!

Il me reste juste un détail à régler, au démarrage tous les moteurs s'emballent, je vérifierai avec le terminal d'où vient le problème.

En tout cas merci de ton aide !

nicolas34:
Il me reste juste un détail à régler, au démarrage tous les moteurs s'emballent, je vérifierai avec le terminal d'où vient le problème.

Essaye de mettre un xx.write(0) juste aprés chaque xx.attach(x) :wink:

Nickel !

Je testerai avec les hélices pour voir la façon dont il se comporte !

Merci de ton aide.