Suite projet, besoin conseils sur mon code

Bonjour,

Je chemine doucement… (voir page)

Ayant reçu mon L298N, j’ai débuté la rédaction de mon code. Mes fin de course sont de type"à languette", avec résistance de tirage.
Le gauche (position ouverture) sera fixé au mur. Le droit (fermeture) au volet pour s’arrêter sur tout obstacle éventuel.

Mon code fonctionne. Est-il correct? (comprendre sensé et propre)

D’autre part, je voudrais injecter une commande manuelle qui prenne la priorité sur l’automatisme, pour en tout temps pouvoir ouvrir/fermer jusqu’à la position voulue avec un bouton à bascule ou bien une télécommande.
Ca se fait comment? :o

Voici mon code:

/******************************
 * Code fonctionnel: condition pluie démarre et arrête le moteur
 * 08 janvier,  fin de course droite fonctionne, fin de course gauche fonctionne
  */


//Déclaration paramètres moteur:
//Moteur A
const int moteurPin1  = 6;  
const int moteurPin2  = 5;  

int fdcD; //Déclaration fin de course droit (volet fermé)
int fdcG; //Déclaration fin de course gauche (volet ouvert)

void setup(){
  Serial.begin(9600); //initialisation moniteur
  pinMode(4, OUTPUT); //affectatiion de pin 4 à A0 du capteur de pluie
  fdcD = 7; //affectation du pin 7 à fdcD
  pinMode(fdcD, INPUT); //mode lecture pour fdcD
  fdcG = 8; // affectation du pin 8 pour fdcG
  pinMode(fdcG,INPUT);//mode de lecture pour fdcG
  }
  
void loop()
{
    //Lecture analogique avec seuils "Pas de pluie", "Pluie modérée", "Pluie"
    if(analogRead(0)<500) Serial.println(" Pluie");//lecture du seuil
    else if(analogRead(0)<700) Serial.println(" Pluie modérée");//lecture du seuil
    else Serial.println(" Pas de pluie notable");// affichage si capteur sec
   

    int Valeur_analogique = analogRead(A0);//Lecture de la valeur analogique et affichage de la valeur lue
    Serial.print("Valeur analogique = ");
    Serial.print(Valeur_analogique);
    
    delay(1000);

//Essai d'introduction code moteur:

boolean etatfdcD = digitalRead(fdcD); //définition de etatfdcD
boolean etatfdcG = digitalRead(fdcG); //définition de etatfdcG




{  if(analogRead(0)<700) //lecture capteur pluie
  { analogWrite(moteurPin1, 150);//ordre rotation -définition du sens
    analogWrite(moteurPin2, 0);//ordre rotation -définition du sens
  }

   if((etatfdcD == HIGH) || (analogRead(0)>700))// lecture état de la condition fin de course et si capteur sec
  { analogWrite(moteurPin1, 0);//arrêt moteur si fdcD enclenché
    analogWrite(moteurPin2, 0);//arrêt moteur si fdcD enclenché
  }
}

{   if (analogRead(0)>700) // lecture capteur pluie retour temps sec
  { analogWrite(moteurPin1, 0);//ordre rotation -définition du sens
    analogWrite(moteurPin2, 150);//ordre rotation -définition du sens
  }

if((etatfdcG == HIGH) && (analogRead(0) > 700))
  { analogWrite(moteurPin1, 0);//arrêt moteur si fdcD enclenché
    analogWrite(moteurPin2, 0);//arrêt moteur si fdcD enclenché
  }




}

}

J’ai un peu mis en forme ton code (des const pour les déclarations constantes, les accolades “là où il faut”, un CTRL T à la fin pour formatter, etc):

/******************************
   Code fonctionnel: condition pluie démarre et arrête le moteur
   08 janvier,  fin de course droite fonctionne, fin de course gauche fonctionne
*/


//Déclaration paramètres moteur:
//Moteur A
const int moteurPin1  = 6;
const int moteurPin2  = 5;

const int fdcD = 7; //Déclaration fin de course droit (volet fermé)
const int fdcG = 8; //Déclaration fin de course gauche (volet ouvert)
const int capPluie = 4; // NON UTILISE ???

void setup() {
  Serial.begin(9600); //initialisation moniteur
  pinMode(capPluie, OUTPUT); //affectation de pin 4 à A0 du capteur de pluie
  // OUTPUT pour un capteur ???
  pinMode(fdcD, INPUT); //mode lecture pour fdcD
  pinMode(fdcG, INPUT); //mode de lecture pour fdcG
}

void loop() {
  //Lecture analogique avec seuils "Pas de pluie", "Pluie modérée", "Pluie"
  int Valeur_analogique = analogRead(A0);//Lecture de la valeur analogique et affichage de la valeur lue
  Serial.print("Valeur analogique = "); Serial.print(Valeur_analogique);
  if (Valeur_analogique < 500) Serial.println(" Pluie"); //lecture du seuil
  else if (Valeur_analogique < 700) Serial.println(" Pluie modérée"); //lecture du seuil
  else Serial.println(" Pas de pluie notable");   // affichage si capteur sec
  delay(1000);

  //Essai d'introduction code moteur:
  boolean etatfdcD = digitalRead(fdcD); //définition de etatfdcD
  boolean etatfdcG = digitalRead(fdcG); //définition de etatfdcG

  if (Valeur_analogique < 700) { //lecture capteur pluie
    analogWrite(moteurPin1, 150);//ordre rotation -définition du sens
    analogWrite(moteurPin2, 0);//ordre rotation -définition du sens
  }

  if ((etatfdcD == HIGH) || (analogRead(0) > 700)) { // lecture état de la condition fin de course et si capteur sec
    analogWrite(moteurPin1, 0);//arrêt moteur si fdcD enclenché
    analogWrite(moteurPin2, 0);//arrêt moteur si fdcD enclenché
  }

  if (analogRead(0) > 700) { // lecture capteur pluie retour temps sec
    analogWrite(moteurPin1, 0);//ordre rotation -définition du sens
    analogWrite(moteurPin2, 150);//ordre rotation -définition du sens
  }

  if ((etatfdcG == HIGH) && (analogRead(0) > 700)) {
    analogWrite(moteurPin1, 0);//arrêt moteur si fdcD enclenché
    analogWrite(moteurPin2, 0);//arrêt moteur si fdcD enclenché
  }
}

Quelques remarques :

  • Tu définis un capteur sur la pin 4, mais tu le mets en OUTPUT et tu ne t’en sers jamais.
  • Autant ne faire qu’une seule lecture de A0, la stocker et traiter sa valeur, plutôt que faire une lecture à chaque if
  • Ta suite de ifs me laisse songeur…
    Il faut que tu vérifies ces conditions pour faire en sorte qu’elles soient exclusives, c’est à dire que tu n’aies pas de cas où plusieurs sont vraies. Sinon, tu vas commander ton moteur de façon contradictoire et l’abîmer…

Pour ajouter une commande manuelle, il faut définir un bouton poussoir. Par exemple :
câblage : GND - Bouton - pin D2

const int pinBP = 2;

Dans le setup :

pinMode (pinBP, INPUT_PULLUP);

Le digitalRead donnera LOW quand le bouton sera enfoncé. Tu crées une variable qui stocke l’état de ta commande (ouvrir, fermer, stopper) et lorsque le bouton est enfoncé, tu modifies cette variable. Puis, tu modifies tes tests selon la valeur de cette variable.

Pour le faire par télécommande, tu dois choisir le type de télécommande (IR, RF, BT, Wifi) et implémenter un truc similaire: il y a des tutos un peu partout…

Je me suis permis de refaire tes ifs : vérifie si c’est bien ce que tu veux faire (j’ai notamment changé un || en un &&)

  if (Valeur_analogique < 700) {  // lecture capteur pluie
    analogWrite(moteurPin1, 150); // ordre rotation -définition du sens
    analogWrite(moteurPin2, 0);   // ordre rotation -définition du sens
  } else {                        // lecture capteur pluie retour temps sec
    analogWrite(moteurPin1, 0);   // ordre rotation -définition du sens
    analogWrite(moteurPin2, 150); // ordre rotation -définition du sens
    if ((etatfdcD == HIGH) || (etatfdcG == HIGH)) {
      analogWrite(moteurPin1, 0); // arrêt moteur si fdcD enclenché
      analogWrite(moteurPin2, 0); // arrêt moteur si fdcD enclenché
    }
  }

Tu risques d’avoir un problème lorsque ton capteur de pluie sera à la limite 700 : il risque d’osciller autour de 700 (699, 700, 701, 698, 701, 700, 699, etc) et ton moteur va chauffer grave…

Il faut mettre de l’hystérésis, c’est à dire le faire sortir de ce genre de boucle fatale… Un bon article à lire ici

Voici une version, à tester, qui gère l’hystérésis :

/******************************
   Code fonctionnel: condition pluie démarre et arrête le moteur
   08 janvier,  fin de course droite fonctionne, fin de course gauche fonctionne
*/


//Déclaration paramètres moteur:
//Moteur A
const int moteurPin1  = 6;
const int moteurPin2  = 5;

const int fdcD = 7; //Déclaration fin de course droit (volet fermé)
const int fdcG = 8; //Déclaration fin de course gauche (volet ouvert)
const int capPluie = 4; // NON UTILISE ???
int marge = 10;     // Marge d'hystérésis
int seuil0 = 700;
int seuil = 700;
enum state {STOP, MONTEE, DESCENTE};
state etat = STOP;

void setup() {
  Serial.begin(9600); //initialisation moniteur
  pinMode(capPluie, OUTPUT); //affectation de pin 4 à A0 du capteur de pluie
  // OUTPUT pour un capteur ???
  pinMode(fdcD, INPUT); //mode lecture pour fdcD
  pinMode(fdcG, INPUT); //mode de lecture pour fdcG
}

void loop() {
  //Lecture analogique avec seuils "Pas de pluie", "Pluie modérée", "Pluie"
  int Valeur_analogique = analogRead(A0);//Lecture de la valeur analogique et affichage de la valeur lue

  Serial.print("Valeur analogique = "); Serial.print(Valeur_analogique);
  if (Valeur_analogique < 500)          Serial.println(" Pluie"); //lecture du seuil
  else if (Valeur_analogique < 700)     Serial.println(" Pluie modérée"); //lecture du seuil
  else Serial.println(" Pas de pluie notable");   // affichage si capteur sec

  // Lecture fin de course
  boolean etatfdcD = digitalRead(fdcD); // définition de etatfdcD
  boolean etatfdcG = digitalRead(fdcG); // définition de etatfdcG
  delay(30);                            // anti rebond

  /*if (Valeur_analogique < seuil) etat = DESCENTE; // lecture capteur pluie
    else etat = MONTEE;                // lecture capteur pluie retour temps sec
    // peut être remplacé par : */
  etat = (Valeur_analogique < seuil) ? DESCENTE : MONTEE;
  if ((etatfdcD == HIGH) || (etatfdcG == HIGH)) etat = STOP; // fin de course

  switch ((int)etat) {
    case STOP:
      seuil = seuil0;
      analogWrite(moteurPin1, 0); // arrêt moteur si fdcD enclenché
      analogWrite(moteurPin2, 0); // arrêt moteur si fdcD enclenché
      break;
    case MONTEE:
      seuil = seuil0 - marge;
      analogWrite(moteurPin1, 0);   // ordre rotation -définition du sens
      analogWrite(moteurPin2, 150); // ordre rotation -définition du sens
      break;
    case DESCENTE:
      seuil = seuil0 + marge;
      analogWrite(moteurPin1, 150); // ordre rotation -définition du sens
      analogWrite(moteurPin2, 0);   // ordre rotation -définition du sens
      break;
  }

  Serial.print ("etat : "); Serial.print(etat);
  Serial.print(" seuil ="); Serial.println(seuil);
  delay(1000); // <-- Est-ce nécessaire (si on enlève les Serial.print pour la version finale) ?
}

Merci beaucoup de ton intérêt Lesept.

Il va falloir que je regarde tout ça en détails pour que ça me rentre dans le crâne. Il va me falloir un certain temps :slight_smile:

(J’ai testé avec ton code du message #2: le moteur n’arrête pas sur fdcD)

Je me figure bien la notion d’hystérésis, mais de là l’intégrer à un programme… Je vais éplucher tout ça tranquille.

Merci encore!

Sgt_McRae: (J'ai testé avec ton code du message #2: le moteur n'arrête pas sur fdcD)

Ça doit être dû au contenu du test : tu as mis || dans ce cas et && pour l'autre FDC. J'ai corrigé pour les versions suivantes. Tiens moi au courant !

Oui, bien sûr, je reviendrai dire ;)

Pour les opérateurs: J'avoue ne plus comprendre pourquoi j'ai utilisé ||. Par contre je suis sûr que sur le moment c'était motivé... Il me semblait que dans un cas, il était nécessaire qu'une des conditions soit réunie, et que dans l'autre les deux le soient. Ben non en fait :D

Tu sais avec quoi je pourrais éditer du code sur fond noir, avec une syntaxe bien différenciée (colorée)? Suis sous Linux...

Essaye sublime text. Je ne sais pas si c'est compatible Linux. On peut utiliser un template pour les couleurs (fond, textes, etc)

Yep, merci!

J'ai trouvé One Dark Arduino

Pas facile à installer car le dossier "Thèmes" n'est pas du tout à l'endroit indiqué.

Bonsoir

oui, sous Linux le dossier thème est içi

dossier thème.png

:smiley:

J’ai dû aller chercher le mien ici:

/home/Sgt_McRae/.local/share/umake/ide/arduino/lib/theme

Bizarre… chemin très particulier et ‘hors du commun’ , correspondant à une installation peu commune de l’IDE Arduino !! Par curiosité comment l’as-tu installé ?

Visiblement pas par la méthode ‘standard’ indiquée içi, méthode la plus souvent utilisée.

A quoi correspond ton dossier .local/share/umake ?

Bonjour,

Le temps passe dramatiquement vite....

[u]En réponse @ al1fch:[/u]

Bon, je suis allé fouiller dans mon journal et ai retrouvé la méthode que j'ai utilisée pour installer Arduino IDE:

"Installer Ubuntu Make : sudo apt-get update sudo apt-get install ubuntu-make Installer Arduino IDE avec Ubuntu Make : sudo umake ide arduino

Ceci téléchargera Arduino IDE depuis le site officiel dans ~/.local/share/umake/ide/arduino et établira les raccourcis et associations de fichiers requises. On peut répéter la manip pour obtenir une version plus récente.

Se rendre dans ~/.local/share/umake/ide/arduino et y ouvrir un terminal. Procéder à l’installation avec :

sudo ./install.sh

Ajout de l’utilisateur au groupe :

sudo usermod -a -G tty Nom_Utilisateur sudo usermod -a -G dialout Nom_Utilisateur modifier les droits de /ttyACM0 avec la commande (la carte doit être connectée !) : sudo chmod a+rw /dev/ttyACM0 il faut ensuite se déconnecter et se reconnecter pour que les modifications soient effectives.

Sources : askubuntu.com projetsdiy.fr doc.ubuntu-fr.org "

Voilou!

Ok, compilation a partir des sources... Pourquoi pas ! (c'est parfois la seule méthode applicable pour ceratins applications)

Le chemin de l'installation n'est effectivement pas le même qu'avec la méthode un peu plus rapide utilisée le plus souvent semble-t-il , indiquée sur le site Arduino. https://www.arduino.cc/en/Guide/Linux