Bonjour à tous,
Tout d'abord, un grand merci à vous qui m'avez aidé dans la résolution de mon problème. J'ai un peu étudié la librairie Greiman (merci à hbachetti) et je vais dans les prochaines semaines étudier Olikraus et Bitbank2 (merci à fdufnews). En attendant, j'a fais la nouvelles version avec la librairie Greiman et ça fonctionne super, je n'ai plus que la moitié (ou presque 12844 octects de l'espace de stockage de programme et 718 octets de mémoire dynamique utilsée).
Voici le code (que je vais sans doute essayer d'optimiser un peu plus):
Merci encore à tous, Jean Antonio
/*
* COMPTE-A-REBOURS 2.1 26/11/2021 pour faire 4 pains, maison, au maximum, consécutivement
*
*
* ** 1.1 version fonctionnelle avec un afficheur 128*32
* ** 2.0 version fonctionnelle avec un afficheur 128*64 MAIS configuré en 128*32 librairies ADAFRUIT
* ** 2.1 Version fonctionnelle avec un afficheur 128*64 correctement configué librairies GREIMAN
*
* L'objectif est d'avoir un minuteur programmable pour pouvoir faire au moins 4 pains en série.
*
* Fonctionnement:
* - à la mise sous tension, le programme demande le nombre de prog qui devront être exécutés,
* avec un minimum de 1 et un maximum de 4. Le réglage se fait à l'aide des bp2 (+1) et bp4 (-1).
* - Affichage du contenu des 4 programmes contenant chacun un temps de pétrissage, un premier
* temps de levée, un second temps de levée et un temps de cuisson. Si le second temps de levée est mis à 0,
* lors du séquencement, le programme passera automatiquement au temps de cuisson lors de l'exécution.
* TOUS les temps sont introduit en minutes
* - Le passage en mode intro se fait en appuyant 5 secondes sur bp5.
* - Lors de la première utilisation, le mode INTRO est activé automatiquement
* - En mode intro, on utilise bp1 à bp4 pour faire +10, +1, -10, -1. On valide avec bp5.
* - Si il y a eu modif, lors de l'appui sur bp5 la valeur en cours est écrasée en EEPROM.
* - Si il n'y a pas eu de modif, on passe à la valeur suivante sans écriture EEPROM.
* Les boutons poussoirs:
* - bp1 - Démarrage Programme 1
* - Passage séquences programme 1
* - + 10 en mode intro
*
* - bp2 - Démarrage Programme 2
* - Passage séquences programme 2
* - + 1 en mode intro
* - + 1 lors du de la mise sous tension pour le nombre de programme(s)
*
* - bp3 - Démarrage Programme 3
* - Passage séquences programme 3
* - - 10 en mode intro
*
* - bp4 - Démarrage Programme 4
* - Passage séquences programme 4
* - - 1 en mode intro
* - - 1 lors du de la mise sous tension pour le nombre de programme(s)
*
* - bp5 - Validation du nombre de programmes
* - Passage en mode INTRO (modification des temps par étapes et par programmes) en appuyant 5 sec
* - Validation des temps d'étapes
* - Acquittement buzer
* Les Led:
* L1 - Temps programme 1 étape(x) écoulé (s'éteind au passage étape suivante)
* - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 1
*
* L2 - Temps programme 2 étape(x) écoulé (s'éteind au passage étape suivante)
* - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 2
*
* L3 - Temps programme 3 étape(x) écoulé (s'éteind au passage étape suivante)
* - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 3
*
* L4 - Temps programme 4 étape(x) écoulé (s'éteind au passage étape suivante)
* - En mode INTRO indique dans qu'on modifie les temps d'étapes du programme 4
*
* Le buzer - S'enclenche à la fin de chaques étapes de chaques programmes et est acquité par un appui
* sur bp5.
* - S'enclenche pendant 5 sec à une fréquence différente pour indiquer la fin d'attente du
* démarrage du programme suivant lorsque nombre de programme est plus grand que 1 mais au
* maximum égal à 4
* Le temps d'attente est égal au temps de cuisson du programme suivant moins 10 minutes.
*/
#include <EEPROM.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
SSD1306AsciiAvrI2c display;
int ledpin1 = 8;
int ledpin2 = 9;
int ledpin3 = 10;
int ledpin4 = 11;
int ledpin = 13;
int buzerpin = 12;
int bp1; // Bouton Poussoir programme 1
int bp2; // Bouton Poussoir programme 2
int bp3; // Bouton Poussoir programme 3
int bp4; // Bouton Poussoir programme 4
int bp5; // Bouton poussoir acqui, mode intro, validation valeurs intro
int bp1mem = 0; // Pour la détection de flancs montants
int bp2mem = 0; // Pour la détection de flancs montants
int bp3mem = 0; // Pour la détection de flancs montants
int bp4mem = 0; // Pour la détection de flancs montants
int bp5mem = 0; // Pour la détection de flancs montants
int cptbp1 = 0; // Pour les étapes du PROGramme 1
int cptbp2 = 0; // Pour les étapes du PROGramme 2
int cptbp3 = 0; // Pour les étapes du PROGramme 3
int cptbp4 = 0; // Pour les étapes du PROGramme 4
int cptbp5 = 0; // Réserve
long start1 = 0; // Utilisée pour le decompte des temporisations.
long start2 = 0; // Utilisée pour le decompte des temporisations.
long start3 = 0; // Utilisée pour le decompte des temporisations.
long start4 = 0; // Utilisée pour le decompte des temporisations.
long temps1; // Pour conversion ms vers min, sec du PROGramme 1
long temps2; // Pour conversion ms vers min, sec du PROGramme 2
long temps3; // Pour conversion ms vers min, sec du PROGramme 3
long temps4; // Pour conversion ms vers min, sec du PROGramme 4
long tempsintro; // Pour passer en mode INTRO/MODIF valeurs EEPROM
int secondes[4]; // Pour conversion ms vers min, sec du PROGramme 2
int minutes[4]; // Pour conversion ms vers min, sec des PROGrammes
int x = 0; // Indice mémoires INTRO
int y = 0; // Compteur pour lecture contenu EEPROM
bool demcr1 = false; // Pour compte à rebours PROGramme 1
bool demcr2 = false; // Pour compte à rebours PROGramme 2
bool demcr3 = false; // Pour compte à rebours PROGramme 3
bool demcr4 = false; // Pour compte à rebours PROGramme 4
bool buzer = false; // Pour activation du buzer
bool mode_intro = false; // Pour passage en mode INTRO/MODIF des valeurs EEPROM
bool premier_cycle = true; // Premier cycle à la mise sous tension pour avoir des valeur cohérentes dans l'EEPROM
int mem[32]; // ARRAY pour lecture EEPROM
// Pour les 4 programmes
// index 0, 8, 16, 24 (temps de pétrissage)
// index 2, 10, 18, 26 (temps de levée 1)
// index 4, 12, 20, 28 (temps de levée 2)
// index 6, 14, 22, 30 (temps de cuisson)
long attente[3]; // Attente entre programmes
long attentestart = 0;
long attentemaintenant = 0;
long progattente; // Contiendra le temps d'attente pour le prog suivant
// si nombre prog > 1
int nombreprog = 1; // Nombre de programme(s) à faire (minimum 1)
long temps_ms; // Durée départ pour compte à rebours
String etape[4]; // Etape en cours programmes (pétrir, levée1, levée2, cuisson)
String etapetst;
String progr; // Programme en cours pour ode intro
void setup() {
Serial.begin(115200);
display.begin(&Adafruit128x64, 0x3C);
display.setFont(System5x7);
// display.setFont(Callibri10);
// Définition des I/O
pinMode(ledpin,OUTPUT);
pinMode(3,INPUT_PULLUP); // PULLUP permet de cabler sans utiliser une résistance.
pinMode(4,INPUT_PULLUP); // PULLUP permet de cabler sans utiliser une résistance.
pinMode(5,INPUT_PULLUP); // PULLUP permet de cabler sans utiliser une résistance.
pinMode(6,INPUT_PULLUP); // PULLUP permet de cabler sans utiliser une résistance.
pinMode(7,INPUT_PULLUP); // PULLUP permet de cabler sans utiliser une résistance.
pinMode(buzerpin,OUTPUT);
pinMode(ledpin1,OUTPUT);
pinMode(ledpin2,OUTPUT);
pinMode(ledpin3,OUTPUT);
pinMode(ledpin4,OUTPUT);
// Initialisation moniteur série
Serial.begin(9600);
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
// Lecture EEPROM
for(y = 0; y < 32; y += 2) //LECTURE contenu EEPROM des 16 premières positions (0->30)un int prend 2 octets en EEPROM
{
EEPROM.get(y,mem[y]);
Serial.print("Position: ");
Serial.print(y);
Serial.print(" ");
Serial.println(mem[y]);
}
if(mem[0] < 0)
{
Serial.println("Mémoires vides, mode intro");
intro();
}else{
Serial.println("Lecture terminée");
}
tempsattente();
}
void loop() {
// Intro nombre de programme(s) à faire (minimum 1)
if(premier_cycle == true) // Test premier cycle machine
{
while(bp5 == LOW && bp5mem == LOW) // Flanc montant
{
majio();
display.set2X();
display.setCursor(0,2);
display.print("Nbre prog: ");
display.setCursor(60,5);
display.print(nombreprog);
if(bp2 == HIGH && bp2mem == LOW) // Flanc montant
{
if(nombreprog < 4)
{
nombreprog++;
}
bp2mem = bp2;
}
bp2mem = bp2;
if(bp4 == HIGH && bp4mem == LOW) // Flanc montant
{
if(nombreprog > 1)
{
nombreprog--;
}
bp4mem = bp4;
}
bp4mem = bp4;
}
Serial.print(" Nombre de prog: ");
Serial.println(nombreprog);
affich_prog(); // Affichage des 4 programmes
}
majio(); // Mise à jour des I/O
/*
* LANCEMENT PROGRAMME 1
*/
if (bp1 == HIGH && bp1mem == LOW) // Flanc montant
{
Serial.println(" Programme 1 ");
if (bp1 == HIGH && cptbp1 <= 4 && demcr1 == false)
{
demcr1 = true; // Démarrage compte à rebours
cptbp1 += 1;
if(cptbp1 == 3 && mem[4] == 0)
{
cptbp1 += 1;
}
start1 = millis();
if(cptbp1 == 2 && nombreprog > 1)
{
attentestart = millis();
progattente = attente[0];
}
}
}
bp1mem = bp1;
/*
* LANCEMENT PROGRAMME 2
*/
if (bp2 == HIGH && bp2mem == LOW) // Flanc montant
{
Serial.println(" Programme 2");
if (bp2 == HIGH && cptbp2 <= 4 && demcr2 == false)
{
demcr2 = true; // Démarrage compte à rebours
cptbp2 += 1;
if(cptbp2 == 3 && mem[12] == 0)
{
cptbp2 += 1;
}
start2 = millis();
if(cptbp2 == 2 && nombreprog > 1)
{
attentestart = millis();
progattente = attente[1];
}
}
}
bp2mem = bp2;
/*
* LANCEMENT PROGRAMME 3
*/
if (bp3 == HIGH && bp3mem == LOW) // Flanc montant
{
Serial.println(" Programme 3");
if (bp3 == HIGH && cptbp3 <= 4 && demcr3 == false)
{
demcr3 = true; // Démarrage compte à rebours
cptbp3 += 1;
if(cptbp3 == 3 && mem[20] == 0)
{
cptbp3 += 1;
}
if(cptbp3 == 2 && nombreprog > 1)
{
attentestart = millis();
progattente = attente[2];
}
start3 = millis();
}
}
bp3mem = bp3;
/*
* LANCEMENT PROGRAMME 4
*/
if (bp4 == HIGH && bp4mem == LOW) // Flanc montant
{
Serial.println(" Programme 4");
if (bp4 == HIGH && cptbp4 <= 4 && demcr4 == false)
{
demcr4 = true; // Démarrage compte à rebours
cptbp4 += 1;
if(cptbp4 == 3 && mem[28] == 0)
{
cptbp4 += 1;
}
start4 = millis();
}
}
bp4mem = bp4;
//
// Attente pour lancer le programme suivant
//
if(attentestart > 0)
{
attentemaintenant = millis();
if((attentemaintenant - attentestart) >= progattente)
{
tone(buzerpin, 2000, 5000);
attentestart = 0;
attentemaintenant = 0;
}
}
// PROGRAMME 1
if (demcr1 == true)
{
switch (cptbp1)
{
case 1:
etape[0] = "Petr: ";
temps_ms = mem[0] * 60000;
compte_a_rebours_1();
break;
case 2:
etape[0] = "Lev1: ";
temps_ms = mem[2] * 60000;
compte_a_rebours_1();
break;
case 3:
etape[0] = "Lev2: ";
temps_ms = mem[4] * 60000;
compte_a_rebours_1();
break;
case 4:
etape[0] = "Cuis: ";
temps_ms = mem[6] * 60000;
compte_a_rebours_1();
break;
default:
break;
}
}
// PROGRAMME 2
if (demcr2 == true)
{
switch (cptbp2)
{
case 1:
etape[1] = "Petr: ";
temps_ms = mem[8] * 60000;
compte_a_rebours_2();
break;
case 2:
etape[1] = "Lev1: ";
temps_ms = mem[10] * 60000;
compte_a_rebours_2();
break;
case 3:
etape[1] = "Lev2: ";
temps_ms = mem[12] * 60000;
compte_a_rebours_2();
break;
case 4:
etape[1] = "Cuis: ";
temps_ms = mem[14] * 60000;
compte_a_rebours_2();
break;
default:
break;
}
}
// PROGRAMME 3
if (demcr3 == true)
{
switch (cptbp3)
{
case 1:
etape[2] = "Petr: ";
temps_ms = mem[16] * 60000;
compte_a_rebours_3();
break;
case 2:
etape[2] = "Lev1: ";
temps_ms = mem[18] * 60000;
compte_a_rebours_3();
break;
case 3:
etape[2] = "Lev2: ";
temps_ms = mem[20] * 60000;
compte_a_rebours_3();
break;
case 4:
etape[2] = "Cuis: ";
temps_ms = mem[22] * 60000;
compte_a_rebours_3();
break;
default:
break;
}
}
// PROGRAMME 4
if (demcr4 == true)
{
switch (cptbp4)
{
case 1:
etape[3] = "Petr: ";
temps_ms = mem[24] * 60000;
compte_a_rebours_4();
break;
case 2:
etape[3] = "Lev1: ";
temps_ms = mem[26] * 60000;
compte_a_rebours_4();
break;
case 3:
etape[3] = "Lev2: ";
temps_ms = mem[28] * 60000;
compte_a_rebours_4();
break;
case 4:
etape[3] = "Cuis: ";
temps_ms = mem[30] * 60000;
compte_a_rebours_4();
break;
default:
break;
}
}
// Acquittement du buzer
if (bp5 == HIGH && buzer == true)
{
noTone(buzerpin);
buzer = false;
}
if(bp5 == HIGH && cptbp1 == 0) digitalWrite(ledpin1, LOW);
if(bp5 == HIGH && cptbp2 == 0) digitalWrite(ledpin2, LOW);
if(bp5 == HIGH && cptbp3 == 0) digitalWrite(ledpin3, LOW);
if(bp5 == HIGH && cptbp4 == 0) digitalWrite(ledpin4, LOW);
// Entrée en mode INTRO
if(bp5 == HIGH && cptbp1 ==0 && cptbp2 == 0 && cptbp3 == 0 && cptbp4 == 0)
{
tempsintro ++;
}else{
if(bp5 == LOW && tempsintro < 1000)
{
tempsintro = 0;
}
}
if(bp5 == HIGH && (tempsintro > 50000))
{
mode_intro = true;
tempsintro = 0;
}
if(mode_intro == true)
{
intro();
}
// Affichage des programme et temps restants
if(demcr1 == true || demcr2 == true || demcr3 == true || demcr4 == true)
{
int cptj = 0;
for(int cpti = 0; cpti <= 3; cpti++)
{
display.setCursor(8,cptj);
display.print(etape[cpti]);
display.print(minutes[cpti]);
display.print(" min ");
display.print(secondes[cpti]);
display.print(" sec ");
cptj += 2;
}
}
premier_cycle = false; // Fin du premier cycle machine cycle exécuté
}
void majio(void)
{
// Lecture des entrées
bp1 = !digitalRead(3); // En mode PULLUP, les entrées logiques sont inversées:
bp2 = !digitalRead(4); // Si bouton poussoir enfoncé, O (LOW)
bp3 = !digitalRead(5); // Si bouton poussoir relaché, 1 (HIGH)
bp4 = !digitalRead(6); // Il faut donc inverser les valeurs lues.
bp5 = !digitalRead(7);
}
void conversion_1(void)
{
minutes[0] = temps1 / 1000 / 60;
secondes[0] = (temps1 / 1000) - (minutes[0] * 60);
if (cptbp1 == 4 && demcr1 == false)
{
cptbp1 = 0;
}
}
void conversion_2(void)
{
minutes[1] = temps2 / 1000 / 60;
secondes[1] = (temps2 / 1000) - (minutes[1] * 60);
if (cptbp2 == 4 && demcr2 == false)
{
cptbp2 = 0;
}
}
void conversion_3(void)
{
minutes[2] = temps3 / 1000 / 60;
secondes[2] = (temps3 / 1000) - (minutes[2] * 60);
if (cptbp3 == 4 && demcr3 == false)
{
cptbp3 = 0;
}
}
void conversion_4(void)
{
minutes[3] = temps4 / 1000 / 60;
secondes[3] = (temps4 / 1000) - (minutes[3] * 60);
if (cptbp4 == 4 && demcr4 == false)
{
cptbp4 = 0;
}
}
void compte_a_rebours_1(void)
{
digitalWrite(ledpin1, LOW);
long temps_restant = temps_ms - (millis() - start1);
temps1 = temps_restant;
if (temps_restant <= 0)
{
if (demcr1 == true)
{
tone(buzerpin,1500);
digitalWrite(ledpin1,HIGH);
buzer = true;
}
demcr1 = false;
}
conversion_1();
}
void compte_a_rebours_2(void)
{
digitalWrite(ledpin2, LOW);
long temps_restant = temps_ms - (millis() - start2);
temps2 = temps_restant;
if (temps_restant <= 0)
{
if (demcr2 == true)
{
tone(buzerpin,1500);
digitalWrite(ledpin2,HIGH);
buzer = true;
}
demcr2 = false;
}
conversion_2();
}
void compte_a_rebours_3(void)
{
digitalWrite(ledpin3, LOW);
long temps_restant = temps_ms - (millis() - start3);
temps3 = temps_restant;
if (temps_restant <= 0)
{
if (demcr3 == true)
{
tone(buzerpin,1500);
digitalWrite(ledpin3,HIGH);
buzer = true;
}
demcr3 = false;
}
conversion_3();
}
void compte_a_rebours_4(void)
{
digitalWrite(ledpin4, LOW);
long temps_restant = temps_ms - (millis() - start4);
temps4 = temps_restant;
if (temps_restant <= 0)
{
if (demcr4 == true)
{
tone(buzerpin,1500);
digitalWrite(ledpin4,HIGH);
buzer = true;
}
demcr4 = false;
}
conversion_4();
}
void intro(void)
{
bool maj = false; // Pour écriture en EEPROM si INTRO/MODIF du contenu EEPROM
display.set2X();
display.clear();
display.setCursor(0,2);
display.print("Mode INTRO");
delay(2000);
display.clear();
x = 0;
while(x < 32)
{
if(x <= 6)
{
digitalWrite(ledpin1, HIGH);
}
if(x >= 8 && x <= 14)
{
digitalWrite(ledpin1, LOW);
digitalWrite(ledpin2, HIGH);
}
if(x >= 16 && x <= 22)
{
digitalWrite(ledpin2, LOW);
digitalWrite(ledpin3, HIGH);
}
if(x >= 24 && x <= 30)
{
digitalWrite(ledpin3, LOW);
digitalWrite(ledpin4, HIGH);
}
test_etape();
affichmodif();
majio();
if(bp1 == HIGH && bp1mem == LOW) // Flanc montant
{
if(mem[x] < 89)
{
mem[x] += 10;
maj = true;
}
test_etape();
}
bp1mem = bp1;
if(bp2 == HIGH && bp2mem == LOW) // Flanc montant
{
if(mem[x] < 99)
{
mem[x] += 1;
maj = true;
}
test_etape();
}
bp2mem = bp2;
if(bp3 == HIGH && bp3mem == LOW) // Flanc montant
{
if(mem[x] >= 11)
{
mem[x] -= 10;
maj = true;
}
test_etape();
}
bp3mem = bp3;
if(bp4 == HIGH && bp4mem == LOW) // Flanc montant
{
if(mem[x] > 0)
{
mem[x] -= 1;
maj = true;
}
test_etape();
}
bp4mem = bp4;
if(maj)
{
affichmodif();
}
if(bp5 == HIGH && bp5mem == LOW) // Flanc montant
{
if(maj == true)
{
EEPROM.put(x,mem[x]);
maj = false;
}
x += 2;
}
bp5mem = bp5;
}
digitalWrite(ledpin4, LOW);
// display.setTextSize(2);
// display.clearDisplay();
// display.setCursor(0,12);
// display.print(" FIN INTRO");
// display.display();
display.set2X();
display.setCursor(0,0);
display.clearField(0, display.displayWidth(),3);
display.setCursor(0,3);
display.print(" FIN INTRO");
delay(5000);
tempsattente();
affich_prog();
mode_intro = false;
}
void test_etape(void)
{
switch (x)
{
case 0:
progr = ("PROG1: ");
etapetst = "Petr: ";
break;
case 2:
progr = ("PROG1: ");
etapetst = "Lev1: ";
break;
case 4:
progr = ("PROG1: ");
etapetst = "Lev2: ";
break;
case 6:
progr = ("PROG1: ");
etapetst = "Cuis: ";
break;
case 8:
progr = ("PROG2: ");
etapetst = "Petr: ";
break;
case 10:
progr = ("PROG2: ");
etapetst = "Lev1: ";
break;
case 12:
progr = ("PROG2: ");
etapetst = "Lev2: ";
break;
case 14:
progr = ("PROG2: ");
etapetst = "Cuis: ";
break;
case 16:
progr = ("PROG3: ");
etapetst = "Petr: ";
break;
case 18:
progr = ("PROG3: ");
etapetst = "Lev1: ";
break;
case 20:
progr = ("PROG3: ");
etapetst = "Lev2: ";
break;
case 22:
progr = ("PROG3: ");
etapetst = "Cuis: ";
break;
case 24:
progr = ("PROG4: ");
etapetst = "Petr: ";
break;
case 26:
progr = ("PROG4: ");
etapetst = "Lev1: ";
break;
case 28:
progr = ("PROG4: ");
etapetst = "Lev2: ";
break;
case 30:
progr = ("PROG4: ");
etapetst = "Cuis: ";
break;
}
}
void affich_prog(void)
{
////// Affichage des valeurs de temporisation des quatres programmes disponibles.
display.set1X();
display.setCursor(0,0);
display.clear();
int ligne;
int cpti = 0;
int cptj = 0;
int cptk = 0;
for(cpti = 1; cpti <= 4; cpti ++)
{
switch(cptk)
{
case 0:
ligne = 0;
break;
case 8:
ligne = 2;
break;
case 16:
ligne = 4;
break;
case 24:
ligne = 6;
break;
default:
break;
}
display.setCursor(0,ligne);
display.print(" PROG");
display.print(cpti);
display.print(": ");
for(cptj == ligne; cptj <= (cptk + 6); cptj += 2)
{
display.print(mem[cptj]);
display.print(" ");
}
if(cptk <= 30)
{
cptk +=8;
}
}
}
void affichmodif(void)
{
display.set1X();
display.setCursor(16,3);
display.print(progr);
display.print(" ");
display.print(etapetst);
display.print(" ");
display.print(mem[x]);
display.print(" ");
}
void tempsattente(void)
{
// Chargerment des attentes inter-programmes
attente[0] = (mem[6] - 10) * 60000; // Attente lancement prog 2 en ms
attente[1] = (mem[14] - 10) * 60000; // Attente lancement prog 3 en ms
attente[2] = (mem[22] - 10) * 60000; // Attente lancement prog 4 en ms
}