Le Wemos s'étant retrouvé avec une mémoire saturée alors que le programme n'est pas complet je suis partit vers un Nano.
Dans une évolution prochaine un Wemos dialoguera avec le Nano pour permettre une communication sans fil entre l'ascenseur et, la centrale ou un téléphone.
Pour le moment, l'ajout de la sauvegarde des positions dans la mémoire EEPROM permanente du Nano.
Ce type de mémoire a une durée de vie faible comparé a la mémoire Flash. 1 000 000 de cycles d'écriture avant de connaitre des difficultés.
Ce qui nous laisse, si on considère que l'on efface et écrit en mémoire chaque jour de l'année 100 cycles 27 années avant d'être ennuyé.
Si on ne fait que 10 cycle par jour, c'est 273 ans de tranquillité. Je ne sais pas pour vous, mais moi je mangerais les pissenlits par la racine depuis longtemps.

Je parle bien d'effacements et d'écriture, pas de lecture. Car en lecture, cela n'abime pas l'EEPROM.
Le programme :
Code : Tout sélectionner
/*
***************************************************
****** Ascenseur avec un moteur pas à pas *******
****** *******
****** Programme V 4.1 *******
****** Du 06/05/2025 *******
****** Par C.ARFEL *******
****** *******
****** Carte Nano *******
****** *******
****** Version 1.0 *******
****** Mise a quai manuelle *******
****** Afficheur lcd 16 x 2 I2C *******
****** RC + 5 sous sol *******
****** Menu par encodeur *******
****** *******
****** *******
****** Liste des bornes utilisées *******
****** *******
****** D5 Capteur infrarouge *******
****** A4 SDA/I2C écran *******
****** A5 SCL/I2C écran *******
****** D2 DIR commande de direction moteur *******
****** D3 STEP commande nb pas moteur *******
****** D5 SW encodeur *******
****** A1 DT encodeur *******
****** A2 Clic encodeur *******
****** D4 ENABLE TMC 2209 *******
****** Arrêt d'urgence + FC total *******
****** RST (reset carte) *******
****** *******
****** Le croquis utilise ***** octets (**%)*******
****** de l'espace de stockage de *******
****** programmes. Le maximum est de *******
****** ****** octets. *******
****** *******
****** Les variables globales utilisent *******
****** **** octets (36%) de mémoire *******
****** dynamique, ce qui laisse **** *******
****** octets pour les variables locales. *******
****** Le maximum est de **** octets. *******
****** *******
****** *******
***************************************************
. Variables and constants in RAM (global, static), used 29024 / 80192 bytes (36%)
║ SEGMENT BYTES DESCRIPTION
╠══ DATA 1540 initialized variables
╠══ RODATA 1172 constants
╚══ BSS 26312 zeroed variables
. Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 60415 / 65536 bytes (92%)
║ SEGMENT BYTES DESCRIPTION
╠══ ICACHE 32768 reserved space for flash instruction cache
╚══ IRAM 27647 code in IRAM
. Code in flash (default, ICACHE_FLASH_ATTR), used 241172 / 1048576 bytes (22%)
║ SEGMENT BYTES DESCRIPTION
╚══ IROM 241172 code in flash
*/
#include <AccelStepper.h> // Bibliothéque moteur pas a pas
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Bibliothéque ecran protocole I2C
#include "RotaryEncoder.h" // Appel de la bibliothéque pour encodeur
#include <EEPROM.h>
#define STEPSS 1 // Nombre par pas d'encodeur
#define POSMIN -5 // Position MINI de l'encodeur
#define POSMAX 9 // Position MAX de l'encodeur
#define BPE 5 // Borne SW encodeur (bouton)
#define Enable 4 // Borne Enable Driver TMC 2209
LiquidCrystal_I2C lcd(0x27, 16, 2); // 0x27 ou 0x3F déclaration adresse du lcd
RotaryEncoder encoder(A1, A2); // Borne de l'encodeur (DT, CLK)
const byte pin_DIR = 2; // Borne contrôle pour TMC2209
const byte pin_STEP = 3; // Borne contrôle pour TMC2209
AccelStepper stepper(AccelStepper::DRIVER, pin_STEP, pin_DIR); // création objet Stepper
int Pos0SS ; // Crans moteur pour la position plateau niveau reseau.
long Pos1SS ; // Crans moteur pour la position plateau 1er sous sol
long Pos2SS ; // Crans moteur pour la position plateau 2ème sous sol
long Pos3SS ; // Crans moteur pour la position plateau 3ème sous sol
long Pos4SS ; // Crans moteur pour la position plateau 4ème sous sol
long Pos5SS ; // Crans moteur pour la position plateau 5ème sous sol
int Position = 0; // variable information position du plateau
int Init = 0; // Variable pour l'initialisation
int Ebpe = 10; // Variable position bouton encodeur 1
int lastPos, newPos; // Variable encodeur
long Aller = 0; // Variable destination
long Deplace ; // variable 1 pour le deplacement réglage
void setup()
{
lcd.init(); // Initialisation de l'afficheur
lcd.backlight(); // Allume l'ecran
lcd.clear(); // Efface l'ecran
lcd.setCursor (0,0); // place le curseur sur la ligne 0 a gauche
lcd.print ("*Initialisation*"); // Affichage sur le lcd
lcd.setCursor (0,1); // passe a la ligne suivante
lcd.print ("* du Programme *"); // affichage sur le lcd
stepper.setMaxSpeed(5000.0); // Vitesse max moteur
stepper.setAcceleration(1000.0); // distance accélération / décélération
encoder.setPosition(10 / STEPSS); // Position initiale encodeur
pinMode (BPE, INPUT); // Initialisation en entrée (de la borne D5) du clic encodeur rotatif
pinMode (Enable, OUTPUT); // Initialisation, en sortie (de la borne D4) Enable TMC2209
}
/*
************************
* Fin de la zone SETUP *
************************
*/
/*
****************************
* Séquence initialisation *
****************************
*/
void Initialisation() { // Module initialisation du plateau Recherche du FC
// Il ne se passe rien d'important ici pour le moment a ce stade du programme.
// lecture des niveaux en mémoire
EEPROM.get (1, Pos0SS); // Crans moteur pour la position plateau niveau reseau.
EEPROM.get (10, Pos1SS);
EEPROM.get (20, Pos2SS);
EEPROM.get (30, Pos3SS);
EEPROM.get (40, Pos4SS);
EEPROM.get (50, Pos5SS);
lcd.clear (); // Efface l'ecran
delay (10);
lcd.setCursor (0,0);
lcd.print (" Niveau reseau. ");
delay(10);
lcd.setCursor(0,1); // place le curseur ligne suivante
lcd.print ("** En attente **");
delay (20);
Init = 1; // Informe que l'initialisation a été faite pour ne pas y revenir
}
/*
**************************************
* Fin de la séquence initialisation *
**************************************
*/
/*
*********************************
* Début boucle principale LOOP *
*********************************
*/
void loop()
{
if (Init <1) { // Si 1er passage executer la ligne suivante sinon passer
Initialisation(); // Vas executer le bloc "initialisation"
}
/*
********************************
* Début de la zone des appels *
********************************
*/
/*
****************************************
* Menu selection par encodeur rotatif *
****************************************
*/
// ________________ Zone lecture encodeur rotatif _______________
encoder.tick();
newPos = encoder.getPosition() * STEPSS;
if (newPos < POSMIN) {
encoder.setPosition(POSMIN / STEPSS);
newPos = POSMIN;
}
else if (newPos > POSMAX) {
encoder.setPosition(POSMAX / STEPSS);
newPos = POSMAX;
}
if (lastPos != newPos) {
if (newPos <= 0){ // valable de -5 a 0
delay (100);
lcd.setCursor (0,0);
lcd.print ("Niveau ");
lcd.print (Position);
lcd.print (" ");
delay(100);
lcd.setCursor(0,1); // place le curseur ligne suivante
lcd.print ("Destination : ");lcd.print(newPos);lcd.print(" ");
delay (100);
lastPos = newPos;
}
if (newPos == 1){ Deplace = 10; Affiche1(); lastPos = newPos; } // Valable si 1
if (newPos == 2){ Deplace = 30; Affiche1(); lastPos = newPos; } // Valable si 2
if (newPos == 3){ Deplace = 50; Affiche1(); lastPos = newPos; } // Valable si 3
if (newPos == 4){ Deplace = 100; Affiche1(); lastPos = newPos; } // Valable si 4
if (newPos == 5){ Deplace = -10; Affiche1(); lastPos = newPos; } // Valable si 5
if (newPos == 6){ Deplace = -30; Affiche1(); lastPos = newPos; } // Valable si 6
if (newPos == 7){ Deplace = -50; Affiche1(); lastPos = newPos; } // Valable si 7
if (newPos == 8){ Deplace = -100; Affiche1(); lastPos = newPos; } // Valable si 8
}
if (digitalRead(BPE) == LOW) { // Control si Bouton encodeur actionné
Ebpe = newPos;
delay(500); // Tempo de pause pour éviter la redondance du clic
}
/*
***************************
* Appel Dans les niveaux *
***************************
*/
if (Ebpe == 1) { ReglageNiveau(); } // Réglage niveau +10
if (Ebpe == 2) { ReglageNiveau(); } // Réglage niveau +20
if (Ebpe == 3) { ReglageNiveau(); } // Réglage niveau +50
if (Ebpe == 4) { ReglageNiveau(); } // Réglage niveau +100
if (Ebpe == 5) { ReglageNiveau(); } // Réglage niveau -10
if (Ebpe == 6) { ReglageNiveau(); } // Réglage niveau -20
if (Ebpe == 7) { ReglageNiveau(); } // Réglage niveau -50
if (Ebpe == 8) { ReglageNiveau(); } // Réglage niveau -100
if (Ebpe == 9) { Affiche2(); }
if (Ebpe == 0) { Aller = Pos0SS; Position = 0; Affiche3(); deplacement(); } // Action si choix RC
if (Ebpe == -1) { Aller = Pos1SS; Position = -1; Affiche3(); deplacement(); } // Action si choix -1
if (Ebpe == -2) { Aller = Pos2SS; Position = -2; Affiche3(); deplacement(); } // Action si choix -2
if (Ebpe == -3) { Aller = Pos3SS; Position = -3; Affiche3(); deplacement(); } // Action si choix -3
if (Ebpe == -4) { Aller = Pos4SS; Position = -4; Affiche3(); deplacement(); } // Action si choix -4
if (Ebpe == -5) { Aller = Pos5SS; Position = -5; Affiche3(); deplacement(); } // Action si choix -5
} // Fin du loop
/*
***************************************************
* Fin boucle principale LOOP *
***************************************************
*/
/*
****************
* Affichage 1 *
****************
*/
void Affiche1(){
lcd.clear ();
delay (10);
lcd.setCursor (0,0);
lcd.print (" Reglage niveau ");
delay(10);
lcd.setCursor(0,1);
lcd.print (" ** "); lcd.print (Deplace); lcd.print (" **");
delay (10);
}
/*
********************
* Fin Affichage 1 *
********************
*/
/*
****************
* Affichage 2 *
****************
*/
void Affiche2(){
lcd.clear ();
delay (10);
lcd.setCursor (0,0);
lcd.print ("** En attente **");
delay(10);
lcd.setCursor(0,1);
lcd.print ("** choisissez **");
delay (10);
}
/*
********************
* Fin Affichage 2 *
********************
*/
/*
****************
* Affichage 3 *
****************
*/
void Affiche3(){
lcd.clear ();
delay (10);
lcd.setCursor (0,0);
lcd.print (" Nombre de pas =");
delay(10);
lcd.setCursor(0,1);
lcd.print (Aller);
delay (2000);
}
/*
********************
* Fin Affichage 3 *
********************
*/
/*
************************
* REGLAGE DES NIVEAUX *
************************
*/
void ReglageNiveau(){
digitalWrite (4, LOW); // allimente moteur
delay (100);
if (Position == 0) { Aller = Pos0SS + (Deplace * 10); stepper.runToNewPosition(Aller); Pos0SS = Aller ; EEPROM.put (0, Pos0SS) ; delay(500) ; }
if (Position == -1) { Aller = Pos1SS + (Deplace * 10); stepper.runToNewPosition(Aller); Pos1SS = Aller ; EEPROM.put (10, Pos1SS) ; delay(500) ; }
if (Position == -2) { Aller = Pos2SS + (Deplace * 10); stepper.runToNewPosition(Aller); Pos2SS = Aller ; EEPROM.put (20, Pos2SS) ; delay(500) ; }
if (Position == -3) { Aller = Pos3SS + (Deplace * 10); stepper.runToNewPosition(Aller); Pos3SS = Aller ; EEPROM.put (30, Pos3SS) ; delay(500) ; }
if (Position == -4) { Aller = Pos4SS + (Deplace * 10); stepper.runToNewPosition(Aller); Pos4SS = Aller ; EEPROM.put (40, Pos4SS) ; delay(500) ; }
if (Position == -5) { Aller = Pos5SS + (Deplace * 10); stepper.runToNewPosition(Aller); Pos5SS = Aller ; EEPROM.put (50, Pos5SS) ; delay(500) ; }
lcd.clear ();
delay (10);
lcd.setCursor (0,0);
lcd.print (" Reglage niveau ");
delay(10);
lcd.setCursor(0,1);
lcd.print (" - Fait - ");
delay (1000);
digitalWrite (4, HIGH); // Désallimente moteur
Ebpe = 10; // Place hors champ la variable de l'encodeur pour éviter une boucle infini.
Affiche2() ;
}
/*
****************************
* FIN REGLAGE DES NIVEAUX *
****************************
****************
* DEPLACEMENT *
****************
*/
void deplacement () { // Action selon choix clik
digitalWrite (4, LOW); // allimente moteur
lcd.clear ();
delay (100);
lcd.setCursor (0,0);
lcd.print ("** Plateforme **");
delay(10);
lcd.setCursor(0,1);
lcd.print ("* En mouvement *");
delay (10);
stepper.runToNewPosition(Aller);
delay(1000) ;
Ebpe = 10; // Place hors champ la variable de l'encodeur pour éviter une boucle infini.
Aller = 0;
digitalWrite (4, HIGH); // Désallimente moteur
lcd.clear ();
delay (100);
lcd.setCursor (0,0);
lcd.print ("Niveau ");
lcd.print (Position);
delay(10);
lcd.setCursor(0,1);
lcd.print ("** En attente **");
delay (1000);
}
/*
********************
* FIN DEPLACEMENT *
********************
*********************
* Fin du programme *
*********************
*/
Etape suivante, mise en place d'un capteur (optique ou a effet Hall ou simplement un micro switch (peu fiable) ) pour rechercher le point zéro a l'allumage.
