![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
mbed-os github
Dependencies: ADS1015 Faulhaber HTU21D_mod MS5837_potless Sensor_Head_RevB_3 USBDevice_dfu Utilsdfu beep
Fork of ARNSRS_testDFU by
main.cpp
- Committer:
- POTLESS_2
- Date:
- 2018-03-29
- Revision:
- 40:32d89e04ead1
- Parent:
- 39:65ff3c4f9675
- Child:
- 41:51ba69648f9d
File content as of revision 40:32d89e04ead1:
#include "mbed.h" #include <string> #include "Sensor_head_revB.h" #include "HTU21D.h" #include "PID.h" #include "Faulhaber.h" #include "Utils.h" //Commandes des servos #define PWM_SERVO_POUMON PB_15 #define nSleep_SERVO_POUMON PC_6 #define FWD_SERVO_POUMON PB_14 #define REV_SERVO_POUMON PB_13 #define Channel_A_SERVO_POUMON PB_1 #define Channel_B_SERVO_POUMON PB_2 #define HOME_SERVO_POUMON 0 #define PWM_SERVO_FUITE PB_10 #define nSleep_SERVO_FUITE PC_5 #define FWD_SERVO_FUITE PB_4 #define REV_SERVO_FUITE PB_5 #define Channel_A_SERVO_FUITE PB_8 #define Channel_B_SERVO_FUITE PB_9 #define HOME_SERVO_FUITE 90 //Ecrit dans le moniteur série de la tablette à 115200 bds si sur 1, penser à mettre NEED_CONSOLE_OUTPUT à 0 #define NEED_ANDROID_OUTPUT 1 //Mode PID, STD à commenter / décommenter #define STD_MODE //#define PID_MODE #ifdef STD_MODE int MODE_FLAG = 0; #endif #ifdef PID_MODE int MODE_FLAG = 2; #endif #if NEED_ANDROID_OUTPUT #define ANDROID(...) { android.printf(__VA_ARGS__); } #else #define ANDROID(...) #endif #if DEBUG_MODE #define DEBUG(...) { serialMonit.printf(__VA_ARGS__); fflush(stdout);} #else #define DEBUG(...) #endif //PinName pwm, PinName nSleep, PinName fwd, PinName rev, PinName channelA, PinName channelB, int pulsesPerRev, int Rapport, Encoding encoding = X2_ENCODING 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, 207, Faulhaber::X2_ENCODING); //Faulhaber Servo_Fuite("Servo_Fuite", PWM_SERVO_FUITE, nSleep_SERVO_FUITE, FWD_SERVO_FUITE, REV_SERVO_FUITE, 1, Channel_A_SERVO_FUITE, Channel_B_SERVO_FUITE, 16, 207, Faulhaber::X2_ENCODING); //Moniteur série, Serial 2 Serial serialMonit(USBTX,USBRX,115200); //COM Série vers Android, Serial 3 Serial android(PC_10,PC_11,115200); //Init de la lib ARNSRS; SENSOR_HEAD_REV_B sensors; //pour Param Venant du PV const int sizeParam = 30; char param[sizeParam]; volatile int indexParam = 0; bool newParamFlag = false; //pour Commandes Android const int sizeAndroid = 20; char Android[sizeAndroid]; volatile int indexAndroid = 0; bool newAndroidFlag = false; char to_android[100]; //Flag pour interrompre l'affichage si on veut... bool FLAG_AFF = true; //Flag pour envoyer à l'app windev... bool FLAG_WINDEV = false; //Flag pour interrompre l'enregistrement si on veut... bool FLAG_REC = true; //Flag pour interrompre les demandes O2 en cours ed calibration... bool FLAG_O2 = true; //Variables de stockage des infos capteurs int co2 = 0; float pression = 0; float Temp1 = 0; int ppO2 = 0; int CellO2_1 = 0; int CellO2_2 = 0; //Variables et constantes OTU float OTU = 0; float COEF_OTU = 0.83; //Mesure du temps d'éxecution du loop Timer REAL_RATE; float RATE = 0; float RATE_TRUE = 0; float Ref_Time = 2.0; //La durée de la boucle désirée... //HTU21D sur l'I2C HTU21D temphumid(PB_9, PB_8); //Temp humid sensor || SDA, SCL float Temp2; int Humid; //Data LOG char to_store[50]; time_t seconds; char Log_File_Name[] = " "; //Contrôle des servos float Consigne_poumon = 0; float volet_poumon_Position = 0; float Consigne_fuite = 0; float volet_fuite_Position = 0; float Volets_Speed = 0.1; float Volet_DeadBand = 5; #ifdef PID_MODE //Paramètre du PID float Kc = 40; float Ti = 0; float Td = 0; float RATE_PID = Ref_Time; float Commande_PID; float consigne = 210; float Max_Input = 1000; float Min_Input = 80; float Max_Output = 85;//Vérifier la valeur pour angle à laisser ouvert... float Min_Output = 5; //Init PID PID control_Servo(Kc, Ti, Td, RATE_PID); #endif //Boolean du status de l'appareil, en mode SECU ou nominal bool EN_MODE_SECU = false; //Test des alim //DigitalIn V_USB(PA_0, PullUp); DigitalIn V_PILES_2(PC_3); AnalogIn V_PILES(PA_1); int Vusb = 1; int VPiles = 1; float VPiles_2 = 1; //Interruption user button InterruptIn button(USER_BUTTON); InterruptIn vpile_off_on(PA_0); // TODO mettre un define sur PA_0 volatile int GO = 0; void Affichage() { //NVIC_DisableIRQ(USART2_IRQn); serialMonit.printf("\r\n"); serialMonit.printf(" CO2 = %d ppm\r\n" , co2); serialMonit.printf(" PPO2 = %d mb\r\n", ppO2); serialMonit.printf(" OTU = %d \r\n", (int)OTU); serialMonit.printf(" Pression = %f msw\r\n", pression); serialMonit.printf(" Temp MS5837 = %f C\r\n", Temp1); serialMonit.printf(" Temp HTU21D = %f C\n\r", Temp2); serialMonit.printf(" Humidity = %d %%\n\r", Humid); serialMonit.printf("\n\r"); serialMonit.printf(" Cell O2 n 1 = %d\r\n" , CellO2_1); serialMonit.printf(" Cell O2 n 2 = %d\r\n" , CellO2_2); serialMonit.printf("\r\n"); serialMonit.printf(" Volet Poumon = %f\r\n" , volet_poumon_Position); serialMonit.printf(" Volet Fuite = %f\r\n" , volet_fuite_Position); serialMonit.printf("\r\n"); serialMonit.printf(" Temps d execution de la boucle = %f seconde(s)\n", (RATE + RATE_TRUE / 1000)); serialMonit.printf("\r\n"); if (FLAG_REC) serialMonit.printf(" Chaine enregistrée = %s\n", to_store); else serialMonit.printf(" Pas d'enregistrement en cours."); serialMonit.printf("\r\n"); serialMonit.printf(" V_USB = %f", Vusb); serialMonit.printf("\r\n\r\n"); fflush(stdout); //NVIC_EnableIRQ(USART2_IRQn); } void pressed() { GO = GO + 1; if (GO > 1) NVIC_SystemReset(); } //Pas nécessaire /* void retour_alim() { DEBUG("-------------- interruption retour alim en cours ---------------\r\n"); NVIC_SystemReset(); } */ //Passage en mode SECU void Mode_SECU() { #ifdef PID_MODE //Mise du PID en mode manuel (desactivation...) control_Servo.setMode(MANUAL_MODE); #endif Consigne_poumon = HOME_SERVO_POUMON; Consigne_fuite = HOME_SERVO_FUITE; Volets_Speed = 0.1; Volet_DeadBand = 10; while(1) { wait_ms(100); if (Servo_Poumon.Pos_OK() == true) break; //if (Servo_Poumon.Pos_OK() == true && Servo_Fuite.Pos_OK() == true) break; } DEBUG("-------------- Appareil en mode SECU ---------------\r\n"); wait_ms(100); EN_MODE_SECU = true; wait_ms(100); int Pos = Servo_Poumon.getPulses(); UTILS::Store_A_Val((float)Pos, "Servo_Poumon"); DEBUG(" position volet poumon sauvegardée = %d pulse(s)\r\n", Pos); //Pos = Servo_Fuite.getPulses(); //UTILS::Store_A_Val((float)Pos, "Servo_Fuite"); //DEBUG(" position volet fuite sauvegardée = %d pulse(s)\r\n", Pos); Servo_Poumon.Sleep(); } //Sequence d'arrêt void Stop_Sequence() { Mode_SECU(); //ejection de la flash pour pas crasher le system de fichiers UTILS::UnMount_Flash(); DEBUG("----------------ARRET DE L'APPAREIL--------------------\r\n"); // préparation deepsleep /* //première méthode mais je ne sais pas ce que ça consomme et il faut normalement reduire le frequence d'horloge avant //il est possible que ça génère un plantage et la rtc ne fonctionnera pas? HAL_PWREx_EnableLowPowerRunMode(); DEBUG("----------------LOW POWER RUN MODE--------------------\r\n"); bool isDSallowed; isDSallowed = sleep_manager_can_deep_sleep(); DEBUG(" Deep sleep autorisé ? %i\r\n", isDSallowed); wait(1.0); DEBUG("\n\r Deepsleep tentative normale !(bouton bleu pour ressortir)\n"); wait(0.1); sleep_manager_sleep_auto(); // ne marche pas, je ne sais pas pk */ DEBUG("\n\r Deepsleep méthode offensive !\n"); /* HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2); // pour PC_13 // Clear wake up Flag __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2); // Enable wakeup pin WKUP2 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW); // low parce qu'on veut que ça redémarre avec le user button TODO à passer sur High pour que ça redémarrage avec l'arrivée du hus sur l'USB */ HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1); // pour PA_0 // 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 // 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 DEBUG("\n\r Attention c'est du brutal ! bouton bleu pour ressort.... ZZZZZZZ ZZZZZ !!!\n"); HAL_PWREx_EnterSHUTDOWNMode(); } //Fonction test de valeur d'entrée digitale int Power_Test(DigitalIn& pin) { pin.mode(PullDown); if(!pin) { Stop_Sequence(); return 0; } else { return 1; } } //Fonction test de valeur d'entrée analogique float Power_Test(AnalogIn& pin) { float Val = pin.read(); return Val; } //Contrôle du status de l'appareil / des constantes bool Check() { if (ppO2 > 100) return true;//Situation OK else return false;//Situation dégradée } //Calcul des OTU float Calcul_OTU() { /* La formule suivante permet de calculer la quantité d' OTU accumulée OTU = T * (2* PpO2 -1)0,83 avec : T = temps de plongée en minutes PpO2 = pression partielle d’ oxygène en bars */ 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); } } //Thread d'intérogation des capteurs, positions servo void SENSORS_thread() { while (true) { //DEEP_DEBUG(" SENSORS_thread\r\n"); //CO2 sur Cozir co2 = sensors.requestCO2(); //P / T sur MS5837 pression = sensors.requestPress(); Temp1 = sensors.requestTemp(); //PPO2 sur ADS1015 if (FLAG_O2) ppO2 = sensors.requestPpO2(); //Cell O2 en mV if (FLAG_O2) CellO2_1 = sensors.requestCellO2_1(); if (FLAG_O2) CellO2_2 = sensors.requestCellO2_2(); //HTU21D Temp2 = temphumid.sample_ctemp(); Humid = temphumid.sample_humid(); //Retour position des servos volet_poumon_Position = Servo_Poumon.Get_Position(); //volet_fuite_Position = Servo_Fuite.Get_Position(); } } void GO_TO_thread() { while (true) { //DEEP_DEBUG(" GO_TO_Thread\r\n"); //Servo_Poumon.Go_To_Prop(Consigne_poumon); //Servo_Poumon.Go_To_PID(Consigne_poumon, Volet_DeadBand); Servo_Poumon.Go_To(Consigne_poumon, Volets_Speed, Volet_DeadBand); //Servo_Fuite.Go_To_Prop(Consigne_fuite); //Servo_Fuite.Go_To_PID(Consigne_fuite); //Servo_Fuite.Go_To(Consigne_fuite, Volets_Speed, Volet_DeadBand ); } } void SECU_thread() { while (true) { //DEEP_DEBUG(" SECU_Thread\r\n"); //Alim USB //Vusb = Power_Test(V_USB); //VPiles = Power_Test(V_PILES); //Divers problèmes à implémenter //if(!Check()) Mode_SECU(); } } //Callback de l'intérruption des envois de commandes depuis le terminal void callbackParam() { while(serialMonit.readable()) { if ((indexParam == sizeParam) || newParamFlag == true) { //éviter la saturation du buffer //NVIC_DisableIRQ(USART2_IRQn); char char_flush = serialMonit.getc(); //NVIC_EnableIRQ(USART2_IRQn); } else { //NVIC_DisableIRQ(USART2_IRQn); param [indexParam ++] = serialMonit.getc();//chargement du buffer dans le message if ((indexParam == sizeParam) || (param[indexParam - 1] == '\n')) {//le message est complet ou nouvelle ligne ou autre si on veut... param[indexParam] = 0; newParamFlag = true; } //NVIC_EnableIRQ(USART2_IRQn); } } } //Callback de l'intérruption des envois de commandes depuis Android void callbackAndroid() { while(android.readable()) { if (indexAndroid == sizeAndroid) //éviter la saturation du buffer android.getc(); else Android [indexAndroid++] = android.getc();//chargement du buffer dans le message if ((indexAndroid == sizeAndroid) || (Android[indexAndroid -1] == '\n')) {//le message est complet ou nouvelle ligne ou autre si on veut... Android[indexAndroid] = 0; newAndroidFlag = true; } } } void Decoding_Message(char message []) { char com[sizeParam] = ""; char numb[] = ""; sscanf(message,"%s %s",&com , &numb); DEEP_DEBUG("\r\n Commande = %s Valeur = %s \r\n\r\n", com, numb); if (0 == strcmp(com, "secu")) { Mode_SECU(); } else if (0 == strcmp(com, "ARNSRS_ID")) { UTILS::Store_A_Val(atoi(numb), "ARNSRS_ID"); } else if (0 == strcmp(com, "monit")) { FLAG_AFF = false; FLAG_WINDEV = true; } else if (0 == strcmp(com, "debug")) { FLAG_AFF = true; FLAG_WINDEV = false; } else if (0 == strcmp(com, "Head_ID")) { //On l'enregistre dans l'eeprom UTILS::write_EEPROM(numb, HEAD_ID); } else if (0 == strcmp(com, "O2_1_ID")) { //On l'enregistre dans l'eeprom UTILS::write_EEPROM(numb, CELL_O2_1_ID); } else if (0 == strcmp(com, "O2_2_ID")) { //On l'enregistre dans l'eeprom UTILS::write_EEPROM(numb, CELL_O2_2_ID); } else if (0 == strcmp(com, "CO2_ID")) { //On l'enregistre dans l'eeprom UTILS::write_EEPROM(numb, CO2_ID); } else if (0 == strcmp(com, "calib_O2")) { FLAG_O2 = false; wait_ms(100); sensors.Calibrate_O2(true, atoi(numb)); wait_ms(100); FLAG_O2 = true; } else if (0 == strcmp(com, "flash_i")) { FLAG_REC = false; UTILS::Flash_Infos(); FLAG_REC = true; } else if (0 == strcmp(com, "flash_u")) { FLAG_REC = false; UTILS::UnMount_Flash(); } else if (0 == strcmp(com, "flash_m")) { UTILS::Mount_Flash(); } else if (0 == strcmp(com, "check_F")) { FLAG_REC = false; serialMonit.printf(" ARNSRS_ID.txt = %d\r\n", (int)UTILS::Read_A_Val("ARNSRS_ID")); //serialMonit.printf(" Calibration_O2.txt = %f\r\n", UTILS::Read_A_Val("Calibration_O2")); serialMonit.printf(" Servo_Poumon.txt = %d\r\n", (int)UTILS::Read_A_Val("Servo_Poumon")); //serialMonit.printf("Servo_Fuite.txt = %d\r\n", (int)UTILS::Read_A_Val("Servo_Fuite"); FLAG_REC = true; } else if (0 == strcmp(com, "check_E")) { sensors.Sensor_head_check(); } else if (0 == strcmp(com, "rec")) { if (FLAG_REC) { FLAG_REC = false; serialMonit.printf("Arrêt du Data Logging."); } else { FLAG_REC = true; serialMonit.printf("Démarrage Data Logging dans %s", Log_File_Name); } } else if (0 == strcmp(com, "help")) { FLAG_AFF = false; UTILS::Help(); } else if (0 == strcmp(com, "start")) { FLAG_AFF = true; } else if (0 == strcmp(com, "stop")) { FLAG_AFF = false; //UTILS::Help(); } else if (0 == strcmp(com, "flash_c")) { FLAG_REC = false; UTILS::Clean_Flash(); } else if (0 == strcmp(com, "dir")) { FLAG_REC = false; UTILS::Dir_Flash(); FLAG_REC = true; } else if (0 == strcmp(com, "get")) { FLAG_REC = false; wait_ms(100); char filename[20]; sprintf(filename, "LOG_%d.txt", atoi(numb)); UTILS::Read_Flash_File(filename); wait_ms(100); FLAG_REC = true; } else if (0 == strcmp(com, "del")) { FLAG_REC = false; char filename[20]; sprintf(filename, "LOG_%d.txt", atoi(numb)); UTILS::Delete_Flash_File(filename); UTILS::Dir_Flash(); FLAG_REC = true; } else if (0 == strcmp(com, "file_s")) { FLAG_REC = false; char filename[20]; sprintf(filename, "LOG_%d.txt", atoi(numb)); UTILS::Get_File_Size(filename); FLAG_REC = true; } else if (0 == strcmp(com, "calib_p")) { Consigne_poumon = 0; volet_poumon_Position = 0; Servo_Poumon.reset(); } else if (0 == strcmp(com, "calib_f")) { Consigne_fuite = 0; volet_fuite_Position = 0; //Servo_Fuite.reset(); } else if (0 == strcmp(com, "sleep")) { Stop_Sequence(); } else if (0 == strcmp(com, "time")) {//Depuis terminal MAC taper : " date +%s " set_time(atoi(numb)); } else if (0 == strcmp(com, "c_pou")) { Consigne_poumon = atof(numb); DEBUG(" Servo Poumon = %f\r\n", Consigne_poumon); } else if (0 == strcmp(com, "c_fui")) { Consigne_fuite = atof(numb); DEBUG(" Servo Fuite = %f\r\n", Consigne_fuite); } else if (0 == strcmp(com, "reset")) { UTILS::UnMount_Flash(); NVIC_SystemReset(); } else { sensors.cozirSend(message); } strcpy(param," "); indexParam = 0; newParamFlag = false; } void Decoding_Message_Android(char message []) { char *commande = 0; float valeur = 0; sscanf(message,"%s %f",&commande , &valeur); if ((char)commande == 'T') { set_time(valeur); } else if ((char)commande == 'I') { Consigne_poumon = (float)valeur; DEBUG(" Servo Poumon = %f\r\n", Consigne_poumon); } else if ((char)commande == 'O') { Consigne_fuite = (float)valeur; DEBUG(" Servo Fuite = %f\r\n", Consigne_fuite); ///////////////////////////////////////// //Pour rajouter une commande //} else if ((char)commande == 'X') { // attribuer à une VARIABLE = valeur; // ou une action, avec ou sans valeur ///////////////////////////////////////// } else if ((char)commande == 'R') { NVIC_SystemReset(); } #ifdef PID_MODE else if ((char)commande == 'p') { Kc = (float)valeur; control_Servo.reset(); control_Servo.setTunings(Kc, Ti, Td); DEBUG" UPDATE PID --> Kc = %f Ti = %f Td = %f\r\n\n", Kc, Ti, Td); } else if ((char)commande == 'i') { Ti = (float)valeur; control_Servo.reset(); control_Servo.setTunings(Kc, Ti, Td); DEBUG(" UPDATE PID --> Kc = %f Ti = %f Td = %f\r\n\n", Kc, Ti, Td); } else if ((char)commande == 'd') { Td = (float)valeur; control_Servo.reset(); control_Servo.setTunings(Kc, Ti, Td); DEBUG(" UPDATE PID --> Kc = %f Ti = %f Td = %f\r\n\n", Kc, Ti, Td); } else if ((char)commande == 'c') { consigne = valeur; control_Servo.setSetPoint(consigne); DEBUG(" UPDATE CONSIGNE PID --> Consigne = %d\r\n\n", consigne); } #endif strcpy(Android," "); indexAndroid = 0; newAndroidFlag = false; } void Create_File_Name_Date() { //Du nom du fichier Date / heure seconds = time(NULL); char Time[40]; strftime(Time, 40, "%a_%d_%m_%Y_%H%M", localtime(&seconds)); sprintf(Log_File_Name, "%s_LOG.txt", Time); DEBUG("Nouveau fichier LOG = %s \r\n", Log_File_Name); } void Create_File_Name_Index() { //Du nom du fichier par Index sprintf(Log_File_Name, "LOG_%d.txt", UTILS::File_Index()); DEBUG(" Nouveau fichier LOG = %s \r\n", Log_File_Name); } int main() { HAL_Init(); //V_USB.mode(PullDown); // on force à zero tant que l'alim par les piles n'est pas en place button.fall(&pressed); //vpile_off_on.rise (&retour_alim); __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); int count = 0; while (1) { if (count == 0) serialMonit.printf("\r\n Appuyez sur le User Button pour commencer...\r\n\r\n"); count = 1; if (GO == 1) { wait(1); serialMonit.attach(&callbackParam, Serial::RxIrq); android.attach(&callbackAndroid, Serial::RxIrq); //Ci-dessous commande pour formater une nouvelle carte //UTILS::Format_Flash(); //Montage Flash UTILS::Mount_Flash(); //Liste des fichiers sur la Flash UTILS::Dir_Flash(); //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")) serialMonit.printf(" Vous devez régler la RTC...\r\n"); if (UTILS::File_Exist("ARNSRS_ID") == false) { UTILS::Store_A_Val(000, "ARNSRS_ID"); DEBUG("ARNSRS ID forcée à 000\r\n"); } bool calib_O2 = true; bool calib_CO2 = true; /* Par défaut les valeur en cas de calibration sur true sont les suivant nbCalibO2 = 5 Mode = SPOOLING Filtre = DIGI_FILTER32 CalibrationCO2 = "CALIB_AIR" Parfois la calibration du Cozir coince...faire reset et relancer... Pour calibrer avec ces paramètres : sensors.Sensors_INIT(true, true); Pour changer utiliser la syntaxe suivante : sensors.Sensors_INIT(true, true, true, 5, SPOOLING, DIGI_FILTER32, CALIB_AIR); */ sensors.Sensors_INIT(calib_O2, calib_CO2); wait(1); //Création du nouveau fichier LOG par index / par date. Create_File_Name_Index(); //Create_File_Name_Date() //Création et écriture du header du fichier LOG sensors.Create_Header(Log_File_Name); Servo_Poumon.Init("Servo_Poumon"); //Servo_Fuite.Init("Servo_Fuite"); DEBUG(" Demarrage des threads...\r\n\r\n"); /* 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 */ wait(1); Thread thread_Volets(osPriorityNormal); thread_Volets.start(callback(GO_TO_thread)); DEBUG(" Volets thread démarré\r\n\r\n"); wait(1); Thread thread_Secu(osPriorityNormal); thread_Secu.start(callback(SECU_thread)); DEBUG(" Secu thread démarré\r\n\r\n"); wait(1); Thread thread_Head(osPriorityNormal); thread_Head.start(callback(SENSORS_thread)); DEBUG(" Info thread démarré\r\n\r\n"); wait(1); #ifdef PID_MODE //Init PID //Entrée PPO2 entre 100 et 1000 mb control_Servo.setInputLimits(Min_Input, Max_Input); //Sortie servo entre 0 et 100 % control_Servo.setOutputLimits(Min_Output, Max_Output); //Mode auto au démarrage control_Servo.setMode(AUTO_MODE); //Consigne à x mb control_Servo.setSetPoint(consigne); #endif DEBUG(" Threads démarrés.....\r\n\r\n Tapez help pour voir la liste des commandes disponibles.\r\n "); while (true) { //Démarrage du Timer mesurant le temps d'éxecution du code REAL_RATE.start(); if (newParamFlag) { DEBUG(" From PC = %s\r\n", param); Decoding_Message(param); } if (newAndroidFlag) { DEBUG(" From Android = %s\r\n", Android); Decoding_Message_Android(Android); } //Fabrication de la chaine Date / heure seconds = time(NULL); char Time_buf[32]; strftime(Time_buf, 32, "%D %I-%M-%S ", localtime(&seconds)); #ifdef PID_MODE //Fabrication de la chaine à enregistrer sprintf(to_store,"%s:%d:%d:%.2f:%.2f:%.2f:%d:%d:%d:%.2f:%.2f:%d:%.3f:%.3f:%.3f:%d", Time_buf, co2, ppO2, pression, Temp1, Temp2, Humid, CellO2_1, CellO2_2, volet_poumon_Position, volet_fuite_Position, MODE_FLAG, Kc, Ti, Td, (int)consigne ); #endif #ifndef PID_MODE //Fabrication de la chaine à enregistrer sans les variables du PID sprintf(to_store,"%s:%d:%d:%.2f:%.2f:%.2f:%d:%d:%d:%.2f:%.2f:%d:%.3f:%.3f:%.3f:%d", Time_buf, co2, ppO2, pression, Temp1, Temp2, Humid, CellO2_1, CellO2_2, volet_poumon_Position, volet_fuite_Position, MODE_FLAG, 0.0, 0.0, 0.0, 0 ); #endif char to_slave[50]; //Fabrication de la chaine pour l'IHM sprintf(to_slave,"<%d:%d:%d:%.2f:%.2f:%.2f:%d:%d:%d:%.2f:%.2f>", co2, ppO2, (int)OTU, pression, Temp1, Temp2, Humid, CellO2_1, CellO2_2, volet_poumon_Position, volet_fuite_Position); //Pour Android on ajoute < et > pour décoder l'arrivée du message if (NEED_ANDROID_OUTPUT == 1) { //sprintf(to_android,"<%s>",to_store); //ANDROID(to_slave); } //Pour windev la même chose que pour l'écran if (FLAG_WINDEV) { //NVIC_DisableIRQ(USART2_IRQn); serialMonit.printf(to_slave); //NVIC_EnableIRQ(USART2_IRQn); } //Calcul des OTU Calcul_OTU(); //Vers le moniteur série if (FLAG_AFF) Affichage(); //Enregistrement de la chaine if (FLAG_REC) UTILS::Write_Flash_File(to_store, Log_File_Name); #ifdef PID_MODE //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(); #endif //Arrêt du Timer mesurant le temps d'éxecution du code REAL_RATE.stop(); //Définition de la nouvelle valeur du temps d'échantillonage du PID. RATE = REAL_RATE.read(); //Reset du Timer REAL_RATE.reset(); //Pour ralentir le code à Ref_Time seconde fixe quelque soit les intéruptions du loop.... if (Ref_Time > RATE) { RATE_TRUE = (Ref_Time - RATE) * 1000; } else { RATE_TRUE = 0; #ifdef PID_MODE control_Servo.setInterval(RATE); #endif DEEP_DEBUG("Pour ralentir le code, Ref_Time doit être supérieur à %f seconde(s)\r\n\n", RATE); } wait_ms(RATE_TRUE); } } } }