Besoin d'aide pour un moteur avec capteurs de fin de course

Bonjour, je me permet de solliciter votre aide pour le code de mon distributeur de croquettes :slight_smile:

  • j'ai un moteur jgy370 , un L298N, 2 boutons et 2 capteurs de fin de course (micro switch)
  • J'aimerais que le bouton 1 fonctionne avec le capteur 1 et que le bouton 2 fonctionne avec le capteur 2.
  • J'ai remarqué dans ma console que quand un mirco-switch (capteur) est enfoncé son état est HIGH et quand il est relaché son état est LOW
  • Mes micro switch sont branchés sur leur patte VC

Je sais que le L298N n'est pas idéal mais l'idée est de faire une rotation toutes les 24h donc ça ne va pas chauffer et ça fera l'affaire

Fonctionnement souhaité :

  • État initial : Le capteur est relâché (LOW).
  • Appui bref sur le bouton : Le moteur commence à tourner dans un sens.
  • Enfoncement du capteur : Le moteur continue à tourner tant que le capteur est enfoncé (HIGH).
  • Relâchement du capteur : Le moteur s'arrête quand le capteur est relâché (LOW).
  • Le moteur reste arrêté pendant 3 secondes.
  • Le moteur tourne dans l'autre sens.
  • Enfoncement du capteur : Le moteur continue à tourner tant que le capteur est enfoncé (HIGH).
  • Le moteur s'arrête de nouveau lorsque le capteur est relâché (LOW).
  • FIN

Et ça pour le bouton 1 associé avec le capteur 1 et pour le bouton 2 associé au capteur 2.

J'ai fait énormément d'essais avec chatgpt mais impossible de faire fonctionner comme je souhaite. Le code fournit me fait changer le sens du moteur quand le switch est enfoncé or je ne veux pas ça. je veux qu'il change de sens quand le switch est enfoncé puis relâché !

voici mon branchement :
// Définition des broches
const int ena = 5;
const int in1 = 6;
const int in2 = 7;
const int bouton1 = 2;
const int bouton2 = 3;
const int capteur1 = 9;
const int capteur2 = 10;

Quelqu'un pourrait il m'aider s'il vous plait ?
Merci infiniment !!!
( je peux fournir le code qui coince )

ça dépend de comment vous l'avez branché... "branchés sur leur patte VC" ça ne veut pas dire grand chose...

oui - vous :slight_smile:

c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

essayez de définir vos états et transitions et poste le schéma ici. ce sera un bon point de départ

(Et pour simplifier votre gestion des boutons, éventuellement utilisez la bibliothèque Button dans easyRun de @bricoleau ou OneButton de Matthias Hertel ou encore Toggle de @dlloyd.)

Merci pour votre réponse !

Je voulais dire NC (normaly closed)

Je ne vois pas trop comment faire un schéma pour ce système.
J'ai dessiné toutes les pièces sur fusion 360 et je vous partage les screenshots afin que vous compreniez mieux.

Et pour essayer d'être plus clair : Le moteur est relié à une sorte d'hélice. Cette hélice doit faire 1/4 de tour pour distribuer 80 grammes de croquettes puis revenir à sa position initiale. Et elle doit effectuer 1/8 de tour et revenir à sa place pour distribuer une ration plus petite. Et pour cela j'ai modélisé sous mon hélice des "chemins" afin d'enclencher les capteurs de fin de course sur 1/4 de tour environ pour l'un et sur 1/8 de tour pour l'autre.
Ce n'est pas évident à expliquer, mais j'espère qu'aves les screenshots et mon descriptifs vous comprendrez..

Je dois avouer que je n'y connais rien en programmation et que pour l'instant je m'y suis entièrement fié au code de chatgpt mais comme dit il ne fonctionne pas comme je le souhaite.


Merci !

Bonjour martymcfly6677

Bon réflexe :wink:
Voilà la question que j'ai posée à ChatGPT (pour une paire BP FDC):

Soit un Arduino UNO, 1 bouton poussoir (BP) et 1 contact de fin de course (FDC).
Le BP est "appairé" avec le FDC.
Au départ le FDC est relâché et donne un HIGH à la lecture (PULLUP).
Par exemple, si je presse le BP le moteur tourne, le FDC devient actif (LOW) jusqu'au moment où FDC redevient inactif (fin du mouvement). Attente de 2 secondes et mouvement en sens inverse jusqu'è ce que FDC 1 redevienne inactif.
Ecris moi le programme.

Et sa proposition de programme:

const int BP = 2;        // Bouton poussoir
const int FDC = 3;       // Fin de course
const int MOTOR_A = 8;   // Moteur sens A
const int MOTOR_B = 9;   // Moteur sens B

void setup() {
  pinMode(BP, INPUT_PULLUP);
  pinMode(FDC, INPUT_PULLUP);
  pinMode(MOTOR_A, OUTPUT);
  pinMode(MOTOR_B, OUTPUT);

  // Moteur à l'arrêt au démarrage
  stopMotor();
}

void loop() {
  // Attente appui sur le bouton (état LOW car pull-up)
  if (digitalRead(BP) == LOW) {
    // Phase aller
    runMotorForward();
    waitFDCChangeToLOW();     // Attendre que FDC soit actif
    waitFDCChangeToHIGH();    // Attendre que FDC redevienne inactif
    stopMotor();

    delay(2000);  // Pause de 2 secondes

    // Phase retour
    runMotorBackward();
    waitFDCChangeToHIGH();    // Attendre que FDC redevienne inactif
    stopMotor();
  }
}

// Fonctions utilitaires

void runMotorForward() {
  digitalWrite(MOTOR_A, HIGH);
  digitalWrite(MOTOR_B, LOW);
}

void runMotorBackward() {
  digitalWrite(MOTOR_A, LOW);
  digitalWrite(MOTOR_B, HIGH);
}

void stopMotor() {
  digitalWrite(MOTOR_A, LOW);
  digitalWrite(MOTOR_B, LOW);
}

void waitFDCChangeToLOW() {
  while (digitalRead(FDC) != LOW) {
    delay(10); // Anti-rebond
  }
}

void waitFDCChangeToHIGH() {
  while (digitalRead(FDC) != HIGH) {
    delay(10); // Anti-rebond
  }
}

Essaies ça.
Si ça fonctionne, on demandera à ChatGPT de faire de même pour 2 paires BP FDC.

Condition pour que le programme fonctionne, les FDC et les BP doivent être câblés d'un côté à GND et de l'autre sur la pin de l'Arduino (technique du INPUT_PULLUP)

A+
Cordialement
jpbbricole

Hello,

Dis moi si j'ai bien compris STP.

La piéce marron vue de dessus de pose sur la pièce violette.

La partie en bosse de la pièce marron, vue de dessus, fait 1/4 et 1/8 de tout.

Quand ces 2 parties passent au dessus des switch NC, ils sont relâchés donc ouvert, ce qui sur un PULLUP donne un état HIGH.

Ton début de cycle commence quand les 2 switchs sont relachés en même temps, et ensuite, tu tourne la piéce marron dans le sens antihoraire jusqu'à ce que le switch 1/4 de tour soit appuyé (LOW).

Exacte ou non?

Merci beaucoup je vais essayer ça ce soir !! en effet c'est vrai que commencer par un seul BP et un FDC est plus judicieux.
Dans mon cas j'avais tout de suite tout demandé à chatGPT et le soucis que j'ai eu à chaque fois est le comportement des FDC : dès que le FDC était enfoncé le moteur s'arrêtait. IL n'arrivait pas à me programmer ça pour que le premier enfoncement du FDC soit ignoré.

Oui mes BP et FDC sont bien cablés comme ceci. Et j'ai cablé la pin NC pour les FDC .

Hello Jef oui c'est exactement ça !

Sur la broche de l'Arduino, tu dois connecter le NO (Normalement Ouvert) et l'autre broche du FDC à GND.
Pour résumer, en position de départ, BP et FDC relâché, tu dois avoir HIGH sur toutes les entrées.
Ces FDC c'est des commutateurs?

Ça te donne le départ pour ta machine à état, cf le pist de JML à ce propos.

Je ne dirais pas que c'est l'unique solution, mais tu as déjà l'état initiale pour démarrer ta "machine à états" proposée par @J-M-L

Je te suggére aussi de regarder la bibliothéque plcLib.h, il y a des exemples simples sur le github de cette lib
Exemple

Cette lib te permet de faire l'équivalent d'un grafcet simple (étape0-->transition1-->étape1........étape0) une machine d'état qui se pilote très facilement selon moi.

Ok je vais jeter un coup d'oeil, mais comme dit je suis super novice !
Merci beaucoup pour le coup de pouce !

Ce sont des micro-switch comme celui ci :

Pardon mais je n'y comprend pas grand chose :confused:

malheureusement ça ne fonctionne pas, j'ai le même soucis que j'ai depuis le début de mes tests. J'ai bien connecté le FDC sur NO . Mais dès que le FDC est enfoncé le moteur s'arrête, alors que moi j'aimerais qu'il le fasse quand le FDC est relâché. J'ai essayé d'inverser HIGH et LOW dans le code mais rien n'y fait c'est toujours pareil.

Voici mon code :

// Déclaration des broches
const int ena = 5;
const int in1 = 6;
const int in2 = 7;

const int bouton1 = 2;
const int capteur1 = 9;

bool cycleEnCours = false;

void setup() {
  // Configuration des broches
  pinMode(ena, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);

  pinMode(bouton1, INPUT_PULLUP);
  pinMode(capteur1, INPUT_PULLUP);

  digitalWrite(ena, LOW); // Moteur arrêté

  Serial.begin(9600);
}

void loop() {
  // Détection du bouton appuyé
  if (digitalRead(bouton1) == LOW && !cycleEnCours) {
    cycleEnCours = true;

    // === Mouvement avant ===
    Serial.println("Mouvement avant");
    moteurAvant();

    // Attente que FDC passe LOW (contact actif)
    while (digitalRead(capteur1) == HIGH);

    // Puis attendre qu’il repasse HIGH (fin de course atteinte)
    while (digitalRead(capteur1) == LOW);

    arretMoteur();
    Serial.println("Fin mouvement avant");

    delay(2000); // Pause de 2 secondes

    // === Mouvement arrière ===
    Serial.println("Mouvement arrière");
    moteurArriere();

    // Même principe : attendre activation puis relâchement du FDC
    while (digitalRead(capteur1) == HIGH);
    while (digitalRead(capteur1) == LOW);

    arretMoteur();
    Serial.println("Fin mouvement arrière");

    cycleEnCours = false;
  }
}

void moteurAvant() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(ena, 200); // Vitesse modérée
}

void moteurArriere() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(ena, 200); // Vitesse modérée
}

void arretMoteur() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(ena, 0);
}

Bonsoir martymcfly6677
Je ne peut pas essayer maintenant, mais, afin de contrôler ton câblage, fais un petit bout de programme qui lit tes entrées, qui doivent donner 0 quand le switch est pressé et 1 quand il est relâché.

PS: Concernant le programme de l'IA, je me suis aperçu que je n'avais pas indiqué le pin ENA, pour régler la vitesse, je corrige ça demain.

A+

J'ai reformulé dans chat GPT et vérifié avec des debug et je tiens une solution : ca fonctione désormais avec un bouton et un FDC !! Je copierai le code ici dès que ça marche avec les 2 boutons et 2 FDC !!

Ben tant qu'on ne se penche pas un peu de prés sur un sujet, on reste super novice non?

Ton switch, c'est un switch Simple Pôle (SP), c'est a dire qu'il y a une broche pour le COMMUN
Double Travail (DT) et 2 contact, 1 Normalement Ouvert (NO) et 1 Normalement Fermé (NF)


Tu câble un fil sur le COM et ensuite tu choisis si tu veut qu'il soit Normalement Ouvert au repos (NO) ou Normalement Fermé au repos (NC).

Pour le code,

C'est dommage, plcLib est vraiment simple à utilisé (mais plus compliqué à expliquer à 22h30).

PS:
Les messages, même effacés, restent lisibles, effectivement c'est plus facile de se faire livrer une solution, je n'ai pas de solution toute prête, désolé.

Pousses un peu plus loin, rajoute à la suite, dans le chat, "fais moi le même programme mais pour 2 paires bouton/fdc de telle façon qu'il n'y a qu'une paire à la fois en fonctionnement"

Pratique ChatGPT :wink:

Bonne nuit
jpbbricole

et voici le code fonctionnel !!
Merci de m'avoir donné le coup de pouce dans la bonne direction :slight_smile:

const int ena = 5;
const int in1 = 6;
const int in2 = 7;

const int bouton1 = 2;
const int capteur1 = 9;

const int bouton2 = 3;
const int capteur2 = 10;

bool cycleEnCours = false;
bool fdcEnfonce = false;

void setup() {
  pinMode(ena, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);

  pinMode(bouton1, INPUT_PULLUP);
  pinMode(capteur1, INPUT_PULLUP);
  pinMode(bouton2, INPUT_PULLUP);
  pinMode(capteur2, INPUT_PULLUP);

  digitalWrite(ena, LOW);
  Serial.begin(9600);
}

void loop() {
  if (!cycleEnCours) {
    if (digitalRead(bouton1) == LOW) {
      gererCycle(capteur1, "FDC 1");
    } else if (digitalRead(bouton2) == LOW) {
      gererCycle(capteur2, "FDC 2");
    }
  }
}

void gererCycle(int pinCapteur, const char* label) {
  cycleEnCours = true;
  fdcEnfonce = false;

  // === MOTEUR AVANT ===
  Serial.print("Moteur AVANT - ");
  Serial.println(label);
  moteurAvant();

  while (true) {
    int etatFDC = digitalRead(pinCapteur);
    Serial.print(label);
    Serial.print(" AVANT: ");
    Serial.println(etatFDC);

    if (etatFDC == LOW) fdcEnfonce = true;
    if (fdcEnfonce && etatFDC == HIGH) break;
  }

  arretMoteur();
  Serial.println("ARRÊT moteur AVANT");
  delay(2000);

  // === MOTEUR ARRIÈRE ===
  Serial.print("Moteur ARRIÈRE - ");
  Serial.println(label);
  moteurArriere();
  fdcEnfonce = false;

  while (true) {
    int etatFDC = digitalRead(pinCapteur);
    Serial.print(label);
    Serial.print(" ARRIÈRE: ");
    Serial.println(etatFDC);

    if (etatFDC == LOW) fdcEnfonce = true;
    if (fdcEnfonce && etatFDC == HIGH) break;
  }

  arretMoteur();
  Serial.println("ARRÊT moteur ARRIÈRE");

  cycleEnCours = false;
}

void moteurAvant() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(ena, 200);
}

void moteurArriere() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(ena, 200);
}

void arretMoteur() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  analogWrite(ena, 0);
}

OK je comprends mieux comment fonctionne les switch ! Je m'en doutait pour le NO et le NC mais pas pour le premier état !
En effet j'ai effacé le commentaire car en poussant un peu avec chatGPT je suis arrivé à une solution qui me semble fonctionner ! Et peut être que c'est un peu trop opportuniste de demander un code tout fait. Je comprend tout à fait l'incitation à apprendre et je suis comme ça dans mon domaine aussi, mais pour la programmation Arduino c'est vraiment exceptionnel pour moi..
Quoi qu'il en soit je suis super agréablement surpris de voir à quel point vous avez été plusieurs à me répondre et à m'aider rapidement ! Super communauté