Besoin d'un avis pour code

Bonjour à tous,

Après m'être longtemps documenté sur arduino et avoir fait certain petit projet en exercices, je voudrais réaliser mon premier projet.

Le but est de contrôlé la montée et descente d'un mat élévateur qui fonctionne avec un vérin hydraulique.

Le fonctionnement du mât est simple, un moteur hydraulique tri-phasé fait tourner une centrale hydraulique, le mât monte.

On alimente une bobine (électrovanne) et le mât descend.

Le système fonctionne déjà.

La bobine ainsi que les relais pour la mise en route du moteur fonctionnenet en 12V DC. (4 relais finder, consommation bobine 0,1A)

L'idée est la suivante:

  • 1 Arduino Uno avec module Xbee pour piloter les relais
  • 2 Commandes à distances Xbee pour faire monter et descendre le mât
  • 2 Capteurs de fin de course en haut et en bas (le mât doit toujours s'arrêter à la même hauteur et démarrer du sol)

Ou j'en suis:

Je veux commencer par faire fonctionner le système avec une seule télécommande et sans capteur de fin de course.

  • pour la télécommande, il s'agit simplement de 2 bouttons connectés sur les DIO du XBEE (1 pour monter et l'autre pour descendre)
  • J'ai configurer les 2 modules xbee correctement, j'utilise simplement Les DIO (la télécommande en input et au niveau de l'arduino en output HIGH)
  • Pour la commande des relais, je passe par un 2N222 entre arduino et relais, cela fonctionne également

Le sketch:

Dans un premier temps je voudrais:

  • 1 appui sur le BP montée, enclenche les 3 bobines pour le moteur triphasé, les relais restent enclechés
  • Pour interrompre la montée, 1 appui sur les boutton montée ou descente, cela interrompt la montée
  • 1 appui sur le boutton de descente enclenche la descente
  • appui sur un des 2 boutton pour interrompre la descente

Voici mon code qui semble fonctionner

int rl_380_1 = 2;
int rl_380_2 = 3;
int rl_380_3 = 4;
int rl_des = 5;
int btn_chgt = 8;
int btn_up = 9;
int btn_dn = 10;

int etat_btn_chgt;
int etat_btn_up;
int etat_btn_dn;

int mvt;

void setup() {
  // put your setup code here, to run once:
  pinMode(rl_380_1, OUTPUT);
  pinMode(rl_380_2, OUTPUT);
  pinMode(rl_380_3, OUTPUT);
  pinMode(rl_des, OUTPUT);
  pinMode(btn_chgt, INPUT);
  pinMode(btn_up, INPUT);
  pinMode(btn_dn, INPUT);
  Serial.begin(9600);
  mvt = 0;

}

void loop() {
  // put your main code here, to run repeatedly:
  etat_btn_chgt = digitalRead(btn_chgt);
  etat_btn_up = digitalRead(btn_up);
  etat_btn_dn = digitalRead(btn_dn);

  if (mvt == 0 && etat_btn_up == LOW && etat_btn_dn == HIGH)
  {
    mvt = 1;
    delay (500);
  }
  if (mvt == 0 && etat_btn_dn == LOW && etat_btn_up == HIGH)
  {
    mvt = 2;
    delay (500);
  }
  if (mvt != 0 && etat_btn_chgt == LOW)
  {
    mvt = 0;
    delay (500);
  }

  if (mvt == 1)
    monter();
  if (mvt == 2)
    descendre();
  if (mvt == 0)
    arret();
}

void monter() {
  digitalWrite(rl_380_1, HIGH);
  digitalWrite(rl_380_2, HIGH);
  digitalWrite(rl_380_3, HIGH);
  digitalWrite(rl_des, LOW);

}

void arret() {
  digitalWrite(rl_380_1, LOW);
  digitalWrite(rl_380_2, LOW);
  digitalWrite(rl_380_3, LOW);
  digitalWrite(rl_des, LOW);
}

void descendre() {
  digitalWrite(rl_380_1, LOW);
  digitalWrite(rl_380_2, LOW);
  digitalWrite(rl_380_3, LOW);
  digitalWrite(rl_des, HIGH);

}

Mes questions:

  • Surtout au niveau du code, j'ai l'impression de me compliquer la vie, celui-ci semble fonctionner, mais je suis certain qu'il y a moyen de l'améliorer et j'ai l'impression d'être mal partit. (Il s'agit réellement de mon premier code "maison")

  • Niveau circuit, faut il prévoir des sécurités supplémentaires au niveau des I/O de l'arduino ? (Je me fait également la main avec fritzing, je posterai un schéma électrique par la suite)

Je voudrais ajouter que niveau sécurité, le mât dispose de sécurités "hydrauliques" (limiteur de pression, clapet anti-chute et butée haute de fin de course "mécaniques"), je veux juste remplacer les boutton de commande actuelle pour pouvoir commander le mât à distance. Le mât est fixe et sert en faite de monte charge. Il ne sert pas d'ascenseur.

Un grand merci à ceux qui auront prit la peine de me lire

le code se lit sans soucis.

il y a des petites améliorations, par exemple:

  • Déclarer les pins en const byte plutôt que int pour économiser de la mémoire

  • Un delay(15); au lieu de delay(500); va suffire pour éviter les rebonds des boutons (pour la plupart des boutons).

  • Au lieu d'utiliser 0,1,2 pour les mouvements vous pourriez utiliser un enum, ça améliore la lisibilité

  • Vous pouvez mettre des else entre vos if puisqu'ils sont exclusifs

  • Vous n'avez pas besoin au final de mettre les tests à la fin pour déclencher les mouvents, vous pouvez les mettre directement dans les premiers if, juste avant de faire le delay()

J'ai pas testé mais en reprenant votre code (tapé ici) ça donnerait ça

const byte rl_380_1 = 2;  // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE
const byte rl_380_2 = 3;  // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE
const byte rl_380_3 = 4;  // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE
const byte rl_des = 5;    // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE
const byte btn_chgt = 8;  // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE
const byte btn_up = 9;    // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE
const byte btn_dn = 10;   // METTRE DES COMMENTAIRES SUR CE QUE CA REPRESENTE

enum : byte {ARRET, MVT_UP, MVT_DOWN } etatMouvement;

// ---------- LES FONCTIONS MOTEURS ----------

void arret() {
  etatMouvement = ARRET;
  digitalWrite(rl_380_1, LOW);
  digitalWrite(rl_380_2, LOW);
  digitalWrite(rl_380_3, LOW);
  digitalWrite(rl_des, LOW);
}

void monter() {
  etatMouvement = MVT_UP;
  digitalWrite(rl_380_1, HIGH);
  digitalWrite(rl_380_2, HIGH);
  digitalWrite(rl_380_3, HIGH);
  digitalWrite(rl_des, LOW);
}

void descendre() {
  etatMouvement = MVT_DOWN;
  digitalWrite(rl_380_1, LOW);
  digitalWrite(rl_380_2, LOW);
  digitalWrite(rl_380_3, LOW);
  digitalWrite(rl_des, HIGH);
}


// ---------- ETAT INITIAL ----------

void setup() {
  pinMode(rl_380_1, OUTPUT);
  pinMode(rl_380_2, OUTPUT);
  pinMode(rl_380_3, OUTPUT);
  pinMode(rl_des, OUTPUT);
  pinMode(btn_chgt, INPUT);
  pinMode(btn_up, INPUT);
  pinMode(btn_dn, INPUT);
  arret();
}


// ---------- LA GESTION DES BOUTONS ----------

void loop() {
  int etat_btn_chgt = digitalRead(btn_chgt);
  int etat_btn_up = digitalRead(btn_up);
  int etat_btn_dn = digitalRead(btn_dn);

  if (etatMouvement == ARRET && etat_btn_up == LOW && etat_btn_dn == HIGH) {
    monter();
    delay (15);
  } else if (etatMouvement == ARRET && etat_btn_dn == LOW && etat_btn_up == HIGH) {
    descendre();
    delay (15);
  }
  
  if (etatMouvement != ARRET && etat_btn_chgt == LOW) {
    arret();
    delay (15);
  }
}

Sinon c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement - vous y lirez une explication sur les enum entre autres)

Merci pour ton aide, grâce à ton tutoriel, j'ai pû faire un code qui me plait beaucoup mieux.

En effet, avec la code précédent, la fonction arrêt me posait problème (à cause du cablâge)

en utilisant switch ... case, cela fonctionne beaucoup mieux et convient bien à mon montage (ci-dessous, le code modifié)

// Pin pour les bouttons
const byte btn_chgt = 8;  // Appui sur un des 2 bouttons
const byte btn_uppin = 9;    // Boutton monter
const byte btn_dnpin = 10;   // Boutton Descendre


// Les pin utilisées pour les relais
const byte rl_380_1 = 2;  // Relais 1 380v
const byte rl_380_2 = 3;  // Relais 2 380v
const byte rl_380_3 = 4;  // Relais 3 380v
const byte rl_des = 5;    // Relais descente

// Variables état bouttons
int etat_btn_chgt = 0;
int etat_btn_up = 0;
int etat_btn_dn = 0;
int prev_etat_btn_chgt = 0;
int prev_etat_btn_up = 0;
int prev_etat_btn_dn = 0;


enum : byte {ARRET, MVT_UP, MVT_DOWN } etatMouvement;

// ---------- LES FONCTIONS MOTEURS ----------

void arret() {
  etatMouvement = ARRET;
  digitalWrite(rl_380_1, LOW);
  digitalWrite(rl_380_2, LOW);
  digitalWrite(rl_380_3, LOW);
  digitalWrite(rl_des, LOW);
}

void monter() {
  etatMouvement = MVT_UP;
  digitalWrite(rl_380_1, HIGH);
  digitalWrite(rl_380_2, HIGH);
  digitalWrite(rl_380_3, HIGH);
  digitalWrite(rl_des, LOW);
}

void descendre() {
  etatMouvement = MVT_DOWN;
  digitalWrite(rl_380_1, LOW);
  digitalWrite(rl_380_2, LOW);
  digitalWrite(rl_380_3, LOW);
  digitalWrite(rl_des, HIGH);
}


// ---------- ETAT INITIAL ----------

void setup() {
  pinMode(rl_380_1, OUTPUT);
  pinMode(rl_380_2, OUTPUT);
  pinMode(rl_380_3, OUTPUT);
  pinMode(rl_des, OUTPUT);
  pinMode(btn_chgt, INPUT);
  pinMode(btn_uppin, INPUT);
  pinMode(btn_dnpin, INPUT);
  Serial.begin(9600);
  arret();
}

// ------------------------------------------------------
// La fonction de call back, appellée automatiquement quand on clique sur le boutton de montée
// ------------------------------------------------------

void clickbuttonup()
{
  switch (etatMouvement) {
    case ARRET: // On était à l'arrêt et on appuie sur le boutton de montée
    monter(); // On appelle la fonction monter
    etatMouvement = MVT_UP; // On change l'état de la variable
    break;

    case MVT_UP: // On était entrain de monter et on veut interrompre la montée
    arret(); // On interromp la montée
    etatMouvement = ARRET; // On change l'état de la variable
    break;

    case MVT_DOWN: // On était entrain de descendre et on veut interrompre la descente
    arret(); // On interromp la descente
    etatMouvement = ARRET; // On change l'état de la variable
    break;
  }
}

// ------------------------------------------------------
// La fonction de call back, appellée automatiquement quand on clique sur le boutton de descente
// ------------------------------------------------------

void clickbuttondn()
{
  switch (etatMouvement) {
    case ARRET: // On était à l'arrêt et on appuie sur le boutton de descente
    descendre(); // On appelle la fonction descendre
    etatMouvement = MVT_DOWN; // On change l'état de la variable
    break;

    case MVT_DOWN: // On était entrain de descendre et on veut interrompre la descente
    arret(); // On interromp la descente
    etatMouvement = ARRET; // On change l'état de la variable
    break;

    case MVT_UP: // On était entrain de monter et on veut interrompre la montée
    arret(); // On interromp la montée
    etatMouvement = ARRET; // On change l'état de la variable
    break;
  }
}



// ---------- LA GESTION DES BOUTONS ----------

void loop() {
etat_btn_up = digitalRead(btn_uppin); //Lit la valeur des boutton et la place dans la variable
etat_btn_dn = digitalRead(btn_dnpin);

// Comparer la valeures à la valeures précédente (montée)
if (etat_btn_up != prev_etat_btn_up) {
  if (etat_btn_up == LOW) {
    clickbuttonup();
  }
}
prev_etat_btn_up = etat_btn_up;

// Comparer la valeures à la valeures précédente (descendre)
if (etat_btn_dn != prev_etat_btn_dn) {
  if (etat_btn_dn == LOW) {
    clickbuttondn();
  }
}
prev_etat_btn_dn = etat_btn_dn;


}

Est ce que les delay serait encore nécessaire?

Je sais que je peux faire un peut de nettoyage dans les variables car certaines ne sont plus utilisées.

Bien à vous

C’est bcp plus structuré ! Bravo :slight_smile: