Advertisement
bipping

step motor_V4

May 5th, 2024
664
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.14 KB | Source Code | 0 0
  1. #include <avr/interrupt.h>
  2. #include <Arduino.h>
  3. //#include <Wire.h>
  4. #include <rgb_lcd.h>
  5. #include <EEPROM.h>
  6. #include <string.h>
  7. #include <avr/sleep.h>
  8.  
  9. //#define SDA A4
  10. //#define SLC A5
  11. #define NOTE_CS6 1109
  12. #define NOTE_DS6 1245
  13.  
  14. // Variables globales
  15. const uint8_t VAL_RGB_R = 255;                            // Valeur R pour LED RGB
  16. const uint8_t VAL_RGB_G = 0;                              // Valeur G pour LED RGB
  17. const uint8_t VAL_RGB_B = 0;                              // Valeur B pour LED RGB
  18. const uint8_t PIN_SWITCH = 2;                             // Pin pour l'interrupteur à bascule
  19. const uint8_t PIN_COURANT_COUPURE = 3;                    // Pin pour détecter une coupure de courant
  20. const uint8_t PIN_LED_ROUGE = 5;                          // Pin pour LED PIN_LED_ROUGE
  21. const uint8_t PIN_LED_VERT = 7;                           // Pin pour LED PIN_LED_VERTE
  22. const uint8_t PIN_LED_ORANGE = 6;                         // Pin pour LED PIN_LED_ORANGE
  23. const uint8_t PIN_MOTEUR_DIR = 8;                         // Pin pour la direction du moteur
  24. const uint8_t PIN_MOTEUR_PUL = 9;                         // Pin pour les impulsions du moteur
  25. const uint8_t PIN_MOTEUR_ENA = 10;                        // Pin pour activer/désactiver le moteur
  26. const uint8_t PIN_BUZZER = 11;                            // Pin pour le Buzzer
  27. const uint8_t PIN_POTARD = A0;                            // Pin pour le potentiometre
  28. const int8_t MAX_TASKS = 10;
  29. const uint32_t INTERVAL_BASE = 3130;                      // interval de temps de base de 3130 µS pour une action
  30. const uint32_t INTERVAL_X3 = 9390;                        // 3x l'interval de base, soit 9390 µS pour une action
  31. const uint32_t INTERVAL_X7 = 21910;                       // 7x l'interval de base, soit 21910 µS pour une action
  32. const uint32_t INTERVAL_X78 = 244140;                     // 78x l'interval de base, soit 244140 µS pour une action
  33. const uint32_t INTERVAL_X156 = 488280;                    // 156x l'interval de base, soit 488280 µS pour une action
  34. const uint32_t LIMITEPASMAX = 120000;                     // Nombre maximal de pas du moteur
  35. uint8_t taskId_updateSwitchState;                         // updateSwitchState
  36. uint8_t taskId_checketatSwitch;                           // checketatSwitch
  37. uint8_t taskId_updatePotardAndPWM;                        // updatePotardAndPWM
  38. uint8_t taskId_LCD_Demarage;                              //
  39. uint8_t taskId_LCD_Update_MAIN;                           //
  40. uint8_t taskId_toggle_PIN_MOTOR;                          // toggle_PIN_MOTOR
  41. uint8_t taskId_modulate_PIN_LED_verte;                    // modulate_PIN_LED vert
  42. uint8_t taskId_modulate_PIN_LED_orange;                   // modulate_PIN_LED orange
  43. uint8_t taskId_toggleBuzzer;                              // toggleBuzzer
  44. uint16_t potard;                                          // Valeur du potentiometre
  45. volatile bool blackout = false;                           // Flag pour indiquer une coupure de courant
  46. volatile uint32_t nombreDePas = 0;                        // Compteur de pas du moteur
  47. volatile bool estCoupureCourant;                          // Verifie si il est oportun d'effectuer une sauvegarde lors d'une coupure de courant
  48. bool etatSwitch = false;                                  // État virtuel de l'interupteur, défini sur enclancher (false)
  49. int8_t taskCount = 0;                                     // Compteur pour suivre le nombre de tâches
  50.  
  51.  
  52. byte L[8] = { 0b00000, 0b11000, 0b01100, 0b00100, 0b01100, 0b10010, 0b10001, 0b00000 }; // Motif personnalisé pour écran LCD
  53.  
  54. // Énumération pour les différents états
  55. enum Etat {
  56.   ETAT_DEMARAGE,
  57.  
  58.   ETAT_ORIGINE_INITIALIZATION,
  59.   ETAT_ORIGINE_MAIN,
  60.  
  61.   ETAT_AVANCE_INITIALIZATION,
  62.   ETAT_AVANCE_MAIN,
  63.  
  64.   ETAT_TRANSITION_AVANCE_TOGGLE,
  65.  
  66.   ETAT_TOGGLE_MAIN,
  67.   ETAT_TOGGLE_CHECKEXITCONDITION,
  68.  
  69.   ETAT_TOGGLE_RECUPERATION,
  70.  
  71.   ETAT_FAIL
  72. };
  73.  
  74. Etat etatActuel;                                          // Variable stockant l'état actuel du système
  75.  
  76. struct Task {
  77.     void (*func)();
  78.     uint32_t nextExecution;
  79.     uint32_t interval;
  80.     bool enabled;
  81. };
  82.  
  83. Task tasks[MAX_TASKS];                                    // Tableau pour stocker les tâches
  84.  
  85. typedef void (*CallbackFunction)();                       // Définir un type de fonction de rappel
  86.  
  87. rgb_lcd display;
  88.  
  89. // Interruption de minuterie pour gérer le signal PWM et compter les pas
  90. ISR(TIMER1_COMPA_vect){  
  91.   toggle(PIN_MOTEUR_PUL);                                 // Bascule l'état du pin moteur
  92.   nombreDePas++;                                          // Incrémente le compteur de pas
  93. }
  94.  
  95. ISR(TIMER0_COMPA_vect) {
  96.   sleep_disable();                                        // Réveiller le MCU
  97.   TIMSK0 &= ~(1 << OCIE0A);                               // désactive  l'interruption de comparaison du Timer0
  98. }
  99.  
  100. // Sauvegarde les données essentielles dans EEPROM en cas de coupure de courant
  101. void interruptionCoupure() {
  102.   blackout = true;                                        // Indique une coupure de courant
  103.   sleep_disable(); // Réveiller le MCU
  104.   TIMSK0 &= ~(1 << OCIE0A);                               // désactive  l'interruption de comparaison du Timer0
  105. }
  106.  
  107. // Récupération des données après une coupure de courant
  108. void recuperation() {
  109.     uint32_t step;
  110.     EEPROM.get(0, step);                                  // Récupère le nombre de pas de EEPROM
  111.     nombreDePas = step;
  112.     EEPROM.update(4, false);                              // Indique que la récupération est faite    
  113.     enableTask(taskId_LCD_Update_MAIN);
  114. }// Fin de recuperation
  115.  
  116. //Fonction d'affichage LCD
  117. void LCD_Update_FAIL() {
  118.   display.clear();
  119.   display.setCursor(0, 0);
  120.   display.print("Erreur");
  121.   display.setCursor(0, 1);
  122.   display.print("Veuillez redemarrer");
  123. }
  124.  
  125. void LCD_Update_DEMARAGE() {
  126.   display.clear();
  127.   display.setCursor(0, 0);
  128.   display.print("Mauvaise position");
  129.   display.setCursor(0, 1);
  130.   display.print("Enclancher l'interrupteur");
  131. }
  132.  
  133. void LCD_Update_MAIN() {
  134.   static uint32_t lastSteps = -1;
  135.   static uint16_t lastPotValue = -1;
  136.  
  137.   if (lastSteps != nombreDePas) {
  138.     display.setCursor(1, 1);
  139.     display.print(nombreDePas);
  140.     lastSteps = nombreDePas;
  141.   }
  142.  
  143.   if (lastPotValue != potard) {
  144.     display.setCursor(10, 1);
  145.     display.print(potard);
  146.     lastPotValue = potard;
  147.   }
  148. }
  149.  
  150. int scheduleTask(void (*func)(), uint32_t interval, bool enabled) {
  151.     if (taskCount < MAX_TASKS) {
  152.       tasks[taskCount].func = func;
  153.       tasks[taskCount].interval = interval;
  154.       tasks[taskCount].nextExecution = micros() + interval;
  155.       tasks[taskCount].enabled = enabled;
  156.       //tasks[taskCount] = {func, micros() + interval, interval, enabled};
  157.       return taskCount++;                                 // Retourne l'index de la nouvelle tâche
  158.     }
  159.     return -1; // Retourne une valeur d'erreur si le tableau est plein
  160. }
  161.  
  162. void setup() {
  163.   Serial.begin(115200);                                   // Démarre la communication série à 115200 bps
  164.   display.begin(16, 2);                                   // Initialise l'écran LCD avec 16 colonnes et 2 lignes
  165.   display.setRGB(VAL_RGB_R, VAL_RGB_G, VAL_RGB_B);        // Définit la couleur de rétroéclairage de l'écran LCD
  166.   display.print("initialization");                        // Affiche le message d'initialisation sur l'écran LCD
  167.  
  168.   // Configuration des pins pour les LEDs et les sorties
  169.   pinMode(PIN_LED_ORANGE, OUTPUT);                        // Config. la LED orange en sortie
  170.   pinMode(PIN_LED_VERT, OUTPUT);                          // Config. la LED verte en sortie
  171.   pinMode(PIN_LED_ROUGE, OUTPUT);                         // Config. la LED rouge en sortie
  172.  
  173.   // Configuration des pins pour les entrées
  174.   pinMode(PIN_POTARD, INPUT);                             // Définit le pin A0 comme entrée pour le potentiomètre
  175.   pinMode(PIN_SWITCH, INPUT_PULLUP);                      // Active la résistance de pull-up sur le pin du bouton
  176.   pinMode(PIN_MOTEUR_DIR, OUTPUT);                        // Config. la direction du moteur en sortie
  177.   pinMode(PIN_MOTEUR_PUL, OUTPUT);                        // Config. le pin de pulsation du moteur en sortie
  178.   pinMode(PIN_MOTEUR_ENA, OUTPUT);                        // Config. le pin d'activation du moteur en sortie
  179.   pinMode(PIN_BUZZER, OUTPUT);                            // Config. le pin du buzzer en sortie
  180.   pinMode(PIN_COURANT_COUPURE, INPUT_PULLUP);             // Active la résistance de pull-up pour la coupure de courant
  181.  
  182.   // Configuration initiale de l'état des sorties
  183.   digitalWrite(PIN_BUZZER, LOW);                          // Éteint le buzzer
  184.   digitalWrite(PIN_SWITCH, HIGH);                         // Initialise le PIN_SWITCH à l'état haut
  185.   digitalWrite(PIN_LED_VERT, HIGH);                       // Allume la LED verte
  186.   digitalWrite(PIN_LED_ORANGE, HIGH);                     // Allume la LED orange
  187.   digitalWrite(PIN_LED_ROUGE, HIGH);                      // Allume la LED rouge
  188.  
  189.   // Signal sonore d'initialisation
  190.   tone(PIN_BUZZER, NOTE_DS6, 500);                        // Joue un ton sur le buzzer
  191.   delay(500);                                             // Attend 500 ms
  192.  
  193.   // Éteint toutes les LEDs après le signal sonore
  194.   digitalWrite(PIN_LED_VERT, LOW);                        // Éteint la LED verte
  195.   digitalWrite(PIN_LED_ROUGE, LOW);                       // Éteint la LED rouge
  196.   digitalWrite(PIN_LED_ORANGE, LOW);                      // Éteint la LED orange
  197.  
  198.   timerPrecedents[TIMER_LED_Vert] = micros();             // Initialise le timer pour la LED verte
  199.   timerPrecedents[TIMER_LED_Orange] = micros();           // Initialise le timer pour la LED Orange
  200.  
  201.   // Vérifie et récupère l'état de coupure de courant depuis l'EEPROM
  202.   bool spin;
  203.   EEPROM.get(4, spin);                       // Récupère l'état de coupure de courant de l'EEPROM
  204.   estCoupureCourant = spin;
  205.  
  206.   // Configuration initiale de l'état du système
  207.   etatActuel = (!estCoupureCourant) ? ETAT_DEMARAGE : ETAT_TOGGLE_RECUPERATION;
  208.  
  209.   // Configuration des interruptions
  210.   attachInterrupt(digitalPinToInterrupt(PIN_COURANT_COUPURE), interruptionCoupure, FALLING); // Interruption sur coupure de courant
  211.  
  212.   // Configuration des Timer pour le mode CTC (Clear Timer on Compare Match)
  213.   TCCR1A = 0;                                             // Réinitialise TCCR1A pour la configuration
  214.   TCCR1B = (1 << WGM12) | (1 << CS11);                    // Configure le mode CTC et le prescaler pour Timer1
  215.  
  216.   TCCR0A = (1 << WGM21);                                  // Configure le Timer 0 pour le mode CTC
  217.   TCCR0B = (1 << CS22) | (1 << CS21) | (1 << CS20);       // Prescaler de 1024
  218.  
  219.   //setupHardware();
  220.  
  221.   taskId_updateSwitchState = scheduleTask(updateSwitchState, INTERVAL_X7, true);
  222.   taskId_checketatSwitch = scheduleTask(checketatSwitch, INTERVAL_X156, false);
  223.   taskId_updatePotardAndPWM = scheduleTask(updatePotardAndPWM, INTERVAL_X78, false);
  224.   taskId_LCD_Demarage = scheduleTask( [] () {LCD_Update_DEMARAGE(); }, INTERVAL_X78, false);
  225.   taskId_LCD_Update_MAIN = scheduleTask( [] () {LCD_Update_MAIN(); }, INTERVAL_X78, false);
  226.   taskId_toggle_PIN_MOTOR = scheduleTask(toggle_PIN_MOTOR, INTERVAL_BASE, false);
  227.   taskId_modulate_PIN_LED_verte = scheduleTask( [] () {modulate_PIN_LED(PIN_LED_VERT); }, INTERVAL_X3, false);
  228.   taskId_modulate_PIN_LED_orange = scheduleTask([]() { modulate_PIN_LED(PIN_LED_ORANGE); }, INTERVAL_X3, false);
  229.   taskId_toggleBuzzer = scheduleTask(toggleBuzzer, INTERVAL_X78, false);
  230.  
  231.   updatePotardAndPWM();                               // Initialise le potard
  232.  
  233.   set_sleep_mode(SLEEP_MODE_PWR_SAVE);                // Définir le mode de sommeil
  234.  
  235.   updateSwitchState();                                // Initialization de l'état de l'interupteur
  236.  
  237.   if (!estCoupureCourant){
  238.     enableTask(taskId_LCD_Demarage);
  239.     enableTask(taskId_modulate_PIN_LED_orange);  
  240.     enableTask(taskId_toggleBuzzer);
  241.   }else{
  242.     enableTask(taskId_LCD_Update_MAIN);
  243.   }
  244.  
  245.   delay(800);                                             // Court délai avant d'activer les interruptions
  246.   sei();                                                  // Active les interruptions globales
  247. }
  248.  
  249. void loop() {
  250.  
  251.   //enableTask(updateSwitchState);
  252.  
  253.   switch (etatActuel) {
  254.     case ETAT_DEMARAGE:
  255.       if(!etatSwitch) {
  256.         etatActuel = ETAT_ORIGINE_INITIALIZATION;
  257.       }else{
  258.        
  259.         //LCD_Update_DEMARGE(display);
  260.  
  261.         //modulate_PIN_LED(PIN_LED_ORANGE);
  262.  
  263.         //toggleBuzzer
  264.        
  265.       }
  266.       break;
  267.     case ETAT_ORIGINE_INITIALIZATION:
  268.       // Initialisations pour l'état d'origine
  269.       origine_initialization();
  270.       etatActuel = ETAT_ORIGINE_MAIN;                        // Définit l'état à ORIGINE
  271.       break;
  272.     case ETAT_ORIGINE_MAIN:
  273.      
  274.       //modulate_PIN_LED(PIN_LED_VERT);
  275.  
  276.       //LCD_Update_ORIGINE(display);
  277.      
  278.       //updatePotardAndPWM
  279.  
  280.       if(etatSwitch) {
  281.         etatActuel = ETAT_AVANCE_INITIALIZATION;
  282.       }
  283.       break;
  284.     case ETAT_AVANCE_INITIALIZATION:
  285.       // Initialisations pour l'état d'avance
  286.       avance_initialization();
  287.       etatActuel = ETAT_AVANCE_MAIN;                         // Définit l'état à AVANCE
  288.       break;
  289.     case ETAT_AVANCE_MAIN:
  290.       //Verifie si le programme doit s'arreter en urgence
  291.       checketatFail();
  292.  
  293.       //LCD_Update_AVANCE(display);
  294.        
  295.       //toggle_PIN_MOTOR
  296.  
  297.       if(nombreDePas >= LIMITEPASMAX || !etatSwitch) {
  298.         etatActuel = ETAT_TRANSITION_AVANCE_TOGGLE;
  299.       }
  300.       break;
  301.     case ETAT_TRANSITION_AVANCE_TOGGLE:
  302.       // Vérifie la condition de sortie de l'état d'avance
  303.       transition_avance_toggle();
  304.  
  305.       etatActuel = ETAT_TOGGLE_MAIN;                         // Définit l'état à TOGGLE
  306.       break;
  307.     case ETAT_TOGGLE_MAIN:
  308.       //Verifie si le programme doit s'arreter en urgence
  309.       checketatFail();
  310.  
  311.       //LCD_Update_TOGGLE(display);
  312.  
  313.       //toggle_PIN_MOTOR
  314.      
  315.       //checketatSwitch
  316.  
  317.       if(nombreDePas == 0){
  318.         etatActuel = ETAT_TOGGLE_CHECKEXITCONDITION;
  319.       }
  320.       break;
  321.     case ETAT_TOGGLE_CHECKEXITCONDITION:
  322.       // Vérifie la condition de sortie de l'état de toggle
  323.       toggle_checkexitcondition();
  324.  
  325.       etatActuel = (etatSwitch) ? ETAT_AVANCE_INITIALIZATION : ETAT_ORIGINE_INITIALIZATION;
  326.       break;
  327.     case ETAT_TOGGLE_RECUPERATION:    
  328.       recuperation();                                   // Appelle la fonction de récupération en cas de coupure
  329.  
  330.       etatActuel = ETAT_TRANSITION_AVANCE_TOGGLE;
  331.       break;
  332.     case ETAT_FAIL:
  333.       // Exécute la séquence d'arrêt d'urgence
  334.       checketatFail();
  335.  
  336.       break;
  337.     default: // ETAT_FAIL:
  338.       // Exécute la séquence d'arrêt d'urgence
  339.       etatActuel = ETAT_FAIL;
  340.       break;
  341.   }
  342.  
  343.   manageTasks();
  344.  
  345. }//Fin de la boucle loop
  346.  
  347. void origine_initialization(){
  348.   disableTask(taskId_LCD_Demarage);
  349.   display.clear();
  350.   display.setCursor(0, 0);
  351.   display.print("Origine");
  352.   display.setCursor(0, 1);
  353.   display.print("Pas: ");
  354.   disableTask(taskId_modulate_PIN_LED_orange);
  355.   disableTask(taskId_toggleBuzzer);
  356.   digitalWrite(PIN_LED_ORANGE, LOW);                  // Éteint la LED orange
  357.   digitalWrite(PIN_LED_VERT, LOW);                    // Éteint la LED verte
  358.   digitalWrite(PIN_LED_ROUGE, HIGH);                  // Allume la LED rouge
  359.   digitalWrite(PIN_MOTEUR_ENA, HIGH);                 // Désactive le frein du moteur
  360.   tone(PIN_BUZZER, NOTE_CS6, 80);                     // Joue la note CS6
  361.   delay(100);                                         // Pause de 100ms
  362.   tone(PIN_BUZZER, NOTE_DS6, 80);                     // Joue la note DS6
  363.   delay(100);                                         // Pause de 100ms
  364.   tone(PIN_BUZZER, NOTE_DS6, 160);                    // Joue la note DS6 plus longue
  365.   delay(250);                                         // Pause de 250ms
  366.   digitalWrite(PIN_LED_ROUGE, LOW);                   // Éteint la LED rouge
  367.   enableTask(taskId_modulate_PIN_LED_verte);
  368.   enableTask(taskId_updatePotardAndPWM);
  369. }
  370.  
  371. void avance_initialization(){
  372.   display.clear();
  373.   display.setCursor(0, 0);
  374.   display.print("Avance");
  375.   display.setCursor(0, 1);
  376.   display.print("Lambda: ");
  377.   disableTask(taskId_modulate_PIN_LED_verte);
  378.   disableTask(taskId_updatePotardAndPWM);
  379.   estCoupureCourant = true;                               // Réinitialise l'indicateur de coupure de courant
  380.   digitalWrite(PIN_MOTEUR_DIR, LOW);                      // Définit le sens de rotation du moteur
  381.   digitalWrite(PIN_MOTEUR_ENA, LOW);                      // Active le moteur
  382.   noInterrupts();                                         // Désactiver les interruptions pendant la configuration
  383.   TIMSK1 |= (1 << OCIE1A);                                // Active l'interruption de comparaison du Timer1, Active le signal PWM
  384.   interrupts();                                           // Réactiver les interruptions
  385.   digitalWrite(PIN_LED_VERT, HIGH);                       // Allume la LED verte
  386.   digitalWrite(PIN_LED_ORANGE, LOW);                      // Éteint la LED orange
  387.   digitalWrite(PIN_LED_ROUGE, LOW);                       // Éteint la LED rouge
  388. }
  389.  
  390. void transition_avance_toggle(){
  391.   display.clear();
  392.   display.setCursor(0, 0);
  393.   display.print("Toggle");
  394.   display.setCursor(0, 1);
  395.   display.print("Lambda: ");
  396.   digitalWrite(PIN_LED_VERT, LOW);                        // Éteint la LED verte
  397.   noInterrupts();                                         // Désactiver les interruptions pendant la configuration
  398.   OCR1A = INTERVAL_BASE;
  399.   interrupts();                                           // Réactiver les interruptions
  400.   digitalWrite(PIN_MOTEUR_DIR, HIGH);                     // Change le sens de rotation du moteur
  401.   digitalWrite(PIN_MOTEUR_ENA, LOW);                      // Active le moteur
  402.   //enableTask(taskId_toggle_PIN_MOTOR);
  403.   enableTask(taskId_checketatSwitch);
  404. }
  405.  
  406. void toggle_checkexitcondition(){
  407.   disableTask(taskId_checketatSwitch);
  408.   noInterrupts();                                         // Désactiver les interruptions pendant la configuration
  409.   TIMSK1 &= ~(1 << OCIE1A);                               // Désactive l'interruption de comparaison du Timer1, Désactive le signal PWM
  410.   interrupts();                                           // Réactiver les interruptions
  411.   estCoupureCourant = false;                              // Réinitialise l'indicateur de coupure de courant
  412.   digitalWrite(PIN_LED_ORANGE, LOW);                      // Éteint la LED orange
  413.   digitalWrite(PIN_LED_VERT, LOW);                        // Éteint la LED verte
  414. }
  415.  
  416. //sauvgarde les données importante si coupure detecter, arrete le programme
  417. void checketatFail() {
  418.   if(blackout || etatActuel == ETAT_FAIL){
  419.     noInterrupts();                                       // Désactive les interruptions
  420.     bool spin =  estCoupureCourant;
  421.     uint32_t step = nombreDePas;
  422.     EEPROM.update(0, step);                               // Sauvegarde le nombre de pas
  423.     EEPROM.update(4, spin);                               // Réinitialise le flag de coupure de courant
  424.     digitalWrite(PIN_MOTEUR_PUL, LOW);                    // Désactive les impulsions
  425.     digitalWrite(PIN_MOTEUR_ENA, HIGH);                   // Désactive le frein du moteur
  426.     digitalWrite(PIN_LED_ROUGE, HIGH);                    // Allume la LED d'urgence
  427.     LCD_Update_FAIL();
  428.     tone(PIN_BUZZER, NOTE_CS6, 1000);                     // Joue la note CS6
  429.  
  430.     while(true) {
  431.       delay(4294967295);                                  // Bloque le système indéfiniment
  432.     }                                                     // Boucle d'arrêt d'urgence
  433.   }
  434. }
  435.  
  436. void manageTasks() {
  437.   uint32_t currentTime = micros();
  438.   uint32_t nextTaskTime = INTERVAL_X156; //Temps de la tache la plus longue, par securité ce sera la durée maximal
  439.  
  440.   // Parcourir les tâches pour trouver la plus proche et exécuter si nécessaire
  441.   for (int i = 0; i < taskCount; i++) {
  442.     if (tasks[i].enabled) {
  443.       if (currentTime >= tasks[i].nextExecution) {
  444.         tasks[i].func();  // Exécuter la fonction
  445.         tasks[i].nextExecution = currentTime + tasks[i].interval;  // Planifier la prochaine exécution
  446.       }
  447.       if (tasks[i].nextExecution < nextTaskTime) {
  448.         nextTaskTime = tasks[i].nextExecution;
  449.       }
  450.     }
  451.   }
  452.  
  453.   // Calculer le temps d'attente
  454.   uint32_t timeToWait = nextTaskTime - currentTime;
  455.   if (timeToWait > 800) {
  456.     // Calculer le nombre de ticks nécessaires pour le Timer 2
  457.     uint16_t timerTicks = min(255, timeToWait / 4);  // 4 est le nombre d'µs par tick avec un prescaler de 1024 à 16 MHz
  458.  
  459.     noInterrupts(); // Désactiver les interruptions pendant la configuration
  460.     OCR0A = timerTicks;  // Définir la valeur pour comparaison A
  461.     TIMSK0 |= (1 << OCIE0A);  // Activer l'interruption Timer 0 Compare Match A
  462.     interrupts(); // Réactiver les interruptions
  463.  
  464.     sleep_mode();  // Dormir jusqu'à la prochaine interruption du timer
  465.   } else if (timeToWait > 300) {
  466.     delayMicroseconds(timeToWait); // Un tres court délai
  467.   }else{
  468.    
  469.   }
  470. }
  471.  
  472. void enableTask(int8_t taskIndex) {
  473.     if (taskIndex >= 0 && taskIndex < taskCount) {
  474.         tasks[taskIndex].enabled = true;
  475.         tasks[taskIndex].nextExecution = micros() + tasks[taskIndex].interval;  // Réinitialise le timing
  476.     }
  477. }
  478.  
  479. void disableTask(int8_t taskIndex) {
  480.     if (taskIndex >= 0 && taskIndex < taskCount) {
  481.         tasks[taskIndex].enabled = false;
  482.     }
  483. }
  484.  
  485. /*/ Exécute une fonction à intervalle régulier basé sur un timer
  486. void checkTimerAndUpdate(uint16_t &previousTime, uint32_t intervalAction, CallbackFunction func) {
  487.   if (micros() - previousTime >= intervalAction ) {
  488.     previousTime = micros();                              // Réinitialise le temps précédent
  489.     func();                                               // Appelle la fonction passée en paramètre
  490.   }
  491. }// Fin de checkTimerAndUpdate*/
  492.  
  493. //Fonction de mise à jour de potard et de la fréquence du PWM du moteur
  494. void updatePotardAndPWM() {
  495.   uint16_t newPotard = map(analogRead(PIN_POTARD), 0, 1023, 11200, 11300); // Map la lecture analogique à la plage désirée
  496.   if (newPotard != potard) {                              // Vérifie si la valeur a changé
  497.     potard = newPotard;                                   // Met à jour la variable globale potard
  498.     noInterrupts();                                       // Désactive les interruptions
  499.     OCR1A = potard;                                       // Met à jour la fréquence de la pin pul, la vitesse du moteur
  500.     interrupts();                                         // Réactiver les interruptions
  501.   }
  502. }// Fin de updatePotardAndPWM
  503.  
  504. // Met à jour l'état de l'interrupteur
  505. void updateSwitchState() {
  506.     if (digitalRead(PIN_SWITCH) != etatSwitch) {          // Verifie si l'interupteur à bascule à changer
  507.       etatSwitch = !etatSwitch;                           // Bascule l'état en utilisant la valeur pointée
  508.     }
  509. }// Fin de updateSwitchState
  510.  
  511. // Fait varier la luminosité de la LED Rouge
  512. void modulate_PIN_LED(uint8_t ledPin) {
  513.   static uint8_t i = 1;                                   // Initialise l'intensité de la LED
  514.   static bool estIncrement = true;                        // Initialise la direction de l'incrémentation
  515.   analogWrite(ledPin, i);                                 // Applique la luminosité à la LED
  516.   i = estIncrement ? i + 1 : i - 1;                       // Incrémente ou décrémente la luminosité
  517.   if(i == 255 || i == 0) {                                // Verifie si i est arrivé au extremiter
  518.     estIncrement = !estIncrement;                         // Inverse la direction si les limites sont atteintes
  519.   }
  520. }// Fin de modulate_PIN_LED
  521.  
  522. // Fonction pour basculer l'état d'une broche
  523. void toggle(int8_t pin) {
  524.     digitalWrite(pin, !digitalRead(pin));                 // Bascule l'état de la broche
  525. } // Fin de toggle
  526.  
  527. void toggleLEDVert() {
  528.     toggle(PIN_LED_VERT);
  529. }
  530.  
  531. void toggleLEDOrange() {
  532.     toggle(PIN_LED_ORANGE);
  533. }
  534.  
  535. // Exécute une action LED en fonction de l'état de l'interrupteur
  536. void checketatSwitch() {
  537.     CallbackFunction func = etatSwitch ? toggleLEDVert : toggleLEDOrange;
  538.     if (digitalRead(etatSwitch ? PIN_LED_VERT : PIN_LED_ORANGE) == HIGH) {
  539.         digitalWrite(etatSwitch ? PIN_LED_VERT : PIN_LED_ORANGE, LOW);
  540.     }
  541.     func();
  542. }// Fin de checkTimerBasedOnState
  543.  
  544. // Actionne le moteur et décompte les pas
  545. void toggle_PIN_MOTOR() {
  546.   toggle(PIN_MOTEUR_PUL);                                 // Bascule le pin du moteur
  547.   noInterrupts();                                         // Désactive les interruptions
  548.   nombreDePas--;                                          // Décrémente le compteur de pas
  549.   interrupts();                                           // Réactive les interruptions
  550. }// Fin de toggle_PIN_MOTOR
  551.  
  552. //tone utilise le Timer2
  553. void toggleBuzzer() {
  554.   static bool isActive = true;
  555.   if (isActive) {
  556.     noTone(PIN_BUZZER);                                   // Arrête le son pendant 84 millisecondes
  557.     isActive = false;                                     //
  558.   } else {
  559.     tone(PIN_BUZZER, NOTE_DS6, 160);                      // Joue la note DS6 pendant 160 millisecondes
  560.     isActive = true;
  561.   }
  562. }
  563.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement