Moteur DC qui fait un bruit ... normal ou pas ?

Portrait de Luke

Bonjour à tous !

Je met en pratique ce que j'ai appris des tutos fournis avec mon kit arduino, là j'ai un moteur DC alimenté par une pile 9V branchée sur la breadboard.

Je pilote la vitesse et le sens du moteur DC via un stick analogiue ( semblable aux manettes playstation ). J'utilise également un L293D ( je crois qu'on appelle ça un pont en H ).

J'utilise la PWM pour gérer la vitesse.

Quand le stick est à 0, le moteur se coupe, quand le stick est à fond j'envoi la valeur 255.Quand le stick est au milieu j'envoi 128 etc ... en PWM.

Bref le tout fonctionne très bien, donc je ne vais pas poster de schéma ni de code. ( sauf si besoin ).

Quand je pilote le moteur avec le stick analogique, j'entend un petit bruit, un genre de " signal " , un bip continu, qui vient du moteur. Ca le fait surtout quand le stick est en début de course. Plus j'enfonce le stick plus le bruit s'intensifie, puis disparait quand le moteur est à pleine vitesse.

Je précise également que j'ai quelques erreurs parfois quand j'upload mon code, je dois débrancher : rebrancher arduino.

Est-ce normal ou j'ai fait un mauvais branchement qui pourrait endommager mon matériel ?

Merci d'avance pour votre aide.

Portrait de Walter

Salut, je suppose que cela vient de la fréquence du PWM qui doit être faible.
Je pense qu'il faudrait soit utiliser un PWM plus rapide mais on restera toujours sous les 20kHz, tu utilise quelle broche de l'arduino ?
Soit ne pas descendre en dessous d'un certain ratio, commencer par exemple à 30%.

Ou encore faire les deux en même temps.

Portrait de Anonyme

Le pont en H n'est pas fait pour driver un moteur en PWM tout simplement ! Par contre on peut l'utiliser mais il faudrait avoir le code pour savoir s'il a été adapté à cette application hors norme ! Alors merci de donner le schéma et le code .

L'explication est dans ce document est là : pwm-et-ponts-en-h.rar

Pour modifier la fréquence du PWM d'un Arduino il faut utiliser le code ci-dessous :

/**
* Divides a given PWM pin frequency by a divisor.
*
* The resulting frequency is equal to the base frequency divided by
* the given divisor:
* - Base frequencies:
* o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
* o The base frequency for pins 5 and 6 is 62500 Hz.
* - Divisors:
* o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
* 256, and 1024.
* o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
* 128, 256, and 1024.
*
* PWM frequencies are tied together in pairs of pins. If one in a
* pair is changed, the other is also changed to match:
* - Pins 5 and 6 are paired on timer0
* - Pins 9 and 10 are paired on timer1
* - Pins 3 and 11 are paired on timer2
*
* Note that this function will have side effects on anything else
* that uses timers:
* - Changes on pins 3, 5, 6, or 11 may cause the delay() and
* millis() functions to stop working. Other timing-related
* functions may also be affected.
* - Changes on pins 9 or 10 will cause the Servo library to function
* incorrectly.
*
* Thanks to macegr of the Arduino forums for his documentation of the
* PWM frequency divisors. His post can be viewed at:
*/
void setPwmFrequency(int pin, int divisor) {
   byte mode;
   if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
      switch(divisor) {
         case 1: mode = 0x01; break;
         case 8: mode = 0x02; break;
         case 64: mode = 0x03; break;
         case 256: mode = 0x04; break;
         case 1024: mode = 0x05; break;
         default: return;
      }
      if(pin == 5 || pin == 6) {
         TCCR0B = TCCR0B & 0b11111000 | mode;
      } else {
         TCCR1B = TCCR1B & 0b11111000 | mode;
      }
   } else if(pin == 3 || pin == 11) {
      switch(divisor) {
         case 1: mode = 0x01; break;
         case 8: mode = 0x02; break;
         case 32: mode = 0x03; break;
         case 64: mode = 0x04; break;
         case 128: mode = 0x05; break;
         case 256: mode = 0x06; break;
         case 1024: mode = 0x7; break;
         default: return;
      }
      TCCR2B = TCCR2B & 0b11111000 | mode;
   }
}
Portrait de Luke

Ok merci pour vos réponses je vais jeter un oeil.

En attendant, voici mon schéma et le code :

d.jpg

/*--------------------------------------------------------------------------------------------
- DECLARATIONS -
---------------------------------------------------------------------------------------------*/

int ENABLE_MOTOR = 5;               // Port moteur
int RECULER = 4;                    // Sens reculer
int AVANCER = 3;                    // Sens avancer
int STICK_X = A0;                   // Port Stick analogique
int STICK_SW = 8;                   // Switch Stick analogique

int Speed;                          // Variable utilisée pour la vitesse

/*--------------------------------------------------------------------------------------------
- SETUP -
---------------------------------------------------------------------------------------------*/

void setup ()
{
  // pinMode(ENABLE_MOTOR, OUTPUT);         // On déclare les ports utilisés 
  pinMode(AVANCER, OUTPUT);
  pinMode(RECULER, OUTPUT);
  pinMode(STICK_SW, INPUT);
  pinMode(STICK_SW,HIGH);
  Serial.begin(9600);
  stopper();                                // Moteur éteint par défaut
}

/*--------------------------------------------------------------------------------------------
- LOOP -
---------------------------------------------------------------------------------------------*/

void loop ()
{
  WheelControl();                           // Fonction de contrôle du moteur
}

/*--------------------------------------------------------------------------------------------
- FONCTIONS -
---------------------------------------------------------------------------------------------*/

// Fonction avancer

void avancer (int Speed) {
  Speed = map(Speed, 0 , 509 , 255 , 0) ;
  analogWrite(ENABLE_MOTOR, Speed);           // On active le moteur à la vitesse souhaitée
  digitalWrite(AVANCER, HIGH);                // On définit le sens avancer
  digitalWrite(RECULER, LOW); 
}

/*--------------------------------------------------------------------------------------------*/
// Fonction reculer

void reculer (int Speed) {
  Speed = map(Speed, 515 , 1023 , 0 , 255) ;
  analogWrite(ENABLE_MOTOR, Speed);           // On active le moteur à la vitesse souhaitée
  digitalWrite(AVANCER, LOW);
  digitalWrite(RECULER, HIGH);                // On définit le sens reculer 
}

/*--------------------------------------------------------------------------------------------*/
// Fonction stopper

void stopper ()
{
   digitalWrite(ENABLE_MOTOR, LOW);           //On éteitnt le moteur
}

/*--------------------------------------------------------------------------------------------*/
// Fonction pour controller la roue

void WheelControl ()
{
  Speed = analogRead(STICK_X);              // On récupère la valeur de du stick analogique
  stopper();                                // Si le stick est au centre on stoppe
  Serial.println("Stop"); 
                                             
    while ( Speed < 510 )                   // Tant qu'il reste enfoncé on avance 
    {
      avancer(Speed);                       // Fonction qui permet d'avancer
      Serial.println("J'avance");
      Serial.print ("Speed = ");           
      Serial.print(Speed);  
      Speed = analogRead(STICK_X);          // Si la valeur change on la récupère
    }
                      
    while ( Speed > 514 )                   // Tant qu'il reste enfoncé on recule
    {
      reculer(Speed);                       // Fonction qui permet de reculer
      Serial.println("Je recule"); 
      Serial.print("Speed = ");             
      Serial.print(Speed);
      Speed = analogRead(STICK_X);          // Si la valeur change on la récupère
    }
}

En fait je veux faire comme sur cette vidéo-> https://www.youtube.com/watch?v=Qi6NCPpMs3k&list=PL5sYQxMUpgkO_FGrsMmfrqhBuZphBJ6uD&index=13

Mais avec un stick analogique à la place du potentiomètre.

Portrait de Anonyme

Ce code me paraît bien compliqué, je pense que les fonctions sont mal utilisées ce qui engendre certainement des problèmes.

Je n'ai pas le temps de m'en occuper plus avant mais je vais te proposer un code que je n'ai pas le temps de tester .

int ENABLE_MOTOR = 5;     // Port moteur
int RECULER = 4;                   // Sens reculer
int AVANCER = 3;                  // Sens avancer
int STICK_X = A0;                // Port Stick analogique
int STICK_SW = 8;               // Switch Stick analogique
int Speed;                                // Variable utilisée pour la vitesse

void setup () {
  pinMode(ENABLE_MOTOR, OUTPUT);         // On déclare les ports utilisés
  pinMode(AVANCER, OUTPUT);
  pinMode(RECULER, OUTPUT);
  pinMode(STICK_SW, INPUT);
  digitalWrite(STICK_SW, HIGH); // <<<<<<<<<<< Erreur chez toi !
  Serial.begin(9600);
}

void loop() {
  CalculVitesse();
  analogWrite(ENABLE_MOTOR, Speed);
  }

void CalculVitesse() {
  int PosStick = analogRead(STICK_X) - 512;
  if ((PosStick > -5) && (PosStick < 5)) { //Cela pour avoir une zone arrêt moteur moins sensible !
    Speed = 0;//
  }
  if (PosStick > 5) { // Entre +5 et 511
    digitalWrite(RECULER, LOW);
    digitalWrite(AVANCER, HIGH);
  }
  if (PosStick < -5) { // Entre -512 et -5
    digitalWrite(AVANCER, LOW);
    digitalWrite(RECULER, HIGH);
    PosStick = PosStick * -1;
  }
  Speed = map(PosStick, 5, 512, 0, 255);
}

Cela me semble plus simple, plus court et plus clair !