[Resolu] Contrôle moteur DC

Bonjour,

J' aurais besoin de vos lumieres :slight_smile:
J'arrive à controler simplement la vitesse d'un simple moteur DC(ventilo PC) en lisant la valeur analogique d'un potentiometre et en faisant un analogwrite sur la base d'un transistor de puissance pour alimenter le moteur, aucun probleme la vitesse varie bien.
Ce que je ne comprend pas c'est qu' avec ce meme analogwrite mais un faisant varier la valeur en entrée entre 0 et 1023 avec une telecommande IR( touche forward augmente la valeur, touche backward la diminue) ca ne fonctionne pas, le moteur tourne a fond ou stoppe il n' y a aucune variation de vitesse !
Si quelqu'un a une idée ?

Merci beaucoup,

Fabrice

Pas de code, pas de chocolat !

Oups désolé :slight_smile:

Bon y a pas de secret ce code vient d'un projet deja existant sur le net, j'en ai d'autres équivalents et j'ai aussi remodelé mon propre code mais à la base c'est celui-ci:

/*

*/

#include <IRremote.h>

int RECV_PIN = 8; // IR Receiver - Arduino Pin Number 8
int pwmPin = 7; // Arduino Pin Number 7 to the Base of the Transistor
int pwmValue;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup() {
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode( pwmPin, OUTPUT);
pwmValue = 0; // Starts the program with turned off motor
}

void loop() {

if (irrecv.decode(&results)) {

analogWrite(pwmPin, pwmValue);

if (results.value == 0xAFAF8374) { // PLAY Button
pwmValue = 255; // 100% Duty Cycle | Max Speed
}
if (results.value == 0x98519C65) { // STOP Button
pwmValue = 0; // 0% Duty Cycke | Turned off
}
if (results.value == 0x93F1BA08) { // FORWARD Button
if(pwmValue <= 245){
pwmValue = pwmValue + 10; // Increases the Duty Cycle of the PWM Signal
delay(20);
}
}
if (results.value == 0x71D086FF) { // BACKWARD Button
if(pwmValue >= 20){
pwmValue = pwmValue - 10; // Decreases the Duty Cycle of the PWM Signal
delay(20);
}
}
Serial.print(pwmValue);
Serial.print(" ");
Serial.println(results.value, HEX);

irrecv.resume(); // Receive the next value
}
delay(100);
}

Malheureusement ni celui-la ni aucun autre ne fonctionne.
Et pourtant le bete code simple pour varier la vitesse avec un potar fonctionne tres bien :

const int transistorPin = 3; // connected to the base of the transistor

void setup() {
Serial.begin(9600);
Serial.println("Allumage moteur");
// set the transistor pin as output:
pinMode(transistorPin, OUTPUT);
}

void loop() {
// read the potentiometer:
//int sensorValue = analogRead(A0);
int sensorValue = 100;
Serial.println(sensorValue);
// map the sensor value to a range from 0 - 255:

int outputValue = map(sensorValue, 0, 1023, 0, 255);
// use that to control the transistor:
analogWrite(transistorPin, outputValue);
}

Ce n'est pourtant qu' un simple analogWrite au départ, sauf que la on convertit la valeur du potentiometre et ca marche, alors que l'autre est le meme analogWrite mais la valeur injectée est codée suivant la touche de la télécommande IR, logiquement ca devrait fonctionner pareil?

Salut;

J'ai rencontré un problème similaire il n'y a pas très longtemps.

Essais de brancher ton moteur sur une broche par exemple la 9 prévu a cette effet (PMW) elles sont repéré avec ce symbole "~".
Tu devrais utiliser la broche 2 pour le récepteur IR.

Une fois la librairie IR activer les broches non repérées de ce symbole fonctionnent en tout ou rien.
Cela est du d’après se que j'en est compris a l’activation des interruption qui modifie le comportement des broches.

A plus !

Tu as certainement déjà vérifié que les codes des touches de la télécommande sont bons ...

Ajoutes des serial.print dans chaque test pour vérifier si tu y entres ...

Ps : dans l'avenir il faut mettre ton programme entre les balises (icône </>)

Désolé pour les balises je suis nouveau sur le site.

J'ai mis des serialprint a divers endroits pour verifier et les valeurs sont correctes.
Ok je peux essayer la broche 2 pour irrecv.enableIRIn mais j' ai deja essayé plusieurs broches ca ne change rien et la lecture du code de la télécommande fonctionne bien, oui bien sur j'ai les codes des touches :slight_smile:
Les pins PWM sont normalement la 3,5,6,9,10 et 11 avec des frequences différentes ca vient peut etre de la, mais la aussi j'ai testé differentes pins ~ mais ca ne change rien ca reste toujours en tout-ou-rien.

Je dois avouer que la je cale je ne vois pas quelle est la subtilité qui fait que ca ne marche pas.

Au niveau du moteur j'attaque directement la base du transistor (normal ou MOSFET ca marche aussi) je sais que c'est pas tres propre et qu'il faudrait un circuit de filtrage pour attaquer le transistor mais bon pour un 1er essai ca fonctionne quand meme, avec la version potentiometre en tout cas.

Je pense que ca doit venir de la au niveau de l'attaque du transistor qui ne se fait pas correctement mais je n'ai pas particulierement de grandes connaissances en électronique pure.

Salut ;

int RECV_PIN = 8; // IR Receiver - Arduino Pin Number 8
int pwmPin = 7; // Arduino Pin Number 7 to the Base of the Transistor
int pwmValue;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode( pwmPin, OUTPUT); 
  pwmValue = 0; // Starts the program with turned off motor
}

Tu devrais déclarer tes broche en constante "const int"
Pourquoi avoir déclaré une variable pwmValue puis l'initialisé à 0 au lancement programme ? Elle serra automatiquement initialisé à 0 par ton programme sauf si tu stock sa valeur dans la mémoire de l'ARDUINO. Ce qui n'est pas le cas de ton programme. tu peux supprimer cette variable et la déclaré dans la fonction "LOOP" (en local).

je vais tester ton programme.

A plus !!

Petit conseil.

Essais de structurer ton programme.
Dans le setup effectue des test de configuration.

Dans le setup tu configure ensuite tu initialise et enfin tu test.

Pour ton moteur = configure la sortie de pilotage en suite tu initialise les valeur utile a son fonctionnement si nécessaire et ensuite tu test le fonctionnement du moteur pour garantir que tout est bien configuré et bien branché. Cela t'évitera de chercher des erreurs dans ton programme quant celles ci proviennent du matériels.

Ton PC fait la même chose au démarrage.

A plus!!

Essais ce programme SETUP avec la broche 4 puis avec la broche 5.

/*
    Controlling a DC Fan Speed with a TV Remote

    Modified IRrecvDemo example from Ken Shirriff IRremote Library
    Ken Shirriff
    http://arcfn.com

    Modified by Dejan Nedelkovski,
    www.HowToMechatronics.com

*/

#include <IRremote.h>

//Déclaration des variables d'equipements.
const int ir = 2; // IR Receiver - Arduino Pin Number 8
const int moteur = 4; // Arduino Pin Number 7 to the Base of the Transistor

//Declaration des variable fonctionnelles.
float pmw;
int on;
float plus;
float moins;

//Déclaration de l'objet "irRecept" pour traitement de la reception signal.
IRrecv irRecept(ir);
//Déclaration de l'objet "ret_val_ir" pour le traitement du retour signal.
decode_results ret_val_ir; // ---* /

void setup() {
  //----Configuration du port serie.
  Serial.begin(9600);

  //---- Configuration de l'infra rouge.
  irRecept.enableIRIn();//--*/

  //---- Configuration de la broche de pilotage moteur.
  pinMode( moteur, OUTPUT);//Broche de pilotage moteur (PMW).

  //Test configuration.
  //Moteur.
  for (int i = 0; i < 254; i++) {
    analogWrite(moteur, i);
    delay(10);
  }//fin de for
  digitalWrite(moteur, LOW);

  //Moniteur
  Serial.println ("Projet pret");

}//Fin de setup.

Essai de piloter ton montage avec ce bout de programme.
Le moteur devrais tourner de plus en plus vite.
J'ai fait des test avec une led et ça fonctionne => broche 4 tout ou rien broche 5 pmw.

A plus!!

J'ai testé ton programme sans rien y changer sauf les commandes.

Les pins PWM sont normalement la 3,5,6,9,10 et 11 avec des frequences différentes ca vient peut etre de la, mais la aussi j'ai testé differentes pins ~ mais ca ne change rien ca reste toujours en tout-ou-rien.

J'ai constaté ton problème en utilisant la broche 4.
J'ai ensuite changé de broches (la 5) et ça "fonctionne" en pwm.

Change de broche !!

A plus !!

Salut;

Je me suis mise à l'exercice de ton projet et voici le code que je te propose.

Bon y a pas de secret ce code vient d'un projet deja existant sur le net, j'en ai d'autres équivalents et j'ai aussi remodelé mon propre code mais à la base c'est celui-ci:

Tu devrais essayer de faire ton propre programme avec tes propre méthodes ca te permet d'évoluer dans la compréhension du langage C.

Voici comment je programme.
Ça fait deux an que je me suis mis a la programmation et je n'ai pas encore la maitrise des outils qui rendrais mes programmes optimale. Mais je m’efforce de monter des programmes structuré sur mes petites bases en C.

/*Proposition de programme de gestion d’équipements par infra rouge (IR).
  Par manumanu forum ARDUINO le 05/03/2016.
 */

/*Déclaration de la librairie utile a l'infrarouge (IR).
  https://github.com/z3t0/Arduino-IRremote
  Version - 2.1.0*/
#include <IRremote.h>
#include <IRremoteInt.h>


//--------Déclaration des variables d’équipements--------.
//Déclaration et affectation d'une variable a la broche du capteur IR.
const int ir = 2;       //Broche du capteur.
//Déclaration et affectation d'une variable a la broche de pilotage moteur.
const int moteur = 5;   //Broche de pilotage.

//--------Affectation des variables d'exploitation des commandes de fonctions de IRremot.h.
//Affectation de l'objet "irRecept" pour traitement de la réception signal.
IRrecv irRecept(ir);        //Affectation d'un mnémonique.
//Affectation de l'objet "ret_val_ir" pour le traitement du retour signal.
decode_results ret_val_ir;  //Affectation d'un mnémonique.


//--------Déclaration des variables fonctionnelles--------.
//---Variable moteur.
float pmw;      //Consigne.
//---Variable de commandes => fonction IRcode();.
int on;         //Mise en service ou arrêt.
float plus;     //Augmentation de la consigne.
float moins;    //Diminution de la consigne.

void setup() {//Setup ----------------------------------------------------------------------------------------------SETUP.
  /*======= Configuration ======*/
  //---- Port série.
  Serial.begin(9600);//Vitesse (débit).

  //---- Infra rouge.
  irRecept.enableIRIn(); // Paramètre pour la réception.

  //---- Broche de pilotage moteur.
  pinMode( moteur, OUTPUT);//Broche de pilotage moteur (PMW).

  /*======= Initialisation ======*/
  //Pas utile.

  /*======= Test Configuration ======*/
  //---- Moteur.
  for (int i = 0; i < 254; i++) { //Boucle de test moteur
    analogWrite(moteur, i);       //Incrémentation de la vitesse moteur.
    delay(10);                    //Arrêt programmé = cadence l'évolution.
  }//fin de for
  digitalWrite(moteur, LOW);      //Arrêt du moteur.

  //---- Moniteur
  Serial.println ("Projet pret"); //Affichage d'un message de confirmation de fin de SET UP.

}//Fin de setup.----------------------------------------------------------------------------------------------- Fin de SETUP

void loop() {//Loop ----------------------------------------------------------------------------------------------LOOP
  delay(150);
  //=========Reception signal IR=============//
  while (irRecept.decode(&ret_val_ir)) {       //Boucle de contrôle de la condition de réception
    Serial.println(ret_val_ir.value, HEX);     //Affichage de la réception en hexadécimal.
    //-----Aplication de la fonction.
    irRecept.resume();                         //Prépare la prochaine valeurs de réception signal.
    IRcode();                                  //Appel de la fonction de décodage des commandes.
  }//Fin de while.

  analogWrite(moteur, pmw);                    //Action finale du programme => Commande du moteur (PMW).
  Serial.print ("consigne loop : "); Serial.println (pmw); //Affichage du résultat au moniteur série.
}//Fin de loop.----------------------------------------------------------------------------------------------- Fin de LOOP

//////////////////////////////////// Fonction IRcode //////////////////////////////////
void IRcode() {
  switch (ret_val_ir.value) { // Actualise la donnée reçu de IR.

    //Traitement de la donnée actualisée en fonction des cas préprogrammé.
    case 0xFFA25D: //Commande de mise en service.
      Serial.println("=========================== power ON / OFF");//Affichage pointeur de la commande.
      on++ ;       // Changement d'état (transitoire) de la variable.
      set_reset(); // Appel de la fonction set_reset().
      break;

    case 0xFF906F: //Commande + .
      Serial.println("=========================== + ");//Affichage pointeur de la commande.
      plus++;      // Changement d'état (transitoire) de la variable.
      set_reset(); // Appel de la fonction set_reset().
      break;

    case 0xFFA857: //Commande - .
      Serial.println("=========================== - ");//Affichage pointeur de la commande.
      moins++;     // Changement d'état (transitoire) de la variable.
      set_reset(); // Appel de la fonction set_reset().
      break;

    /*RESERVE
      case 0x: //Commande ??? .
      Serial.println("=========================== - ");//Affichage pointeur de la commande.
      ______++;     // Changement d'état (transitoire) de la variable par ++.
      set_reset(); // Appel de la fonction set_reset().
      break;

      case 0x: //Commande ??? .
      Serial.println("=========================== - ");//Affichage pointeur de la commande.
      ______++;     // Changement d'état (transitoire) de la variable par ++.
      set_reset(); // Appel de la fonction set_reset().
      break;
      FIN DE RESERVE*/

    default:
      Serial.println("========");
  }
}//////////////////////////////////// FIN DE IRcode //////////////////////////////////

/////////////////////////////////// Fonction set_reset //////////////////////////////////
void set_reset() {

  /*Par principe du front montant d'une commande ou d'un bouton poussoir.
    Première impulsion = mise en service.
    Seconde impulsion = mise hors service.
    Deux état possibles; 0 ou 1 en sortie de fonction.*/

  //=========================== Commande ON / OFF ===========================
  if (on != 0) {            //Contrôle le front montant de la commande donnée "on".
    if ( on == 1) {         //Si "on" est égale à 1.première commande.
      Serial.println("ON :");
      on = 1;               // "on" passe à 1 => Mise en service.
    }

    if (on == 2) {          //Si "on" est égale à 2.Deuxième commande.
      on = 0;               // "on" passe à 0 => Mise hors service.
      Serial.println("OFF :");
      pmw = 0;              //Remise a zéro de la commande.
    }
    //Serial.print(set); Serial.println(); //Contrôle de l'état de service ON/OFF. ==> Test.
  }//=========================== Fin de ON / OFF ===========================//

  /*------------------------------Gestion des commandes-------------------------------
    Par principe du front montant d'une commande ou d'un bouton poussoir.
    Incrémentation ou décrémentation de 25.5 point représentant le dixième du signale PMW de 255 points.
    Soit 10 imputions*/

  //===========================// Commande + //===========================//
  if (plus != 0) {          //Controle le front montant de la commande "+".
    pmw = pmw + 25, 5;      //Incrémentation 1/10em.
    Serial.print("Commande moteur :"); Serial.println(pmw);
  }
  plus = 0;                 //Remise a zéro de la commande.
  //=========================== Fin de + ===========================//

  //===========================// Commande - //===========================//
  if (moins != 0) {         //Contrôle le front montant de la commande "-".
    pmw = pmw - 25, 5;      //Décrémentation 1/10em.
    Serial.print("Commande moteur :"); Serial.println(pmw);
  }
  moins = 0;                //Remise a zéro de la commande.
  //=========================== Fin de - ===========================//
  
  /*Empêche le dépassement de la consigne à plus de 255*/
  pmw = constrain(pmw, 0, 255); // Mise en butée de la consigne.
}//////////////////////////////////// FIN DE set_reset //////////////////////////////////

Je suis plutôt d'avis de laisser faire mais la voilà !!

A plus!!

Bonjour Manumanu et les autres :wink:

Génial, ca marche !!!

Ca venait simplement du choix de lin pin pwm ou le code que j'avais était très pourri?

En tout cas merci beaucoup et ton code est absolument superbe de clarté et d' efficacité :slight_smile:

J'en profite pour te demander que contient la librairie IRremoteInt.h par rapport à IRremote.h ?

Et que fait pmw = pmw - 25, 5; dans la fonction set_reset() ?
Evidemment elle incrémente par pas de 25 oui mais a quoi sert le ", 5" à la fin ?

J'ai honte et mes questions semblent stupides mais je débute :slight_smile: et heureusement que les forums existent pour les cas comme moi :wink:

D'ailleurs je présente mes hommages à tous les membres et administrateurs qui nous donne la possibilité de partager toutes ces informations de manière aussi ludique que pratique.

Fabrice

J'avais oublié: pour la partie puissance j'utilise un IRF630 ou IRF740 de récupération, ca ne craint rien pour l' arduino?

Salut CelticLord;

Non ton code n’était pas pourrir !! Avec l’expérience tu vas apprendre a faire des codes par toi meme !!
J'ai commencé aussi en décortiquant des exemples. :wink:
C'est juste le choix de la broche de sortie qui n'allait pas.

J'avais oublié: pour la partie puissance j'utilise un IRF630 ou IRF740 de récupération, ca ne craint rien pour l' arduino?

Si la puissance ne traverse pas directement l'ARDUINO non tu ne craint rien.
Je ne connait pas les IRF630 ou IRF740

J'ai honte et mes questions semblent stupides mais je débute et heureusement que les forums existent pour les cas comme moi

Toute questions doit être posé si l' metteur estime en avoir besoins. Aucune question est stupide.
Est stupide celui qui a peur de le paraitre.

Et que fait pmw = pmw - 25, 5; dans la fonction set_reset() ?
Evidemment elle incrémente par pas de 25 oui mais a quoi sert le ", 5" à la fin

J'ai divisé le signale de sortie (PWM) par dix ce qui donne 25.5 points. les 5 dixième servent serve a avoir un chiffre juste pour un pas sur deux. 25.5 => premier pas 50 deuxième pas. pour fini a une valeur maxi à 255 pile.

A plus!