[résolu] entrée qui crame

Bonjour et meilleurs vœux à tous,

J'ai un système automatique de portail dont la carte électronique est HS.

J'ai entrepris de la refaire avec un arduino nano pour ouvrir et fermer une porte cochère en ajoutant un verrouillage porte fermée en haut et en bas et une surveillance du courant moteur pour arrêter indépendamment chaque moteur en cas de surcharge.

Au départ avec des ponts H mosfet, mais mon programme n'étant pas encore au point, j'ai cramé plusieurs transistors. Du coups, je suis passé à une commande par relais.

Je surveille le courant par une résistance en série avec chaque moteur de 0,1 ohm. Comme le courant maximal est de 8 ampère, on mesure au maximum 0.8 V aux bornes de ces résistances et donc aux entrées du nano. Pourtant j'ai cramé 2 entrées.
A4 cramé, j'ai déplacé en A7, grillée aussi.

J'ai pensé à l'extracourant de rupture aux bornes du contact du relais que je n'avait pas protégé.

Je pense donc ajouter une diode de roue-libre plus une diode à pointe aux bornes de l'entrée (j'en ai qui commencent à conduire à 0.8 V), comme sur le schéma que j'ai griffonné, qu'en pensez vous ? (original à gauche, modification à droite)

Pour éviter les "delay()" incompatibles avec la surveillance des moteurs, j'ai utilisé une librairie séquenceur pour ne pas m'embrouiller avec millis(), ça facilite énormément à mon niveau de débutant tardif...

L'état actuel du programme :

//*
   Porte droite ne s'arrete pas
*/

//#include <LowPower.h>
#include <Servo.h>
#include "simpleBouton.h"
#include <ScheduleTable.h>

SchedTable<8> ouvrePorte(5500);
SchedTable<5> fermePorte(4500);
//SchedTable<3> fermePorte(500);
//SchedTable<2> fermedroite(1000);
SchedTable<2> Signal(15, 80);//2 actions dans table de 10 unités de 100 ms
SchedTable<2> batFaible(40, 50);//2 actions dans table de 20 unités de 100 ms
SchedTable<4> verrouBas(1600);

// pins
simpleBouton boutonF(2);//contact fermeture télécommande
simpleBouton bouton(3); //contact ouverture + bouton porte
const int pinPF = 4 ;//contact fin de course porte fermée
const int pinLED = 5;
const int pinAs = 6; //alim des servos
Servo servoB;  // pin 7 servo haut inversion erreur
Servo servoH;  // pin 8 servo bas
const int pinF2 = 9; // relais inverseur gauche
const int pinD = 10; // moteur D
const int pinF1 = 11; // inverseur moteur D
const int pinG = 12; // moteurG
const int pinPO = 13; // contact fdc porte ouverte
const int pinbat = A6 ; // contrôle batterie
const int pinI2 = A5 ; // courant moteur 2
const int pinI1 = A7 ; // courant moteur droit

// états
bool demarreD = false; // rotation moteur 1
bool demarreG = false; // rotation moteur 2
bool action = false; // au repos
bool clos = false; // fermé
bool ouvert;
bool verrou; // 1 en fin de fermeture 0 après verouillage
bool fermeture;
bool ouverture;

// variables
unsigned long chrono; // temps intermédiaire
int iD; //courant moteur droit (résistance 0.1 ohm)
int iG; // gauche
int In = 100; // 4 A  ; maxi plus de 7  A; normal=0.8 A;
int niveauBat;
int Vbat;
int Vn = 590; // tension < 23v, déchargée ou moteurs bloqués
int Vdem = 500;// démarrage 19.4 V protection batterie basse

void setup() {
  Serial.begin(9600);
  pinMode(pinLED, OUTPUT);
  pinMode(pinF2, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(pinF1, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinAs, OUTPUT);
  pinMode(pinPF, INPUT_PULLUP);// contact porte fermée
  pinMode(pinPO, INPUT_PULLUP);// contact porte ouverte

  ouvrePorte.at(1,    [] { ouverture = true; Signal.start(); servoB.attach(7); servoH.attach(8); } );
  ouvrePorte.at(100,  [] { servoH.write(0); } );
  ouvrePorte.at(100,  [] { servoB.write(0); } );
  ouvrePorte.at(1200, [] { digitalWrite(pinD, HIGH); demarreD = true; } );
  ouvrePorte.at(1500, [] { demarreD = false; servoH.write(170); } );
  ouvrePorte.at(2500, [] { servoB.detach(); servoH.detach(); } );
  ouvrePorte.at(5000, [] { digitalWrite(pinG, HIGH); demarreG = true; } ); //
  ouvrePorte.at(5400, [] { demarreG = false; } );

  fermePorte.at(1,    [] { digitalWrite (pinF2, 1); digitalWrite (pinF1, 1);});
  fermePorte.at(100,  [] { demarreG = false; digitalWrite (pinG, 1);}); //démarre moteur gauche
  fermePorte.at(400,  [] { demarreG = true;});
  fermePorte.at(4100, [] { demarreD = false; digitalWrite (pinD, 1);}); //démarre moteur droit
  fermePorte.at(4400, [] { demarreD = true;});
/*
fermePorte.at(1,    [] { fermeture = true; Signal.start(); digitalWrite (pinF2, 1); digitalWrite (pinF1, 1);});
  fermePorte.at(100,  [] { digitalWrite (pinG, HIGH); demarreG = true;}); //démarre moteur gauche
  fermePorte.at(500,  [] { demarreG = false;});

  fermedroite.at(300, [] { digitalWrite(pinD, HIGH); demarreD = true;}); //démarre moteur droit
  fermedroite.at(700, [] { demarreD = false;});
*/
  Signal.at(5, [] { digitalWrite(6, HIGH); });// pinAS
  Signal.at(6, [] { digitalWrite(6, LOW); });


  batFaible.at(5, [] { digitalWrite(6, HIGH); });// pinLED
  batFaible.at(6, [] { digitalWrite(6, LOW); });

  verrouBas.at(1,    [] { servoB.attach(7); });
  verrouBas.at(100,  [] { servoB.write(170);}); //démarre moteur gauche
  verrouBas.at(1000, [] { servoB.detach(); fermeture = false; Signal.stop();});
}

void loop() {
  ScheduleTable::update();
  static bool armement = false;
  bouton.actualiser();
  boutonF.actualiser();// bouton fermeture
  clos = digitalRead(pinPF);
  ouvert = digitalRead(pinPO);
  niveauBat = analogRead(pinbat); //

  iG = analogRead(pinI2);
  if (!demarreG && (iG > 105))//5 A
  {
    digitalWrite (pinG, 0);// arrêt moteur 1
    digitalWrite (pinF2, 0);// inverseur 1
    demarreG = false;
    fermePorte.start(1);
  }

  iD = analogRead(A7);
  if ((iD > 90) && !demarreD)//3.4 A
  {
    digitalWrite (pinD, 0);// arrêt moteur 1
    digitalWrite (pinF1, 0);// inverseur 1
    demarreD = false;
  }

  if (!demarreD || !demarreG)// Surintensitée hors démarrage moteur
  {
    if (niveauBat < 590)arret(); // < 23 v = batterie défectueuse
  }

  if (!action) // au repos
  {
    if (boutonF.vientDEtreEnfonce())
    {
      action = true;
      fermePorte.start(1);//via la télécommande
    }

    if (bouton.vientDEtreEnfonce())
    {
      action = true;
      ouvrePorte.start(1);//via la télécommande et bouton
    }

    if (!clos) //porte fermée, verrous fermés
    {
      // niveauBat = analogRead(pinbat); // vérifié porte fermée
      // if (niveauBat < 590)batFaible.start();// < 23 v = batterie défectueuse
    }

  }//fin !action

  else if (action)// portes en action
  {
    if (bouton.vientDEtreEnfonce() || boutonF.vientDEtreEnfonce())
    {
      action = false;// retour au repos
      arret();// arret d'urgence
      //LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
    }

  if (iG > 20)
  {
    Serial.print(" iG : "); Serial.print(iG); Serial.print(" iD : "); Serial.print(iD);
    Serial.println();
  }

    if (!clos && fermeture) // verrouillage porte fermée
    {
      verrouBas.start(1);
    }

    if (ouverture && !ouvert)// arrêt porte gauche ouverte
    {
      Signal.stop();
      ouverture = false;
    }

  }// fin action
} // end of loop

void arret() {
  ouvrePorte.stop();
  fermePorte.stop();
  digitalWrite (pinD, 0);// moteur 1
  digitalWrite (pinF1, 0);// inverseur 1
  digitalWrite (pinG, 0);// moteur 2
  digitalWrite (pinF2, 0);// inverseur 2
  Signal.stop();
}// fin stop()

bonjour

normalement la diode de roue libre est branché en paralléle sur une """inductance"""
donc la ,par définition c 'est pas une roue libre...

laisse tomber ton montage,
il y a beaucoup mieux maintenant pour 2 euros !

Merci pour vos réponses.

OK PBZOOM mais un moteur universel reste une grosse inductance et à la coupure d'alimentation, avec l'inertie il va se transformer en générateur de tension inverse pendant quelques millisecondes. La diode devrait encaisser le courant et réduire la tension à 0.7 V. Je pense que la "roue libre" est encore plus valable, non ?

C'est probablement avec cette surtension inverse que j'ai cramé les entrée du nano. Du coups l'ajout de la diode aux bornes de l'entrée est superflue ?

roro_manche:
laisse tomber ton montage,
il y a beaucoup mieux maintenant pour 2 euros !

Je connais et j'économise 4 roros. De plus j'aime bien comprendre le pourquoi du comment :wink:

L'avantage du transistor sur le relais c'est que l'on peut piloter le moteur en PWM et le faire ralentir en approchant de la butée et par là même ne pas le couper alors que le courant est maximum.

Un truc m'interpelle. La porte je suppose qu'elle doit s'ouvrir et se fermer donc il doit y avoir une inversion de la tension aux bornes du moteur. C'est fait au plus prêt du moteur au-dessus du relais?

Ce que veut dire PBZOOM c’est que ta diode n’est pas au bon endroit, il faut la mettre en parallèle de ton inductance pour protéger. Pas en parallèle de ce que tu veux protéger.

Ici ton inductance c’est ton moteur, donc place ta diode non pas en parallèle du contact mais du moteur.

Le montage d'une diode de roue libre c'est en inverse sur le moteur.

Quand le moteur est coupé il change de mode de fonctionnement et passe en mode génératrice mais surtout à la coupure du courant il se produit une tension "de Lentz" qui peut atteindre des centaines de volts.

C'est cette tension, qui produit des arcs électriques dans le transistor de commande, qu'il faut court-circuiter à la base c'est à dire directement aux bornes du moteur.

Comme ta diode est placée elle sera "percée" par l'arc électrique tout comme le transistor et se transformera en court-circuit.

Plus de documentation voir "Loi de Lentz".

fdufnews:
Un truc m'interpelle. La porte je suppose qu'elle doit s'ouvrir et se fermer donc il doit y avoir une inversion de la tension aux bornes du moteur. C'est fait au plus prêt du moteur au-dessus du relais?

Bien vu ! Le schéma que j'ai mis est simplifié.
Il y a un relais double-inverseur alimenté seulement à la fermeture quelques millisecondes avant la commutation de l'alimentation.

Seul le contact représenté encaisse la surtension.

L'avantage du transistor sur le relais c'est que l'on peut piloter le moteur en PWM et le faire ralentir en approchant de la butée et par là même ne pas le couper alors que le courant est maximum.

Je n'ai prévu de butée que pour la dernière porte à se fermer.
Je me sert de la détection de surintensité pour arrêter le moteur sur le moindre obstacle, ce qui évite de blesser... Et puis elles s'arrêtent aussi en cas de vent fort, ce qui évite de griller les moteurs pas assez puissants et la batterie de 2AH que j'ai prévu (c'est aussi pour ça que je ne démarre pas 2 moteurs en même temps, y compris le servos moteurs.

C'est rare et l'opérateur (bibi ou autre) est là pour relancer et au pire passer en mode manuel. :wink:

68tjs:
Comme ta diode est placée elle sera "percée" par l'arc électrique tout comme le transistor et se transformera en court-circuit.

La 1N4007 supporte 1000 V et 30 A en pointe, ça devrait aller :wink:

que se passe t'il en cas de pic de tension positif sur la résistance de shunt (0.1 ohm)?

Ce pic de tension est dirigé vers l'entrée de l'Arduino.

I faudrait certainement une diode entre l'entré de l'Arduino et le +5V. Anode sur entrée Arduino.

Bonne bidouille

Ok j'ai compris :confused:
Je vais devoir refaire avec des relais simple inverseur. Dans cette configuration il y a toujours une diode aux bornes du moteur et plus aucun courant inverse dans la résistance de mesure :

achess:
Je pensais que ça revenait au même à la coupure d'alimentation, la surtension se retrouve aux bornes du contact du relais, d'une impédance brusquement "infinie" à l'instant de la coupure.

Bonjour,

Oui, ça revient à peu près au même si on néglige l'impédance de la source et des fils.
De toute façon, si on inverse le sens du moteur on ne peut pas mettre les diodes aux bornes du moteur.

kamill:
De toute façon, si on inverse le sens du moteur on ne peut pas mettre les diodes aux bornes du moteur.

Non mais on peut mettre la diode entre l'alim positive et le relais qui commande la coupure.
Le plus simple pour protéger les entrées de l'ATmega ce serait de mettre une diode zener sur l'entrée du processeur. Je ne sais pas si c'est ça que achess entendait par l'expression "diode à pointe" dans son schéma. Comme le shunt est prévu pour une tension de l'ordre de 0,8V au maximum. Il faudrait choisir une zener 2,7V par exemple pour avoir une marge afin qu'elle ne se mette pas à conduire trop tôt. Et choisir un modèle capable d'encaisser un peu de courant quand même au moment de la surtension.

kamill:
De toute façon, si on inverse le sens du moteur on ne peut pas mettre les diodes aux bornes du moteur.

La solution est d'utiliser une pseudo pont de diode comme ci-dessous.

Oui, les diodes sont bien mises sur les commutateurs comme dans le schéma de achess.

Oui, c'est le même principe.

Merci à tous. :wink:

Je compte refaire le circuit dont les pastilles se décollent à force d'être soudé/désoudé.

Je vois que tu as enlevé la résistance sur A7.
C'était une bonne idée de mettre une résistance de 1k car ça limite le courant dans les diodes de protection des entrées.

Ah ok ! Je l'ajouterais cette résistance alors :wink:

Pour finir, le montage actuel avec relais double inverseur est plus simple, il suffit d'une diode pour l'avoir en parallèle avec le moteur quelque soit la position du relais (OFF = ouverture ou ON = fermeture)