Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <avr/interrupt.h>
- #include <Arduino.h>
- #include <Wire.h>
- #include <rgb_lcd.h>
- #include <EEPROM.h>
- //#define SDA A4
- //#define SLC A5
- #define NOTE_CS6 1109
- #define NOTE_DS6 1245
- rgb_lcd lcd;
- // Variables globales
- const uint8_t VAL_RGB_R = 255; // Valeur R pour LED RGB
- const uint8_t VAL_RGB_G = 0; // Valeur G pour LED RGB
- const uint8_t VAL_RGB_B = 0; // Valeur B pour LED RGB
- const int8_t PIN_SWITCH = 2; // Pin pour l'interrupteur à bascule
- const int8_t PIN_COURANT_COUPURE = 3; // Pin pour détecter une coupure de courant
- const int8_t PIN_LED_ROUGE = 5; // Pin pour LED PIN_LED_ROUGE
- const int8_t PIN_LED_VERT = 6; // Pin pour LED PIN_LED_VERTe
- const int8_t PIN_LED_ORANGE = 7; // Pin pour LED PIN_LED_ORANGE
- const int8_t PIN_MOTEUR_DIR = 8; // Pin pour la direction du moteur
- const int8_t PIN_MOTEUR_PUL = 9; // Pin pour les impulsions du moteur
- const int8_t PIN_MOTEUR_ENA = 10; // Pin pour activer/désactiver le moteur
- const int8_t PIN_BUZZER = 11; // Pin pour le Buzzer
- const uint16_t PIN_POTARD = A0; // Pin pour le potentiometre
- const int8_t NUM_TIMERS = 10; // Nombre total de timers
- const int8_t TIMER_SWITCH = 7; // Timer pour l'interrupteur
- const int8_t TIMER_POTARD = 8; // Timer pour le potentiometre
- const int8_t TIMER_LED_Orange = 0; // Timer pour LED PIN_LED_ORANGE
- const int8_t TIMER_LED_Vert = 1; // Timer pour LED PIN_LED_VERTe
- const int8_t TIMER_LED_Rouge = 3; // Timer pour LED PIN_LED_ROUGE
- const int8_t TIMER_MOTOR = 2; // Timer pour le moteur
- const int8_t TIMER_LCD_Origine = 4; // Timer pour l'affichage LCD (origine)
- const int8_t TIMER_LCD_avance = 5; // Timer pour l'affichage LCD (avance)
- const int8_t TIMER_LCD_toggle = 6; // Timer pour l'affichage LCD (alternance)
- const int8_t TIMER_ETAT = 9; // Timer pour l'état
- uint16_t timerPrecedents[NUM_TIMERS]; // Temps précédent pour chaque timer
- const uint16_t INTERVAL_BASE = 3130; // interval de temps pour une action quelconque
- const uint16_t INTERVAL_X3 = 9390; // interval de temps pour une action quelconque
- const uint32_t INTERVAL_X78 = 244140; // interval de temps pour une action quelconque
- const uint32_t INTERVAL_X156 = 488280; // interval de temps pour une action quelconque
- const uint32_t LIMITEPASMAX = 120000; // Nombre maximal de pas du moteur
- volatile uint32_t nombreDePas = 0; // Compteur de pas du moteur
- volatile bool signalPWM = false; // État du signal PWM
- volatile bool estCoupureCourant; // État de la coupure de courant
- bool etatSwitch = false; // État virtuel de l'interupteur, défini sur enclancher (false)
- bool sense = false; // direction du moteur
- bool estInitOrigineEffectue = false; // Indique si la fonction initOrigine a été exécutée
- bool conditionEtatBascule = false; // Indique si les conditions d'initialisation de 'ETAT_AVANCE' ou 'ETAT_TOGGLE' sont remplies
- byte L[8] = { 0b00000, 0b11000, 0b01100, 0b00100, 0b01100, 0b10010, 0b10001, 0b00000 }; // Motif personnalisé pour écran LCD
- // Énumération pour les différents états
- enum Etat { ETAT_ORIGINE, ETAT_AVANCE, ETAT_TOGGLE, ETAT_FAIL };
- Etat etatActuel; // Variable stockant l'état actuel du système
- // Interruption de minuterie pour gérer le signal PWM et compter les pas
- ISR(TIMER1_COMPA_vect){
- if(signalPWM == true){ // Vérifie si le signal PWM est actif
- toggle(PIN_MOTEUR_PUL); // Bascule l'état du pin moteur
- nombreDePas++; // Incrémente le compteur de pas
- }
- }
- // Sauvegarde les données essentielles dans EEPROM en cas de coupure de courant
- void interruptionCoupure(volatile bool estCoupureCourant, volatile uint32_t &nombreDePas) {
- if (!estCoupureCourant) { // Vérifie si une coupure de courant a eu lieu
- EEPROM.update(0, nombreDePas); // Sauvegarde le nombre de pas
- EEPROM.update(4, false); // Réinitialise le flag de coupure de courant
- etatActuel = ETAT_FAIL; // Change l'état à défaut
- } // Utilise une procédure d'interruption déclarée dans setup
- }// Fin de interruptionCoupure
- // Récupération des données après une coupure de courant
- void recuperation(volatile bool estCoupureCourant, volatile uint32_t &nombreDePas, bool &sense) {
- if (!estCoupureCourant) { // Si aucune coupure n'a eu lieu
- EEPROM.get(0, nombreDePas); // Récupère le nombre de pas de EEPROM
- sense = true; // Réinitialise la direction du moteur
- etatActuel = ETAT_TOGGLE; // Change l'état pour le retour à l'origine
- EEPROM.update(4, true); // Indique que la récupération est faite
- }
- }// Fin de recuperation
- // Lecture et mise à l'échelle de la valeur du potentiomètre
- const uint16_t potard() {
- return map(analogRead(PIN_POTARD), 0, 1023, 11200, 11300); // Map la lecture analogique à la plage désirée
- } // Fin de potard
- void Lambda(){
- OCR1A = potard(); // mets à jour le rapport de cycle du PWM
- }
- // Fonction pour basculer l'état d'une broche
- void toggle(int8_t pin) {
- digitalWrite(pin, !digitalRead(pin)); // Bascule l'état de la broche
- } // Fin de toggle
- // Exécute une fonction à intervalle régulier basé sur un timer
- void checkTimerAndUpdate(uint16_t &previousTime, uint32_t intervalAction, void (*func)(bool*, int8_t*), bool etatSwitch, int8_t ledPin) {
- if (micros() - previousTime >= intervalAction ) {
- previousTime = micros(); // Réinitialise le temps précédent
- func(&etatSwitch, &ledPin); // Appelle la fonction passée en paramètre
- }
- }// Fin de checkTimerAndUpdate
- // Met à jour l'état de l'interrupteur
- void updateSwitchState(bool *etatSwitch, int8_t *ledPin) {
- if (digitalRead(*ledPin) != *etatSwitch) {
- *etatSwitch = !(*etatSwitch); // Bascule l'état en utilisant la valeur pointée
- }
- }// Fin de updateSwitchState
- // Actionne le moteur et décompte les pas
- void toggle_PIN_MOTOR(bool *etatSwitch, int8_t *ledPin) {
- toggle(PIN_MOTEUR_PUL); // Bascule le pin du moteur
- noInterrupts(); // Désactive les interruptions
- nombreDePas--; // Décrémente le compteur de pas
- interrupts(); // Réactive les interruptions
- }// Fin de toggle_PIN_MOTOR
- // Bascule l'état de la LED
- void toggle_PIN_LED(bool *etatSwitch, int8_t pin) {
- toggle(pin); // Bascule l'état de la pin LED
- }// Fin de toggle_PIN
- // Fait varier la luminosité de la LED Rouge
- void modulate_PIN_LED_ROUGE(bool *etatSwitch, int8_t *ledPin) {
- static uint8_t i = 1; // Initialise l'intensité de la LED
- static bool estIncrement = true; // Initialise la direction de l'incrémentation
- analogWrite(PIN_LED_ROUGE, i); // Applique la luminosité à la LED
- i = estIncrement ? i + 1 : i - 1; // Incrémente ou décrémente la luminosité
- if(i == 255 || i == 0) { // Inverse la direction si les limites sont atteintes
- estIncrement = !estIncrement;
- }
- }// Fin de modulate_PIN_LED_ROUGE
- // Exécute une action LED en fonction de l'état de l'interrupteur
- void checkTimerBasedOnState(bool &etatSwitch, uint16_t *timerPrecedents, void (*toggle_PIN_LED)) {
- uint16_t *timerValue = etatSwitch ? &timerPrecedents[TIMER_LED_Vert] : &timerPrecedents[TIMER_LED_Orange];
- static int8_t ledPin = etatSwitch ? PIN_LED_VERT : PIN_LED_ORANGE;
- if(digitalRead(!etatSwitch ? PIN_LED_VERT : PIN_LED_ORANGE) == HIGH) { // Si la LED non-active est allumée
- digitalWrite(!etatSwitch ? PIN_LED_VERT : PIN_LED_ORANGE, LOW); // Éteint cette LED
- }
- checkTimerAndUpdate(*timerValue, INTERVAL_X156, toggle_PIN_LED, etatSwitch, ledPin); // Vérifie le timer et met à jour l'état
- }// Fin de checkTimerBasedOnState
- // Vérifie les conditions d'arrêt du moteur et exécute l'arrêt si nécessaire
- void CheckSortieAvance() {
- if (!etatSwitch || (nombreDePas >= LIMITEPASMAX)) { // Si l'état du switch est désactivé ou le nombre de pas dépasse la limite
- digitalWrite(PIN_LED_VERT, LOW); // Éteint la LED verte
- sense = true; // Inverse le sens de rotation
- signalPWM = false; // Désactive le signal PWM
- } // Fin de condition et bloc if
- } // Fin de la fonction CheckSortieAvance
- // Vérifie si le moteur a atteint l'origine et réinitialise certains états
- void CheckSortieToggle () {
- if(nombreDePas == 0) { // Si le nombre de pas est à zéro
- estCoupureCourant = true; // Active l'indicateur de coupure de courant
- sense = false; // Réinitialise le sens de rotation
- estInitOrigineEffectue = false; // Indique que l'init origine n'est pas effectuée
- digitalWrite(PIN_LED_ORANGE, LOW); // Éteint la LED orange
- digitalWrite(PIN_LED_VERT, LOW); // Éteint la LED verte
- } // Fin de condition et bloc if
- } // Fin de la fonction CheckSortieToggle
- // Prépare le système pour retourner à l'origine
- void initOrigine() {
- if (!estInitOrigineEffectue) { // Si l'init d'origine n'est pas effectuée
- recuperation(estCoupureCourant, nombreDePas, sense); // Appelle la fonction de récupération en cas de coupure
- digitalWrite(PIN_LED_ORANGE, LOW); // Éteint la LED orange
- digitalWrite(PIN_LED_VERT, LOW); // Éteint la LED verte
- digitalWrite(PIN_LED_ROUGE, HIGH); // Allume la LED rouge
- digitalWrite(PIN_MOTEUR_ENA, HIGH); // Désactive le frein du moteur
- tone(PIN_BUZZER, NOTE_CS6, 80); // Joue la note CS6
- delay(100); // Pause de 100ms
- tone(PIN_BUZZER, NOTE_DS6, 80); // Joue la note DS6
- delay(100); // Pause de 100ms
- tone(PIN_BUZZER, NOTE_DS6, 160); // Joue la note DS6 plus longue
- signalPWM = false; // Désactive le signal PWM
- delay(250); // Pause de 250ms
- digitalWrite(PIN_LED_ROUGE, LOW); // Éteint la LED rouge
- estInitOrigineEffectue = true; // Marque l'initialisation d'origine comme effectuée
- } // Fin de condition et bloc if
- } // Fin de la fonction initOrigine
- // Prépare le système pour avancer vers une position cible
- void initAvance() {
- if (!conditionEtatBascule) { // Si la condition pour basculer n'est pas remplie
- estCoupureCourant = false; // Réinitialise l'indicateur de coupure de courant
- signalPWM = true; // Active le signal PWM
- digitalWrite(PIN_MOTEUR_DIR, LOW); // Définit le sens de rotation du moteur
- digitalWrite(PIN_MOTEUR_ENA, LOW); // Active le moteur
- digitalWrite(PIN_LED_VERT, HIGH); // Allume la LED verte
- digitalWrite(PIN_LED_ORANGE, LOW); // Éteint la LED orange
- digitalWrite(PIN_LED_ROUGE, LOW); // Éteint la LED rouge
- conditionEtatBascule = true; // Change l'état de conditionEtatBascule
- } // Fin de condition et bloc if
- } // Fin de la fonction initAvance
- // Initialise la bascule pour le retour à la position cible
- void initToggle() {
- if (conditionEtatBascule) { // Si la condition de bascule est remplie
- digitalWrite(PIN_MOTEUR_DIR, HIGH); // Change le sens de rotation du moteur
- digitalWrite(PIN_MOTEUR_ENA, LOW); // Active le moteur
- digitalWrite(PIN_LED_ROUGE, HIGH); // Allume la LED rouge
- conditionEtatBascule = false; // Change l'état de conditionEtatBascule
- } // Fin de condition et bloc if
- } // Fin de la fonction initToggle
- void LCD_Update(const char* state, const char* line0ExtraText, uint8_t line0ExtraPos,
- uint8_t line1ExtraPos, bool createSpecialChar) {
- lcd.clear(); // Nettoie l'écran LCD
- lcd.home(); // Réinitialise le curseur
- lcd.print(state); // Affiche l'état fourni en paramètre
- if (line0ExtraText != NULL) { // Si du texte supplémentaire est fourni pour la ligne 0
- lcd.setCursor(line0ExtraPos, 0); // Définit la position du curseur
- lcd.print(line0ExtraText); // Affiche le texte supplémentaire
- }
- lcd.setCursor(1, 1); // Place le curseur en (1,1)
- lcd.print(nombreDePas); // Affiche le compteur de pas
- lcd.setCursor(10, 1); // Place le curseur en (10,1)
- lcd.print(potard()); // Affiche la valeur du potentiomètre
- if (createSpecialChar) { // Si un caractère spécial doit être créé
- lcd.createChar(1, L); // Crée un caractère spécial
- lcd.setCursor(line1ExtraPos, 1); // Place le curseur pour le caractère spécial
- lcd.write(byte(1)); // Affiche le caractère spécial
- }
- }
- void etatFailSafe() {
- signalPWM = false; // Arrête le moteur
- digitalWrite(PIN_MOTEUR_PUL, LOW); // Désactive les impulsions
- digitalWrite(PIN_MOTEUR_ENA, HIGH); // Coupe l'alimentation du moteur
- digitalWrite(PIN_LED_ROUGE, HIGH); // Allume la LED d'urgence
- etatActuel = ETAT_FAIL;
- } // Gère l'état de défaillance du système
- void updateEtatActuel() {
- if ((nombreDePas == 0 && sense == false && etatSwitch == false) && (etatActuel == ETAT_TOGGLE || etatActuel == ETAT_ORIGINE)) {
- etatActuel = ETAT_ORIGINE; // Définit l'état à ORIGINE
- } else if ((nombreDePas < LIMITEPASMAX && sense == false && etatSwitch == true) && (etatActuel != ETAT_FAIL)) {
- etatActuel = ETAT_AVANCE; // Définit l'état à AVANCE
- } else if ((nombreDePas > 0 && sense == true) && (etatActuel == ETAT_TOGGLE || etatActuel == ETAT_AVANCE)) {
- etatActuel = ETAT_TOGGLE; // Définit l'état à TOGGLE
- }else {
- etatActuel = ETAT_FAIL; // Définit un état échec
- }
- } // Met à jour l'état actuel du système
- void setup() {
- Serial.begin(115200); // Démarre la communication série à 115200 bps
- lcd.begin(16, 2); // Initialise l'écran LCD avec 16 colonnes et 2 lignes
- lcd.setRGB(VAL_RGB_R, VAL_RGB_G, VAL_RGB_B); // Définit la couleur de rétroéclairage de l'écran LCD
- lcd.print("initialization"); // Affiche le message d'initialisation sur l'écran LCD
- // Configuration des pins pour les LEDs et les sorties
- pinMode(PIN_LED_ORANGE, OUTPUT); // Config. la LED orange en sortie
- pinMode(PIN_LED_VERT, OUTPUT); // Config. la LED verte en sortie
- pinMode(PIN_LED_ROUGE, OUTPUT); // Config. la LED rouge en sortie
- // Configuration des pins pour les entrées
- pinMode(PIN_POTARD, INPUT); // Définit le pin A0 comme entrée pour le potentiomètre
- pinMode(PIN_SWITCH, INPUT_PULLUP); // Active la résistance de pull-up sur le pin du bouton
- pinMode(PIN_MOTEUR_DIR, OUTPUT); // Config. la direction du moteur en sortie
- pinMode(PIN_MOTEUR_PUL, OUTPUT); // Config. le pin de pulsation du moteur en sortie
- pinMode(PIN_MOTEUR_ENA, OUTPUT); // Config. le pin d'activation du moteur en sortie
- pinMode(PIN_BUZZER, OUTPUT); // Config. le pin du buzzer en sortie
- pinMode(PIN_COURANT_COUPURE, INPUT_PULLUP); // Active la résistance de pull-up pour la coupure de courant
- // Configuration initiale de l'état des sorties
- digitalWrite(PIN_BUZZER, LOW); // Éteint le buzzer
- digitalWrite(PIN_SWITCH, HIGH); // Initialise le PIN_SWITCH à l'état haut
- digitalWrite(PIN_LED_VERT, HIGH); // Allume la LED verte
- digitalWrite(PIN_LED_ORANGE, HIGH); // Allume la LED orange
- digitalWrite(PIN_LED_ROUGE, HIGH); // Allume la LED rouge
- // Signal sonore d'initialisation
- tone(PIN_BUZZER, NOTE_DS6, 500); // Joue un ton sur le buzzer
- delay(500); // Attend 500 ms
- // Éteint toutes les LEDs après le signal sonore
- digitalWrite(PIN_LED_VERT, LOW); // Éteint la LED verte
- digitalWrite(PIN_LED_ROUGE, LOW); // Éteint la LED rouge
- digitalWrite(PIN_LED_ORANGE, LOW); // Éteint la LED orange
- // Initialisation des valeurs de temps pour les timers
- timerPrecedents[TIMER_ETAT] = micros(); // Initialise le timer pour
- timerPrecedents[TIMER_LCD_toggle] = micros(); // Initialise le timer pour le mode toggle LCD
- timerPrecedents[TIMER_LCD_avance] = micros(); // Initialise le timer pour le mode avance LCD
- timerPrecedents[TIMER_LCD_Origine] = micros(); // Initialise le timer pour le mode origine LCD
- timerPrecedents[TIMER_LED_Orange] = micros(); // Initialise le timer pour la LED orange
- timerPrecedents[TIMER_LED_Vert] = micros(); // Initialise le timer pour la LED verte
- timerPrecedents[TIMER_LED_Rouge] = micros(); // Initialise le timer pour la LED rouge
- timerPrecedents[TIMER_SWITCH] = micros(); // Initialise le timer pour le bouton switch
- timerPrecedents[TIMER_POTARD] = micros(); // Initialise le timer pour le bouton switch
- timerPrecedents[TIMER_MOTOR] = micros(); // Initialise le timer pour le moteur
- // Configuration initiale de l'état du système
- Etat etatActuel = ETAT_ORIGINE; // Définit l'état actuel comme origine
- // Vérifie et récupère l'état de coupure de courant depuis l'EEPROM
- EEPROM.get(4, estCoupureCourant); // Récupère l'état de coupure de courant de l'EEPROM
- // Configuration des interruptions
- attachInterrupt(digitalPinToInterrupt(PIN_COURANT_COUPURE), interruptionCoupure, FALLING); // Interruption sur coupure de courant
- // Configuration de Timer1 pour le mode CTC (Clear Timer on Compare Match)
- TCCR1A = 0; // Réinitialise TCCR1A pour la configuration
- TCCR1B = (1 << WGM12) | (1 << CS11); // Configure le mode CTC et le prescaler pour Timer1
- OCR1A = potard(); // Configure OCR1A pour correspondre à la valeur du potentiomètre
- TIMSK1 |= (1 << OCIE1A); // Active l'interruption de comparaison du Timer1
- delay(800); // Court délai avant d'activer les interruptions
- sei(); // Active les interruptions globales
- }
- void loop() {
- // Vérifie et met à jour l'état du switch toutes les 244.140 ms
- checkTimerAndUpdate(timerPrecedents[TIMER_SWITCH], INTERVAL_X78, updateSwitchState, etatSwitch, PIN_SWITCH);
- // Structure de contrôle principale basée sur l'état actuel
- switch (etatActuel) {
- case ETAT_ORIGINE:
- // Initialisations pour l'état d'origine
- initOrigine();
- // Mise à jour LED rouge toutes les 9.390 ms
- checkTimerAndUpdate(timerPrecedents[TIMER_LED_Rouge], INTERVAL_X3, modulate_PIN_LED_ROUGE, NULL, PIN_LED_ROUGE);
- // Mise à jour LCD pour l'état d'origine toutes les 244.140 ms
- checkTimerAndUpdate(timerPrecedents[TIMER_LCD_Origine], INTERVAL_X78, [] (bool*, int8_t*) { LCD_Update("Origine", NULL, 0, 11, true); }, NULL, NULL);
- //commentaire
- checkTimerAndUpdate(timerPrecedents[TIMER_POTARD], INTERVAL_X78, Lambda, NULL, PIN_POTARD);
- break;
- case ETAT_AVANCE:
- // Initialisations pour l'état d'avance
- initAvance();
- // Mise à jour LCD pour l'état d'avance toutes les 244.140 ms
- checkTimerAndUpdate(timerPrecedents[TIMER_LCD_avance], INTERVAL_X78, [] (bool*, int8_t*) { LCD_Update("Programme", "Lambda", 10, 15, true); }, NULL, NULL);
- // Mise à jour de l'action du moteur toutes les 5.625 ms (par default) via ISR*
- // checkTimerAndUpdate(timerPrecedents[TIMER_MOTOR], Lambda, toggle_PIN_MOTOR, NULL, NULL);
- // Vérifie la condition de sortie de l'état d'avance
- CheckSortieAvance();
- break;
- case ETAT_TOGGLE:
- // Initialisations pour l'état de toggle
- initToggle();
- // Mise à jour LCD pour l'état de toggle toutes les 244.140 ms
- checkTimerAndUpdate(timerPrecedents[TIMER_LCD_toggle], INTERVAL_X78, [] (bool*, int8_t*) { LCD_Update("toggle", "Lambda", 10, 15, true); }, NULL, NULL);
- // Mise à jour de l'action du moteur toutes les 3.130 ms
- checkTimerAndUpdate(timerPrecedents[TIMER_MOTOR], INTERVAL_BASE, toggle_PIN_MOTOR, NULL, PIN_MOTEUR_PUL);
- // Vérifie l'état du switch et agit sur les LEDs selon un délai
- checkTimerBasedOnState(etatSwitch, timerPrecedents, toggle_PIN_LED);
- // Vérifie la condition de sortie de l'état de toggle
- CheckSortieToggle();
- break;
- case ETAT_FAIL:
- // Exécute la séquence d'arrêt d'urgence
- etatFailSafe();
- break;
- default: // ETAT_FAIL:
- // Exécute la séquence d'arrêt d'urgence
- etatFailSafe();
- break;
- }
- // Met à jour l'état actuel basé sur les conditions actuelles
- checkTimerAndUpdate(timerPrecedents[TIMER_ETAT], INTERVAL_BASE, updateEtatActuel, NULL, NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement