Centre de contrôle d'un dessiccateur de fruits et légumes

Dependencies:   F746_GUI DS1820 JMAPwmOut OneWire QSPI_DISCO_F746NG mbed

Centre de contrôle d'un dessiccateur de fruits et légumes

Le dessiccateur utilise une résistance de chauffage qui sont commandés par deux triacs contrôlés par la carte de développement STMICROELECTRONICS STM32F746G-DISCO. La température est mesurée par du capteur DS18B20. L'écran LCD TFT du STM32F746G-DISCO permet une interface conviviale.

Fournitures :

  • carte de développement STMICROELECTRONICS STM32F746G-DISCO (car elle a un écran LCD TFT) montée sur un circuit imprimé réalisé sous Windows avec le programme TCI.exe;
  • un capteur de température OneWire DS18B20;
  • un module de commande des triacs monté sur un circuit imprimé réalisé avec le programme TCI.exe;
  • un dispositif de chauffage/ventilation obtenu du démontage d'un chauffage électrique d'appoint (à 7€ chez Mr Bricolage);
  • un boitier parallélépipédique réalisé en résine polyester/fibre de verre et équipé de grille en inox;

A faire pour la publication :

  • circuit imprimé carte microcontrôleur
  • circuit imprimé commande triacs
  • boitier

main.cpp

Committer:
jmambroi
Date:
2017-05-27
Revision:
3:5dff448d2ed1
Parent:
2:96d32c19b5be

File content as of revision 3:5dff448d2ed1:

#include "main.hpp"

Serial pc(SERIAL_TX, SERIAL_RX);
using namespace Mikami;

DigitalOut led(LED1);

//Les pattes de commande
//DigitalIn patteDS1820(D14);   // Inutile et néfaste
JMAPwmOut triacChauffage(D9);
//JMAPwmOut triacVentilateur(D10);
JMAPwmOut triacVentilateur(D7);  // D10 ne semble plus fonctionner donc D7
//JMAPwmOut triacChauffage(D0);     // Premier essai
//JMAPwmOut triacVentilateur(D1);

float periodeVentilateur = 200;
float periodeChauffage = 200;

int dureeAttenteTotale[4]   = {0, 0, 0, 10}; //durée d'attente totale, ie départ dans j-h:m:s en décimal, elle est fixe
int dureeAttenteRestante[4] = {0, 0, 0, 10}; //durée d'attente restante j-h:m:s en décimal, elle est décrémentée
int dureeMarcheTotale[4]    = {0, 1, 4, 20}; //durée de marche totale j-h:m:s en décimal
int dureeMarcheRestante[4]  = {0, 1, 4, 20}; //durée de marche restante j-h:m:s en décimal, elle est décrémentée

uint8_t tamponQSPI[TAILLE_TAMPON];
uint8_t etat                            = ARRETE;       // par defaut, il est arrété
uint8_t etatPrecedent                   = ARRETE;       // par defaut, il est arrété
uint8_t ecranActuel                     = ECRAN_ACCUEIL;// c'est l'écran par defaut
// Ventilateur
uint8_t vitesseVentilateur              = 5;            // moyen par defaut, 0 -> 10 ?
int tableauDureeImpulsionVentilateur[11]= {periodeVentilateur, 9 * (periodeVentilateur / 10), 8 * periodeVentilateur / 10, 7 * periodeVentilateur / 10, 6 * periodeVentilateur / 10, 5 * periodeVentilateur / 10, 4 * periodeVentilateur / 10, 3 * periodeVentilateur / 10, 2 * periodeVentilateur / 10, 1 * periodeVentilateur / 10, 1};
bool ventilateurEnMarche                = false;
// Chauffage
int seuilChauffage                      = 0;
int tableauSeuilsChauffage[11] = {10, 9, 8, 6, 5, 4, 3, 2, 1, 1, 0}; // % de la puissance de chauffage 100%, 90%... 20%, 10%, 0%
//int tableauSeuilsChauffage[11] = {10, 10, 9, 9, 8, 8, 6, 6, 3, 1, 0}; // % de la puissance de chauffage 100%, 90%... 20%, 10%, 0%
//int tableauSeuilsChauffage[11] = {6, 6, 6, 6, 5, 5, 4, 4, 3, 1, 0}; // % de la puissance de chauffage 100%, 90%... 20%, 10%, 0%
//int tableauSeuilsChauffage[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // % de la puissance de chauffage 100%, 90%... 20%, 10%

//int tableauDureeImpulsionChauffage[11] = {1, (periodeChauffage / 10), 2*periodeChauffage / 10, 3 * periodeChauffage / 10, 4 * periodeChauffage / 10, 5 * periodeChauffage / 10, 6 * periodeChauffage / 10, 7 * periodeChauffage / 10, 8 * periodeChauffage / 10, 9 * periodeChauffage / 10, periodeChauffage};
int tableauDureeImpulsionChauffage[11] = {periodeChauffage, 9 * (periodeChauffage / 10), 8 * periodeChauffage / 10, 7 * periodeChauffage / 10, 6 * periodeChauffage / 10, 5 * periodeChauffage / 10, 4 * periodeChauffage / 10, 3 * periodeChauffage / 10, 2 * periodeChauffage / 10, 1 * periodeChauffage / 10, 1};
float tableauSeuilsTemperature[11];                     // temperatureConsigne - x% de temperatureConsigne
float temperatureConsigne               = 30.0;         // La température de consigne
float temperature                       = 0.0;          // La température
float temperature2                      = 0.0;          // La température ancienne

bool ok                                 = false;
bool qspiOk                             = false;
bool donneesModifiees                   = false;
int numero                              = 0;
volatile bool clicHorloge               = false;// Ticker Horloge
volatile bool clicSauvegarde            = false;// Ticker Sauvegarde

// l'interface d'accueil
Label attente(0, 20, "", Label::LEFT, Font12, CYAN, NOIR);
Label marche(0, 35, "", Label::LEFT, Font12, CYAN, NOIR);
Label temperatureDessiccateur(0, 50, "", Label::LEFT, Font12, CYAN, NOIR);
Label temperatureConsigneDessiccateur(0, 65, "", Label::LEFT, Font12, CYAN, NOIR);
Label vitesseDessiccateur(0, 80, "", Label::LEFT, Font12, CYAN, NOIR);
Label etatDessiccateur(0, 95, "", Label::LEFT, Font12, ROUGE, NOIR);
Label alerte(0, 250, "", Label::LEFT, Font12, ROUGE, NOIR);
ButtonGroup* groupeBoutons = NULL;  // 

// Les objets
LCD_DISCO_F746NG lcd = attente.GetLcd();
QSPI_DISCO_F746NG qspi;
Ticker horloge;
Ticker sauvegarde;
//DS1820 ds1820(D14);     // D14 : patte de donnees du DS1820
DS1820 ds1820(D8);     // D8 : patte de donnees du DS1820

int main() {
    led = 0;
    pc.baud(115200);        // Connexion au pc
    // Initialisation du capteur de température
    initialiseDS1820();
    initialiseQSPI();

    // Les interruptions
    horloge.attach(&interruptionHorloge, 1.0);
    sauvegarde.attach(&interruptionSauvegarde, 60.0);
    triacChauffage.period_ms(periodeChauffage);
    triacChauffage.pulsewidth_ms(0); // toujours éteint
    triacVentilateur.period_ms(periodeVentilateur);
    triacVentilateur.pulsewidth_ms(0); // toujours éteint

    // set_time(1483228800); //  Sun Jan 1 00:00:00 2017
    // set_time(1483228800 + 3600*24*51+ 12*3600 + 10*60 + 5); // localtime = Tue Feb 21 12:10:05 2017
    for (int i = 0; i < 11; i++) {
        tableauSeuilsTemperature[i] = temperatureConsigne - tableauSeuilsChauffage[i] * temperatureConsigne / 100;   // temperatureConsigne - tableauSeuilsChauffage[i]% de temperatureConsigne
    }
    calculeLargeurImpulsion();
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Seuils : %3.1f, %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f\n", tableauSeuilsTemperature[0], tableauSeuilsTemperature[1], tableauSeuilsTemperature[2], tableauSeuilsTemperature[3], tableauSeuilsTemperature[4], tableauSeuilsTemperature[5], tableauSeuilsTemperature[6], tableauSeuilsTemperature[7], tableauSeuilsTemperature[8], tableauSeuilsTemperature[9], tableauSeuilsTemperature[10]);
    pc.printf(infos);
    groupeBoutons = new ButtonGroup(posXBoutonHaut, posYBoutonHaut, largeurBouton, hauteurBouton, 4, boutonsAccueil, 5, 15, 1, -1,
                                    Font12, BLANC, 0xFF003538, 0xFFB70068, 0xFFFF7FFF);
    // Initialisation avec l'écran d'accueil
    lcd.Clear(NOIR);
    lcd.SetBackColor(NOIR);
//    alerte.Draw("                                         ", NOIR);
    afficheInfos();
    afficheEcranAccueil();
    while(1) {
        if (clicSauvegarde && ((etat ==  EN_MARCHE) || (etat ==  EN_ATTENTE) || (etat ==  EN_PAUSE) || donneesModifiees)) {
            clicSauvegarde = false;
            donneesModifiees = false;
            sauveDonnees();
            }
        else {
            int num = -1;
            groupeBoutons->GetTouchedNumber(num);
            if (num == 3) { //réglage du dessiccateur
//pc.printf(".");
                etatPrecedent = etat;
                ecranActuel = ECRAN_REGLAGE_DESSICCATEUR;
                afficheEcranReglageDessiccateur();
                etat = etatPrecedent;
                ecranActuel = ECRAN_ACCUEIL;
//                pc.printf("Reglage\n");
                afficheEcranAccueil();
                num = -1;
                }
/*            else if (num == 1) {
                etatPrecedent = etat;
                etat = EN_PAUSE;
                pc.printf("En pause\n");
                triacChauffage.pulsewidth_ms(0); // toujours éteint
                triacVentilateur.pulsewidth_ms(0); // toujours éteint
                afficheEcranAccueil();
                num = -1;
                }*/
            else if (num >= 0) {
/*                sprintf(infos, "->%d\n", num);
                pc.printf(infos);*/
                afficheEcranAccueil();
                num = -1;
            }
        }
    }
}

void afficheEcranAccueil(void) {
    int numero = -1;
    if (etat == ARRETE) {
        groupeBoutons->Activate(0);
        groupeBoutons->Inactivate(1);
        groupeBoutons->Inactivate(2);
        groupeBoutons->Activate(3);
        }
    else if (etat == EN_ATTENTE) {
        groupeBoutons->Inactivate(0);
        groupeBoutons->Activate(1);
        groupeBoutons->Activate(2);
        groupeBoutons->Activate(3);
        }
    else if (etat == EN_MARCHE) {
        groupeBoutons->Inactivate(0);
        groupeBoutons->Activate(1);
        groupeBoutons->Activate(2);
        groupeBoutons->Activate(3);
        }
    else if (etat == EN_PAUSE) {
        groupeBoutons->Activate(0);
        groupeBoutons->Inactivate(1);
        groupeBoutons->Inactivate(2);
        groupeBoutons->Activate(3);
    }
    groupeBoutons->DrawAll();
    lcd.SetBackColor(NOIR);
    groupeBoutons->GetTouchedNumber(numero);
//    wait(0.2);
    switch (numero) {
        case 0 :    // Demarrer
//            lcd.SetBackColor(NOIR);
//            alerte.Draw(" je passe en attente !", BLEU);
            etat = EN_ATTENTE;
            seuilChauffage = 0;
            ecranActuel = ECRAN_ACCUEIL;
            groupeBoutons->Inactivate(0);
            groupeBoutons->Activate(1);
            groupeBoutons->Activate(2);
            groupeBoutons->Activate(3);
            break;
        case 1 :    // Arreter -> Suspendre
//            lcd.SetBackColor(NOIR);
//            alerte.Draw(" je me mets en pause !", BLEU);
            etat = ARRETE;
            triacChauffage.pulsewidth_ms(0); // toujours éteint
            triacVentilateur.pulsewidth_ms(0); // toujours éteint
            ecranActuel = ECRAN_ACCUEIL;
            seuilChauffage = 0;
            groupeBoutons->Activate(0);
            groupeBoutons->Inactivate(1);
            groupeBoutons->Inactivate(2);
            groupeBoutons->Activate(3);
            afficheInfos();
            break;
        case 2 :    // Arreter
//            lcd.SetBackColor(NOIR);
//            alerte.Draw(" je m'arrete !", BLEU);
            triacChauffage.pulsewidth_ms(0); // toujours éteint
            triacVentilateur.pulsewidth_ms(0); // toujours éteint
            etat = ARRETE;
            ecranActuel = ECRAN_ACCUEIL;
            seuilChauffage = 0;
            groupeBoutons->Activate(0);
            groupeBoutons->Inactivate(1);
            groupeBoutons->Inactivate(2);
            groupeBoutons->Activate(3);
            initialiseDurees();
            afficheDureeAttenteRestante(CYAN);
            afficheDureeMarcheRestante(CYAN);
            sauveDonnees();
            break;
        case 3 :    // Regler le dessiccateur
//            etat = ARRETE;
            ecranActuel = ECRAN_REGLAGE_DESSICCATEUR;
            seuilChauffage = 0;
            break;
        default :
            break;
    }
    numero = -1;
}

void decrementeDuree(int* ptr) {
    int i = 3;
    bool retenue = false;
    int valeur = ptr[i];
    valeur--;
    if(valeur < 0) {
        valeur = 59;    //59
        retenue = true; //il faut décrémenter les minutes
    }
    ptr[i] = valeur;
    i--;    // Les minutes
    valeur = ptr[i];
    if (retenue) {
        retenue = false;
        valeur--;       //on décrémente les minutes
        if (valeur < 0) {
            valeur = 59;    //59
            retenue = true; //il faut décrémenter les heures
        }
        ptr[i] = valeur;
    }
    i--;    // Les heures
    valeur = ptr[i];
    if (retenue) {
        retenue = false;
        valeur--;       //on décrémente les heures
        if (valeur < 0) {
            valeur = 23;    //23
            retenue = true; //il faut décrémenter les jours
        }
        ptr[i] = valeur;
    }
    i--;    // Les jours
    valeur = ptr[i];
    if (retenue) {
        valeur--;       //on décrémente les jours
        if (valeur < 0) {
            valeur = 0;    // pas de jour négatifs
        }
        ptr[i] = valeur;
    }
}

void afficheInfos(void) {
    if (ecranActuel == ECRAN_ACCUEIL) {
        afficheDureeAttenteRestante(CYAN);
        afficheDureeMarcheRestante(CYAN);
        afficheVitesseVentilateur(CYAN);
        afficheTemperatureConsigne(JAUNE);
        afficheTemperature(CYAN);
        afficheEtat(ROUGE);
    }
}

void afficheDureeAttenteRestante(uint32_t couleur) {
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Duree d'attente : %dj %dh %dmn %ds", dureeAttenteRestante[0], dureeAttenteRestante[1], dureeAttenteRestante[2], dureeAttenteRestante[3]);
    lcd.SetBackColor(NOIR);
    attente.Draw(infos, CYAN);
}

void afficheDureeMarcheRestante(uint32_t couleur) {
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Duree marche    : %dj %dh %dmn %ds", dureeMarcheRestante[0], dureeMarcheRestante[1], dureeMarcheRestante[2], dureeMarcheRestante[3]);
    lcd.SetBackColor(NOIR);
    marche.Draw(infos, couleur);
}

void afficheEtat(uint32_t couleur) {
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Etat du dessiccateur : %s", etats[etat]);
    lcd.SetBackColor(NOIR);
    etatDessiccateur.Draw(infos, couleur);
}

void afficheTemperature(uint32_t couleur) {
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Temperature : %.1f degres (%d, %d)", temperature, seuilChauffage, tableauDureeImpulsionChauffage[seuilChauffage]);
//    sprintf(infos, "Temperature : %.1f degres (%d)", temperature, seuilChauffage);
    lcd.SetBackColor(NOIR);
    temperatureDessiccateur.Draw(infos, couleur);
}

void afficheTemperatureConsigne(uint32_t couleur) {
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Consigne temperature : %.1f degres", temperatureConsigne);
    lcd.SetBackColor(NOIR);
    temperatureConsigneDessiccateur.Draw(infos, couleur);
}

void afficheVitesseVentilateur(uint32_t couleur) {
    char infos[TAILLE_TAMPON]; // Tampon des infos
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "Vitesse du ventilateur : %d (%d)", vitesseVentilateur, tableauDureeImpulsionVentilateur[vitesseVentilateur]);
    lcd.SetBackColor(NOIR);
    vitesseDessiccateur.Draw(infos, couleur);
}

void initialiseDonnees(void) {
    memset(tamponQSPI, 0, TAILLE_TAMPON);
    if (qspi.Read(tamponQSPI, ADRESSE_LECTURE_ECRITURE, TAILLE_TAMPON) != QSPI_OK) {
        pc.printf("Impossible de lire les donnees dans la memoire QSPI\n");
        qspiOk = false;
        }
    else {
        dureeAttenteTotale[0] = tamponQSPI[4];
        dureeAttenteTotale[1] = tamponQSPI[5];
        dureeAttenteTotale[2] = tamponQSPI[6];
        dureeAttenteTotale[3] = tamponQSPI[7];
        dureeAttenteRestante[0] = tamponQSPI[8];
        dureeAttenteRestante[1] = tamponQSPI[9];
        dureeAttenteRestante[2] = tamponQSPI[10];
        dureeAttenteRestante[3] = tamponQSPI[11];
        dureeMarcheTotale[0] = tamponQSPI[12];
        dureeMarcheTotale[1] = tamponQSPI[13];
        dureeMarcheTotale[2] = tamponQSPI[14];
        dureeMarcheTotale[3] = tamponQSPI[15];
        dureeMarcheRestante[0] = tamponQSPI[16];
        dureeMarcheRestante[1] = tamponQSPI[17];
        dureeMarcheRestante[2] = tamponQSPI[18];
        dureeMarcheRestante[3] = tamponQSPI[19];
        etat = tamponQSPI[20]; // etat
        temperatureConsigne = (float)tamponQSPI[22];    // temp
        vitesseVentilateur = tamponQSPI[24];     // vitesse du ventilateur
        pc.printf("Valeurs lues -> attente : %u, %u, %u, %u, %u, %u, %u, %u, marche : %u, %u, %u, %u, %u, %u, %u, %u, etat %u(%u), temp : %u.%u, ventilo : %u\n", tamponQSPI[4], tamponQSPI[5], tamponQSPI[6], tamponQSPI[7], tamponQSPI[8], tamponQSPI[9], tamponQSPI[10], tamponQSPI[11],
                  tamponQSPI[12], tamponQSPI[13], tamponQSPI[14], tamponQSPI[15], tamponQSPI[16], tamponQSPI[17], tamponQSPI[18], tamponQSPI[19], tamponQSPI[20], tamponQSPI[3], tamponQSPI[22] , tamponQSPI[23] , tamponQSPI[24]);
        qspiOk = true;
    }
}

void initialiseDurees(void) {
    for (int i = 0; i < 4; i++) {
        dureeAttenteRestante[i] = dureeAttenteTotale[i];
        dureeMarcheRestante[i] = dureeMarcheTotale[i];
    }
}

void interruptionHorloge(void) {
    clicHorloge = true;
    if (ecranActuel == ECRAN_ACCUEIL) {
        afficheInfos();
    }
    if (ok) {
        temperature = ds1820.read();
        ds1820.startConversion();
    }
    if (etat == ARRETE) {
        if (etatPrecedent != etat) {
            triacChauffage.pulsewidth_ms(0); // toujours éteint
            triacVentilateur.pulsewidth_ms(0); // toujours éteint
            if (ecranActuel == ECRAN_ACCUEIL) {
                afficheEtat(ROUGE);
            }
            etatPrecedent = etat;
        }
        }
    else if (etat == EN_ATTENTE) {
        if ((dureeAttenteRestante[0] <= 0) && (dureeAttenteRestante[1] <= 0) && (dureeAttenteRestante[2] <= 0) && (dureeAttenteRestante[3] <= 0)) {
            if (ecranActuel == ECRAN_ACCUEIL) {
//                alerte.Draw(" je passe en marche !", VERT);
            }
            etat = EN_MARCHE;
            etatPrecedent = EN_ATTENTE;
            sauveDonnees();
            calculeLargeurImpulsion();
            triacChauffage.pulsewidth_ms(tableauDureeImpulsionChauffage[seuilChauffage]); // marche
            triacVentilateur.pulsewidth_ms(tableauDureeImpulsionVentilateur[vitesseVentilateur]); // marche
            dureeAttenteRestante[0] = 0;
            dureeAttenteRestante[1] = 0;
            dureeAttenteRestante[2] = 0;
            dureeAttenteRestante[3] = 0;
            }
        else {
            decrementeDuree(dureeAttenteRestante);
            if (ecranActuel == ECRAN_ACCUEIL) {
                afficheDureeAttenteRestante(CYAN);
                afficheVitesseVentilateur(CYAN);
            }
        }
        if (etatPrecedent != etat) {
            if (ecranActuel == ECRAN_ACCUEIL) {
                afficheEtat(ROUGE);
            }
            etatPrecedent = etat;
        }
        }
    else if (etat == EN_MARCHE) {
        if ((dureeMarcheRestante[0] <= 0) && (dureeMarcheRestante[1] <= 0) && (dureeMarcheRestante[2] <= 0) && (dureeMarcheRestante[3] <= 0)) {
/*            if (ecranActuel == ECRAN_ACCUEIL) {
                lcd.SetBackColor(NOIR);
                alerte.Draw(" je m'arrete !", BLEU);
            }*/
            
    
            etat = ARRETE;
            seuilChauffage = 0;
            etatPrecedent = EN_MARCHE;
            triacChauffage.pulsewidth_ms(0); // toujours éteint
            triacVentilateur.pulsewidth_ms(0); // toujours éteint
            initialiseDurees();
            sauveDonnees();
            clicSauvegarde = true;
            afficheDureeAttenteRestante(CYAN);
            afficheDureeMarcheRestante(CYAN);
            groupeBoutons->Activate(0);
            groupeBoutons->Inactivate(1);
            groupeBoutons->Inactivate(2);
            groupeBoutons->Activate(3);
            groupeBoutons->Inactivate(4);
            }
        else {
            decrementeDuree(dureeMarcheRestante);
            if (ecranActuel == ECRAN_ACCUEIL) {
                calculeLargeurImpulsion();
                triacChauffage.pulsewidth_ms(tableauDureeImpulsionChauffage[seuilChauffage]); // marche
                triacVentilateur.pulsewidth_ms(tableauDureeImpulsionVentilateur[vitesseVentilateur]); // marche
                afficheDureeMarcheRestante(CYAN);
            }
        }
        if (etatPrecedent != etat) {
            afficheEtat(ROUGE);
            etatPrecedent = etat;
        }
        }
    else if (etat == EN_PAUSE) {
        pc.printf("\nJe suis en pause\n");
        triacChauffage.pulsewidth_ms(0); // toujours éteint
        triacVentilateur.pulsewidth_ms(0); // toujours éteint
        etat = ARRETE;
        }
    else {
        if ((ecranActuel == ECRAN_ACCUEIL) && (etat == EN_MARCHE)) {
            calculeLargeurImpulsion();
            triacChauffage.pulsewidth_ms(tableauDureeImpulsionChauffage[seuilChauffage]); // marche
            triacVentilateur.pulsewidth_ms(tableauDureeImpulsionVentilateur[vitesseVentilateur]); // marche
        }
    }
    clicHorloge = false;
}

void afficheEcranReglageDessiccateur(void) {
    lcd.Clear(NOIR);
    triacChauffage.pulsewidth_ms(0); // toujours éteint
    triacVentilateur.pulsewidth_ms(0); // toujours éteint

//    alerte.Draw(etats[etat], VERT);
    Button ok(100, 225, 100, 40, "Valider", Font16, GRIS_SOMBRE, GuiBase::ENUM_BACK, VERT, ROUGE);
    Button annuler(300, 225, 100, 40, "Annuler", Font16, VERT, GuiBase::ENUM_BACK, ROUGE, BLEU);
    // Durée d'attente
    Label duree(15, 0, "Duree d'attente", Label::LEFT, Font16);
    Button plusJ(10, 20, 48, 40, "+");
    Button moinsJ(10, 90, 48, 40, "-");
    Button plusH(60, 20, 48, 40, "+");
    Button moinsH(60, 90, 48, 40, "-");
    Button plusM(110, 20, 48, 40, "+");
    Button moinsM(110, 90, 48, 40, "-");
    Button plusS(160, 20, 48, 40, "+");
    Button moinsS(160, 90, 48, 40, "-");
    Label jour(12, 70, "", Label::LEFT, Font16);
    Label heure(62, 70, "", Label::LEFT, Font16);
    Label minute(112, 70, "", Label::LEFT, Font16);
    Label seconde(162, 70, "", Label::LEFT, Font16);
//  Durée de chauffage
    Label dureec(260, 0, "Duree de chauffage", Label::LEFT, Font16);
    Button plusJc(260, 20, 48, 40, "+");
    Button moinsJc(260, 90, 48, 40, "-");
    Button plusHc(310, 20, 48, 40, "+");
    Button moinsHc(310, 90, 48, 40, "-");
    Button plusMc(360, 20, 48, 40, "+");
    Button moinsMc(360, 90, 48, 40, "-");
    Button plusSc(410, 20, 48, 40, "+");
    Button moinsSc(410, 90, 48, 40, "-");
    Label jourc(262, 70, "", Label::LEFT, Font16);
    Label heurec(312, 70, "", Label::LEFT, Font16);
    Label minutec(362, 70, "", Label::LEFT, Font16);
    Label secondec(412, 70, "", Label::LEFT, Font16);

    // Réglage de la température
    lcd.SetBackColor(NOIR);
    Label temperature(10, 140, "Temperature : ", Label::LEFT, Font16);
    lcd.SetBackColor(NOIR);
    SeekBar barreTemperature(10, 190, 200, 20.0, 60.0, temperatureConsigne,
                             "20", "40", "60", 0xFFB0B0FF, 30, 4, GRIS_CLAIR, 0xFFB0B0B0, NOIR);
    lcd.SetBackColor(NOIR);
    NumericLabel<int> labelTemperature(180, 140, "%3d", (int) barreTemperature.GetValue());

    // Réglage de la vitesse du vetitateur
    lcd.SetBackColor(NOIR);
    Label vitesse(250, 140, "Vitesse : ", Label::LEFT, Font16);
    lcd.SetBackColor(NOIR);
    SeekBar barreVitesse(250, 190, 200, 0, 10, vitesseVentilateur,
                         "0", "5", "10", 0xFFB0B0FF, 40, 5, GRIS_CLAIR, 0xFFB0B0B0, NOIR);
    lcd.SetBackColor(NOIR);
    NumericLabel<int> labelVitesse(400, 140, "%3d", (int) barreVitesse.GetValue());
    
    uint8_t j, h, m, s;
    uint8_t jc, hc, mc, sc;
    if (etat == ARRETE) {
        j = dureeAttenteTotale[0];
        h = dureeAttenteTotale[1];
        m = dureeAttenteTotale[2];
        s = dureeAttenteTotale[3];
        jc = dureeMarcheTotale[0];
        hc = dureeMarcheTotale[1];
        mc = dureeMarcheTotale[2];
        sc = dureeMarcheTotale[3];
        }
    else if (etat == EN_ATTENTE) {
        j = dureeAttenteRestante[0];
        h = dureeAttenteRestante[1];
        m = dureeAttenteRestante[2];
        s = dureeAttenteRestante[3];
        jc = dureeMarcheTotale[0];
        hc = dureeMarcheTotale[1];
        mc = dureeMarcheTotale[2];
        sc = dureeMarcheTotale[3];
        }
    else if (etat == EN_MARCHE) {
        j = dureeAttenteTotale[0];
        h = dureeAttenteTotale[1];
        m = dureeAttenteTotale[2];
        s = dureeAttenteTotale[3];
        jc = dureeMarcheRestante[0];
        hc = dureeMarcheRestante[1];
        mc = dureeMarcheRestante[2];
        sc = dureeMarcheRestante[3];
        }
    else if (etat == EN_PAUSE) {
        j = dureeAttenteTotale[0];
        h = dureeAttenteTotale[1];
        m = dureeAttenteTotale[2];
        s = dureeAttenteTotale[3];
        jc = dureeMarcheRestante[0];
        hc = dureeMarcheRestante[1];
        mc = dureeMarcheRestante[2];
        sc = dureeMarcheRestante[3];
    }
    char tampon[TAILLE_TAMPON];
    sprintf(tampon, "%us", s);    
    seconde.Draw(tampon);
    sprintf(tampon, "%umn", m);
    minute.Draw(tampon);
    sprintf(tampon, "%uh", h);
    heure.Draw(tampon);
    sprintf(tampon, "%uj", j);
    jour.Draw(tampon);

    sprintf(tampon, "%us", sc);    
    secondec.Draw(tampon);
    sprintf(tampon, "%umn", mc);
    minutec.Draw(tampon);
    sprintf(tampon, "%uh", hc);
    heurec.Draw(tampon);
    sprintf(tampon, "%uj", jc);
    jourc.Draw(tampon);

    while (!(ok.Touched() || annuler.Touched())) {
        if (barreTemperature.Slide()) {
            lcd.SetBackColor(NOIR);
            labelTemperature.Draw("%3d", (int) barreTemperature.GetValue());
        }        
        if (barreVitesse.Slide()) {
            lcd.SetBackColor(NOIR);
            labelVitesse.Draw("%3d", (int) barreVitesse.GetValue());
        }        
        if (plusJ.Touched()) {
            if (j < 31)
                j++;
            sprintf(tampon, "%uj", j);
            jour.Draw(tampon);
            wait(0.2);
            plusJ.Draw();
            }
        else if (plusH.Touched()) {
            if (h < 23)
                h++;
            else if (h >= 23)
                h = 0;
            sprintf(tampon, "%uh", h);
            heure.Draw(tampon);
            wait(0.2);
            plusH.Draw();
            }
        else if (plusM.Touched()) {
            if (m < 59)
                m++;
            else if (m >= 59)
                m = 0;
            sprintf(tampon, "%umn", m);
            minute.Draw(tampon);
            wait(0.2);
            plusM.Draw();
            }
        else if (plusS.Touched()) {
            if (s < 59)
                s++;
            else if (s >= 59)
                s = 0;
            sprintf(tampon, "%us", s);
            seconde.Draw(tampon);
            wait(0.2);
            plusS.Draw();
            }
        else if (moinsJ.Touched()) {
            if (j > 0)
                j--;
            sprintf(tampon, "%uj", j);
            jour.Draw(tampon);
            wait(0.2);
            moinsJ.Draw();
            }
        else if (moinsH.Touched()) {
            if (h > 0)
                h--;
            else if (h <= 0)
                h = 23;
            sprintf(tampon, "%uh", h);
            heure.Draw(tampon);
            wait(0.2);
            moinsH.Draw();
            }
        else if (moinsM.Touched()) {
            if (m > 0)
                m--;
            else if (m <= 0)
                m = 59;
            sprintf(tampon, "%umn", m);
            minute.Draw(tampon);
            wait(0.2);
            moinsM.Draw();
            }
        else if (moinsS.Touched()) {
            if (s > 0)
                s--;
            else if (s <= 0)
                s = 59;
            sprintf(tampon, "%us", s);
            seconde.Draw(tampon);
            wait(0.2);
            moinsS.Draw();
            }
        // Durée chauffage, plus
        else if (plusJc.Touched()) {
            if (jc < 31)
                jc++;
            sprintf(tampon, "%uj", jc);
            jourc.Draw(tampon);
            wait(0.2);
            plusJc.Draw();
            }
        else if (plusHc.Touched()) {
            if (hc < 23)
                hc++;
            else if (hc >= 23)
                hc = 0;
            sprintf(tampon, "%uh", hc);
            heurec.Draw(tampon);
            wait(0.2);
            plusHc.Draw();
            }
        else if (plusMc.Touched()) {
            if (mc < 59)
                mc++;
            else if (mc >= 59)
                mc = 0;
            sprintf(tampon, "%umn", mc);
            minutec.Draw(tampon);
            wait(0.2);
            plusMc.Draw();
            }
        else if (plusSc.Touched()) {
            if (sc < 59)
                sc++;
            else if (sc >= 59)
                sc = 0;
            sprintf(tampon, "%us", sc);
            secondec.Draw(tampon);
            wait(0.2);
            plusSc.Draw();
            }
        // Moins
        else if (moinsJc.Touched()) {
            if (jc > 0)
                jc--;
            sprintf(tampon, "%uj", jc);
            jourc.Draw(tampon);
            wait(0.2);
            moinsJc.Draw();
            }
        else if (moinsHc.Touched()) {
            if (hc > 0)
                hc--;
            else if (hc <= 0)
                hc = 23;
            sprintf(tampon, "%uh", hc);
            heurec.Draw(tampon);
            wait(0.2);
            moinsHc.Draw();
            }
        else if (moinsMc.Touched()) {
            if (mc > 0)
                mc--;
            else if (mc <= 0)
                mc = 59;
            sprintf(tampon, "%umn", mc);
            minutec.Draw(tampon);
            wait(0.2);
            moinsMc.Draw();
            }
        else if (moinsSc.Touched()) {
            if (sc > 0)
                sc--;
            else if (sc <= 0)
                sc = 59;
            sprintf(tampon, "%us", sc);
            secondec.Draw(tampon);
            wait(0.2);
            moinsSc.Draw();
        }
    }
    if (ok.Touched()) {
        temperatureConsigne = (int) barreTemperature.GetValue();
        vitesseVentilateur = (int) barreVitesse.GetValue();
        // Il faut que la vitesse du ventilateur soit cohérente par rapport à la puissance de chauffage
        if ((temperatureConsigne >= 50) && (vitesseVentilateur < 10))
            vitesseVentilateur = 10;
        else if ((temperatureConsigne >= 40) && (vitesseVentilateur < 5))
            vitesseVentilateur = 5;
        else if ((temperatureConsigne >= 30) && (vitesseVentilateur < 3))
            vitesseVentilateur = 3;
        for (int i = 0; i < 11; i++) {
            tableauSeuilsTemperature[i] = temperatureConsigne - tableauSeuilsChauffage[i] * temperatureConsigne / 100;   // temperatureConsigne - tableauSeuilsChauffage[i]% de temperatureConsigne
        }
        if (etat == ARRETE) {
            triacChauffage.pulsewidth_ms(0);
            triacVentilateur.pulsewidth_ms(0);
            dureeAttenteTotale[0] = j;
            dureeAttenteTotale[1] = h;
            dureeAttenteTotale[2] = m;
            dureeAttenteTotale[3] = s;
            dureeMarcheTotale[0] = jc;
            dureeMarcheTotale[1] = hc;
            dureeMarcheTotale[2] = mc;
            dureeMarcheTotale[3] = sc;
            dureeAttenteRestante[0] = j;
            dureeAttenteRestante[1] = h;
            dureeAttenteRestante[2] = m;
            dureeAttenteRestante[3] = s;
            dureeMarcheRestante[0] = jc;
            dureeMarcheRestante[1] = hc;
            dureeMarcheRestante[2] = mc;
            dureeMarcheRestante[3] = sc;
            }
        else if (etat == EN_ATTENTE) {
            triacChauffage.pulsewidth_ms(0);
            triacVentilateur.pulsewidth_ms(0);
            dureeMarcheTotale[0] = jc;
            dureeMarcheTotale[1] = hc;
            dureeMarcheTotale[2] = mc;
            dureeMarcheTotale[3] = sc;
            dureeAttenteRestante[0] = j;
            dureeAttenteRestante[1] = h;
            dureeAttenteRestante[2] = m;
            dureeAttenteRestante[3] = s;
            }
        else if (etat == EN_PAUSE) {
            triacChauffage.pulsewidth_ms(0);
            triacVentilateur.pulsewidth_ms(0);
            dureeMarcheTotale[0] = jc;
            dureeMarcheTotale[1] = hc;
            dureeMarcheTotale[2] = mc;
            dureeMarcheTotale[3] = sc;
            dureeAttenteRestante[0] = j;
            dureeAttenteRestante[1] = h;
            dureeAttenteRestante[2] = m;
            dureeAttenteRestante[3] = s;
            }
        else if (etat == EN_MARCHE) {
            calculeLargeurImpulsion();
            triacChauffage.pulsewidth_ms(tableauDureeImpulsionChauffage[seuilChauffage]); // marche
            triacVentilateur.pulsewidth_ms(tableauDureeImpulsionVentilateur[vitesseVentilateur]); // marche
            dureeAttenteTotale[0] = j;
            dureeAttenteTotale[1] = h;
            dureeAttenteTotale[2] = m;
            dureeAttenteTotale[3] = s;
            dureeMarcheRestante[0] = jc;
            dureeMarcheRestante[1] = hc;
            dureeMarcheRestante[2] = mc;
            dureeMarcheRestante[3] = sc;
        }
        char infos[TAILLE_TAMPON]; // Tampon des infos
        memset(infos, 0, TAILLE_TAMPON);
        sprintf(infos, "Seuils : %3.1f, %3.1f %3.1f %3.1f, %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f %3.1f", tableauSeuilsTemperature[0], tableauSeuilsTemperature[1], tableauSeuilsTemperature[2], tableauSeuilsTemperature[3], tableauSeuilsTemperature[4], tableauSeuilsTemperature[5], tableauSeuilsTemperature[6], tableauSeuilsTemperature[7], tableauSeuilsTemperature[8], tableauSeuilsTemperature[9], tableauSeuilsTemperature[10]);
        pc.printf("\n");
        pc.printf(infos);
        pc.printf("\n");
        numero = 0;
        lcd.SetBackColor(NOIR);
//        alerte.Draw(infos, CYAN);
//        donneesModifiees = true;
        sauveDonnees();
//        wait(1);
        }
    else if (annuler.Touched()) {
        if (etat == EN_MARCHE) {
            calculeLargeurImpulsion();
            triacChauffage.pulsewidth_ms(tableauDureeImpulsionChauffage[seuilChauffage]); // marche
            triacVentilateur.pulsewidth_ms(tableauDureeImpulsionVentilateur[vitesseVentilateur]); // marche
        }
    }
    lcd.Clear(NOIR);
    ecranActuel = ECRAN_ACCUEIL;
    etat = etatPrecedent;
    afficheEcranAccueil();
//    alerte.Draw(etats[etat], VERT_SOMBRE);
//    wait(0.5);
}

void sauveDonnees(void) {
    int temperature, dixieme;
    qspi.Erase_Block(ADRESSE_LECTURE_ECRITURE);
    memset(tamponQSPI, 0, TAILLE_TAMPON);
    tamponQSPI[0] = (uint8_t)'J';
    tamponQSPI[1] = (uint8_t)'M';
    tamponQSPI[2] = (uint8_t)'A';
    tamponQSPI[3] = etat;
    tamponQSPI[4] = dureeAttenteTotale[0];
    tamponQSPI[5] = dureeAttenteTotale[1];
    tamponQSPI[6] = dureeAttenteTotale[2];
    tamponQSPI[7] = dureeAttenteTotale[3];
    tamponQSPI[8] = dureeAttenteRestante[0];
    tamponQSPI[9] = dureeAttenteRestante[1];
    tamponQSPI[10] = dureeAttenteRestante[2];
    tamponQSPI[11] = dureeAttenteRestante[3];
    tamponQSPI[12] = dureeMarcheTotale[0];
    tamponQSPI[13] = dureeMarcheTotale[1];
    tamponQSPI[14] = dureeMarcheTotale[2];
    tamponQSPI[15] = dureeMarcheTotale[3];
    tamponQSPI[16] = dureeMarcheRestante[0];
    tamponQSPI[17] = dureeMarcheRestante[1];
    tamponQSPI[18] = dureeMarcheRestante[2];
    tamponQSPI[19] = dureeMarcheRestante[3];
    tamponQSPI[20] = etat; // etat
    tamponQSPI[21] = 1;     // Température de consigne ; signe 0 = -; 1 = +
    temperature = (int) temperatureConsigne;
    dixieme = (int)((temperatureConsigne - temperature) * 10);
    tamponQSPI[22] = temperature;    // temp
    tamponQSPI[23] = dixieme;     // dixiemes de degré
    tamponQSPI[24] = vitesseVentilateur;     // force du ventilateur
    if (qspi.Write(tamponQSPI, ADRESSE_LECTURE_ECRITURE, TAILLE_TAMPON) != QSPI_OK) {
        pc.printf("\nSauvegarde en memoire QSPI non realisee\n");
        qspiOk = false;
        }
    else {
        pc.printf("\nSauvegarde en memoire QSPI reussie\n");
        numero = 0;
/*        pc.printf("Valeur sauvegardee, attente : %u, %u, %u, %u, %u, %u, %u, %u, marche : %u, %u, %u, %u, %u, %u, %u, %u, etat %u, temp : %u.%u, ventilo : %u\n", tamponQSPI[4], tamponQSPI[5], tamponQSPI[6], tamponQSPI[7], tamponQSPI[8], tamponQSPI[9], tamponQSPI[10], tamponQSPI[11],
                  tamponQSPI[12], tamponQSPI[13], tamponQSPI[14], tamponQSPI[15], tamponQSPI[16], tamponQSPI[17], tamponQSPI[18], tamponQSPI[19], tamponQSPI[20], tamponQSPI[22] , tamponQSPI[23] , tamponQSPI[24]);
        pc.printf("Verif temperatures : %3.1f -> %u, %u, \n", temperatureConsigne, temperature, dixieme);
        memset(tamponQSPI, 0, TAILLE_TAMPON);
        qspi.Read(tamponQSPI, ADRESSE_LECTURE_ECRITURE, TAILLE_TAMPON);
        pc.printf("Valeurs enregistrees, attente : %u, %u, %u, %u, %u, %u, %u, %u, marche : %u, %u, %u, %u, %u, %u, %u, %u, etat %u, temp : %u.%u, ventilo : %u\n", tamponQSPI[4], tamponQSPI[5], tamponQSPI[6], tamponQSPI[7], tamponQSPI[8], tamponQSPI[9], tamponQSPI[10], tamponQSPI[11],
                    tamponQSPI[12], tamponQSPI[13], tamponQSPI[14], tamponQSPI[15], tamponQSPI[16], tamponQSPI[17], tamponQSPI[18], tamponQSPI[19], tamponQSPI[20], tamponQSPI[22] , tamponQSPI[23] , tamponQSPI[24]);*/
    }

}

void interruptionSauvegarde(void) {
    clicSauvegarde = true;
}

void initialise(void) {
//    qspi.Erase_Block(ADRESSE_LECTURE_ECRITURE);
    memset(tamponQSPI, 0, TAILLE_TAMPON);
    tamponQSPI[0] = (uint8_t)'J';
    tamponQSPI[1] = (uint8_t)'M';
    tamponQSPI[2] = (uint8_t)'A';
    tamponQSPI[3] = ARRETE; // etat
    tamponQSPI[4] = dureeAttenteTotale[0];
    tamponQSPI[5] = dureeAttenteTotale[1];
    tamponQSPI[6] = dureeAttenteTotale[2];
    tamponQSPI[7] = dureeAttenteTotale[3];
    tamponQSPI[8] = dureeAttenteRestante[0];
    tamponQSPI[9] = dureeAttenteRestante[1];
    tamponQSPI[10] = dureeAttenteRestante[2];
    tamponQSPI[11] = dureeAttenteRestante[3];
    tamponQSPI[12] = dureeMarcheTotale[0];
    tamponQSPI[13] = dureeMarcheTotale[1];
    tamponQSPI[14] = dureeMarcheTotale[2];
    tamponQSPI[15] = dureeMarcheTotale[3];
    tamponQSPI[16] = dureeMarcheRestante[0];
    tamponQSPI[17] = dureeMarcheRestante[1];
    tamponQSPI[18] = dureeMarcheRestante[2];
    tamponQSPI[19] = dureeMarcheRestante[3];
    tamponQSPI[20] = ARRETE; // etat
    tamponQSPI[21] = 1;     // Température de consigne ; signe 0 = -; 1 = +
    tamponQSPI[22] = 30;    // temp
    tamponQSPI[23] = 5;     // dixiemes de degré
    tamponQSPI[24] = 5;     // force du ventilateur
    if (qspi.Write(tamponQSPI, ADRESSE_LECTURE_ECRITURE, TAILLE_TAMPON) != QSPI_OK) {
        pc.printf("Memoire non initialisee\n");
        qspiOk = false;
        }
    else {
        pc.printf("Memoire initialisee\n");
        pc.printf("Valeurs initiales, attente : %u, %u, %u, %u, %u, %u, %u, %u, marche : %u, %u, %u, %u, %u, %u, %u, %u, etat %u, temp : %u.%u, ventilo : %u\n", tamponQSPI[4], tamponQSPI[5], tamponQSPI[6], tamponQSPI[7], tamponQSPI[8], tamponQSPI[9], tamponQSPI[10], tamponQSPI[11],
                    tamponQSPI[12], tamponQSPI[13], tamponQSPI[14], tamponQSPI[15], tamponQSPI[16], tamponQSPI[17], tamponQSPI[18], tamponQSPI[19], tamponQSPI[20], tamponQSPI[22] , tamponQSPI[23] , tamponQSPI[24]);
        memset(tamponQSPI, 0, TAILLE_TAMPON);
        qspi.Read(tamponQSPI, ADRESSE_LECTURE_ECRITURE, TAILLE_TAMPON);
        pc.printf("Valeurs enregistrees, attente : %u, %u, %u, %u, %u, %u, %u, %u, marche : %u, %u, %u, %u, %u, %u, %u, %u, etat %u, temp : %u.%u, ventilo : %u\n", tamponQSPI[4], tamponQSPI[5], tamponQSPI[6], tamponQSPI[7], tamponQSPI[8], tamponQSPI[9], tamponQSPI[10], tamponQSPI[11],
                    tamponQSPI[12], tamponQSPI[13], tamponQSPI[14], tamponQSPI[15], tamponQSPI[16], tamponQSPI[17], tamponQSPI[18], tamponQSPI[19], tamponQSPI[20], tamponQSPI[22] , tamponQSPI[23] , tamponQSPI[24]);
                              
    }
}

void initialiseDS1820(void) {
    if(ds1820.begin()) {
        lcd.SetBackColor(NOIR);
        alerte.Draw("DS1820 initialise sur D8 (PI_2)", JAUNE);
        pc.printf("DS1820 initialise sur D8 (PI_2)");
        ds1820.setResolution(12);
        ds1820.startConversion();
        wait(1);
        temperature = ds1820.read();
        ok = true;
        alerte.Draw("", NOIR);
        } 
    else {
        lcd.SetBackColor(NOIR);
        alerte.Draw("Pas de capteur DS1820 sur le bus OneWire (D8) !", ROUGE);
        pc.printf("Pas de capteur DS1820 sur le bus OneWire (D8) !");
        wait(1);
        alerte.Draw("", NOIR);
        ok = false;
    }
}

void initialiseQSPI(void) {
    QSPI_Info pQSPI_Info;
    if (qspi.Init() != QSPI_OK) {
        lcd.SetBackColor(NOIR);
        alerte.Draw("Initialisation QSPI ratee", ROUGE);
        pc.printf("Initialisation QSPI ratee");
//        pc.printf();
        qspiOk = false;
        wait(1);
        alerte.Draw("", NOIR);
        }
    else {
        lcd.SetBackColor(NOIR);
        alerte.Draw("Initialisation QSPI reussie", JAUNE);
        pc.printf("\n\nInitialisation QSPI reussie\n");
        qspiOk = true;
        wait(1);
        alerte.Draw("", NOIR);
    }
    
    // Check memory informations
    qspi.GetInfo(&pQSPI_Info);
    if ((pQSPI_Info.FlashSize          != N25Q128A_FLASH_SIZE) ||
        (pQSPI_Info.EraseSectorSize    != N25Q128A_SUBSECTOR_SIZE) || 
        (pQSPI_Info.ProgPageSize       != N25Q128A_PAGE_SIZE) ||
        (pQSPI_Info.EraseSectorsNumber != N25Q128A_SUBSECTOR_SIZE) ||
        (pQSPI_Info.ProgPagesNumber    != N25Q128A_SECTOR_SIZE)) {
        led = 1;
        lcd.SetBackColor(NOIR);
        alerte.Draw("Lecture des informations ratee\n");
        qspiOk = false;
        }
    else {
        pc.printf("Lecture des informations reussie\n");
        if (qspi.Read(tamponQSPI, ADRESSE_LECTURE_ECRITURE, TAILLE_TAMPON) != QSPI_OK) {
            qspiOk = false;
            lcd.SetBackColor(NOIR);
            alerte.Draw("Lecture de la memoire QSPI ratee\n", ROUGE);
            led = 1;
            wait(1);
            led = 0;
            }
        else if ((tamponQSPI[0] == 'J') && (tamponQSPI[1] == 'M') && (tamponQSPI[2] == 'A')) {    // on teste la signature
            pc.printf("Memoire QSPI deja initialisee\n");
            led = 1;
            initialiseDonnees();
            led = 0;
            }
        else {  // on initialise la memoire
            pc.printf("Memoire QSPI non initialisee\nInitialisation en cours\n");
            if (qspi.Erase_Block(ADRESSE_LECTURE_ECRITURE) != QSPI_OK) {
                pc.printf("Bloc non efface\n");
                qspiOk = false;
                }
            else {
                pc.printf("Bloc efface\n");
                led = 1;
                initialise();
                led = 0;
            }
        }
    }
}

void calculeLargeurImpulsion(void) {
    seuilChauffage = 0;
    if ((temperature <= tableauSeuilsTemperature[0])) {
        seuilChauffage = tableauSeuilsChauffage[0];
        }
    else if (temperature < temperatureConsigne) {
        if ((temperature >= tableauSeuilsTemperature[0]) && (temperature < tableauSeuilsTemperature[1])) {
            seuilChauffage = tableauSeuilsChauffage[0];
            }
        else if ((temperature >= tableauSeuilsTemperature[1]) && (temperature < tableauSeuilsTemperature[2])) {
            seuilChauffage = tableauSeuilsChauffage[1];
            }
        else if ((temperature >= tableauSeuilsTemperature[2]) && (temperature < tableauSeuilsTemperature[3])) {
            seuilChauffage = tableauSeuilsChauffage[2];
            }
        else if ((temperature >= tableauSeuilsTemperature[3]) && (temperature < tableauSeuilsTemperature[4])) {
            seuilChauffage = tableauSeuilsChauffage[3];
            }
        else if ((temperature >= tableauSeuilsTemperature[4]) && (temperature < tableauSeuilsTemperature[5])) {
            seuilChauffage = tableauSeuilsChauffage[4];
            }
        else if ((temperature >= tableauSeuilsTemperature[5]) && (temperature < tableauSeuilsTemperature[6])) {
            seuilChauffage = tableauSeuilsChauffage[5];
            }
        else if ((temperature >= tableauSeuilsTemperature[6]) && (temperature < tableauSeuilsTemperature[7])) {
            seuilChauffage = tableauSeuilsChauffage[6];
            }
        else if ((temperature >= tableauSeuilsTemperature[7]) && (temperature < tableauSeuilsTemperature[8])) {
            seuilChauffage = tableauSeuilsChauffage[7];
            }
        else if ((temperature >= tableauSeuilsTemperature[8]) && (temperature < tableauSeuilsTemperature[9])) {
            seuilChauffage = tableauSeuilsChauffage[8];
            }
        else if ((temperature >= tableauSeuilsTemperature[9]) && (temperature < tableauSeuilsTemperature[10])) {
            seuilChauffage = tableauSeuilsChauffage[9];
        }
        }
    else if (temperature >= temperatureConsigne) {
        seuilChauffage = tableauSeuilsChauffage[10]/*0*/;
    }
    if (seuilChauffage > 10)
        seuilChauffage = 10;
    if (seuilChauffage < 0)
        seuilChauffage = 0;
/*    char infos[TAILLE_TAMPON];
    memset(infos, 0, TAILLE_TAMPON);
    sprintf(infos, "%d (%.1f, %d) ", seuilChauffage, temperature, tableauDureeImpulsionChauffage[seuilChauffage]);
    pc.printf(infos);
    numero++;
    if (numero > 5) {
        numero = 0;
        pc.printf("\n");
    }*/
}