Moteur DC et servo moteur bug librairie servo.h

Bonjour,

et voici un nouveau probleme, pour la conception du robot de notre equipe nous avons un bug quand on rajoute les servos moteurs ( 6 au total), du moment que je rajoute servo.h les moteurs ne sont plus commandable par le joystick. J'ai lu pas mal de chose mais pas de solution: Bogue avec la bibliothèque Servo, comment corriger ce problème ??? - #19 by LamiRene.

/*  Arduino DC Motor Control - PWM | H-Bridge | L298N

Rajout d'un servo moteur pour simuler la porte etverifier comptabilité avec les moteurs A et B
*/

#include <Servo.h>

#define in1A_MotorLeftA 4 
#define in2A_MotorLeftA 5 
#define enA_MotorLeftA 6  

#define in1B_MotorRightB 7 
#define in2B_MotorRightB 8 
#define enB_MotorRightB 9  

#define PinSwitchLED 13 

int Speed_MotorLeftA = 0;
int Speed_MotorRightB = 0;

int SwitchOnLED = HIGH;  // HIGH = switch OFF
int TimerLED = 0;


Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  pinMode(enA_MotorLeftA, OUTPUT);
  pinMode(enB_MotorRightB, OUTPUT);
  pinMode(in1A_MotorLeftA, OUTPUT);
  pinMode(in2A_MotorLeftA, OUTPUT);
  pinMode(in1B_MotorRightB, OUTPUT);
  pinMode(in2B_MotorRightB, OUTPUT);

  pinMode(PinSwitchLED, OUTPUT);

  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

myservo.attach(11);  // attaches the servo on pin 9 to the servo object    pb des que l'on attache le servo un moteur ne reponds plus
}

void loop() {

 for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

  int xAxis = analogRead(A0); // Read Joysticks X-axis
  int yAxis = analogRead(A1); // Read Joysticks Y-axis

  int ySign = 1 ; // Identify if Y is move forward 1   or   move backward -1 ; will be used to accomodate speed of the wheels
  int UTurnAllowed = 0; // when Y is in neutral position and willing to make U turn without going forward or backgroud ; 0 for no UTurn, 1 for UTurn

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor Left A backward
    digitalWrite(in2A_MotorLeftA, HIGH);
    digitalWrite(in1A_MotorLeftA, LOW);
    // Set Motor Right B backward
    digitalWrite(in1B_MotorRightB, HIGH);
    digitalWrite(in2B_MotorRightB, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 470, 0, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  else if (yAxis > 550) {
    // Set Motor Left A forward
    digitalWrite(in1A_MotorLeftA, HIGH);
    digitalWrite(in2A_MotorLeftA, LOW);
    
    // Set Motor Right B forward
    digitalWrite(in1B_MotorRightB, LOW);
    digitalWrite(in2B_MotorRightB, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 550, 1023, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  // If Y axis of the joystick stays in neutral position then allow U Turn and reduce speed to zero
  else {
    // Autorize U Turn
    UTurnAllowed = 1;
    
    //Set PWM to zero
    Speed_MotorLeftA = 0;
    Speed_MotorRightB = Speed_MotorLeftA ;
  }



  // Sign of Y will be -1 if yAxis < 512   otherwise   Sign of Y will be +1 (default value)
    if (yAxis < 512) {
      ySign = -1 ;
    }
 
  // X-axis used for left and right control
    if (xAxis > 650) {  // Go to the left
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 650, 1023, 0, 255);
    if (UTurnAllowed == 1) { // Means Y is in neutral position
      Speed_MotorLeftA = xMapped ;
      Speed_MotorRightB = xMapped ;
      
      // Set Motor Left A backward
      digitalWrite(in2A_MotorLeftA, HIGH);
      digitalWrite(in1A_MotorLeftA, LOW);
      // Set Motor Right B forward
      digitalWrite(in1B_MotorRightB, LOW);
      digitalWrite(in2B_MotorRightB, HIGH);
    }
    else {
      // if ySign>0 THEN Move to left forward - decrease left motor speed, increase right motor speed    
      // if ySign<0 THEN Move right backward - decrease right motor speed, increase left motor speed
      Speed_MotorLeftA = Speed_MotorLeftA - xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB + xMapped*ySign;
    }
  }
  if (xAxis < 370) {  // Go to the right
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 370, 0, 0, 255);
    if (UTurnAllowed == 1) {  // Means Y is in neutral position
      Speed_MotorLeftA = xMapped;
      Speed_MotorRightB = xMapped;
      
      // Set Motor Left A forward
      digitalWrite(in2A_MotorLeftA, LOW);
      digitalWrite(in1A_MotorLeftA, HIGH);
      // Set Motor Right B backward
      digitalWrite(in1B_MotorRightB, HIGH); //////HIGH
      digitalWrite(in2B_MotorRightB, LOW);      
    }
    else {
      // if ySign>0 THEN Move right forward - decrease right motor speed, increase left motor speed
      // if ySign<0 THEN Move to left backward - decrease left motor speed, increase right motor speed    
      Speed_MotorLeftA = Speed_MotorLeftA + xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB - xMapped*ySign;
    }
  }
  
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  // Confine the range from Min 70 to Max 255
  if (Speed_MotorLeftA > 200) {
      Speed_MotorLeftA = 200;
  }
  if (Speed_MotorLeftA < 70) {
     Speed_MotorLeftA = 0;
  }
  if (Speed_MotorRightB > 200) {
      Speed_MotorRightB = 200;
  }
  if (Speed_MotorRightB < 70) {
     Speed_MotorRightB = 0;
  }

  
  // Switch On LEDs
  if ((Speed_MotorLeftA  > 100) || (Speed_MotorRightB > 100)) { 
     TimerLED = 10000 ;
  }
  else {
     TimerLED =  TimerLED - 1;
  }

  if (TimerLED > 0) {
    SwitchOnLED = LOW; // LOW = switch ON
  }
  else {
    SwitchOnLED = HIGH; // HIGH = switch OFF
    TimerLED = 0;
  }
  digitalWrite(PinSwitchLED, SwitchOnLED);      



  // Send PWM signals
  analogWrite(enA_MotorLeftA, Speed_MotorLeftA); // Send PWM signal to Motor Left A
  analogWrite(enB_MotorRightB, Speed_MotorRightB); // Send PWM signal to Motor Right B
}

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Bonjour charlesly

Si tu mets ces lignes en remarque:

	//for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
		//// in steps of 1 degree
		//myservo.write(pos);              // tell servo to go to position in variable 'pos'
		//delay(15);                       // waits 15ms for the servo to reach the position
	//}
	//for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
		//myservo.write(pos);              // tell servo to go to position in variable 'pos'
		//delay(15);                       // waits 15ms for the servo to reach the position
	//}

As tu le même problème?

Cordialement
jpbbricole

hello, sur le lien que tu donnes
je viens de lire les 125 posts. à tu essayé ce que l'ami rené dis en post #124 ?

oui la meme chose

Je veux bien qu'il y ait un bug dans servo.h, mais pas ce qui est décrit ici.

Servo.h a besoin d'un timer 16 bit pour fonctionner, et sur une uno, il n'y en a qu'un, le timer 1
analogWrite a besoin d'un timer pour délivrer son signal, et peut utiliser un timer 8 ou 16 bits.

Si on utilise les deux, il ne faut pas utiliser le même timer. On est obligé de prendre le timer 1 pour servo.h (c'est le seul 16 bits) et on ne peut donc pas utiliser les broches de la Uno 9 et 10 , il reste les timers 0 ou 2 pour analogWrite, c'est à dire les broches 5 et 6 (timer 0), ainsi que 3 et 11 (timer 2).

Or dans le programme, analogWrite(enB_MotorRightB,... est sur la broche 9. Il doit suffire d'utiliser la broche 11 à la place qui est libre.


Ce que disait l'ami rené, n'est pas applicable à la uno. Servo utilise un seul timer si on veut piloter jusqu'à 12 servo, 2 timers si on veut piloter entre 13 et 24 servos... Dans le cas de l'ami rené, il a moins de 12 servos et par défaut servo.h utilise d'abord le timer 5 avec une méga. Sa correction demande d'utiliser par défaut le timer 1, ce qui va libérer les broches 38, 39 et 40 qui fonctionneront avec analogWrite. La uno n'ayant qu'un seul timer 16 bits on ne peut pas changer le "par défaut".

Merci pour cette réponse. Pour notre projet on a changé de carte arduino , on passe sur une méga.
Car au final on va avoir 7 servo moteurs à gérer ,2 moteurs DC, une manette PS4( sur un host shield) et pour finir une écran display.

pourquoi on a besoin d'un timer ?( je veux bien un petit cours)
J avais essayé de mettre sur la broche 11 avec le arduino uno mais cela ne fonctionnait pas.

J ai mis tous le codes et le cablage sur la mega recu ce soir mais cela ne fonction pas

/*  Arduino DC Motor Control - PWM | H-Bridge | L298N

Rajout d'un servo moteur pour simuler la porte etverifier comptabilité avec les moteurs A et B
*/

#include <Servo.h>

#define in1A_MotorLeftA 26 
#define in2A_MotorLeftA 28 
#define enA_MotorLeftA 6  

#define in1B_MotorRightB 24 
#define in2B_MotorRightB 22
#define enB_MotorRightB 9  

#define PinSwitchLED 13 

int Speed_MotorLeftA = 0;
int Speed_MotorRightB = 0;

int SwitchOnLED = HIGH;  // HIGH = switch OFF
int TimerLED = 0;


Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  pinMode(enA_MotorLeftA, OUTPUT);
  pinMode(enB_MotorRightB, OUTPUT);
  pinMode(in1A_MotorLeftA, OUTPUT);
  pinMode(in2A_MotorLeftA, OUTPUT);
  pinMode(in1B_MotorRightB, OUTPUT);
  pinMode(in2B_MotorRightB, OUTPUT);

  pinMode(PinSwitchLED, OUTPUT);

  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

myservo.attach(23);  // attaches the servo on pin 9 to the servo object    pb des que l'on attache le servo un moteur ne reponds plus
}

void loop() {

 for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

  int xAxis = analogRead(A0); // Read Joysticks X-axis
  int yAxis = analogRead(A1); // Read Joysticks Y-axis

  int ySign = 1 ; // Identify if Y is move forward 1   or   move backward -1 ; will be used to accomodate speed of the wheels
  int UTurnAllowed = 0; // when Y is in neutral position and willing to make U turn without going forward or backgroud ; 0 for no UTurn, 1 for UTurn

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor Left A backward
    digitalWrite(in2A_MotorLeftA, HIGH);
    digitalWrite(in1A_MotorLeftA, LOW);
    // Set Motor Right B backward
    digitalWrite(in1B_MotorRightB, HIGH);
    digitalWrite(in2B_MotorRightB, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 470, 0, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  else if (yAxis > 550) {
    // Set Motor Left A forward
    digitalWrite(in1A_MotorLeftA, HIGH);
    digitalWrite(in2A_MotorLeftA, LOW);
    
    // Set Motor Right B forward
    digitalWrite(in1B_MotorRightB, LOW);
    digitalWrite(in2B_MotorRightB, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 550, 1023, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  // If Y axis of the joystick stays in neutral position then allow U Turn and reduce speed to zero
  else {
    // Autorize U Turn
    UTurnAllowed = 1;
    
    //Set PWM to zero
    Speed_MotorLeftA = 0;
    Speed_MotorRightB = Speed_MotorLeftA ;
  }



  // Sign of Y will be -1 if yAxis < 512   otherwise   Sign of Y will be +1 (default value)
    if (yAxis < 512) {
      ySign = -1 ;
    }
 
  // X-axis used for left and right control
    if (xAxis > 650) {  // Go to the left
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 650, 1023, 0, 255);
    if (UTurnAllowed == 1) { // Means Y is in neutral position
      Speed_MotorLeftA = xMapped ;
      Speed_MotorRightB = xMapped ;
      
      // Set Motor Left A backward
      digitalWrite(in2A_MotorLeftA, HIGH);
      digitalWrite(in1A_MotorLeftA, LOW);
      // Set Motor Right B forward
      digitalWrite(in1B_MotorRightB, LOW);
      digitalWrite(in2B_MotorRightB, HIGH);
    }
    else {
      // if ySign>0 THEN Move to left forward - decrease left motor speed, increase right motor speed    
      // if ySign<0 THEN Move right backward - decrease right motor speed, increase left motor speed
      Speed_MotorLeftA = Speed_MotorLeftA - xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB + xMapped*ySign;
    }
  }
  if (xAxis < 370) {  // Go to the right
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 370, 0, 0, 255);
    if (UTurnAllowed == 1) {  // Means Y is in neutral position
      Speed_MotorLeftA = xMapped;
      Speed_MotorRightB = xMapped;
      
      // Set Motor Left A forward
      digitalWrite(in2A_MotorLeftA, LOW);
      digitalWrite(in1A_MotorLeftA, HIGH);
      // Set Motor Right B backward
      digitalWrite(in1B_MotorRightB, HIGH); //////HIGH
      digitalWrite(in2B_MotorRightB, LOW);      
    }
    else {
      // if ySign>0 THEN Move right forward - decrease right motor speed, increase left motor speed
      // if ySign<0 THEN Move to left backward - decrease left motor speed, increase right motor speed    
      Speed_MotorLeftA = Speed_MotorLeftA + xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB - xMapped*ySign;
    }
  }
  
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  // Confine the range from Min 70 to Max 255
  if (Speed_MotorLeftA > 200) {
      Speed_MotorLeftA = 200;
  }
  if (Speed_MotorLeftA < 70) {
     Speed_MotorLeftA = 0;
  }
  if (Speed_MotorRightB > 200) {
      Speed_MotorRightB = 200;
  }
  if (Speed_MotorRightB < 70) {
     Speed_MotorRightB = 0;
  }

  
  // Switch On LEDs
  if ((Speed_MotorLeftA  > 100) || (Speed_MotorRightB > 100)) { 
     TimerLED = 10000 ;
  }
  else {
     TimerLED =  TimerLED - 1;
  }

  if (TimerLED > 0) {
    SwitchOnLED = LOW; // LOW = switch ON
  }
  else {
    SwitchOnLED = HIGH; // HIGH = switch OFF
    TimerLED = 0;
  }
  digitalWrite(PinSwitchLED, SwitchOnLED);      



  // Send PWM signals
  analogWrite(enA_MotorLeftA, Speed_MotorLeftA); // Send PWM signal to Motor Left A
  analogWrite(enB_MotorRightB, Speed_MotorRightB); // Send PWM signal to Motor Right B
}

Rappel: pour un servomoteur "normal" il faut fournir un signal de commande de période 20ms avec un état haut entre 1ms et 2ms qui va déterminer sa position.

Le cœur du AtMega2560 (celui qui équipe la Mega) contient de quoi exécuter un programme. Mais en plus il y a des circuits spécialisés qui vont décharger le programme de certaines tâches. Ce sont les entrées/sorties, les compteurs de temps, les dialogues séries... Quand on veut gérer un servomoteur, on peut très bien se passer de la fonction comptage de temps:
− on met une sortie à HIGH
− on fait une boucle qui dure entre 1ms et 2ms en fonction de la position souhaité du servo
− on met la sortie à LOW
− on fait une boucle qui dure entre 20ms-1ms et 20ms-2ms pour que la période soit de 20ms
− on recommence.
C'est ainsi que fonctionne la bibliothèque STEPPER. Ce qui fait que quand un moteur tourne on ne peut rien faire d'autre.

Si on n'a que cela à faire, c'est très facile, mais il faut au moins changer la valeur. On peut alors faire une procédure pour cela. Si on connaît le temps de cette procédure, on peut l'exécuter pendant l'état LOW de la sortie. On attendra un peu moins longtemps.

Mais c'est assez compliqué de calculer ce temps. Et l'utilisation d'un timer permet de libérer complètement le cœur. On peut alors faire n'importe quoi à la place de passer son temps à boucler.
On a au moins deux possibilités:
− on vaque à nos occupations et régulièrement on regarde l'heure et on fait ou non une action. Par exemple si le signal doit être HIGH pendant 1ms, quand on le met haut, on repère le temps et régulièrement on appelle une fonction run() qui regarde si le temps est écoulé ou pas. Si le temps est atteint, on remet la sortie à LOW et on note le temps pour mesurer les 20ms-Nms restantes. C'est ce que l'on peut faire si on doit partir dans une heure, on regarde la montre de temps en temps. C'est assez simple, mais cela oblige à regarder régulièrement l'heure. C'est ainsi que fonctionnent certaines bibliothèques dans lesquelles une fonction run() doit être appelée le plus souvent possible (AccelStepper, oneButton)
− On peut aussi si on a un rendez vous mettre le téléphone à sonner. Ainsi on peut tranquillement faire autre chose. En terme de micro cela s'appelle un timer. C'est ce qui est fait avec SERVO. Supposons que l'on ait 3 servos qui demandent une impulsion de 1ms pour le premier, de 2ms pour le deuxième et de 1,5ms pour le troisième. Pendant que le programme tourne (il peut même utiliser un delay(10000); ) on fait:
− toutes les sorties des trois servo étant au départ à LOW, on passe la première sortie à HIGH on note que l'on est en train de s'occuper du premier servo, et on règle la minuterie (le timer) à 1ms. et on retourne à nos occupations.
− quand le timer sonne l'heure, le programme courant est interrompu, on repasse toutes les sortie à LOW (une seule au maxi en réalité), on passe la suivante à HIGH si il y en a une, et on remet le timer à 1ms 2ms 1,5msou 20ms-1ms-2ms-1,5ms suivant le cas.
C'est pour cela que l'on a besoin d'un timer. Cela permet que cette tâche s'exécute en arrière plan. On a donc l'impression que cela fonctionne tout seul.

Le timer utilisé par SERVO doit être capable de mesurer des temps entre 1ms et 19ms avec une "assez bonne" précision. A donc été choisi un timer 16 bits. C'est le timer 1 sur une Uno, et je crois le timer 5 sur une Mega.

Pour utiliser analogWrite, les circuits de la Mega sole font presque tout seul, il suffit de mettre les paramètres dans des registres. Mais ces circuits utilisent un timer. C'est comme servo, mais cela est câblé car c'est une utilisation courante.

Comme analogWrite demande une période fixe et que SERVO demande des temps différents (p ex 1ms 2ms 1,5ms ou 15,5ms) ils ne peuvent pas partager la même ressource.

Si servo n'utilisait pas de timer, on ne pourrait rien faire pendant que l'on envoie le signal. Mais le signal doit être envoyé en permanence.

On pourrait aussi créer le signal par PWM, c'est à dire utiliser la sortie du timer pour donner le signal au servo (période 20ms, impulsion de 1ms à 2ms), mais il faudrait un timer par servomoteur.


Par défaut pour moins de 12 servos, SERVO utilise le timer 5 ce qui rend les anaolgWrite impossibles sur les broches 38 à 40. Mais tu ne les utilisent pas. SERVO ne devrait pas dans ce cas poser problème.


Si on veut un bug de SERVO, on peut voir avec le fonctionnement que si on a 12 servos qui ont besoin de 2ms d'impulsions, la période ne peut plus être inférieure à 12x2ms sout 22ms au lieu des 20ms. Mais cela ne devrait pas gêner la plupart des servos.

D'après le dessin du montage, une alimentation 9V est en place. Le dessin montre une pile si c'est le cas sa durée de vie sera très faible et elle risque de ne pas pouvoir fournir assez de courant pour les moteurs.
Quoi qu'il en soit, je crois voir que la méga est alimentée en 9V et que le servo est alimenté en 5V via la carte mega. Si c'et le cas, tant que la bibliothèque servo n'est pas en place, il n'y a peut être pas d'impulsion sur la commande du servo et ce dernier ne sachant pas ou aller peut très bien ne pas bouger du tout et ne rien consommer. Quand SERVO est en place, il va nécessairement bouger à l'initialisation et consommer du courant. Mais le régulateur de la carte méga ne peut pas délivrer suffisamment de courant pour la carte Mega ET le servo, sa tension va chuter ce qui va planter la Mega.
On ne doit pas alimenter en 5V en sortie de la carte Uno ou Mega un "gros" consommateur (Ecran TFT, moteur, servo...) Il faut une alim externe. Dans ton cas si tu as besoin de 9V pour les moteurs CC et de 5V pour le servo, il faut soit utiliser deux alims (une de 5V et une de 9V) ou une de 9V et un régulateur externe (régulateur linéaire 7805 ou mieu un stpdown) pour passer du 9V au 5V.

Il est possible que si la Mega est relié par l'USB, que le courant du servo vienne de l'USB. L'USB peut souvent fournir ce courant, mais il n'y a pas de garantie.

c est une alimentation 12v /3A que j'utilise.
ce schema fonctionne tres bien.

/*  Arduino DC Motor Control - PWM | H-Bridge | L298N
Rajout d'un servo moteur pour simuler la porte etverifier comptabilité avec les moteurs A et B
*/
//#include <Servo.h>
#define in1A_MotorLeftA 26 
#define in2A_MotorLeftA 28 
#define enA_MotorLeftA 6  

#define in1B_MotorRightB 24 
#define in2B_MotorRightB 22
#define enB_MotorRightB 9  

int Speed_MotorLeftA = 0;
int Speed_MotorRightB = 0;

//Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  pinMode(enA_MotorLeftA, OUTPUT);
  pinMode(enB_MotorRightB, OUTPUT);

  pinMode(in1A_MotorLeftA, OUTPUT);
  pinMode(in2A_MotorLeftA, OUTPUT);
  pinMode(in1B_MotorRightB, OUTPUT);
  pinMode(in2B_MotorRightB, OUTPUT);

  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

//myservo.attach(13);  /

}

void loop() {

 /*for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
*/
  int xAxis = analogRead(A0); // Read Joysticks X-axis
  int yAxis = analogRead(A1); // Read Joysticks Y-axis

  int ySign = 1 ; // Identify if Y is move forward 1   or   move backward -1 ; will be used to accomodate speed of the wheels
  int UTurnAllowed = 0; // when Y is in neutral position and willing to make U turn without going forward or backgroud ; 0 for no UTurn, 1 for UTurn

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor Left A backward
    digitalWrite(in2A_MotorLeftA, HIGH);
    digitalWrite(in1A_MotorLeftA, LOW);
    // Set Motor Right B backward
    digitalWrite(in1B_MotorRightB, HIGH);
    digitalWrite(in2B_MotorRightB, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 470, 0, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  else if (yAxis > 550) {
    // Set Motor Left A forward
    digitalWrite(in1A_MotorLeftA, HIGH);
    digitalWrite(in2A_MotorLeftA, LOW);
    
    // Set Motor Right B forward
    digitalWrite(in1B_MotorRightB, LOW);
    digitalWrite(in2B_MotorRightB, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 550, 1023, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  // If Y axis of the joystick stays in neutral position then allow U Turn and reduce speed to zero
  else {
    // Autorize U Turn
    UTurnAllowed = 1;
    
    //Set PWM to zero
    Speed_MotorLeftA = 0;
    Speed_MotorRightB = Speed_MotorLeftA ;
  }



  // Sign of Y will be -1 if yAxis < 512   otherwise   Sign of Y will be +1 (default value)
    if (yAxis < 512) {
      ySign = -1 ;
    }
 
  // X-axis used for left and right control
    if (xAxis > 650) {  // Go to the left
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 650, 1023, 0, 255);
    if (UTurnAllowed == 1) { // Means Y is in neutral position
      Speed_MotorLeftA = xMapped ;
      Speed_MotorRightB = xMapped ;
      
      // Set Motor Left A backward
      digitalWrite(in2A_MotorLeftA, HIGH);
      digitalWrite(in1A_MotorLeftA, LOW);
      // Set Motor Right B forward
      digitalWrite(in1B_MotorRightB, LOW);
      digitalWrite(in2B_MotorRightB, HIGH);
    }
    else {
      // if ySign>0 THEN Move to left forward - decrease left motor speed, increase right motor speed    
      // if ySign<0 THEN Move right backward - decrease right motor speed, increase left motor speed
      Speed_MotorLeftA = Speed_MotorLeftA - xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB + xMapped*ySign;
    }
  }
  if (xAxis < 370) {  // Go to the right
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 370, 0, 0, 255);
    if (UTurnAllowed == 1) {  // Means Y is in neutral position
      Speed_MotorLeftA = xMapped;
      Speed_MotorRightB = xMapped;
      
      // Set Motor Left A forward
      digitalWrite(in2A_MotorLeftA, LOW);
      digitalWrite(in1A_MotorLeftA, HIGH);
      // Set Motor Right B backward
      digitalWrite(in1B_MotorRightB, HIGH); //////HIGH
      digitalWrite(in2B_MotorRightB, LOW);      
    }
    else {
      // if ySign>0 THEN Move right forward - decrease right motor speed, increase left motor speed
      // if ySign<0 THEN Move to left backward - decrease left motor speed, increase right motor speed    
      Speed_MotorLeftA = Speed_MotorLeftA + xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB - xMapped*ySign;
    }
  }
  
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  // Confine the range from Min 70 to Max 255
  if (Speed_MotorLeftA > 200) {
      Speed_MotorLeftA = 200;
  }
  if (Speed_MotorLeftA < 70) {
     Speed_MotorLeftA = 0;
  }
  if (Speed_MotorRightB > 200) {
      Speed_MotorRightB = 200;
  }
  if (Speed_MotorRightB < 70) {
     Speed_MotorRightB = 0;
  }

  
  

  // Send PWM signals
  analogWrite(enA_MotorLeftA, Speed_MotorLeftA); // Send PWM signal to Motor Left A
  analogWrite(enB_MotorRightB, Speed_MotorRightB); // Send PWM signal to Motor Right B
}

et celui fonctionne pas
pourtant je suis bien sur une pin pwn 13 et pas de probleme de timer sur celle la

le servo fonctionne mais la telecommande est KO et les moteurs se lancent mais anarchiquement

/*  Arduino DC Motor Control - PWM | H-Bridge | L298N
Rajout d'un servo moteur pour simuler la porte etverifier comptabilité avec les moteurs A et B
*/
#include <Servo.h>
#define in1A_MotorLeftA 26 
#define in2A_MotorLeftA 28 
#define enA_MotorLeftA 6  

#define in1B_MotorRightB 24 
#define in2B_MotorRightB 22
#define enB_MotorRightB 9  

int Speed_MotorLeftA = 0;
int Speed_MotorRightB = 0;

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  pinMode(enA_MotorLeftA, OUTPUT);
  pinMode(enB_MotorRightB, OUTPUT);

  pinMode(in1A_MotorLeftA, OUTPUT);
  pinMode(in2A_MotorLeftA, OUTPUT);
  pinMode(in1B_MotorRightB, OUTPUT);
  pinMode(in2B_MotorRightB, OUTPUT);

  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

myservo.attach(13);  // attaches the servo on pin 9 to the servo object    pb des que l'on attache le servo un moteur ne reponds plus
}

void loop() {

 for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

  int xAxis = analogRead(A0); // Read Joysticks X-axis
  int yAxis = analogRead(A1); // Read Joysticks Y-axis

  int ySign = 1 ; // Identify if Y is move forward 1   or   move backward -1 ; will be used to accomodate speed of the wheels
  int UTurnAllowed = 0; // when Y is in neutral position and willing to make U turn without going forward or backgroud ; 0 for no UTurn, 1 for UTurn

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor Left A backward
    digitalWrite(in2A_MotorLeftA, HIGH);
    digitalWrite(in1A_MotorLeftA, LOW);
    // Set Motor Right B backward
    digitalWrite(in1B_MotorRightB, HIGH);
    digitalWrite(in2B_MotorRightB, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 470, 0, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  else if (yAxis > 550) {
    // Set Motor Left A forward
    digitalWrite(in1A_MotorLeftA, HIGH);
    digitalWrite(in2A_MotorLeftA, LOW);
    
    // Set Motor Right B forward
    digitalWrite(in1B_MotorRightB, LOW);
    digitalWrite(in2B_MotorRightB, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    Speed_MotorLeftA = map(yAxis, 550, 1023, 0, 255);
    Speed_MotorRightB = Speed_MotorLeftA ;
  }
  // If Y axis of the joystick stays in neutral position then allow U Turn and reduce speed to zero
  else {
    // Autorize U Turn
    UTurnAllowed = 1;
    
    //Set PWM to zero
    Speed_MotorLeftA = 0;
    Speed_MotorRightB = Speed_MotorLeftA ;
  }



  // Sign of Y will be -1 if yAxis < 512   otherwise   Sign of Y will be +1 (default value)
    if (yAxis < 512) {
      ySign = -1 ;
    }
 
  // X-axis used for left and right control
    if (xAxis > 650) {  // Go to the left
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 650, 1023, 0, 255);
    if (UTurnAllowed == 1) { // Means Y is in neutral position
      Speed_MotorLeftA = xMapped ;
      Speed_MotorRightB = xMapped ;
      
      // Set Motor Left A backward
      digitalWrite(in2A_MotorLeftA, HIGH);
      digitalWrite(in1A_MotorLeftA, LOW);
      // Set Motor Right B forward
      digitalWrite(in1B_MotorRightB, LOW);
      digitalWrite(in2B_MotorRightB, HIGH);
    }
    else {
      // if ySign>0 THEN Move to left forward - decrease left motor speed, increase right motor speed    
      // if ySign<0 THEN Move right backward - decrease right motor speed, increase left motor speed
      Speed_MotorLeftA = Speed_MotorLeftA - xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB + xMapped*ySign;
    }
  }
  if (xAxis < 370) {  // Go to the right
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 370, 0, 0, 255);
    if (UTurnAllowed == 1) {  // Means Y is in neutral position
      Speed_MotorLeftA = xMapped;
      Speed_MotorRightB = xMapped;
      
      // Set Motor Left A forward
      digitalWrite(in2A_MotorLeftA, LOW);
      digitalWrite(in1A_MotorLeftA, HIGH);
      // Set Motor Right B backward
      digitalWrite(in1B_MotorRightB, HIGH); //////HIGH
      digitalWrite(in2B_MotorRightB, LOW);      
    }
    else {
      // if ySign>0 THEN Move right forward - decrease right motor speed, increase left motor speed
      // if ySign<0 THEN Move to left backward - decrease left motor speed, increase right motor speed    
      Speed_MotorLeftA = Speed_MotorLeftA + xMapped*ySign;
      Speed_MotorRightB = Speed_MotorRightB - xMapped*ySign;
    }
  }
  
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  // Confine the range from Min 70 to Max 255
  if (Speed_MotorLeftA > 200) {
      Speed_MotorLeftA = 200;
  }
  if (Speed_MotorLeftA < 70) {
     Speed_MotorLeftA = 0;
  }
  if (Speed_MotorRightB > 200) {
      Speed_MotorRightB = 200;
  }
  if (Speed_MotorRightB < 70) {
     Speed_MotorRightB = 0;
  }

 

  // Send PWM signals
  analogWrite(enA_MotorLeftA, Speed_MotorLeftA); // Send PWM signal to Motor Left A
  analogWrite(enB_MotorRightB, Speed_MotorRightB); // Send PWM signal to Motor Right B
}

@vileroi
Belle explication👍

hmmmm.
je ne saurais pas expliquer la différence entre les 2 montages, mais peux tu m'ôter un doute?

le L298N que je connais un peu (j'en ai 2 qui pilotent les moteurs de ma voiture télécommandée) a un fonctionnement un peu vicieux:
Si tu l'alimentes en moins de 12V, il est capable d'alimenter une carte arduino en 5V par sa sortie +5V.
Si tu l'alimentes entre 12 et 24V (il faut positionner un jumper), non seulement la sortie +5V n'est plus capable d'alimenter une arduino, mais en plus il faut ELLE l'alimenter en 5V, par exemple avec une sortie de la carte arduino.
De mémoire, en dessous de 12V d'alimentation, le L298N s'alimente lui même par ce biais. Au dessus, il a besoin de courant pour ses puces, le courant principal étant uniquement distribué sur les moteurs. J'ai eu l'occasion d'aider un membre du forum et c'était précisément ce point qui bloquait.
Une fois qu'il a passé un cable depuis la carte arduino vers la broche 5V du L298N, tout a tourné comme un charme.

Bon courage!

Dans le deuxième montage, le servo est alimenté via le régulateur de la Mega, non? On ne peut pas alimenter un moteur avec le régulateur.