Problème servo et moteurs CC contrôlés depuis la même carte

Bonjour,

J'ai un petit soucis avec une carte arduino nano. Je souhaite avec cette carte contrôler 4 servomoteurs sg90 ainsi qu'un moteur CC à l'aide d'un module L298N. L'arduino et le L298N sont alimentés avec une alim 12V pouvant aller jusqu'à 6A. Les servo sont quant à eux alimentés avec le L298N qui me permet de sortir du 5V.

Le moteur en question est celui d'un train miniature. Il ne va que dans un sens et sa vitesse est définie par la valeur d'un potentiomètre. Les servo, quant à eux, me permettent d'aiguiller le train sur 3 voies différentes en fonction de la valeur de BP dans le code, qui est géré par un jeu de boutons poussoirs et de résistances.

Voici le code :

#include <Servo.h>

Servo ServoAig1;
Servo ServoAig2;
Servo ServoAig3;
Servo ServoAig4;
const int angleMin=75;
const int angleMax=100;
int Vit;
int BP;

void setup(){
  pinMode(3, OUTPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  ServoAig1.attach(6);
  ServoAig2.attach(9);
  ServoAig3.attach(10);
  ServoAig4.attach(11);
  ServoAig1.write(angleMin);// Initialisation des servo
  ServoAig2.write(angleMin);
  ServoAig3.write(angleMin);
  ServoAig4.write(angleMin);
  TCCR2B = (TCCR2B & 0b11111000) | 0x07; // Modification de la fréquence de la PWM
}

void loop(){
  Vit = map(analogRead(A0), 0, 1023, 0, 255);
  BP = analogRead(A1);

// Aiguillé sur Voie 1
    if (BP > 250 && BP < 500){
      ServoAig1.write(angleMin);
      ServoAig3.write(angleMax);
      ServoAig4.write(angleMax);
    }
// Aiguillé sur Voie 2
    if (BP > 500 && BP < 750){
      ServoAig1.write(angleMax);
      ServoAig2.write(angleMin);
      ServoAig3.write(angleMin);
      ServoAig4.write(angleMax);
    }
// Aiguillé sur Voie 3
    if (BP > 750){
      ServoAig1.write(angleMax);
      ServoAig2.write(angleMax);
      ServoAig4.write(angleMin);
    }

// Vitesse train
  analogWrite(3,Vit);
  delay(10);
}

Voici mon problème:
Lorsque le potentiomètre est à 0 (train à l'arrêt), les servo marchent très bien et aiguillent correctement la voie. Cependant, lorsque je fais avancer le train, les servo deviennent "fous", c'est-à-dire qu'ils n’arrêtent pas de bouger légèrement comme s'il y avait des interférences. J'avais remarqué le même phénomène lorsqu'on essaye de les positionner à 0°, or ici je les fais aller de 75° à 100°. Le train, lui, fonctionne quand même.

Voici mes questions:
Quelqu'un a-t-il déjà rencontré ce problème ou sait-il comment le résoudre?
Est-ce un problème de timer ou autre?
Est-ce que c'est dû au fait que je modifie la fréquence de la PWM pour ne plus entendre le bruit du moteur de la loco?

Merci d'avance pour vos réponses.
Cordialement

Bonsoir,

en passant, mais sans aucune certitude, je ne sais pas si c'est cela, je n'ai pas beaucoup d'expérience avec les servos moteurs.

dans ta boucle loop tu redonnes en permanence (modulo le délai de 10 ms) des nouvelles consignes de PWM même si c'est la même que la précédente. Si jamais le fait de redonner une nouvelle consigne reprogramme le timer utilisé par le générateur de PWM alors c'est normal qu'il tremble.

Par contre cela n'explique pas le fait qu'ils ne tremblent pas lorsque le train est à l'arrêt (analogWrite(3,Vit);). ?!?

Pour tester je déplacerai le corps de la loop dans le setup. Du coup les valeurs des PWM seront fixées une fois pour toute au démarrage. Validant ou invalidant mon l'hypothèse.

Une remarque : rien qui explique le problème mais les valeurs 500 et 750 ne sont pas prise en compte dans tes tests.

Bonsoir,

Merci de ta réponse rapide.

Pour faire plus simple, j'avais aussi testé le même code mais en enlevant toute la partie de contrôle des servo dans le loop. J'ai juste gardé le contrôle du train :

#include <Servo.h>

Servo ServoAig1;
Servo ServoAig2;
Servo ServoAig3;
Servo ServoAig4;
const int angleMin=75;
const int angleMax=100;
int Vit;

void setup(){
  pinMode(3, OUTPUT);
  pinMode(A0, INPUT);
  ServoAig1.attach(6);
  ServoAig2.attach(9);
  ServoAig3.attach(10);
  ServoAig4.attach(11);
  ServoAig1.write(angleMin);// Initialisation des servo
  ServoAig2.write(angleMin);
  ServoAig3.write(angleMin);
  ServoAig4.write(angleMin);
  TCCR2B = (TCCR2B & 0b11111000) | 0x07; // Modification de la fréquence de la PWM
}

void loop(){
  Vit = map(analogRead(A0), 0, 1023, 0, 255);
  
// Vitesse train
  analogWrite(3,Vit);
  delay(10);
}

Du coup, les servo se sont initialisés à angleMin sans trembler. Mais dès que j'ai commencé de faire avancer le train, ils ont recommencé à trembler.

Par contre, j'ai essayé le même code sans les initialiser, c'est-à-dire sans les commandes "ServoAig.write(angleMin)" et là ils ne tremblaient plus. Mais je ne pouvais plus les faire bouger, donc c'est inutile x).

Je ne sais pas quelle carte tu utilises mais d'après la doc de servo (Servo - Arduino Reference) :

On boards other than the Mega, use of the library disables
analogWrite() (PWM) functionality on pins 9 and 10, whether 
or not there is a Servo on those pins

Message précédent pas du tout pertinent :-(, Oublie...

Et si tu sors aussi le analogWrite "de la loop" ?

C'est une nano.

Oui, la librairie servo supprime la pwm sur les bornes 9 et 10. Mais je n'utilise que la borne 3 en pwm pour commander le moteur.

Je peux essayer de sortir le analogWrite mais ce n'est pas mon but ^^. J'ai besoin de modifier la vitesse de mon train à tout instant. Si je met le analogWrite uniquement dans le setup, la vitesse de mon train sera définie uniquement au démarrage de l'arduino et je ne pourrais plus le contrôler via le potentiomètre.

Peut être que les servo se mettent à trembler lorsque je fais tourner le train parce qu’il n'y a pas assez de courant. Je les alimente via le L298N qui peut fournir jusqu'à 2A. Peut être que 2A ce n'est pas suffisant pour faire fonctionner 4 servo + un moteur.

Je peux essayer de sortir le analogWrite mais ce n'est pas mon but ^^. J'ai besoin de modifier la vitesse de mon train à tout instant

Oui je comprends, mais c'est juste pour vérifier si le problème viens du analogWrite, d'ailleurs fait le quand même dans le setup pour fixer la vitesse du train comme cela si ça marche tu pourras éliminer le problème de consommation électrique.

Sinon si tu laisses 1 seul servo avec le moteur ?

J'ai testé avec un servo et même chose.

J'ai mesuré le courant sur le 5V du servo. Lorsque le train était à l'arrêt, le servo consomme 3.67 mA et lorsque le train roule, il en consomme plus de 2A... Il semble qu'il y ai du pompage quelque part mais je ne vois pas d'où.

Poste peut-être un schéma de tes branchements.

voilà.
Fil rouge : 12V (gros) ou 5V (fin). Le L298N me permet de généré du 5V à partir du 12V qu'on lui inject. C'est avec ça que j'alimente le servo.

Fil noir : masse.

Fil vert : entré analogique du potar.

Fil jaune : sortie PWM (soit pour le L298N pour contrôler la tension du moteur CC, soit pour le servo)

Il y a aussi 2 bornes sur le L298N (IN1 et IN2), une reliée au 5V, l'autre à la masse. Elles sont là juste pour indiquer le sens de rotation du moteur.

Fil rouge : 12V (gros) ou 5V (fin). Le L298N me permet de généré du 5V à partir du 12V qu'on lui inject. C'est avec ça que j'alimente le servo.

Cela dépasse mes compétences... Pour moi le 5V du L298N sert à alimenter les circuits logiques en aucun cas de sortie mais je n'ai jamais joué avec un L298N...

D'autres t'aideront je n'en doute pas.

Merci pour ton aide en tout cas.

Il semblerait que le servo tremble à cause de microcoupure de la loco sur les rails.
Y-a-t'il des solutions? Condensateur ou autre?

C'est peut être ridicule, mais je commencerais par .. une alim par composant: 12 volts pour l'arduino (un peu haut; peut chauffer); 12 volts pour le L298, et un condensateur de filtrage généreux, et 5 volts pour les servos
seules les masses étant relièes entre elles;
Je mettrais progressivement les alims en commun (ça fait beaucoup),mais je commencerais avec un montage surdimensionné (pour ne me préoccupper que du logiciel)

En aucun cas (je ne sais si c'est une erreur de dessin ou ...) le L298 comme alimentation 5v ....
LA note d'applicationhttps://www.sparkfun.com/datasheets/Robotics/L298_H_Bridge.pdf indique, pour le découplage haute fréquence 100nF au plus près des pattes (5v et haute tension) du L298; 470uF pour la haute tension (12 v) sert de découplage basse fréquence (c'est très généreux)
Aucun de ces condensateurs n'est dans votre schéma...