Pb pilotage moteur DC

Bonjour, j'ai créé un automatisme pour piloter l'ouverture / fermeture de mon poulailler. Ca fonctionne depuis un an environ avec de temps en temps des défauts que je ne comprends pas. J'ai passé un peu plus de temps pour analyser la situation et le moteur qui sert dans un sens pour l'ouverture et dans l'autre sens pour la fermeture, ne tourne pas toujours dans le sens voulu. Ca n'arrive pas souvent mais ça arrive. J'ai fait plusieurs tests. Le programme actuel fonctionne avec les deux sorties actiees (forward, backward). J'ai essayé de verrouiller le problème en n'acionnant que la sortie du sens voulu (forward ou backward), mais dans ce cas, le moteur ne tourne plus du tout, ni en envoyant une tension analogique sur l'une ou l'autre des broches pour piloter la vitesse. Donc je suis perdu. J'ai essayé de simplifier le programme pour ne garder que les parties qui concernent ce probleme. Voir ci dessous. Le problème est à la ligne 112 (14 lignes avant la fin) : analogWrite(analog_Out_moteur_ouverture, Output_Moteur_Ouverture); // On désactive le capteur ouverture (cable dans mauvais sens) là ou il y a un emoji. A cette commande, le moteur tourne quelquefois dans un sens, quelquefois dans l'autre

//#include <LiquidCrystal.h>

// Constantes Entrées Sorties Analogiques
const int analog_Out_moteur_ouverture = 11;  // Analog output pin that the LED Bleue is attached to (simul moteur ouverture)
const int analog_Out_moteur_fermeture = 10;  // Analog output pin that the LED Jaune is attached to (simul moteur fermeture)

// Constantes Sorties digitales
const int moteur_forward_ferme = 12;   // pin commande sens de rotation
const int moteur_backward_ouvre = 13;  // pin commande sens de rotation

// Constantes Entrees Digitales
const int fin_course_ouvert = 2;     // pin fin de course ouvert (trappe)
const int fin_course_ferme = 4;      // pin fin de course fermé (trappe)

// Constantes pour le programme
const int Output_Value_min = 100;               // valeur de démarrage moteur - 100 pour tige filetee - 60 pour gros tube ==> 80
const int Tempo_Time_out = 12000;               // Time out fermeture ou ouverture portillon ==> 12 secondes
const int Tempo_Time_out_ouv_lente = 25000;     // Time out ouverture lente portillon ==> 25 secondes
const int tempo_test_capt_o_f = 2000;           // Tempo test capteur ouv ferm         

// Variables discretes (booleen):
bool Etat_fin_course_ouvert;        // variable for reading etat fin de course ouverture
bool Etat_fin_course_ferme;         // variable for reading etat fin de course fermeture

// Variables entieres:
int Output_Moteur_Ouverture = 0;    // value output to the PWM (analog out)
int Output_Moteur_Fermeture = 0;    // value output to the PWM (analog out)

// Gestion du temps
unsigned long currentTime_1 = 0;  // Chrono LED moteur
unsigned long currentTime_2 = 0;  // Chrono time-out moteur

//Library version:1.1 Ecran LCD
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup() {
  // INITIALISATION

  // Initialisation Ecran LCD
  lcd.init();  // initialize the lcd

  // initialize the pushbutton pin as an input:
  pinMode(fin_course_ouvert, INPUT);     // pinMode (fin_course_ouvert, INPUT_PULLUP); // active la résistance interne de la broche concernée
  pinMode(fin_course_ferme, INPUT);      // pinMode (fin_course_ferme, INPUT_PULLUP); // active la résistance interne de la broche concernée

  // init sorties commande sens moteur
  pinMode(moteur_forward_ferme, OUTPUT);
  pinMode(moteur_backward_ouvre, OUTPUT);

  // init valeur sortie moteur
  digitalWrite(moteur_forward_ferme, HIGH);   // Autorise fermeture
  digitalWrite(moteur_backward_ouvre, HIGH);  //  Autorise Ouverture

  // Init sorties commande analogique moteur à 0
  Output_Moteur_Ouverture = 0;
  Output_Moteur_Fermeture = 0;
  analogWrite(analog_Out_moteur_ouverture, Output_Moteur_Ouverture);
  analogWrite(analog_Out_moteur_fermeture, Output_Moteur_Fermeture);
  //  
  // Lecture capteurs et initialisation valeur moteur
  Etat_fin_course_ouvert = digitalRead(fin_course_ouvert);
  Etat_fin_course_ferme = digitalRead(fin_course_ferme);
  Output_Moteur_Ouverture = Output_Value_min;  // Init waleur moteur
  // Portillon ouvert : il faut vérifier que le câble est dans le bon sens
  // On fait tourner le moteur un court instant pour desactiver capteur ouverture et donc verifier que le cable est dans le bon sens
  currentTime_2 = millis();  // Démarrage du chrono Time-out
  while (millis()-currentTime_2 <= tempo_test_capt_o_f) {
    lcd.setCursor(0, 1);
    lcd.print ("Fermeture lente ");   // affichage mode normal
    Output_Moteur_Fermeture = Output_Value_min;  // Démarrage moteur vitesse min
    analogWrite(analog_Out_moteur_fermeture, Output_Moteur_Fermeture);
  }
  // Time-out atteint, arret moteur
  Output_Moteur_Fermeture = 0; // arrêt moteur pour vérifier sens du cable 
  analogWrite(analog_Out_moteur_fermeture, Output_Moteur_Fermeture);
  delay (2000);
  Etat_fin_course_ouvert = digitalRead (fin_course_ouvert); // lecture etat capteur pour verifier décolement
  // 
  if (Etat_fin_course_ouvert == LOW) {    // le capteur est décollé ==> enroulement ok ==> on ouvre
    lcd.setCursor(0, 1);
    lcd.print ("Ouverture lente ");   // affichage mode normal
    //
    currentTime_2 = millis();  // Démarrage du chrono Time-out
    Output_Moteur_Fermeture = Output_Value_min;  // Démarrage moteur vitesse min // NEW
    while (Etat_fin_course_ouvert == LOW && (millis() - currentTime_2) < tempo_test_capt_o_f) {    // Boucle jusqu'à ouverture ou time-out
      analogWrite(analog_Out_moteur_ouverture, Output_Moteur_Ouverture);
      Etat_fin_course_ouvert = digitalRead(fin_course_ouvert);
    }
    analogWrite(analog_Out_moteur_ouverture, 0); // arrêt moteur
    lcd.setCursor(0, 1);  
    lcd.print ("Portillon ouvert");   // affichage mode normal
  }  
  else {                             // le capteur est toujours actif ==> défaut d'enroulement.
    // Il faut tourner dans l'autre sens (ouverture) pour fermer. D'abord réenrouler le cable O ==> F ==> O, puis fermer
    lcd.setCursor(0, 1);
    lcd.print ("Repar posit cabl");   // affichage mode normal
    repare_cable();       // re-enroule cable dans le bon sens    
  }
}

void loop() {
}

void repare_cable() {                   // Sous programme pour ré-enrouler le cable dans le bon sens
  //
  Output_Moteur_Ouverture = Output_Value_min;  // Démarrage moteur vitesse min
  // On décole le capteur ouverture
  delay(500);
  currentTime_2 = millis();  // Démarrage du chrono Time-out
  while ((millis() - currentTime_2) < tempo_test_capt_o_f) {
    analogWrite(analog_Out_moteur_ouverture, Output_Moteur_Ouverture);  // On désactive le capteur ouverture (cable dans mauvais sens).  :weary_face:
  }
  // Réenrouler cable dans le bon sens
  Etat_fin_course_ouvert = digitalRead (fin_course_ouvert);
  currentTime_2 = millis();  // Démarrage du chrono Time-out  
  while (Etat_fin_course_ouvert == LOW && (millis() - currentTime_2) < Tempo_Time_out_ouv_lente) {
    analogWrite(analog_Out_moteur_ouverture, Output_Moteur_Ouverture);  // Le portillon va se fermer puis s'ouvrir car le câble est dans le mauvais sens
    Etat_fin_course_ouvert = digitalRead (fin_course_ouvert);
  }
  Output_Moteur_Ouverture = 0;
  analogWrite(analog_Out_moteur_ouverture, Output_Moteur_Ouverture);  
}



Post mis dans la mauvaise section, on parle anglais dans les forums généraux, je viens de déplacer le post dans la section francophone.

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

bonjour,

Quel est le module interface de puissance ?
un schema ?

j'ai testé un module IBT2 24V pont MOSFET pour 2 sens de rotation
..mais avec un PIC18F
le sens de rotation du moteur peut etre definie aussi par l'ecart PWM1 PWM2 sur chaque commande left right.
L'arret doit etre validé avec les 2 PWM à zero
La commande Enable 1 ou 2 ne differencie pas la validité du sens de rotation
Enable 1 ou 2 actif quel que ce soit sens horaire ou trigo

Bonjour, merci pour votre aide. Le module est
DollaTek BTS7960 Module pilote de moteur haute puissance 5,5 V à 27 V 43 A
Quand je fais tourner dans un sens j'envoie une valeur (100 de memoire dans le programme) sur la sortie 10 ou 11 (RPWM ou LPWM), l'autre sortie étant à 0. Les deux sorties R-EN et L-EN (12 et 13) sont activées sinon le moteur ne tourne ni dans un sens, ni dans l'autre. Si un seul est High, le moteur ne tourne pas

D'apres ce que je comprends, Output_Moteur_Ouverture ne peut prendrfe que la valeur 0 ou 100
Output_Moteur_Ouverture est une consigne en %PWM, ou en point 0 à 1023 pour 0 à 100% ?
si la valeur est trop faible le moteur risque de caler

Risque de caler ou de ne pas démarrer.Ce qui peut arriver aussi, et c'est ce que j'ai actuellement avec un moteur DC (à vide je le précise) et un BTS7960, à priori le couple de démarrage n'est pas le même dans un sens ou dans l'autre, donc avec des PWM de faible valeurs, parfois il démarre bien dans les 2 sens, parfois il ne veut pas démarrer dans un sens.

Dans mon programme non simplifié, je démarre à 100 et j'accelere jusque 120. Ca fonctionne tres bien sauf que quelquefois ca part dans le mauvais sens

il démarre toujours, mais pas toujours dans le bon sens

Bonjour vincent5157
Serait-il possible d'avoir le schéma électrique ainsi que la partie mécanique. J'avoue que je ne comprends la nécessité de connaître le sens de l'enroulement du câble.
Dans le programme je ne vois pas la commande d'ouverture et de fermeture (BP, Horloge ...)
Ne voyez là aucune critique de ma part mais il y a beaucoup de chose dans le setup. Placer les actions dans des méthode séparées permet de gagner en clarté en peut faire justement ressortir plus facilement les aléas technologiques.

Cordialement

Pas de souci, c'est normal. Le schéma est très simple. C'est un module DollaTek BTS7960.
RPWM sur broche 10 de l'arduino Uno
LPWM sur broche 11
R-EN (forward enable) sur broche 12
L-EN (reverse enable) sur broche 13
R-IS et L-IS non câblés (alarmes)
VCC et GND
Pour la mécanique, c'est un moteur de perceuse que j'ai récupéré et qui enroule un câble pour ouvrir le portillon du poulailler. Lorsque le câble est enroulé, le portillon est ouvert. Déroulé : fermé. Si le câble est enroulé dans le mauvais sens (ça arrive) et que je commande la fermeture le moteur tire sur le câble au lieu de le dérouler. C'est pour cette raisin qu'à l'initialisation je vérifie la position du câble en commandant pendant un court instant la fermeture. Si le câble est dans le bon sens, le capteur de portillon ouvert passe à 0. Dans le cas contraire, le câble est dans le mauvais sens et je cherche à le remettre comme il doit être avec la commande ouverture (le câble va se dérouler puis se ré-enrouler jusqu'à ce que le portillon soit à nouveau ouvert mais câble dans le bon sens. J'espère que c'est clair

J'ai retiré le programme "loop" pour simplifier. La commande se fait avec un capteur de lumière. La nuit on ferme, le jour on ouvre

Le problème est là. Cela ne devrait jamais arriver.
Il n'y a aucune raison pour que le câble s'enroule dans le mauvais sens si le moteur s'arrête correctement lorsqu'il arrive aux butées haute et basse.

Bonjour
fdufnews a raison, le câble ne devrait jamais s’enrouler dans le mauvais sens. La seule raison serait que le moteur ne s'arrête pas sur les fins de courses.
Comme il s'agit d'un câble qui s'enroule sur une axe, la seule possibilité que je vois c'est un défaut sur la butée basse. Dans ce cas le moteur ne s'arrête pas, le câble s'enroule sur l'axe et la port remonte. Pour la butée haute le câble ne peut pas s'enrouler dans l'autre sens puisqu'il est bout de course.

Oui, c'est clair. Je ne connais pas ce module mais il y a un document qui me paraît bien expliquer son fonctionnement quant au sens de rotation et à la vitesse du moteur.

voir réponse commune avec af13

Merci à tous les deux. Vous avez parfaitement compris le fonctionnement du portillon. Oui, ça ne devrait pas arriver mais ça arrive quand même. Effectivement, quelquefois les poules déplacent des cochonneries qui bloquent la fermeture et le capteur fermeture ne s'active pas, le moteur continue à tourner et le cable s'enroule dans le mauvais sens et le portillon s'ouvre. J'ai pris en compte ce pb en mettant un time-out sur la fermeture. Si capteur pas atteint avant tant de temps ...
Il se peut donc que le problème que je recherche et que j'ai décrit dans mon premier post arrive aussi à un autre moment mais que je n'arrive pas à capter et identifier. Si vous avez des idées pour faire avancer l'analyse je suis preneur. Je pensais par exemple stopper le programme quand ça arrive et afficher l'état de plusieurs variables ou capteurs, mais dans ce cas le moteur va continuer à tourner et essayer d'arracher le portilon ...
C'est quand même bizarre qu'en executant plusieurs fois de suite le même programme, le moteur ne réagisse pas tout le temps de la même manière

Merci beaucoup pour cette documentation. Oui, c'est bien comme cela que je l'utilise saut que les enable ne sont pas cables sur 5V mais sont sur des sorties de l'arduino que j'active en debut de programme

Bonjour vincent5157

Quelle valeur de PULLUP externe as tu mis sur les pin:
Etat_fin_course_ouvert
et
Etat_fin_course_ferme

Cordialement
jpbbricole

bonjour,

Quel raport de diametre d'enroulement du cable entre le debut et la fin ?
comment le moteur deroule le cable ?
c'est un enrouleur de cable de type aspirateur
le cable rentre des qu'on ne tire plus dessus ou qu'on le lache ?

Voilà qui est plus clair et qui corrobore un peu nos suppositions.

Il faudrait déjà résoudre le problème d’activation des capteurs. Nettoyer les salissures étant une option à bannir, je ne vois qu’une solution. Revoir le système de fermeture.

Par exemple vous pouvez fermer la porte horizontalement et non verticalement en plaçant le mécanisme de glissière sur la partie supérieure.

Ou alors opter pour un mouvement rotatif, avec un entraînement par courroie pour réduire la vitesse de rotation de la porte.

Quoiqu’il en soit, tant que vous n’êtes pas assuré d’atteindre les fins de courses vous aurez toujours des problèmes, quelque soit le mécanisme employé.