Mise sous tension, sorties s'activent et se désactivent

Bonjour,

Je travail depuis quelques temps sur une machine de réglage industrielle contrôlée par une carte Arduino.

Mon soucis:
Lors de la mise sous tension de la carte, certaines sorties s'activent et se désactivent 4-5 fois avant de rester désactivées.

Je ne parviens pas a trouver la cause de ceci, ni a trouver une solution (peut-être au niveau du code)

Auriez-vous déjà eu a faire a ce genre de comportement?

Merci beaucoup,
Luis

Bonjour

Pour avoir le l'aide il faut fournir un ensemble d'informations détaillées sur le montage , voir ici
Bonnes Pratiques du Forum

Bonjour,
A l'initialisation, les I/O sont configurées en entrées. Donc les lignes ne sont pas polarisées et elles flottent. Elles resteront flottantes jusqu'au moment où tu définiras leur état, généralement dans le setup(). Cette période transitoire peut durer quelques secondes le temps que le bootloader s'exécute et passe la main à ton application.
Si tu veux qu'elles soient dans un état connu il faut prévoir des résistances de tirage pour les placer dans un état correct.
De plus, dans le code d'initialisation, si tu fais

pinMode(maPin, OUTPUT)
digitalWrite(maPin, HIGH)

La sortie en question va se trouver à zéro pendant quelques ms car le registre de donné des ports de sortie est à 0 après l'initialisation du processeur.
Pour éviter ça il vaut mieux faire:

digitalWrite(maPin, HIGH)
pinMode(maPin, OUTPUT)

Si tu as d'autres problèmes, il faudra mettre ton code pour qu'on y jette un œil.

Bonjour Al1fc,

Bien noté, merci :slight_smile:

Je n'ai pas juger utile de mettre le code car le soucis se produit même en envoyer un programme vide dans la carte

Mais malgré tout, le voici:

/*
 * 07-08-20
 * Code bulleur LPE-0056
 * Nouvelle génération exclusivité MVE
 * Luis Wanzoul
 * 
 * validé le 23/03/21
*/

// Stepper motor et roulettes:
#include <SPI.h>
#include <HighPowerStepperDriver.h>
#include <Arduino.h>

#define RCod_Dr_B 2
#define RCod_Dr_A 3
#define RCod_Gch_B 20
#define RCod_Gch_A 21

float compteur_Dr = 0;
float compteur_Gch = 0;

const uint8_t CSPin_Dr = 53;
const uint8_t CSPin_Gch = 43;

  // This period is the length of the delay between steps, which controls the
  // stepper motor's speed.  You can increase the delay to make the stepper motor
  // go slower.  If you decrease the delay, the stepper motor will go faster, but
  // there is a limit to how fast it can go before it starts missing steps.
const uint16_t StepPeriodUs = 100;

HighPowerStepperDriver sd;
HighPowerStepperDriver sd1;

// Vannes:
int V1 = 13;      // vanne 1 de mise sous pression machine ( pas utilisée dans code )
int V2a = 12;     // bobine 1 V2 - Sortie Verrin moteur 1
int V2b = 11;     // bobine 2 V2 - Rentrée Verrin moteur 1
int V3a = 10;     // bobine 1 V3 - Sortie Verrin moteur 2
int V3b = 9;      // bobine 2 V3 - Rentrée Verrin moteur 2
int V4a = 8;      // bobine 1 V4 - Sortie Verrin avant
int V4b = 7;      // bobine 2 V4 - Rentrée Verrin avant
int V5a = 6;      // bobine 1 V5 - Sortie Verrin arriere
int V5b = 5;      // bobine 2 V5 - Rentrée Verrin arriere
int V6a = 4;      // bobine 1 V6 - Rentrée Sortie Verrin dessus
int V6b = 1;      // bobine 2 V6 - Verrin dessus
int V7 = 0;       // vanne 7 - selection haute ou basse pression vanne
int V8 = 14;       // vanne 8 - mise sous pression vanne
int V9 = 15;       // vanne piston
int V10 = 16;     // vanne retour piston
// Switch Pression:
int SwPr_Pos1 = 28;     // Haute Pression
int SwPr_Pos2 = 29;     // Basse Pression
// Switch Activation:
int SwAct_Pos1 = 26;    // Vanne Activé
int SwAct_Pos2 = 27;    // Vanne Cyclage
// Poussoires Ouverture, Fermeture:
int Com = 31;           // Poussoir Commun
int Ferm = 24;          // Poussoir Fermeture
int Ouv = 25;           // Poussoir Ouverture
// Switch selection verins:
int ChVer_Pos1 = 30;    // Switch choix verin 3x ou 5x
// Variable internes
int Etat_Mach = LOW;            // Memoire machoire fermée
int Etat_Com;                   // Memoire poussoir commun
int Etat_Ferm;                  // Memoire poussoir fermé
int Etat_Ouv;
int Etat_ChVer_Pos1;
int Etat_SwAct_Pos1;
int Etat_SwAct_Pos2;
int Etat_SwPr_Pos1;
int Etat_SwPr_Pos2;
int Der_Etat_Com = LOW;         // Memoire dernier etat poussoir commun
int Der_Etat_Ferm = LOW;        // Memoire dernier etat poussoir fermé
int Tps_Pouss = 2000;           // durée de l'appui voulu sur les poussoires pour fermer
long Dur_Pouss;                 // durée de l'appui mesuré sur les poussoires pour fermer
boolean Mem_Pouss_Com = false;  // Memoire pur valider la poussee Commun si durée sufisante
boolean Mem_Pouss_Ferm = false; // Memoire pur valider la poussee Fermer si durée sufisante

//---------------------VOID IRQ CODEUR MESURE DE VITESSE Droite----
void Isr_Dr() {
  if (digitalRead(RCod_Dr_A)) {
    compteur_Dr = compteur_Dr - 1;
  } else {
    compteur_Dr = compteur_Dr + 1;
  }
  if (compteur_Dr > 0) {
    sd.setDirection(0);
    sd.step();
    delayMicroseconds(StepPeriodUs);
    compteur_Dr = compteur_Dr - 1;
  } else {
    sd.setDirection(1);
    sd.step();
    delayMicroseconds(StepPeriodUs);
    compteur_Dr = compteur_Dr + 1;
  }
}
//---------------------VOID IRQ CODEUR MESURE DE VITESSE Gauche----
void Isr_Gch() {
  if (digitalRead(RCod_Gch_A)) {
    compteur_Gch = compteur_Gch + 1;
  } else {
    compteur_Gch = compteur_Gch - 1;
  }
  if (compteur_Gch > 0) {
    sd1.setDirection(0);
    sd1.step();
    delayMicroseconds(StepPeriodUs);
    compteur_Gch = compteur_Gch - 1;
  } else {
    sd1.setDirection(1);
    sd1.step();
    delayMicroseconds(StepPeriodUs);
    compteur_Gch = compteur_Gch + 1;
  }
}

void setup() 
{
  Etat_Mach = false;

// Sorties Vannes:
  pinMode(V1, OUTPUT);
  pinMode(V2a, OUTPUT);
  pinMode(V2b, OUTPUT);
  pinMode(V3a, OUTPUT);
  pinMode(V3b, OUTPUT);
  pinMode(V4a, OUTPUT);
  pinMode(V4b, OUTPUT);
  pinMode(V5a, OUTPUT);
  pinMode(V5b, OUTPUT);
  pinMode(V6a, OUTPUT);
  pinMode(V6b, OUTPUT);
  pinMode(V7, OUTPUT);
  pinMode(V8, OUTPUT);
  pinMode(V9, OUTPUT);
  pinMode(V10, OUTPUT);

// Entrees Commandes (Poussoirs, joystick,...)
  pinMode(SwPr_Pos1, INPUT_PULLUP);
  pinMode(SwPr_Pos2, INPUT_PULLUP);
  pinMode(SwAct_Pos1, INPUT_PULLUP);
  pinMode(SwAct_Pos2, INPUT_PULLUP);
  pinMode(Com, INPUT_PULLUP);
  pinMode(Ferm, INPUT_PULLUP);
  pinMode(Ouv, INPUT_PULLUP);
  pinMode(ChVer_Pos1, INPUT_PULLUP); // 3 verins ou 5 verins

// Moteurs Pas à Pas
//  Serial.begin(9600); // cause l'activation des portes 12(V7) et (V6b)
  pinMode(RCod_Dr_B, INPUT);
  pinMode(RCod_Dr_A, INPUT);
  attachInterrupt(digitalPinToInterrupt(RCod_Dr_B), Isr_Dr, RISING );
  pinMode(RCod_Gch_B, INPUT);
  pinMode(RCod_Gch_A, INPUT);
  attachInterrupt(digitalPinToInterrupt(RCod_Gch_B), Isr_Gch, RISING );
 
  SPI.begin();
  sd.setChipSelectPin(CSPin_Dr);
    // Give the driver some time to power up.
  delay(1);
    // Reset the driver to its default settings and clear latched status
    // conditions.
  sd.resetSettings();
  sd.clearStatus();
    // Select auto mixed decay.  TI's DRV8711 documentation recommends this mode
    // for most applications, and we find that it usually works well.
  sd.setDecayMode(HPSDDecayMode::AutoMixed);
    // Set the current limit. You should change the number here to an appropriate
    // value for your particular system.
  sd.setCurrentMilliamps36v4(1500);
    // Set the number of microsteps that correspond to one full step.
  sd.setStepMode(HPSDStepMode::MicroStep2);
    // Enable the motor outputs.
  sd.enableDriver();
  sd1.setChipSelectPin(CSPin_Gch);
    // Give the driver some time to power up.
  delay(1);
    // Reset the driver to its default settings and clear latched status
    // conditions.
  sd1.resetSettings();
  sd1.clearStatus();
    // Select auto mixed decay.  TI's DRV8711 documentation recommends this mode
    // for most applications, and we find that it usually works well.
  sd1.setDecayMode(HPSDDecayMode::AutoMixed);
    // Set the current limit. You should change the number here to an appropriate
    // value for your particular system.
  sd1.setCurrentMilliamps36v4(1500);
    // Set the number of microsteps that correspond to one full step.
  sd1.setStepMode(HPSDStepMode::MicroStep2);
    // Enable the motor outputs.
  sd1.enableDriver();
}

// ************ Main Code ************
void loop() 
{
  digitalWrite(V1, HIGH); // vanne principale sous tension

// ********************************************************** Gestion pressions (Vannes)
  Etat_SwPr_Pos1 = digitalRead(SwPr_Pos1);
  Etat_SwPr_Pos2 = digitalRead(SwPr_Pos2);
    // ---Pas de pression---
  if ((Etat_SwPr_Pos1 == HIGH) && (Etat_SwPr_Pos2 == HIGH)){ //Attention Etach Mach forcée High pour test && (Etat_Mach == HIGH)
    digitalWrite(V7, LOW);
    digitalWrite(V8, LOW);
  }
    // ---Basse Pression---
  if ((Etat_SwPr_Pos1 == HIGH) && (Etat_SwPr_Pos2 == LOW)){ //&& (Etat_Mach == HIGH)){
    digitalWrite(V7, LOW);
    digitalWrite(V8, HIGH);
  }
    // ---Haute Pression---
  if ((Etat_SwPr_Pos1 == LOW) && (Etat_SwPr_Pos2 == HIGH)){ // && (Etat_Mach == HIGH)){
    digitalWrite(V7, HIGH);
    digitalWrite(V8, HIGH);
  }

// ********************************************************** Gestion etat excité et desexcité (Piston)
  Etat_SwAct_Pos2 = digitalRead(SwAct_Pos2);
  Etat_SwAct_Pos1 = digitalRead(SwAct_Pos1);
    // ---Cyclage vanne---
  if ((Etat_SwAct_Pos2 == LOW) && (Etat_SwAct_Pos1 == HIGH)){
    for (int i = 0; i <=4; i++){
      digitalWrite(V9, HIGH);   // vanne piston
      digitalWrite(V10, LOW);   // vanne retour piston
      delay(100);  // en ms                     
      digitalWrite(V9, LOW);   // vanne piston
      digitalWrite(V10, HIGH); // vanne retour piston   
      delay(100);  // en ms  
    } 
  }
    // ---Activation vanne (pousser piston)---
  else if ((Etat_SwAct_Pos2 == HIGH)  && (Etat_SwAct_Pos1 == LOW)) {
    digitalWrite(V9, HIGH);   // vanne piston
    digitalWrite(V10, LOW);   // vanne retour piston
  }
    // ---Vanne au repos---
  else {
    digitalWrite(V9, LOW);   // vanne piston
    digitalWrite(V10, HIGH); // vanne retour piston
  }
}               

Merci

Serait-il possible de mesurer le niveau de tension pendant le démarrage du processeur. C’est bien possible que les fluctuations de tension sont la cause de ton problème. Il I a des vannes, et les vannes ont des inductances, ceci veut dire des amplificateurs additionnels.
(Je suis pas francophone d’origine)

Dommage, on aurais gagné du temps.
Dans ton setup() tu programmes tes I/O en entrée ou en sortie mais tu ne définis pas l'état des sorties. Donc tant qu'elles ne sont pas utilisées, elles sont à zéro.
Est-ce ce que tu veux?

Normal puisque les sorties restent dans un état indéfini dans ce cas.

Salut fdufnews,

C'est bien ca oui
Du coup en codant ceci

  digitalWrite(V1, HIGH) pinMode(V1, OUTPUT) ;

Ce devrait le faire

Je test ca tout de suite et reviens vers vous

Il faut bien vérifier dans quel état doit se trouver chacune des sorties et faire l'initialisation correcte. Le plus simple c'est de faire une liste des sorties et de noter l'état dans lequel elle doivent se trouver pour éviter d'en oublier.
A noter aussi, l'ordre dans lequel les sorties sont initialisées a son importance.
Par exemple, Il vaut mieux initialiser d'abord dans l'état inactif l'enable d'un driver moteur ou le select d'un périphérique avant de faire l'initialisation de la ligne de commande comme ça tu es certain que le périphérique en question est bien désactivé.
De même il est préférable de commencer par les sorties les plus critiques en matière de sécurité.
A ce sujet d'ailleurs, s'il y a des problèmes de sécurité, il ne faut pas hésiter à placer un relais sur l'alimentation des équipement "dangereux" pour s'assurer que la puissance n'est pas disponible tant que l'application n'a pas terminé son initialisation et que le système n'est pas sûr.

Ta solution fonctionne parfaitement!
je m'en veux de ne pas y avoir pensé avant, c'est tellement basique !
Merci beaucoup

Pour ce qui est des priorités d'initialisation, je vais y jeter un coup d'œil, mais nous n'avons pas grand chose de très critique sur cette petite machine.
Ca n'empêche, autant faire les choses bien

Merci à tous pour votre aide !

Luis

de rien