Pilotage de volet roulant filaire - Arduino freeze

Bonjour à tous,
voici mon premier post dans ce forum qui m'a bien aidé dans la création de mes différents projets arduino. J'ai commencé par un premier programme de pilotage de volets roulant puis une second gérant mon chauffage et enfin une porte de poulailler automatique.
Je tenais à remercier toute la communauté de développeurs et de passionnés autour de l'arduino.
Je suis de formation technique comprenant la programmation et l'électronique mais sans les maitriser.
Aujourd'hui, je vous demande de l'aide sur un plantage récurrent de mon programme de pilotage de mes volets roulants. Le programme est fonctionnel depuis au moins 3 ans mais plante au bout d'un temps très variable de la journée à une semaine sans que je n'arrive à comprendre pourquoi.

Présentation partie matérielle :
le système est composé d'une alimentation 12V et deux autres 5V, un arduino méga, de cartes relais, de cartes d'optocoupleur et de 12 boutons poussoirs volet roulant.

  • l'alimentation 12V 1,6A alimente l'arduino
  • une des alimentations 5V 2A alimente les cartes relais 30A, qui sont également connecté au VCC et GND de l'arduino
  • l'autre alimentation 5V 0,5A alimente les cartes opto coupleurs en interface avec les poussoirs
  • les cartes relais sont équipés d'un opto en interface avec l'arduino, la consommation est de l'ordre de 5 mA par entrée
  • les cartes opto en interface avec les poussoirs me permettent d'obtenir un signal garantissant moins de perturbation (au départ je pensais que c'était là la source de mon pb mais cela n'a rien changé)

j'ai 10 volets roulants (VR) avec 12 poussoirs soient 24 entrées nécessaires et 20 sorties pour commander les VR.

Les connexions sont réalisées avec des borniers à vis avec des fils rigides téléphonique de 0,7mm environ.
Une distance de 3 cm est respectée entre la BT et le 230V au niveau filaire.
Il n'y a pas de bouclage du GND.
Je n'ai pas encore équipé mon circuit de condensateur pour absorber les éventuelles parasites ou baisse de tension.
La tension mesurée au moment du basculement de l'ensemble des relais reste globalement stable au tour de 5V (j'observe une chute de 200 mV).

Voici mon code :

// suppression du watch qui est non fonctionnel
// variable de boucle
byte i = 0;
long compteur = 0;

// Variable declaration de temps
unsigned long prevMillisx = 0;
#define frequency_of_pulse 200 // en ms
#define filtrage 50 // en ms
#define filtrage_stop 10 // en ms

// Variable de position des VR (3 position haute, 2 position intermédiaire, 1 position basse, 0 position fermée)
byte POSITION_VR[10] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 10 positions

// Durée du mouvement des VR en ms
unsigned long TPS_DEPART_MVT_VR[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 10 temps

// Etat poussoir VR
boolean BP_VR_HAUT[12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // 12 BP
boolean BP_VR_BAS[12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // 12 BP
boolean BP_VR_STOP[12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // 12 BP

// Amplitude des VR en ms à la montée
const unsigned int AMPLITUDE_VR[12] = {36000, 36000, 36000, 36000, 36000, 27000, 34500, 25000, 23000, 23500};

// delta amplitude des VR en ms à la descente pour ne pas être complètement fermé
const unsigned int AMPLITUDE_VR_delta[12] = {5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000};

// Variable declaration des entrées (utilisation des I/O analogiques en numérique)
const uint8_t BROCHE_POUSSOIR_VR_HAUT[12] = {24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 50, 44}; //22 Défaut sur cette entrée
const uint8_t BROCHE_POUSSOIR_VR_BAS[12] = {25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 51, 45}; //23 Défaut sur cette entrée

// Variable declaration des sorties (commande relais)
const uint8_t BROCHE_RELAIS_VR_HAUT[10] = {A0, A2, A4, A6, A8, A10, A12, A14, 2, 4}; // défaut sur 9
const uint8_t BROCHE_RELAIS_VR_BAS[10] = {A1, A3, A5, A7, A9, A11, A13, A15, 3, 5}; //

void setup()
{
  // initialisation de la communication série
  Serial.begin(9600); // ouvre le port série et fixe le debit de communication à 9600 bauds

  Serial.println(F("init"));

  for (i = 0; i <= 11 ; i++) {
    pinMode(BROCHE_POUSSOIR_VR_HAUT[i], INPUT_PULLUP);
    pinMode(BROCHE_POUSSOIR_VR_BAS[i], INPUT_PULLUP);
  }

  for (i = 0; i <= 9 ; i++) {
    pinMode(BROCHE_RELAIS_VR_HAUT[i], OUTPUT);
    pinMode(BROCHE_RELAIS_VR_BAS[i], OUTPUT);
  }

}

void loop() {

  if (pulse()) {

    // pilotage manuel, utilisation d'un filtrage sur les entrées BP
    // défini à partir des broches poussoir, les commandes BP
    for (i = 0; i <= 11 ; i++) {
      lecture_entree(BP_VR_HAUT[i], BP_VR_BAS[i], BROCHE_POUSSOIR_VR_HAUT[i], BROCHE_POUSSOIR_VR_BAS[i], i);
    }

    // Action montée ou descente VR en fonction de l'état des poussoirs ou des commandes automatisée
    // Concernant la commande générale maison bas (poussoir entrée 10 et poussoir escalier 11)
    if (BP_VR_BAS[10] == 0 || BP_VR_BAS[11] == 0) {
      for (i = 0; i <= 4 ; i++) {
        BP_VR_BAS[10] = 1;
        BP_VR_BAS[11] = 1;
        BP_VR_BAS[i] = 0;
      } Serial.println(F("BP BAS GEN"));
    }
    if (BP_VR_HAUT[10] == 0 || BP_VR_HAUT[11] == 0) {
      for (i = 0; i <= 4 ; i++) {
        BP_VR_HAUT[10] = 1;
        BP_VR_HAUT[11] = 1;
        BP_VR_HAUT[i] = 0;
      } Serial.println(F("BP HAUT GEN"));
    }

    // Concerne les commandes individuelles des différents VR
    for (i = 0; i <= 9 ; i++) {
      ACTION_VR(BP_VR_BAS[i], BP_VR_HAUT[i], BROCHE_RELAIS_VR_BAS[i], BROCHE_RELAIS_VR_HAUT[i], POSITION_VR[i], TPS_DEPART_MVT_VR[i], AMPLITUDE_VR[i], AMPLITUDE_VR_delta[i]);
    }
  }

}

bool pulse() {

  if ((millis() - prevMillisx) >= frequency_of_pulse || (millis() - prevMillisx) < 0) {
    prevMillisx = millis();
    return true;
  }
  else return false;
}

void lecture_entree(boolean &BP_VR_HAUT, boolean &BP_VR_BAS, const uint8_t PIN_INPUT_HAUT, const uint8_t PIN_INPUT_BAS, byte NUM_VR) {
  compteur = 0;
  while (digitalRead(PIN_INPUT_BAS) == HIGH && digitalRead(PIN_INPUT_HAUT) == LOW && compteur < filtrage)
  {
    compteur++;
    delay(1);
    if (compteur == filtrage) {
      BP_VR_HAUT = 0;
    }

  }

  while (digitalRead(PIN_INPUT_HAUT) == HIGH && digitalRead(PIN_INPUT_BAS) == LOW && compteur < filtrage)
  {
    compteur++;
    delay(1);
    if (compteur == filtrage) {
      BP_VR_BAS = 0;
    }

  }

  while (digitalRead(PIN_INPUT_BAS) == LOW && digitalRead(PIN_INPUT_HAUT) == LOW && compteur < filtrage)
  {
    compteur++;
    delay(1);
    if (compteur == filtrage_stop) {
      BP_VR_HAUT = 0; BP_VR_BAS = 0;
    }
  }
}

void ACTION_VR(boolean &ETAT_INPUT_BAS, boolean &ETAT_INPUT_HAUT, byte PIN_OUTPUT_BAS, byte PIN_OUTPUT_HAUT, byte &POSITION_VR, unsigned long &TPS_DEPART_MVT_VR, unsigned int AMPLITUDE_VR, unsigned int AMPLITUDE_VR_delta) {
  if (digitalRead(PIN_OUTPUT_HAUT) == HIGH && digitalRead(PIN_OUTPUT_BAS) == HIGH || ETAT_INPUT_HAUT == 0 && ETAT_INPUT_BAS == 0 || digitalRead(PIN_OUTPUT_HAUT) == HIGH && ETAT_INPUT_BAS == 0 || ETAT_INPUT_HAUT == 0 && digitalRead(PIN_OUTPUT_BAS) == HIGH) {
    digitalWrite(PIN_OUTPUT_HAUT, LOW);
    digitalWrite(PIN_OUTPUT_BAS, LOW);
    POSITION_VR = 2;
    Serial.print(F("Arrêt VR"));
    delay(50);
    ETAT_INPUT_BAS = 1;
    ETAT_INPUT_HAUT = 1;
  }

  if (ETAT_INPUT_HAUT == 0 && digitalRead(PIN_OUTPUT_HAUT) == LOW && POSITION_VR != 3) {
    //digitalWrite(PIN_OUTPUT_BAS,LOW);
    digitalWrite(PIN_OUTPUT_HAUT, HIGH);
    Serial.print(F("Commande relais montée VR : ")); Serial.println(PIN_OUTPUT_HAUT);
    POSITION_VR = 2;
    TPS_DEPART_MVT_VR = millis();
  }
  if (ETAT_INPUT_BAS == 0 && digitalRead(PIN_OUTPUT_BAS) == LOW && POSITION_VR != 0) {
    //digitalWrite(PIN_OUTPUT_HAUT,LOW);
    digitalWrite(PIN_OUTPUT_BAS, HIGH);
    Serial.print(F("Commande relais descente VR : ")); Serial.println(PIN_OUTPUT_BAS);
    POSITION_VR = 2;
    TPS_DEPART_MVT_VR = millis();
  }

  if (digitalRead(PIN_OUTPUT_HAUT) == HIGH && ((millis() - TPS_DEPART_MVT_VR) > (AMPLITUDE_VR + 5000))) {
    digitalWrite(PIN_OUTPUT_HAUT, LOW);
    POSITION_VR = 3;
  }

  if (digitalRead(PIN_OUTPUT_BAS) == HIGH && POSITION_VR != 1 && ((millis() - TPS_DEPART_MVT_VR) > (AMPLITUDE_VR - AMPLITUDE_VR_delta))) {
    digitalWrite(PIN_OUTPUT_BAS, LOW);
    POSITION_VR = 1;
  }

  if (digitalRead(PIN_OUTPUT_BAS) == HIGH && POSITION_VR == 1 && ((millis() - TPS_DEPART_MVT_VR) > AMPLITUDE_VR_delta)) {
    digitalWrite(PIN_OUTPUT_BAS, LOW);
    POSITION_VR = 0;
  }

  ETAT_INPUT_BAS = 1;
  ETAT_INPUT_HAUT = 1;
}i

merci à vous pour vos recommandations éventuelles
cordialement

quelle consommation par sortie ?

la carte dispose d'un Max total et Max par port GPIO en courant fourni ou consommé


pourquoi ne pas avoir pris 5V aussi pour la MEGA ? vous faites bosser le régulateur pour dissiper les ~7V multipliés par l'intensité consommée sous forme de chaleur. Si le régulateur chauffe trop il peut se mettre en protection et planter votre MEGA.


vous auriez pu utiliser une bibliothèque pour les boutons et créer une classe pour vos volets, ça aurait pas mal simplifié le code.

voici un exemple (qui ne gère pas la durée / position)

une fois la classe écrite, le code du sketch principal est simple

#include <Toggle.h>
#include "VoletRoulant.h"

VoletRoulant volets[] = {
  {24, 25, A0, A1, 36000ul, 5000ul},
  {26, 27, A2, A3, 36000ul, 5000ul},
};
const size_t nbVolets = sizeof volets / sizeof * volets;

const uint8_t pinPoussoirEntreeToutHaut = 50;
const uint8_t pinPoussoirEntreeToutBas  = 51;
Toggle poussoirEntreeToutHaut;
Toggle poussoirEntreeToutBas;

void setup() {
  for (auto& unVolet : volets) unVolet.begin();
  poussoirEntreeToutHaut.begin(pinPoussoirEntreeToutHaut);
  poussoirEntreeToutBas.begin(pinPoussoirEntreeToutBas);
  Serial.begin(115200);
}

void loop() {
  for (auto& unVolet : volets) unVolet.testerAction();
  
  poussoirEntreeToutHaut.poll();
  if (poussoirEntreeToutHaut.onPress()) for (auto& unVolet : volets) unVolet.appuiHaut();
  poussoirEntreeToutBas.poll();
  if (poussoirEntreeToutBas.onPress()) for (auto& unVolet : volets) unVolet.appuiBas();
}

Bonjour J-M-L,

chaque sortie consomme 5 mA
chaque entrée consomme 2 mA

c'est par méconnaissance du fonctionnement de la carte. C'est que dernièrement que j'ai connecté le 5V de l'arduino à l'alimentation 5V qui alimente les relais pour régler un problème de fonctionnel. Je vais suivre votre suggestion en enlevant l'alimentation 12V.

votre exemple est très intéressant, je vais regarder comment l'adapter à mon projet. Merci pour le temps passé.

Assurez vous que les alims liées aux relais et faisant fonctionner la MEGA soient bien découplées. Vous ne voulez pas de chute de tension lors d’un appel de courant (par exemple activation de tous les relais d’un coup - la bobine qui va déclencher les relais tire entre 70 et 150mA. Vous avez 10 relais qui s’activent ça fait une demande immédiate de 1.5A potentiellement juste pour les bobines. Certaines alims 5V ne vont pas suivre. Éventuellement un gros Condo à l’entrée de la MEGA pour éviter la chute de tension aiderait à absorber ces pics de demande (et éventuellement en entrée des bobines)


Vous n’avez pas de système de détection de fin de course pour vos volets ?
Est-ce qu’il y a une protection auto qui fait que le moteur se coupe quand le volet est arrivé en haut ou en bas ?

Bonjour,

si la même alimentation 5V n'est pas connecté sur le 5V de l'arduino et sur l'alim des cartes relais, ça perturbe l'arduino. il me sort des tensions de 3,5V en sortie pour commander les relais. Pourtant j'ai bien 5V sur la borne 5V.

Combien de Farad à peut près ?

oui j'ai bien des fins de courses, ils sont bien réglés.
par contre, il m'arrive souvent d'arrêter les volets dans une position intermédiaire, je suppose que mes relais en prennent un coup.

je viens de tester avec une seule alimentation 5V pour l'arduino et les relais. La tension passe de 5,06 à 4,89V lorsque je commande 5 VR. L'arduino n'a pas planté.

10 à 100 microfarad ça devrait aller. Assurez vous que le condensateur soit largement OK pour 5V

Bonjour,
après un mois et demi, plus aucun plantage de l'arduino. Il s'agissait bien de l'alimentation 12V.
Merci bcp de tes conseils J-M-L.

Bonne nouvelle !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.