Automatisme Fauteuil Monte Escalier

Bonjour
Voici le code initial 
//************************************************************************************//
// Association des entrées de la platine, aux sorties utilisées sur notre Arduino Uno //
//************************************************************************************//
const int bouton1 = 5; // Broche du premier bouton poussoir (montée)
const int bouton2 = 6; // Broche du deuxième bouton poussoir (descente)
const int led1 = 2; // Broche de la première LED (allumée si MONTÉE demandée)
const int led2 = 3; // Broche de la deuxième LED (allumée si DESCENTE demandée)
#define bornePWM        10      // On associe la borne "PWM" de la platine à la pin D10 de l'Arduino (PWM possible sur cette broche)
#define borneDIR        9       // On associe la borne "DIR" de la platine à la pin D9 de l'Arduino


int etatBouton1 = 0; // Variable pour stocker l'état du premier bouton
int etatBouton2 = 0; // Variable pour stocker l'état du deuxième bouton
//*************************//
// Constantes du programme //
//*************************//
#define vitesseMinimale            60       // Rapport cylique minimal du signal PWM, pour faire tourner le moteur au minimum de sa vitesse (en pratique, on évitera de trop approcher la valeur  0)
#define vitesseMaximale            255      // Rapport cylique maximal du signal PWM, pour faire tourner le moteur au maximum de sa vitesse


//************************//
// Variables du programme //
//************************//
int vitesse;                    // Spécifie la vitesse de rotation du moteur, entre son minimum (0) et son maximum (255) <= signal PWM

void setup() {
  pinMode(bouton1, INPUT); // Définir le premier bouton comme entrée
  pinMode(bouton2, INPUT); // Définir le deuxième bouton comme entrée
  pinMode(led1, OUTPUT); // Définir la première LED comme sortie
  pinMode(led2, OUTPUT); // Définir la deuxième LED comme sortie
  pinMode(bornePWM, OUTPUT);	//Borne associé à la commande de vitesse en PWM (sortie)
  pinMode(borneDIR, OUTPUT);	//Borne associé au sens de rotation du moteur (sortie)
}

void loop() {
  vitesse = vitesseMinimale;	//Vitesse paramétrée au minimum (on peut changer la valeur mini dans la déclaration des constantes du programme)

  etatBouton1 = digitalRead(bouton1); // Lire l'état du premier bouton
  etatBouton2 = digitalRead(bouton2); // Lire l'état du deuxième bouton

  if (etatBouton1 == HIGH && etatBouton2 == LOW) {	//Bouton montée appuyé ET bouton descente relâché
  // ***************** Pilotage des LEDs (pas nécessaire) ******************** //
    digitalWrite(led1, HIGH); // Allumer la première LED
    digitalWrite(led2, LOW); // Éteindre la deuxième LED

  // ***************** MONTÉE ******************** //
    digitalWrite(borneDIR, HIGH);	//Etat haut sur l'entrée DIR de la platine = montée du monte escalier
    analogWrite(bornePWM, vitesse);	//Commande en vitesse par PWM
  // ********************************************* //

  } else if (etatBouton2 == HIGH && etatBouton1 == LOW) {	//Bouton descente appuyé ET bouton montée relâché
  // ***************** Pilotage des LEDs (pas nécessaire) ******************** //
    digitalWrite(led2, HIGH); // Allumer la deuxième LED
    digitalWrite(led1, LOW); // Éteindre la première LED

  // ***************** DESCENTE ******************* //
    digitalWrite(borneDIR, LOW);	//Etat bas sur l'entrée DIR de la platine = descente du monte escalier
    analogWrite(bornePWM, vitesse);	//Commande en vitesse par PWM
  // ********************************************* //

  } else {
  // ***************** Pilotage des LEDs (pas nécessaire) ******************** //
    digitalWrite(led1, LOW); // Éteindre la première LED
    digitalWrite(led2, LOW); // Éteindre la deuxième LED
  // ***************** ARRÊT du moteur ******************** //
    analogWrite(bornePWM, 0);	//Arrêt du moteur PWM=0
  }

}

bras_Montee_Descente_v2(2).ino (3,8 Ko)

Je souhaite ajouter les fins de course qui sont embarqués sur le fauteuil
un fc :upper limit ralentissement du fauteuil : sollicité en bas du rail par la butée méca
un fc : final limit arrêt en haut ou en bas
un fc lower limit ralentissement du fauteuil : sollicité en haut du rail par la butée méca
Ces fins de course atteignent les butées mécaniques haute et basse qui sont installées sur le rail du monte escalier
Je souhaite de l'aide ayant du mal avec les if , les while
merci par avance

Bonsoir,

Est ce qu'il y a une question asfociée à votre post?

Ma question curiosité par rapport au code:

Est-ce qu'il y a des fin de courses installés sur votre machine?

Ils n'apparaissent pas dans le code.

oui je viens de rajouter un explication supplémentaire à, prpos des fins de course

Bonjour papyjac33400

Ca veut dire que le bouton montée ou descente est appuyé le temps du parcours?
Le fcLower reste actif jusqu'à la fin de course du fauteuil ou c'est une impulsion "au passage"?

A+
Cordialement
jpbbricole

Pour clarifier les infos, si j'ai bien compris:

Il y a 3 FDC sur le fauteuil.
Dans l'ordre mécanique
1 FDC upper en bas
1 FDC haut ou bas au milieu
1 FDC lower en haut

Quand le fauteuil monte, dans l'ordre
FDC lower s'active ---> on ralentit
FDC haut ou bas s'active ---> on s'arrête

Quand le fauteuil descend de tout en haut vers le bad
FDC haut et bas de désactive
FDC lower se désactive
FDC upper s'active ---> on ralentit
FDC haut et bas s'active ---> on s'arrête.

Est-ce exacte?

Quels sont les états de repos des FDC, Fermés au repos/Ouverts activés ou l'inverse?

Il le semble que l'idéal dans votre cas est “la Machine à états” décrite par @J-M-L ICI

PS: C’est bien “upper” qui est en bas et “lower" en haut?

Pour moi “upper limit” = limite supérieure, mais ce n' est qu'un nom.

Bonjour jpbbricole
Non ce sont les boutons 1 et 2 qui sont maintenus pour faire la montée et ou la descente
cela correspond aux microswitch qui sont installés sur les bras du fauteuil

Bonjour jpbbricole
Non ce sont les boutons 1 et 2 qui sont maintenus pour faire la montée et ou la descente
cela correspond aux microswitch qui sont installés sur les bras du fauteuil

les fc sont fermés quand ils ne sont pas sollicités
Détail important:
Quand le fauteuil est arrêté en position haute ou basse on
peut redémarrer avec bouton 1 ou bouton2 pour remonter ou redescendre

Bonsoir papyjac33400

Est ce que le programme du post#1 fonctionne?
Veux tu que je te modifie ce programme afin d'y ajouter les FDC ainsi que le ralentissement ou veux tu plutôt l'explication comment faire?

A+
Bonne soirée
jpbbricole

le programme fonctionne sans les fdc ...mais tu peux le modifier sans pb pour intégrer les fdc ...je patauge trop ..et merci par avance
Le schéma est-il suffisamment explicite ?
Bonne soirée

Bonsoir papyjac33400

Oui tout à fait :+1:

Je te mettrai un maximum de remarques afin de rendre la chose plus compréhensible.
C'est pour demain.

Bonne soirée
jpbbricole

Bonjour papyjac33400

Voilà, c'est fait, j'ai fait les modifications en gardant ton "écriture" du programme, quitte, plus tard à l'optimiser.

Par rapport à ton schéma, il y a un contact de fin pour Haut (borneFDCfinHaut) et pour Bas (borneFDCfinBas), cela permet de savoir où l'on est.
Tout les contacts ajoutés sont d'un côté à GND (technique PULLUP) fermés les FDC donnent un 0 ou LOW.
On pourrait faire le même type de branchements pour les boutons, ça simplifie le câblage, ainsi plus de potentiel comme le 5V. à amener aux contacts ou FDC, seulement du GND.

Le programme:

/*
    Name:       AF_papyjac33400_MonteEscaliers.ino
    Created:	01.12.2025 20:03:46
    Author:     papyjac33400/jpbbricole
	Remarque:	Ajout de fins de course et de ralentissemant à un monte-escaliers #11
				https://forum.arduino.cc/t/automatisme-fauteuil-monte-escalier/1417327
*/
//************************************************************************************//
// Association des entrées de la platine, aux sorties utilisées sur notre Arduino Uno //
//************************************************************************************//
const int bouton1 = 5;			// Broche du premier bouton poussoir (montée)
const int bouton2 = 6;			// Broche du deuxième bouton poussoir (descente)
const int led1 = 2;				// Broche de la première LED (allumée si MONTÉE demandée)
const int led2 = 3;				// Broche de la deuxième LED (allumée si DESCENTE demandée)
#define bornePWM        10		// On associe la borne "PWM" de la platine à la pin D10 de l'Arduino (PWM possible sur cette broche)
#define borneDIR        9		// On associe la borne "DIR" de la platine à la pin D9 de l'Arduino

#define borneFDCfinHaut   7		// On associe la borne "FDCfinH" de la platine à la pin D7 de l'Arduino, fin de course Haut
#define borneFDCfinBas    8		// On associe la borne "FDCfinB" de la platine à la pin D8 de l'Arduino, fin de course Bas
#define borneFDCslowHaut  11	// On associe la borne "FDCSlowH" de la platine à la pin D11 de l'Arduino, Slow mode Haut
#define borneFDCslowBas   12	// On associe la borne "FDCSlowB" de la platine à la pin D12 de l'Arduino, Slow mode Bas
const int fdcEtatOn = HIGH;		// Etat des FDC quand ils sont actifs, un côté du FDC à GND, FDC inactif = LOW

int etatBouton1 = 0; // Variable pour stocker l'état du premier bouton
int etatBouton2 = 0; // Variable pour stocker l'état du deuxième bouton
//*************************//
// Constantes du programme //
//*************************//
#define vitesseMinimale            60       // Rapport cylique minimal du signal PWM, pour faire tourner le moteur au minimum de sa vitesse (en pratique, on évitera de trop approcher la valeur  0)
#define vitesseMaximale            255      // Rapport cylique maximal du signal PWM, pour faire tourner le moteur au maximum de sa vitesse


//************************//
// Variables du programme //
//************************//
int vitesse;                    // Spécifie la vitesse de rotation du moteur, entre son minimum (0) et son maximum (255) <= signal PWM

void setup() {
	Serial.begin(115200);
	
	pinMode(bouton1, INPUT); // Définir le premier bouton comme entrée
	pinMode(bouton2, INPUT); // Définir le deuxième bouton comme entrée
	pinMode(led1, OUTPUT); // Définir la première LED comme sortie
	pinMode(led2, OUTPUT); // Définir la deuxième LED comme sortie
	pinMode(bornePWM, OUTPUT);	//Borne associé à la commande de vitesse en PWM (sortie)
	pinMode(borneDIR, OUTPUT);	//Borne associé au sens de rotation du moteur (sortie)

	// Initialisation des FDC en PULLUP, c'est à dire qu'un côté du contact est à GND et l'autre sur la pin
	pinMode(borneFDCfinHaut, INPUT_PULLUP); //FDC haut
	pinMode(borneFDCfinBas, INPUT_PULLUP); //FDC Bas
	pinMode(borneFDCslowHaut, INPUT_PULLUP); //Slow mode haut
	pinMode(borneFDCslowBas, INPUT_PULLUP); //Slow mode bas
}

void loop() {
	//vitesse = vitesseMinimale;	//Vitesse paramétrée au minimum (on peut changer la valeur mini dans la déclaration des constantes du programme)

	etatBouton1 = digitalRead(bouton1); // Lire l'état du premier bouton
	etatBouton2 = digitalRead(bouton2); // Lire l'état du deuxième bouton
	
	if (etatBouton1 == HIGH && etatBouton2 == LOW && digitalRead(borneFDCfinHaut) != fdcEtatOn) {	//Bouton montée appuyé ET bouton descente relâché et fdcHaut inactif
		// ***************** Pilotage des LEDs (pas nécessaire) ******************** //
		Serial.println("M");
		digitalWrite(led1, HIGH); // Allumer la première LED
		digitalWrite(led2, LOW); // Éteindre la deuxième LED

		// ***************** MONTÉE ******************** //
		digitalWrite(borneDIR, HIGH);	//Etat haut sur l'entrée DIR de la platine = montée du monte escalier
		if (digitalRead(borneFDCslowHaut) == fdcEtatOn){ // Si le FDCslow haut est activé
			vitesse = vitesseMinimale;
		} else { 
		vitesse = vitesseMaximale; 
		}
		analogWrite(bornePWM, vitesse);	//Commande en vitesse par PWM
		// ********************************************* //

		} else if (etatBouton2 == HIGH && etatBouton1 == LOW  && digitalRead(borneFDCfinBas) != fdcEtatOn) {	//Bouton descente appuyé ET bouton montée relâché et fdcBas inactif
		// ***************** Pilotage des LEDs (pas nécessaire) ******************** //
		Serial.println("D");
		digitalWrite(led2, HIGH); // Allumer la deuxième LED
		digitalWrite(led1, LOW); // Éteindre la première LED

		// ***************** DESCENTE ******************* //
		digitalWrite(borneDIR, LOW);	//Etat bas sur l'entrée DIR de la platine = descente du monte escalier
		if (digitalRead(borneFDCslowBas) == fdcEtatOn){ // Si le FDCslow bas est activé
			vitesse = vitesseMinimale;
			} else {
			vitesse = vitesseMaximale;
		}
		analogWrite(bornePWM, vitesse);	//Commande en vitesse par PWM
		// ********************************************* //

		} else {
		Serial.println("S");
		// ***************** Pilotage des LEDs (pas nécessaire) ******************** //
		digitalWrite(led1, LOW); // Éteindre la première LED
		digitalWrite(led2, LOW); // Éteindre la deuxième LED
		// ***************** ARRÊT du moteur ******************** //
		analogWrite(bornePWM, 0);	//Arrêt du moteur PWM=0
	}

}

Si tu mets la console de l'IDE à 115200, tu verra l'état du programme:
S pour Stop
M pour Monter
D pour Descendre

N'hésites, surtout pas à poser des questions :wink:

A+
Bonne journée
jpbbricole

Super ..j'ai du "grain à moudre"...
petite remarque :le fin de course baptisé borneFDCfinHaut et celui borneFDCfinBas est strictement le même ..sur le schéma il s'appelle Final limit
Bravo pour la progr supplémentaire qui me permet de suivre la séquence pas à pas

Bonjour papyjac33400

Oui, mais je l'ai dédoublé de telle façon qu'il y a un fdcFinalHaut et un fdcFinalBas, ainsi quand le siège est à un bout du parcours on sait de quel côté il est.

En écrivant cette réponse et en réfléchissant un peu, il est possible de savoir de quel côté l'on est en lisant le fdcSlow puisque si l'on arrive en fin de course, ce fdcSlow est forcément actif, donc on pourrai se passer de ce fdcFinal que j'ai ajouté.

Je regarde cette méthode.

A+
jpbbricole

ça marche bien... mais quand j'arrive à l'arrêt en haut ou en bas je dois pouvoir repartir ( appui bouton1 ou bouton2) à l'inverse independamment du fdcFinalHaut et fdcFinalBas qui sont libérés par le nouveau déplacement du fauteuil
C'est le fonctionnement classique d'un fauteuil monte escalier


Un bout de grafcet...

Je regarde ça, je vais m'absenter pour environ 2 heures et je m'y réattelle.

Bonjour,

Si mes souvenirs sont bons, le principe du GRAFCET est de décrire le passage d’une étape à l’autre suite à une (seule) transition.

Juste aprés l'étape initiale “0”, vous décrivez 2 transitions pour passer à l’etape “montée” ou “ descente” dont une transition est “MARCHE”.

Je ne crois pas que ce soit trés réglementaire d’avoir 2 transitions successives, mais laissons de côté l'aspect réglementaire, je ne crois tout simplement pas que se soit possible. ou facile à coder.

Tout d’abord, qu’est ce que “MARCHE”, c’est un BP?

Je pense que vous pouvez supprimer cette transition, elle n’est pas utile pour la divergence en OU.

Autre remarque, c’est le principe du GRAFCET.

A partir de l’étape “0”, si vous supprimez la transition “MARCHE” en appuyant sur BP1, vous divergez vers “montée”.

Si vous voulez changer de sens en cours de montée, le GRAFCET que vous décrivez ne vous l’autorise pas. Il vous impose d’attendre d’être arrivé en haut et de retour à l’étape “0”, vous n’avez pas le choix.

C’est le principe de l’ascenseur, vous ne pouvez pas changer de sens tant que vous ne vous n’êtes pas arrêté à l’étage initialement demandé.

Avec de la logique combinatoire, on aurait pus envisager ce cas par exemple.

Je maintient BP1, je monte

En cours de route, je relâche BP1, et j’appuie BP2, même si je ne suis pas en haut, je change de sens.

ON EST BIEN D’ACCORD, C’EST LE GRAFCET QUI VOUS INTERESSE?

Dans ce cas, c’est une “machine à états” qu’il vous faut pour résoudre votre probléme.

Il existe aussi des bibliothéque pour programmer un GRAFCET avec Arduino, on en parle pas souvent sur ce forum (il faut que je retrouve son noms).

CORRECTIONS:

J’ai retrouvé le nom et un exemple d’utilisation ici

GRAFCET FEU TRICOLORE

Exact je suis allé trop vite la transition marche est inutile
par contre il manque une transition après les étapes arrêt pour reboucler
Merci pour votre message

Ce que vous voulez faire dans l’étape “Arrêt”, vous pouvez le déplacer dans l’étape “0”.

De même que aprés les transitions upper limite ou lower limit, je pense que vous pouvez converger en une seule branche vers l'étape ralentissement.

Du moins je le crois

Sur le GitHub, il y a des exemples de convergences et divergences dans

Ma Gitane (ma chienne) demande sa ballade avant que le soleil se couche, j'aurais bien fais un essai avant…

Bonjour papyjac33400

Après mûre réflexions (comme on dit :wink:), ne serait ce pas plus judicieux d'avoir, à la place de
2 FDCslow et 1 FDCfin
1 FDCslow et 2 FDCfin

De toute façon, la vitesse est la même que ce soit en montée comme en descente alors que la fin est soit en haut ou soit en bas?

A+
jpbbricole