Detection de code IR avec d'autres taches

Bonjour a tous,
J'ai un projet necessitant la lecture d'un code IR en parallèle de gestion d'autres tache mais mon code ratte regulierement des signeaux IR.
J'ai essayé avec des interruptions mais plus aucun code n'était detecté.
Voici mon code complet (tournant sur une arduino uno r4 wifi ) :

#include <IRremote.h>
#include "SerialMP3Player.h"
#include <LiquidCrystal_I2C.h>
#include <RTC.h>
#include "data.h"
#include <SPI.h>
#include <WiFiS3.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <Stepper.h>
double stepsPerRevolution = 2048;
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11); 
const char ssid[] = "mon wifi";
const char pass[] = "ma clef wifi";
const char* server = "api.openweathermap.org";
String apiKey = "ma clef api";
String location = "ma location ";  // Remplace par ta ville
String currentTrackName = ""; // Variable globale pour suivre le titre actuel de la piste
int scrollIndex = 0;          // Variable globale pour l'index de défilement
unsigned long lastUpdate = 0; // Variable globale pour le dernier temps de mise à jour

const int pinIR = 2;
bool pause = 0;
bool etat = 1;
bool modifiealarme = 0;
int nummodif = 0;
int currentTrack = 1; // Start with the first track
int totalTracks = 255; // Placeholder for the total number of tracks
String trackName = mp3_files[currentTrack-1];
int alarme[] = {17, 40, 30};
bool alarmeon = 1;
int meteo =0;
bool rideauState =1;
byte Cloche[] = {
  B00100,
  B01110,
  B01110,
  B01110,
  B11111,
  B00000,
  B00100,
  B00000
};
byte leftArrow[8] = {
  B00000,
  B00100,
  B01100,
  B11111,
  B01100,
  B00100,
  B00000,
  B00000
};
byte rightArrow[8] = {
  B00000,
  B00100,
  B00110,
  B11111,
  B00110,
  B00100,
  B00000,
  B00000
};

#define TX 3
#define RX 4
SerialMP3Player mp3(RX, TX);

LiquidCrystal_I2C lcd(0x27, 16, 2); // Adresse I2C, nombre de colonnes et lignes

WiFiClient client;
int status = WL_IDLE_STATUS;
int ecran = 2;

#define EEPROM_ALARM_STATE_ADDR 4  // Adresse pour l'état de l'alarme
#define EEPROM_ALARM_HOUR_ADDR 6   // Adresse pour l'heure de l'alarme
#define EEPROM_ALARM_MINUTE_ADDR 2 // Adresse pour les minutes de l'alarme
#define EEPROM_ALARM_SECOND_ADDR 3 // Adresse pour les secondes de l'alarme

void saveAlarmToEEPROM() {
  EEPROM.update(EEPROM_ALARM_HOUR_ADDR, alarme[0]);
  EEPROM.update(EEPROM_ALARM_MINUTE_ADDR, alarme[1]);
  EEPROM.update(EEPROM_ALARM_SECOND_ADDR, alarme[2]);
  EEPROM.update(EEPROM_ALARM_STATE_ADDR, alarmeon); // Ajouter cette ligne  
  Serial.println("saved");
}


void loadAlarmFromEEPROM() {
  alarmeon = EEPROM.read(EEPROM_ALARM_STATE_ADDR);
  alarme[0] = EEPROM.read(EEPROM_ALARM_HOUR_ADDR);
  alarme[1] = EEPROM.read(EEPROM_ALARM_MINUTE_ADDR);
  alarme[2] = EEPROM.read(EEPROM_ALARM_SECOND_ADDR);
 if (alarme[0]>24) alarme[0]=24;
 if (alarme[1]>60) alarme[1]=60;
if (alarme[2]>60) alarme[2]=60;
if (alarme[0]>24|| alarme[1]>60 ||alarme[2]>60 ) saveAlarmToEEPROM();
}
void playTrack(int trackNumber) {
  mp3.play(trackNumber);
}
void setup() {
  RTC.begin();
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(7, OUTPUT);
  noTone(7);
  myStepper.setSpeed(10);
  lcd.init();
  lcd.setCursor(0, 0);
  lcd.print("Initialisation");
  lcd.createChar(1, Cloche);
  lcd.createChar(2, leftArrow);
  lcd.createChar(3, rightArrow);

  // Configuration du Wi-Fi
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("Connecté au réseau Wi-Fi");

  mp3.begin(9600);
  mp3.sendCommand(CMD_SEL_DEV, 0, 2);
  playTrack(currentTrack);

  IrReceiver.begin(pinIR, ENABLE_LED_FEEDBACK);
  lcd.clear();
  loadAlarmFromEEPROM();

  
  

  // Mettre à jour l'heure du RTC lors du téléversement
   RTCTime startTime(19, Month::JUNE, 2024, 15, 56, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE);

  RTC.setTime(startTime);
  
}
  






bool printCurrentWeather() {
  if (client.connect(server, 80)) {
    String url = "/data/2.5/forecast?q=" + location + "&appid=" + apiKey + "&units=metric&lang=fr&cnt=5";
    client.println("GET " + url + " HTTP/1.1");
    client.println("Host: " + String(server));
    client.println("Connection: close");
    client.println();

    while (client.connected() && !client.available()) {
      delay(1);
    }

    String line = "";
    while (client.available()) {
      line += client.readStringUntil('\n');
    }

    int startIndex = line.indexOf('{');
    int endIndex = line.lastIndexOf('}');
    if (startIndex != -1 && endIndex != -1) {
      String json = line.substring(startIndex, endIndex + 1);
      DynamicJsonDocument doc(1024);
      deserializeJson(doc, json);

      float temp = doc["list"][meteo]["main"]["temp"];
      float humidity = doc["list"][meteo]["main"]["humidity"];
      String weatherDescription = doc["list"][meteo]["weather"][0]["description"];
      
      lcd.setCursor(0, 0);
      lcd.print(temp);
      lcd.print(" C");
      lcd.print("; ");
      lcd.print(humidity);
      lcd.print("%");
      lcd.setCursor(0, 1);
      lcd.print(weatherDescription);
     
    } else {
      
      return 0;
      
    }
  } else {
    Serial.println("falied");
    return 0;
    
  }
  client.stop();
  return 1;
}
String getTimeFromAPI() {
  if (client.connect("worldtimeapi.org", 80)) {
    // Envoyer une requête HTTP GET à l'API World Time
    client.println("GET /api/timezone/Europe/Paris HTTP/1.1");
    client.println("Host: worldtimeapi.org");
    client.println("Connection: close");
    client.println();

    // Attendre la réponse
    while (client.connected() && !client.available()) {
      delay(1);
    }

    // Lire la réponse
    String line = "";
    while (client.available()) {
      line += client.readStringUntil('\n');
    }

    // Extraire le JSON de la réponse
    int startIndex = line.indexOf('{');
    int endIndex = line.lastIndexOf('}');
    if (startIndex != -1 && endIndex != -1) {
      String json = line.substring(startIndex, endIndex + 1);
      DynamicJsonDocument doc(1024);
      deserializeJson(doc, json);

      // Extraire le champ "datetime"
      const char* datetime = doc["datetime"];

      // Formater les heures, minutes et secondes en chaîne de caractères "HH:MM:SS"
      String time = String(datetime).substring(11, 19);
      return time;
    } else {
      Serial.println(line);
      return "00:00:00";
    }
  } else {
    Serial.println("Erreur de connexion à l'API World Time");
    return "00:00:00";
  }
  client.stop(); // Fermer la connexion
}

void updateDisplay() {
 String time = getTimeFromAPI();
  int currentHour = (time.substring(0, 2)).toInt() ; 
  int currentMinute = (time.substring(3, 5)).toInt();
  int currentSecond = (time.substring(6, 8)).toInt();
  
  char buffer[9]; // "HH:MM:SS" + null terminator
  snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", currentHour, currentMinute, currentSecond);

  // Extraire les valeurs d'heure, minute et seconde à partir de la chaîne `time`
 
  switch (ecran) {

    case 2 :
      lcd.setCursor(3, 0);
      lcd.print(time);
      char buffer[9]; // "HH:MM:SS" + null terminator
      snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", alarme[0],alarme[1],alarme[2]);
      lcd.setCursor(3, 1);
      lcd.print(String(buffer));
     
      if (alarmeon == 1) {
        lcd.setCursor(15, 1);
        lcd.write(byte(1));
      }

      lcd.setCursor(0, 0);
      lcd.write(byte(2));
      lcd.setCursor(15, 0);
      lcd.write(byte(3));
    break;
    case 1 :
      while (!printCurrentWeather());
      lcd.setCursor(15, 0);
      lcd.write(byte(3));
    break;
    case 3 :
      if (trackName != currentTrackName) { // Si le titre a changé
        currentTrackName = trackName;
        scrollIndex = 0; // Réinitialise l'index de défilement
        lastUpdate = 0;  // Réinitialise le temps de mise à jour
      }
      lcd.setCursor(1, 0);
      lcd.print("vous ecoutez :");
      lcd.setCursor(0, 1);
      scrollText(currentTrackName, 1, 500);
      lcd.setCursor(0, 0);
      lcd.write(byte(2));
      lcd.setCursor(15, 0);
      lcd.write(byte(3));
    break;
    case 4 :
    break;
  }
  if (currentHour >= 7 && currentHour <= 21 && etat == 1) {
    lcd.backlight();
    if (rideauState == 1) {
      myStepper.step(2048 * 2);
      rideauState = !rideauState;
    }
  } else {
    lcd.noBacklight();
    if (rideauState == 0) {
      myStepper.step(-2048 * 2);
      rideauState = !rideauState;
    }
  }
  if (currentHour == alarme[0] && currentMinute == alarme[1] && currentSecond == alarme[2] && alarmeon == 1) {
    tone(7, 440, 10000);
    
  }
}

void scrollText(String text, int row, int delayTime) {
  int textLength = text.length();

  if (textLength <= 16) {
    // Si le texte est de 16 caractères ou moins, l'afficher simplement
    lcd.setCursor(0, row);
    lcd.print(text);
  } else {
    // Si le texte est plus long que 16 caractères, le faire défiler
    String scrollText = text + " ";

    if (millis() - lastUpdate >= delayTime) {
      lastUpdate = millis();
      lcd.setCursor(0, row);
      String displayText = scrollText.substring(scrollIndex, scrollIndex + 16);
      lcd.print(displayText);
      scrollIndex++;
      if (scrollIndex == textLength - 15) { // Ajuster la condition de réinitialisation
        scrollIndex = 0;
      }
    }
  }
}




void loop() {
  if (IrReceiver.decode()) {
    unsigned long irCode = IrReceiver.decodedIRData.decodedRawData;
    handleIRCode(irCode);
    IrReceiver.resume();
  }
else {
  static unsigned long lastUpdate = 0;
  if (millis() - lastUpdate >= 800) {
    lastUpdate = millis();
    updateDisplay();
  }

  if (mp3.available()) {
    String response = mp3.decodeMP3Answer();
    if (response.indexOf("Completed") != -1) {
      currentTrack++;
      if (currentTrack > totalTracks) {
        currentTrack = 1;
      }
      playTrack(currentTrack);
      trackName = mp3_files[currentTrack-1];
    }
  }
}
}

void handleIRCode(unsigned long irCode) {
  if (irCode == 4094424840) {
    
      if (etat == 0) {
        mp3.wakeup();
        lcd.display();
        etat = !etat;
      } else {
        mp3.sleep();
        lcd.noDisplay();
        lcd.noBacklight();
        etat = !etat;
      }
      }

    else {
      if (etat == 1) {
        switch (irCode) {
          case 3877173000: // bouton play/pause
            if (pause == 0) {
              mp3.pause();
              pause = !pause;
            } else {
              mp3.play();
              pause = !pause;
            }
            break;

          case 3860461320: // next
            mp3.playNext();
            lcd.clear();
            currentTrack++;
            if (currentTrack > totalTracks) {
              currentTrack = 1;
            }
            trackName = mp3_files[currentTrack-1];
            break;

          case 3760191240: // previous
            mp3.playPrevious();
            lcd.clear();
            currentTrack--;
            if (currentTrack < 1) {
              currentTrack = totalTracks;
            }
            trackName = mp3_files[currentTrack-1];
            break;

          case 3191994120: // volume up 
            mp3.volUp();
            break;

          case 3175282440: // volume down
            mp3.volDown();
            break;

          case 4044289800: // alarme
            alarmeon = !alarmeon;
            Serial.println(alarmeon);
            lcd.clear();
            updateDisplay();
            saveAlarmToEEPROM(); // Utiliser la fonction saveAlarmToEEPROM qui sauvegarde l'état de l'alarme
            break;

          case 2974742280: // dim
            lcd.backlight();
            delay(10000);
            break;

          case 3944019720: // fleche droite
            if (modifiealarme == 0) {
              ecran += 1;
              if (ecran > 3) {
                ecran = 3;
              }
              lcd.clear();
              updateDisplay();
            } else {
              nummodif += 1;
              if (nummodif > 5) {
                modifiealarme = 0;
                saveAlarmToEEPROM();
              }
              Serial.println(nummodif);
            }
            break;

          case 3927308040: // fleche gauche
            if (modifiealarme == 0) {
              ecran -= 1;
              if (ecran < 1) {
                ecran = 1;
              }
              lcd.clear();
              updateDisplay();
            } else {
              nummodif -= 1;
              if (nummodif < 0) {
                modifiealarme = 0;
                saveAlarmToEEPROM();
              }
              Serial.println(nummodif);
            }
            break;

          case 3960731400: // fleche bas
            if (ecran == 2) {
              if (modifiealarme == 0) {
                modifiealarme = 1;
                nummodif = 0;
              } else {
                if (nummodif == 0 || nummodif == 2 || nummodif == 4) {
                  alarme[nummodif / 2] -= 10;
                } else {
                  switch (nummodif) {
                    case 1:
                      alarme[0] -= 1;
                      break;
                    case 3:
                      alarme[1] -= 1;
                      break;
                    case 5:
                      alarme[2] -= 1;
                      break;
                  }
                }
                updateDisplay();
              }
            } else if (ecran == 1) {
              meteo--;
              if (meteo < 0) meteo = 0;
            }
            break;

          case 3977443080: // fleche haut
            if (ecran == 2 && modifiealarme == 1) {
              if (nummodif == 0 || nummodif == 2 || nummodif == 4) {
                alarme[nummodif / 2] += 10;
              } else {
                switch (nummodif) {
                  case 1:
                    alarme[0] += 1;
                    break;
                  case 3:
                    alarme[1] += 1;
                    break;
                  case 5:
                    alarme[2] += 1;
                    break;
                }
              }
              updateDisplay();
            } else if (ecran == 1) {
              meteo++;
              if (meteo > 40) meteo = 40;
            }
            break;
        }
      }
    }
}

le fichier data.h contient un tableau avec les titre corespondant aux mp3 du lecteur mp3 en serie sous forme de tableau
Merci pour toute l'aide que vous pourrez m'apporter

La bibliothèque mp3 que vous utilisez dépend de SoftwareSerial

Qui dépend des interruptions… et ça peut entraîner des délais sur la réception de commandes qui nécessitent une interruption toutes les 50 micro secondes

Essayez avec un port série matériel éventuellement

Qu'est ce que vous appelez un port série matériel exactement?

une instance de la classe HardwareSerial et pas SoftwareSerial exactement

en gros votre arduino a un ou plusieurs ports séries (UART) gérés au niveau matériel. On utilise (à reculons et moult précautions) un émulation en logiciel de la fonction UART quand on souhaite avoir un port supplémentaire, non disponible au niveau matériel.

l'arduino uno r4 wifi ne dispose que d'un seul port matériel, utilisé pour l'upload de code et le debug souvent. Ici vous l'utilisez pour du debug. Peut être serait il envisageable de le dédier à votre SerialMP3Player ?

sinon il existe d'autres cartes (ESP32 par exemple si vous voulez le WiFi) qui ont plusieurs ports matériels.