mbed-os github

Dependencies:   ADS1015 Faulhaber HTU21D_mod MS5837_potless Sensor_Head_RevB_3 USBDevice_dfu Utilsdfu beep

Fork of ARNSRS_testDFU by POTLESS

Files at this revision

API Documentation at this revision

Comitter:
POTLESS_2
Date:
Fri Jun 29 09:40:02 2018 +0000
Parent:
57:a0827fa46b03
Child:
59:fd64ca9dae27
Commit message:
avec motif OTU, motif ?mulation EEPROM avec flash, DFU natif

Changed in this revision

Faulhaber.lib Show annotated file Show diff for this revision Revisions of this file
Sensor_Head_RevB_3.lib Show annotated file Show diff for this revision Revisions of this file
Utils.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Faulhaber.lib	Tue Jun 26 09:45:56 2018 +0000
+++ b/Faulhaber.lib	Fri Jun 29 09:40:02 2018 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/teams/POTLESS/code/Faulhaber/#4968ac975009
+https://os.mbed.com/teams/POTLESS/code/Faulhaber/#fa3570a43582
--- a/Sensor_Head_RevB_3.lib	Tue Jun 26 09:45:56 2018 +0000
+++ b/Sensor_Head_RevB_3.lib	Fri Jun 29 09:40:02 2018 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/teams/POTLESS/code/Sensor_Head_RevB_3/#858f5b4556d6
+https://os.mbed.com/teams/POTLESS/code/Sensor_Head_RevB_3/#41c72aba66e4
--- a/Utils.lib	Tue Jun 26 09:45:56 2018 +0000
+++ b/Utils.lib	Fri Jun 29 09:40:02 2018 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/teams/POTLESS/code/Utilsdfu/#d077adaed6da
+https://os.mbed.com/teams/POTLESS/code/Utilsdfu/#f2c000337b82
--- a/main.cpp	Tue Jun 26 09:45:56 2018 +0000
+++ b/main.cpp	Fri Jun 29 09:40:02 2018 +0000
@@ -28,7 +28,7 @@
 
 //Pin de test des alims
 #define PIN_V_PILES_ANALOG PA_1
-#define PIN_V_PILES_DIGI PC_3
+#define PIN_V_PILE_DIGI PC_3
 #define PIN_V_USB_DIGI PA_0
 
 //#define OUTPUT(...) { NVIC_DisableIRQ(USART3_IRQn); serialMonit.printf(__VA_ARGS__); fflush(stdout);NVIC_EnableIRQ(USART3_IRQn);}
@@ -39,8 +39,8 @@
 
 //PinName pwm, PinName nSleep, PinName fwd, PinName rev, PinName channelA, PinName channelB, int pulsesPerRev, int Rapport, Encoding encoding = X2_ENCODING
 //Angle 0 -> tuyau fermé, Angle 90 -> tuyau ouvert
-Faulhaber Servo_Poumon("Servo_Poumon", PWM_SERVO_POUMON, nSleep_SERVO_POUMON, FWD_SERVO_POUMON, REV_SERVO_POUMON, Channel_A_SERVO_POUMON, Channel_B_SERVO_POUMON, 16, 1257, Faulhaber::X2_ENCODING);
-Faulhaber Servo_Fuite("Servo_Fuite", PWM_SERVO_FUITE, nSleep_SERVO_FUITE, FWD_SERVO_FUITE, REV_SERVO_FUITE, Channel_A_SERVO_FUITE, Channel_B_SERVO_FUITE, 16, 207, Faulhaber::X2_ENCODING);
+Faulhaber Servo_Poumon(VOLET_POUMON_ADDR, PWM_SERVO_POUMON, nSleep_SERVO_POUMON, FWD_SERVO_POUMON, REV_SERVO_POUMON, Channel_A_SERVO_POUMON, Channel_B_SERVO_POUMON, 16, 1257, Faulhaber::X2_ENCODING);
+Faulhaber Servo_Fuite(VOLET_FUITE_ADDR, PWM_SERVO_FUITE, nSleep_SERVO_FUITE, FWD_SERVO_FUITE, REV_SERVO_FUITE, Channel_A_SERVO_FUITE, Channel_B_SERVO_FUITE, 16, 207, Faulhaber::X2_ENCODING);
 
 //Communication USB, OTG_FS
 USBSerial serialMonit(0x0483, 0x5740, 0x0001, false);
@@ -85,9 +85,6 @@
 //Flag pour interrompre les demandes O2 en cours ed calibration...
 bool FLAG_O2 = true;
 
-//Flag pour passage en DFU...
-bool FLAG_DFU = false;
-
 //Variables de stockage des infos capteurs
 int co2 = 0;
 float pression = 0;
@@ -97,8 +94,9 @@
 int CellO2_2 = 0;
 
 //Variables et constantes OTU
+Ticker OTU_Ticker;
 float OTU = 0;
-float COEF_OTU = 0.83;
+float EXP_OTU = 0.83;
 
 //Mesure du temps d'éxecution du loop
 Timer REAL_RATE;
@@ -124,7 +122,7 @@
 float Consigne_fuite = HOME_SERVO_FUITE;
 float volet_fuite_Position;
 float Volets_Speed = 1;
-float Volet_DeadBand = 5;
+float Volet_DeadBand = 10;
 
 //Paramètre du PID
 float Kc = 40;
@@ -154,6 +152,9 @@
 int VPiles = 1;
 float VPiles_val = 1;
 
+bool flag_USB = false;
+bool flag_Pile = false;
+
 //Commande à envoyer à l'IHM
 //0 -> Marche
 //1 -> Au dodo
@@ -161,34 +162,34 @@
 int Commande_IHM = 0;
 
 //Interruption pin
-InterruptIn vpile_off_on(PIN_V_PILES_DIGI);
+InterruptIn vpile_off_on(PIN_V_PILE_DIGI);
 InterruptIn vusb_off_on(PIN_V_USB_DIGI);
 
 //Pin enable du régulateur 5 v
 DigitalOut E5V(PA_4);
 
 //Pin enable du régulateur 3.3 v
-DigitalOut E3V(PB_11);
+DigitalOut E3V(PB_11, PullDown);
 
 //Pin du Buzzer
 Beep buzzer(PC_8);
 
 
-    /*
+/*
 
-    Pour mémoire, les réglage de priorité des thread
+Pour mémoire, les réglage de priorité des thread
 
-          osPriorityIdle          = -3,          ///< priority: idle (lowest)
-          osPriorityLow           = -2,          ///< priority: low
-          osPriorityBelowNormal   = -1,          ///< priority: below normal
-          osPriorityNormal        =  0,          ///< priority: normal (default)
-          osPriorityAboveNormal   = +1,          ///< priority: above normal
-          osPriorityHigh          = +2,          ///< priority: high
-          osPriorityRealtime      = +3,          ///< priority: realtime (highest)
-          osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
-    */
-    
-//Déclaration des Threads    
+      osPriorityIdle          = -3,          ///< priority: idle (lowest)
+      osPriorityLow           = -2,          ///< priority: low
+      osPriorityBelowNormal   = -1,          ///< priority: below normal
+      osPriorityNormal        =  0,          ///< priority: normal (default)
+      osPriorityAboveNormal   = +1,          ///< priority: above normal
+      osPriorityHigh          = +2,          ///< priority: high
+      osPriorityRealtime      = +3,          ///< priority: realtime (highest)
+      osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
+*/
+
+//Déclaration des Threads
 Thread thread_Secu(osPriorityLow);
 Thread thread_Head(osPriorityLow);
 Thread thread_Volets_POUMON(osPriorityLow);
@@ -200,45 +201,61 @@
     wait_ms(500);
     buzzer.beep(1000,0.3);
     wait(1);
-    
+
     E5V = 0;
     E3V = 0;
-    
+
     //Mise en veille
     HAL_PWREx_EnablePullUpPullDownConfig() ;
     HAL_PWREx_EnableGPIOPullDown(PWR_GPIO_A, PWR_GPIO_BIT_0);
-    HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1); // pour PA_0
+
+    HAL_PWREx_EnableGPIOPullDown(PWR_GPIO_C, PWR_GPIO_BIT_13);
+    HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2); // pour PC_13 est le WKUP2_0 (présence PILES) ;
+
+    HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1); // pour PA_0 (présence USB)
+    HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2); // pour PC_13 est le WKUP2_0 (présence PILES) ;
+
     // Clear wake up Flag
     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF1);
-    // Enable wakeup pin WKUP2
-    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); // high est la valeur par défaut
+    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
+
+    if (flag_USB) {
+        HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_LOW);
+        HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_HIGH);
+    }
+    if (flag_Pile) {
+        HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_HIGH);
+        HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);
+    }
+
     // Set RTC back-up register RTC_BKP31R to indicate
     //later on that system has entered shutdown mode
     WRITE_REG( RTC->BKP31R, 0x1 );
     //Enter shutdown mode
     HAL_PWREx_EnterSHUTDOWNMode();
 }
-    
+
 void USB_unpluged()
 {
     DEBUG("  La prise USB a été débranchée.\n");
-    
+
     //Arrêt des enregistrements
     FLAG_REC = false;
-    
+
     /*
     //Mise en veille de l'IHM
     Commande_IHM = 1;
     IHM("<0 0 ;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;%d>\r\n", Commande_IHM);
     FLAG_DISPLAY = false;
     Commande_IHM = 0;
-    
+
     DigitalOut Screen(PC_4);
     Screen = 0;
     */
-    
+
     E3V = 0;
-    
+
+    /*
     //Enregistrement position des servos sans mettre en sécu
     int Pos_P = Servo_Poumon.getPulses();
     UTILS::Store_A_Val((float)Pos_P, "Servo_Poumon.sys");
@@ -247,33 +264,46 @@
     int Pos_F = Servo_Fuite.getPulses();
     UTILS::Store_A_Val((float)Pos_F, "Servo_Fuite.sys");
     DEBUG("  position volet fuite sauvegardée = %d pulse(s)\r\n", Pos_F);
+    */
 
-/*
-    __disable_irq();
+    UTILS::UnMount_Flash();
 
-    thread_Secu.terminate();
+    UTILS::EffacePage(2, 31, 1);
+    //Enregistrement position des servos sans mettre en sécu
+    uint64_t Pos_P = Servo_Poumon.getPulses();
+    UTILS::Write(VOLET_POUMON_ADDR, Pos_P);
+    DEBUG("  position volet poumon sauvegardée = %d pulse(s)\r\n", (int) Pos_P);
 
-    wait(300);
+    uint64_t Pos_F = Servo_Fuite.getPulses();
+    UTILS::Write(VOLET_FUITE_ADDR, Pos_F);
+    DEBUG("  position volet fuite sauvegardée = %d pulse(s)\r\n", (int) Pos_F);
 
-    thread_Head.terminate();
+    /*
+        __disable_irq();
 
-    wait(300);
-    
-    thread_Volets_POUMON.terminate();
-    
-    wait(300);
-    
-    thread_Volets_FUITE.terminate();
-    
-    wait(300);
-*/    
-    //ejection de la flash pour pas crasher le system de fichiers
-    UTILS::UnMount_Flash();
-    
+        thread_Secu.terminate();
+
+        wait(300);
+
+        thread_Head.terminate();
+
+        wait(300);
+
+        thread_Volets_POUMON.terminate();
+
+        wait(300);
+
+        thread_Volets_FUITE.terminate();
+
+        wait(300);
+
+        //ejection de la flash pour pas crasher le system de fichiers
+        UTILS::UnMount_Flash();
+    */
     //Mise en veille
     Au_Dodo();
 }
-        
+
 void FLASH_set_boot_bank(int bank)
 {
     //HAL_DeInit();
@@ -354,12 +384,12 @@
     Volets_Speed = 1;
     Volet_DeadBand = 10;
 
-    
-        while(1) {
-            wait_ms(100);
-            if (Servo_Poumon.Pos_OK() == true && Servo_Fuite.Pos_OK() == true) break;
-        }
-    
+
+    while(1) {
+        wait_ms(100);
+        if (Servo_Poumon.Pos_OK() == true && Servo_Fuite.Pos_OK() == true) break;
+    }
+
 
     OUTPUT("  Appareil en mode SECU\r\n");
 
@@ -368,7 +398,8 @@
     EN_MODE_SECU = true;
 
     wait_ms(100);
-    
+
+    /*
     int Pos_P = Servo_Poumon.getPulses();
     UTILS::Store_A_Val((float)Pos_P, "Servo_Poumon.sys");
     DEBUG("  position volet poumon sauvegardée = %d pulse(s)\r\n", Pos_P);
@@ -378,6 +409,18 @@
     UTILS::Store_A_Val((float)Pos_F, "Servo_Fuite.sys");
     DEBUG("  position volet fuite sauvegardée = %d pulse(s)\r\n", Pos_F);
     OUTPUT("  Volet fuite en sécu\r\n");
+    */
+    UTILS::EffacePage(2, 31, 1);
+    //Enregistrement position des servos en sécu pour plus de précision
+    uint64_t Pos_P = Servo_Poumon.getPulses();
+    UTILS::Write(VOLET_POUMON_ADDR, Pos_P);
+    DEBUG("  position volet poumon sauvegardée = %d pulse(s)\r\n", (int) Pos_P);
+    OUTPUT("  Volet poumon en sécu\r\n");
+
+    uint64_t Pos_F = Servo_Fuite.getPulses();
+    UTILS::Write(VOLET_FUITE_ADDR, Pos_F);
+    DEBUG("  position volet fuite sauvegardée = %d pulse(s)\r\n",(int) Pos_F);
+    OUTPUT("  Volet fuite en sécu\r\n");
 
     Servo_Poumon.Sleep();
     Servo_Fuite.Sleep();
@@ -393,14 +436,14 @@
     Mode_SECU();
 
     wait(1);
-    
+
     //ejection de la flash pour pas crasher le system de fichiers
     UTILS::UnMount_Flash();
 
     OUTPUT("  Ejection de la Flash\r\n");
 
     wait(1);
-    
+
     Au_Dodo();
 }
 
@@ -434,7 +477,7 @@
 }
 
 //Calcul des OTU
-float Calcul_OTU()
+void Calcul_OTU()
 {
     /*
     La formule suivante permet de calculer la quantité d' OTU accumulée
@@ -446,7 +489,7 @@
 
     if (ppO2 > 500) {
         float val = (2 * (float)ppO2/1000 - 1);//je divise par 1000 car la PP est en mb...
-        OTU += Ref_Time * pow(val, COEF_OTU);
+        OTU += pow(val, EXP_OTU);//T = 1 car le ticker est executé toutes les 60 secondes, 1 minute....
     }
 }
 
@@ -476,7 +519,7 @@
         volet_fuite_Position = Servo_Fuite.Get_Position();
 
         //Calcul des OTU
-        Calcul_OTU();
+        //Calcul_OTU();
 
     }
 }
@@ -506,7 +549,7 @@
 void SECU_thread()
 {
     while (true) {
-    //Mettre toutes les vérifs de sécu....
+        //Mettre toutes les vérifs de sécu....
     }
 }
 
@@ -533,7 +576,7 @@
 
     while(display.readable()) {
         if ((indexIHM  == sizeIHM) || newIHMFlag  == true) { //éviter la saturation du buffer
-            NVIC_DisableIRQ(USART3_IRQn); 
+            NVIC_DisableIRQ(USART3_IRQn);
             char char_flush = display.getc();
             NVIC_EnableIRQ(USART3_IRQn);
         } else {
@@ -566,16 +609,20 @@
         /*FLAG_PID = 0;
         FLAG_AFF = false;
         FLAG_WINDEV = false;
-        control_Servo.setMode(MANUAL_MODE);*/
+        control_Servo.setMode(MANUAL_MODE);
         Commande_IHM = 1;
         IHM("<0 0 ;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;%d>\r\n", Commande_IHM);
         FLAG_DISPLAY = false;
         Commande_IHM = 0;
         wait(300);
         Au_Dodo();
+        */
+        E3V = 0;
     } else if (0 == strcmp(com, "ARNSRS_ID")) {
-        OUTPUT("  Changement de l'ID de l'appareil pour le N°: %s?\r\n", numb);
-        UTILS::Store_A_Val(atoi(numb), "ARNSRS_ID");
+        OUTPUT("  Changement de l'ID de l'appareil pour le N°: %s\r\n", numb);
+        //UTILS::Store_A_Val(atoi(numb), "ARNSRS_ID");
+        UTILS::EffacePage(2, 30, 1);
+        UTILS::Write(ID_ARNSRS_ADDR, (uint64_t) atoi(numb));
     } else if (0 == strcmp(com, "monit")) {
         FLAG_AFF = false;
         FLAG_WINDEV = true;
@@ -615,9 +662,14 @@
         OUTPUT("  Montage de la Flash.\r\n");
         UTILS::Mount_Flash();
     } else if (0 == strcmp(com, "check_F")) {
+        /*
         OUTPUT("  ARNSRS_ID.sys   = %d\r\n", (int)UTILS::Read_A_Val("ARNSRS_ID.sys"));
         OUTPUT("  Servo_Poumon.sys   = %d\r\n", (int)UTILS::Read_A_Val("Servo_Poumon.sys"));
         OUTPUT("  Servo_Fuite.sys    = %d\r\n", (int)UTILS::Read_A_Val("Servo_Fuite.sys"));
+        */
+        OUTPUT("  ARNSRS ID   = %d\r\n", (int) UTILS::Read(ID_ARNSRS_ADDR));
+        OUTPUT("  Dernière Position volet poumon enregistrée  = %d\r\n", (int) UTILS::Read(VOLET_POUMON_ADDR));
+        OUTPUT("  Dernière Position volet fuite enregistrée   = %d\r\n", (int) UTILS::Read(VOLET_FUITE_ADDR));
     } else if (0 == strcmp(com, "check_E")) {
         sensors.Sensor_head_check(&serialMonit);
     } else if (0 == strcmp(com, "rec")) {
@@ -665,13 +717,13 @@
         char filename[20];
         UTILS::Get_File_Size(&serialMonit, numb);
     } else if (0 == strcmp(com, "calib_p")) {
-        Consigne_poumon = 0;
-        volet_poumon_Position = 0;
+        Consigne_poumon = HOME_SERVO_POUMON;
+        volet_poumon_Position = HOME_SERVO_POUMON;
         Servo_Poumon.reset();
         OUTPUT("  Volet poumon Calibré.\r\n");
     } else if (0 == strcmp(com, "calib_f")) {
-        Consigne_fuite = 0;
-        volet_fuite_Position = 0;
+        Consigne_fuite = HOME_SERVO_FUITE;
+        volet_fuite_Position = HOME_SERVO_FUITE;
         Servo_Fuite.reset();
         OUTPUT("  Volet fuite Calibré.\r\n");
     } else if (0 == strcmp(com, "sleep")) {
@@ -719,14 +771,20 @@
         OUTPUT("  MAJ CONSIGNE PID -->  Consigne = %d\r\n", consigne);
     } else if (0 == strcmp(com, "dfu")) {
         OUTPUT("  Passage en DFU...\r\n");
-        FLAG_DFU = true;
+        FLAG_REC = false;
+        Mode_SECU();
+        UTILS::UnMount_Flash();
+        UTILS::EffacePage(2, 30, 1);
+        UTILS::Write(ID_ARNSRS_ADDR, (uint64_t) 11111);
+        wait(1);
+        NVIC_SystemReset();
     } else if (0 == strcmp(com, "PID")) {
         if (FLAG_PID == 1) {
-            control_Servo.setMode(MANUAL_MODE);
+            //control_Servo.setMode(MANUAL_MODE);
             OUTPUT("  PID OFF\r\n");
             FLAG_PID = 0;
         } else if (FLAG_PID == 0) {
-            control_Servo.setMode(AUTO_MODE);
+            //control_Servo.setMode(AUTO_MODE);
             OUTPUT("  PID ON\r\n");
             FLAG_PID = 1;
         }
@@ -753,13 +811,13 @@
     OUTPUT("?\r\n");
 
     if (0 == strcmp(com, "1")) {
-        
+
     } else if (0 == strcmp(com, "2")) {
-        
+
     } else if (0 == strcmp(com, "3")) {
 
     } else {
-        
+
     }
 
     strcpy(IHM," ");
@@ -788,36 +846,48 @@
 
 int main()
 {
-
+    
     HAL_Init();
 
     __HAL_RCC_PWR_CLK_ENABLE();
     HAL_PWR_EnableBkUpAccess();
 
+    UTILS::DFU();
+    
     E5V = 1;
     E3V = 1;
 
+    if (PIN_V_USB_DIGI) flag_USB = true;
+    if (PIN_V_PILE_DIGI) flag_Pile = true;
+
+    UTILS::PVD_Config();
+
     buzzer.beep(1000,0.5);
-    
+
     //Ci-dessous commande pour formater une nouvelle carte
-    UTILS::Format_Flash();
+    //UTILS::Format_Flash();
 
     //Montage Flash
     UTILS::Mount_Flash();
+    /*
+        if (UTILS::File_Exist("ARNSRS_ID.sys") == false) {
+            UTILS::Store_A_Val(000, "ARNSRS_ID.sys");
+            DEBUG("ARNSRS ID forcée à 000\r\n");
+        }
+    */
+    //pour le premier lancement quand l'appareil n'a pas d'ID.
+    //int ID = 0;
+    //UTILS::Write(ADRESSE_ID, ID);
 
-    if (UTILS::File_Exist("ARNSRS_ID.sys") == false) {
-        UTILS::Store_A_Val(000, "ARNSRS_ID.sys");
-        DEBUG("ARNSRS ID forcée à 000\r\n");
-    }
-    
     DEBUG("\r\n\r\n  Démarrage de l'appareil, veuillez patienter...\r\n\r\n");
-    
+
 
     //Vérification RTC, si on est le 01/01/70, c'est qu'il y a un problème...
     seconds = time(NULL);
     char YEAR[10];
     strftime(YEAR, 10, "%D", localtime(&seconds));
-    if (0 == strcmp(YEAR, "01/01/70")); DEBUG("  Vous devez régler la RTC...\r\n\r\n");
+    if (0 == strcmp(YEAR, "01/01/70"));
+    DEBUG("  Vous devez régler la RTC...\r\n\r\n");
 
     bool calib_O2 = false;
     bool calib_CO2 = false;
@@ -833,9 +903,14 @@
     //Création et écriture du header du fichier LOG
     sensors.Create_Header(Log_File_Name);
 
+    /*
     Servo_Poumon.Init("Servo_Poumon.sys");
     Servo_Fuite.Init("Servo_Fuite.sys");
 
+    Servo_Poumon.Init(VOLET_POUMON_ADDR);
+    Servo_Fuite.Init(VOLET_FUITE_ADDR);
+    */
+
     DEBUG("  Demarrage des threads...\r\n\r\n");
 
     wait(1);
@@ -853,7 +928,7 @@
     wait(1);
 
     thread_Volets_POUMON.start(callback(GO_TO_thread_POUMON));
-    
+
     wait(1);
 
     thread_Volets_FUITE.start(callback(GO_TO_thread_FUITE));
@@ -870,7 +945,7 @@
     //Consigne à x mb
     control_Servo.setSetPoint(consigne);
     //Mode auto au démarrage
-    control_Servo.setMode(MANUAL_MODE);
+    control_Servo.setMode(AUTO_MODE);
 
     DEBUG("  Cliquez sur le bouton help pour voir la liste des \r\n  commandes administrateur disponibles.\r\n");
 
@@ -879,15 +954,17 @@
     UTILS::Dir_Flash(&serialMonit);
 
     serialMonit.attach(&callbackParam);
-    
+
     display.attach(&callbackIHM);
-
+    
+    OTU_Ticker.attach(&Calcul_OTU, 60);
+    
     vusb_off_on.fall(&USB_unpluged);
 
     buzzer.beep(1000,0.3);
     wait_ms(500);
     buzzer.beep(1000,0.3);
-    
+
     while (true) {
 
         //Démarrage du Timer mesurant le temps d'éxecution du code
@@ -897,7 +974,7 @@
             DEEP_DEBUG("  From PC = %s\r\n", param);
             Decoding_Message(param);
         }
-        
+
         if (newIHMFlag) {
             DEEP_DEBUG("  From IHM = %s\r\n", IHM);
             Decoding_IHM(IHM);
@@ -928,7 +1005,7 @@
                 Td,
                 consigne,
                 Commande_IHM
-                );
+               );
 
 
         //Pour windev
@@ -960,28 +1037,13 @@
             }
         }
 
-        //Passage en DFU
-        if (FLAG_DFU) {
-            FLAG_DFU = false;
-            FLAG_REC = false;
-            thread_Secu.terminate();
-            wait_ms(300);
-            thread_Head.terminate();
-            wait_ms(300);
-            thread_Volets_POUMON.terminate();
-            wait_ms(300);
-            thread_Volets_FUITE.terminate();
-            wait_ms(300);
-            UTILS::UnMount_Flash();
-            FLASH_set_boot_bank(2);
-            OUTPUT("  Reboot...\r\n");
-            HAL_NVIC_SystemReset;
-        }
 
         //Update du PID
-        control_Servo.setProcessValue(ppO2);
-        //Nouvelle sortie servo fuite si on est pas en mode SECU
-        //if(!EN_MODE_SECU) Consigne_fuite = control_Servo.compute();
+        if (FLAG_PID == 1 && EN_MODE_SECU == false) {
+            control_Servo.setProcessValue(ppO2);
+            //Nouvelle sortie servo fuite si on est pas en mode SECU
+            Consigne_fuite = control_Servo.compute();
+        }
 
         //Arrêt du Timer mesurant le temps d'éxecution du code
         REAL_RATE.stop();