Comment envoyer et recevoir des données sur la voie série

Bonjour à tous, Je suis débutant dans le langage Arduino,

J'ai 8 LEDS que j'aimerais allumer l'un à la suite des autres en envoyer au port série COM une valeur par exemple 1 pour allumer le LED 1 et 2 pour allumer le LED 2 et ainsi de suite et chaque LED restera allumé en fonction de minutes qui lui ai attribuées.

J'ai vraiment besoin de votre aide !

 
String mensaj;
String data;
int post=0;
String led;
long mins;
long delai1=0;
long delai2=0;
long delai3=0;
long delai4=0;
long delai5=0;
long delai6=0;
long delai7=0;
long delai8=0;
long delai9=0;

String minutes;


void setup() {


Serial.begin(9600);
 
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);



}

void loop() {
  
   
   
  while (Serial.available()>0){
  String mensaj=Serial.readString();
  data=mensaj;
  led= data.substring(0,1);
  led=led.toInt();
  minutes=data.substring(1,3);
  mins = minutes. toInt(); 

  
  }
   if(led==1){
    
  
   delai1+=mins*60000;
    
    digitalWrite(1,HIGH);
    delay(delai1);
    digitalWrite(1,LOW);
    
    Serial.end();
  }

  if(led==2){
      
    delai2+=mins*60000;
    
    digitalWrite(2,HIGH);
    delay(delai2);
    digitalWrite(2,LOW);
    
    Serial.flush();
  }
  if(led==3){
    
  
     delai3+=mins*60000;
    
    digitalWrite(3,HIGH);
    delay(delai3);
    digitalWrite(3,LOW);
    
    Serial.end();
 }
  if(led==4){
    
  
    delai4+=mins*60000;
    
    digitalWrite(4,HIGH);
    delay(delai4);
    digitalWrite(4,LOW);
    
    Serial.end();
 }
  if(led==5){
   
  
    delai5+=mins*60000;
    
    digitalWrite(5,HIGH);
    delay(delai5);
    digitalWrite(5,LOW);
    
    Serial.end();
  }
  if(led==6){
    
  
   delai6+=mins*60000;
    
    digitalWrite(6,HIGH);
    delay(delai6);
    digitalWrite(6,LOW);
    
    Serial.end();
 }
  if(led==7){
    
  
    delai7+=mins*60000;
    
    digitalWrite(7,HIGH);
    delay(delai7);
    digitalWrite(7,LOW);
    
    Serial.end();
  }
  if(led==8){
   
  
   delai8+=mins*60000;
    
    digitalWrite(8,HIGH);
    delay(delai8);
    digitalWrite(8,LOW);
    
    Serial.end();
  }
 

}

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Bonjour pathy2023

Sous quelle forme introduit tu tes commendes. Pour moi, seul un chiffre est nécessaire, vu que le temps d'attente est défini en fonction du chiffre entré-

Une chose à faire, est de supprimer tout les Serial.end(); qui coupe ta communication avec la console.
Tu utilises la pin 1, ce n'est pas prudent, ça fait partie des communications de ta console (via le câble USB)
image

Ta variable led est déclarée String led; et, ensuite, tu fais led=led.toInt(); ce n'est pas très "catholique", le mieux est de déclarer int led; et, ensuite, à la réception,

		led= data.substring(0,1).toInt();
		//led=led.toInt();

On pourrai "affiner" la réception, mais, essaies déjà ces modifications.

Dernière chose, à la fin de chaque condition if(led==n){ mettre led = 0;

PS: Afin de voire "vivre" ton programme, places, avant le if(led==1){:

	if (led != 0)
	{
		Serial.println(led);
	}

A+
Cordialement
jpbbricole

Si vous voulez comprendre le cas général de comment écouter le port série (ou gérer un flux asynchrone genre keypad) vous pouvez jeter un oeil à mon petit tuto sur le sujet

Ici vous êtes dans un cas particulier ou la commande tient sur un octet donc un simple switch sur la réception série suffit

switch(Serial.read()) {
  case '1': …. ; break;
  case '2': …. ; break;
  case '3': …. ; break;
  default: break;
}

Et vous remplacez les par l’action à réaliser pour chaque cas

Ça traitera la réception série mais pas l’extinction automatique après x secondes

Au final C’est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

2 Likes

Bonjour jpbbricole

Je tiens à tiens à te remercier beaucoup ton intervention et pour tes conseils et voici le code après quelques modification .

concernant forme de commandes , j'ai introduit par exemple 25 qui sera divisé à la lecture ( le 2 représente le LED et le 5 represente les minutes.)


String mensaj;
String data;
int led;
long mins;
long delai1=0;
long delai2=0;
long delai3=0;
long delai4=0;
long delai5=0;
long delai6=0;
long delai7=0;
long delai8=0;
long delai9=0;


void setup() {


Serial.begin(9600);
 
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);



}

void loop() {
  
   
   
  while (Serial.available()>0){
  String mensaj=Serial.readString();
  data=mensaj;
  led=data.substring(0,1).toInt();
  mins=data.substring(1,3).toInt();

  
  }
   if(led==1){
    
  
   delai1+=mins*60000;
    
    digitalWrite(1,HIGH);
    delay(delai1);
    digitalWrite(1,LOW);
    
  }

  if(led==2){
      
    delai2+=mins*60000;
    
    digitalWrite(2,HIGH);
    delay(delai2);
    digitalWrite(2,LOW);
    
  }
  if(led==3){
    
  
     delai3+=mins*60000;
    
    digitalWrite(3,HIGH);
    delay(delai3);
    digitalWrite(3,LOW);
 }
  if(led==4){
    
  
    delai4+=mins*60000;
    
    digitalWrite(4,HIGH);
    delay(delai4);
    digitalWrite(4,LOW);
 }
  if(led==5){
   
  
    delai5+=mins*60000;
    
    digitalWrite(5,HIGH);
    delay(delai5);
    digitalWrite(5,LOW);
    
  }
  if(led==6){
    
  
   delai6+=mins*60000;
    
    digitalWrite(6,HIGH);
    delay(delai6);
    digitalWrite(6,LOW);
    
 }
  if(led==7){
    
  
    delai7+=mins*60000;
    
    digitalWrite(7,HIGH);
    delay(delai7);
    digitalWrite(7,LOW);
    
  }
  if(led==8){
   
  
   delai8+=mins*60000;
    
    digitalWrite(8,HIGH);
    delay(delai8);
    digitalWrite(8,LOW);
    
  }
 

}

Je suis à ta disposition pour affiner le code et pour pouvez me proposer une autre alternative à la place de pin 1 et je tiens à vous rappeler que suis vraiment novice.

Bonjour J-M-L, je te remercie beaucoup également pour tes tutos qui sont une vraie source d'inspiration.

Je ne sais pas, si ca sera possible pour vous de jeter un œil à code et voir comment le corriger .


String mensaj;
String data;
int led;
long mins;
long delai1=0;
long delai2=0;
long delai3=0;
long delai4=0;
long delai5=0;
long delai6=0;
long delai7=0;
long delai8=0;
long delai9=0;


void setup() {


Serial.begin(9600);
 
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);



}

void loop() {
  
   
   
  while (Serial.available()>0){
  String mensaj=Serial.readString();
  data=mensaj;
  led=data.substring(0,1).toInt();
  mins=data.substring(1,3).toInt();

  
  }
   if(led==1){
    
  
   delai1+=mins*60000;
    
    digitalWrite(1,HIGH);
    delay(delai1);
    digitalWrite(1,LOW);
    
  }

  if(led==2){
      
    delai2+=mins*60000;
    
    digitalWrite(2,HIGH);
    delay(delai2);
    digitalWrite(2,LOW);
    
  }
  if(led==3){
    
  
     delai3+=mins*60000;
    
    digitalWrite(3,HIGH);
    delay(delai3);
    digitalWrite(3,LOW);
 }
  if(led==4){
    
  
    delai4+=mins*60000;
    
    digitalWrite(4,HIGH);
    delay(delai4);
    digitalWrite(4,LOW);
 }
  if(led==5){
   
  
    delai5+=mins*60000;
    
    digitalWrite(5,HIGH);
    delay(delai5);
    digitalWrite(5,LOW);
    
  }
  if(led==6){
    
  
   delai6+=mins*60000;
    
    digitalWrite(6,HIGH);
    delay(delai6);
    digitalWrite(6,LOW);
    
 }
  if(led==7){
    
  
    delai7+=mins*60000;
    
    digitalWrite(7,HIGH);
    delay(delai7);
    digitalWrite(7,LOW);
    
  }
  if(led==8){
   
  
   delai8+=mins*60000;
    
    digitalWrite(8,HIGH);
    delay(delai8);
    digitalWrite(8,LOW);
    
  }
 

}

Merci d'avance

Bonsoir pathy2023

On va procéder par étapes, tout d'abord, il te faut changer la pin 1 qui est utilisée par la communication série comme indiqué ici.

Ensuite, dans chaque test if(led==n){ mettre led = 0; sinon une fois une LED sélectionnée, à chaque tour de loop() on trouvera la condition comme vraie.

La lecture du port de communication se fait par;

	if (Serial.available()){
		String mensaj=Serial.readStringUntil('\n');

Info sur readStringUntil et trim()

Il faut que le moniteur aie
image
comme terminaison.

Il y a une nouvelle variable:
long delaisMinute = 500; // 60000
qui permet d'accélérer les essais, quitte à remettre 60000 pour retrouver des minutes.

Voici le programme corrigé:

String mensaj;
String data;
int led;
long mins;
//long delai1=0;
//long delai2=0;
//long delai3=0;
//long delai4=0;
//long delai5=0;
//long delai6=0;
//long delai7=0;
//long delai8=0;
//long delai9=0;

long delaisMinute = 500;  // 60000     // Delais pour une minute, a diminuer pour accélérer l'attente pour le développement

void setup() {


	Serial.begin(9600);
	
	pinMode(1,OUTPUT);
	pinMode(2,OUTPUT);
	pinMode(3,OUTPUT);
	pinMode(4,OUTPUT);
	pinMode(5,OUTPUT);
	pinMode(6,OUTPUT);
	pinMode(7,OUTPUT);
	pinMode(8,OUTPUT);



}

void loop() {
	if (Serial.available()){
		String mensaj=Serial.readStringUntil('\n');
		mensaj.trim();     // Pour nettoyer mensaj
		data=mensaj;
		led=data.substring(0,1).toInt();
		mins=data.substring(1,3).toInt();
	}

	if (led != 0)
	{
		Serial.println(led);
	}

	if(led==1){
		//delai1+=mins*delaisMinute;
		
		digitalWrite(1,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(1,LOW);

		led = 0;
	}

	if(led==2){
		
		//delai2+=mins*delaisMinute;
		
		digitalWrite(2,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(2,LOW);
		
		led = 0;
	}
	if(led==3){
		
		
		//delai3+=mins*delaisMinute;
		
		digitalWrite(3,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(3,LOW);
		
		led = 0;
	}
	if(led==4){
		
		
		//delai4+=mins*delaisMinute;
		
		digitalWrite(4,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(4,LOW);
		delay(mins*delaisMinute);
		
		led = 0;
	}
	if(led==5){
		
		
		//delai5+=mins*delaisMinute;
		
		digitalWrite(5,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(5,LOW);
		
		
		led = 0;
	}
	if(led==6){
		
		
		//delai6+=mins*delaisMinute;
		
		digitalWrite(6,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(6,LOW);
		
		
		led = 0;
	}
	if(led==7){
		
		
		//delai7+=mins*delaisMinute;
		
		digitalWrite(7,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(7,LOW);
		
		led = 0;
	}
	if(led==8){
		
		
		//delai8+=mins*delaisMinute;
		
		digitalWrite(8,HIGH);
		delay(mins*delaisMinute);
		digitalWrite(8,LOW);
		
		
		led = 0;
	}
	

}

Prochaines étapes, mettre les pin des diodes en tableau et créer une fonction unique pour allumer n'importe quelle LED.

A+
Cordialement
jpbbricole

Ce serait mieux de mettre un unsigned long pour les variables liées au temps comme delaisMinute

Un souci avec l’approche prise dans le code c’est qu’il est bloquant. Une fois une led allumée on ne peut plus traiter de commande avant extinction de la led.

Il faudrait pour cela introduire millis() et une approche non bloquante

Bonjour jpbbrocole

J'ai pu jeté un œil sur vos conseils et ceux de J-M-L ensuite j'ai pu travaillé sur le code en retirant delay car celui-ci bloquait le traitement de code.


String mensaj;
String data;
int led;
long mins;
long mins;
long mins2=0;;
long sec2=0;
long mins3=0;;
long sec3=0;
long mins4=0;
long sec4=0;
long mins5=0;
long sec5=0;
long mins6=0;
long sec6=0;
long mins7=0;
long sec7=0;
long mins8=0;
long sec8=0;

long delaisMinute = 500;  // 60000     // Delais pour une minute, a diminuer pour accélérer l'attente pour le développement

void setup() {


	Serial.begin(9600);
	
	
	pinMode(2,OUTPUT);
	pinMode(3,OUTPUT);
	pinMode(4,OUTPUT);
	pinMode(5,OUTPUT);
	pinMode(6,OUTPUT);
	pinMode(7,OUTPUT);
	pinMode(8,OUTPUT);



}

void loop() {
	if (Serial.available()){
		String mensaj=Serial.readStringUntil('\n');
		mensaj.trim();     // Pour nettoyer mensaj
		data=mensaj;
		led=data.substring(0,1).toInt();
		mins=data.substring(1,3).toInt();
	}

	if (led != 0)
	{
		Serial.println(led);
	}

	

	if(led==2){
		
	
      mins2=mins*delaisMinute;
	
		
     digitalWrite(2,HIGH);
    
    if (sec2==0) {
      sec2 =60;
      mins2--;
      }
      if (mins2 <0){ 
      sec2 = 0; 
     mins2 = 0; 
    
     digitalWrite(2,LOW);
     led = 0;

    }else{
    sec2--;
    
    Serial.println(String(mins2) + " : " + String(sec2));
    }
	}
	if(led==3){
		
			
	
      mins3=mins*delaisMinute;
	
		
     digitalWrite(3,HIGH);
    
    if (sec3==0) {
      sec3 =60;
      mins3--;
      }
      if (mins3 <0){ 
      sec3 = 0; 
     mins3 = 0; 
    
     digitalWrite(3,LOW);
     led = 0;

    }else{
    sec3--;
    
    Serial.println(String(mins3) + " : " + String(sec3));
    }
    
	}
	if(led==4){
		
		 mins4=mins*delaisMinute;
	
		
     digitalWrite(4,HIGH);
    
    if (sec4==0) {
      sec4 =60;
      mins4--;
      }
      if (mins4 <0){ 
      sec4 = 0; 
     mins4 = 0; 
    
     digitalWrite(4,LOW);
     led = 0;

    }else{
    sec4--;
    
    Serial.println(String(mins4) + " : " + String(sec4));
    }
	}
	if(led==5){
		
		mins5=mins*delaisMinute;
	
		
     digitalWrite(5,HIGH);
    
    if (sec5==0) {
      sec5 =60;
      mins5--;
      }
      if (mins5 <0){ 
      sec5 = 0; 
     mins5 = 0; 
    
     digitalWrite(5,LOW);
     led = 0;

    }else{
    sec5--;
    
    Serial.println(String(mins5) + " : " + String(sec5));
    }
	}
	if(led==6){
		
		mins6=mins*delaisMinute;
	
		
     digitalWrite(6,HIGH);
    
    if (sec6==0) {
      sec6 =60;
      mins6--;
      }
      if (mins6 <0){ 
      sec6 = 0; 
     mins6 = 0; 
    
     digitalWrite(6,LOW);
     led = 0;

    }else{
    sec6--;
    
    Serial.println(String(mins6) + " : " + String(sec6));
    }
	}
	if(led==7){
		
		mins7=mins*delaisMinute;
	
		
     digitalWrite(7,HIGH);
    
    if (sec7==0) {
      sec7 =60;
      mins7--;
      }
      if (mins7 <0){ 
      sec7 = 0; 
     mins7 = 0; 
    
     digitalWrite(7,LOW);
     led = 0;

    }else{
    sec7--;
    
    Serial.println(String(mins7) + " : " + String(sec7));
    }
	}
	if(led==8){
		
		mins8=mins*delaisMinute;
	
		
     digitalWrite(8,HIGH);
    
    if (sec8==0) {
      sec8 =60;
      mins8--;
      }
      if (mins8 <0){ 
      sec8 = 0; 
     mins8 = 0; 
    
     digitalWrite(8,LOW);
     led = 0;

    }else{
    sec8--;
    
    Serial.println(String(mins8) + " : " + String(sec8));
    }
	}
	

}

et à ce stade, le code n'est pas au point et nous pouvons voir comment mieux exploiter la fonction millis().

merci beaucoup pour votre promptitude.

Pour faciliter la gestion de l'ensemble, je pense qu'il serait plus clair de travailler avec une structure

struct s_led{
uint8_t : pin; // broche où est connectée la LED
boolean : etat; // true = allumée, false = éteinte
unsigned long : temps; // durée d'allumage en millisecondes
unsigned long : temps_depart; // heure de l'allumage
}

et ensuite de déclarer un tableau

s_led tab_led[8] = {2, false, 0,
3, false, 0, 0,
4, false, 0, 0,
5, false, 0, 0,
6, false, 0, 0,
7, false, 0, 0,
8, false, 0, 0,
9, false, 0 0,
}

Ensuite lorsque tu reçois une commande tu affectes l'état et la durée à l'élément du tableau correspondant.

Si tu reçois l'ordre d'allumer la led 2 tu fais

tab_led[1].etat = true;
tab_led[1].temps = le_temps_que_tu_veux;
tab_led[1].temps_depart = millis();

Ensuite, dans loop() tu parcours le tableau et tu vérifies si le temps s'est écoulé auquel cas tu remets etat = false et temp_depart = 0;

Bonjour fdufnews

Merci beaucoup pour votre intervention,

J'aimerais vous demander, si c'est possible de corriger mon code en d'adoptant votre idée ensuite nous pouvons voir ce peu ca peux donner.

Merci beaucoup pour votre promptitude.

Bonjour pathy2023

Je ne pense pas corriger, je pense que tu ne pars pas dans la bonne direction, il te faut travailler avec des tableaux, ça te simplifie nettement le programme.
D'ici 1 heure, je te mets un exemple.

A+
Cordialement
jpbbricole

Bonjour pathy2023

Voilà une version où les LED sont en tableau, ledPin[], ce qui permet d'indexer toutes les commandes.
La temporisation par delay() est remplacée par une temporisation par millis(),

	if (led != 0 && (millis() - ledOnMillis >= ledOnTempo))     // Si LED en cours et son temps échu

ainsi ton programme n'est plus bloqué pendant l'allumage de ta LED.
Essaies de commander une LED alors que la précédente n'est pas terminée.
Mets ta console à 115200, tu verra "fonctionner" le programme.

Le programme:

/*
	Name:       ARDFR_pathy2023_DonneesSeriePh2.ino
	Created:	26.07.2023
	Author:     jpbbricole / pathy2023

	Utilisation des millis() pour la temporisation.
	Ainsi, le programme n'est plus bloqué pendant le temps d'allumage de la LED
*/

String mensaj;
String data;
int led;
unsigned long mins;

const int ledPin[] = {1, 2, 3, 4, 5, 6, 7, 8};
const int ledNombre = sizeof(ledPin) / sizeof(ledPin[0]);     // CVompte le nombre de LED
const int ledEtatOn = HIGH;     // Etat pour allumer la LED

unsigned long ledOnTempo = 0;     // Temps d'allumage de la LED
unsigned long ledOnMillis = 0;     // Temps d'allumage de la LED chronométrage

long delaisMinute = 1000;  // 60000     // Delais pour une minute, a diminuer pour accélérer l'attente pendant le développement

void setup()
{
	Serial.begin(115200);
	
	for (int l = 0; l < ledNombre; l ++)
	{
		pinMode(ledPin[l], OUTPUT);
		digitalWrite(ledPin[l],!ledEtatOn);     // Eteindre la LED
	}
}

void loop()
{
	if (Serial.available())
	{
		String mensaj=Serial.readStringUntil('\n');
		mensaj.trim();     // Pour nettoyer mensaj
		data=mensaj;

		if (led != 0)    // Si une LED en cours
		{
			Serial.print("Systeme occupe par LED " + String(led));
			Serial.println("\t reste = " + String(ledOnTempo - (millis() - ledOnMillis)));
		} 
		else     // Autrement, allumer la LED demandée
		{
			led=data.substring(0,1).toInt();
			mins=data.substring(1,3).toInt();
			ledAllumerMinutes(led, mins);
		}
	}

	//--------------------------------- Allumage temporaire de la LED
	if (led != 0 && (millis() - ledOnMillis >= ledOnTempo))     // Si LED en cours et son temps échu
	{
		ledOnMillis = 0;
		digitalWrite(ledPin[led-1],!ledEtatOn);     // Eteindre la LED, -1 parce que indice de tableau démarre à 0

		Serial.print("LED = " + String(led) + " FIN");

		led = 0;     // Plus de LED en cours
	}
	else     // Si temporisation en cours
	{
		digitalWrite(ledPin[led-1],ledEtatOn);     // Allumer la LED, -1 parce que indice de tableau démarre à 0
	}
}

void ledAllumerMinutes(int ledNum, unsigned long minutes)
{
	Serial.print("LED = " + String(ledNum));
	Serial.println("\t Minutes = " + String(minutes));

	ledOnTempo = minutes*delaisMinute;
	ledOnMillis = millis();     // Démarrage du chrono
}

Serais tu intéressée par une version où on peut allumer plusieurs LED avec chaqunes leur temps, donc toutes les LED indépendantes?

A+
Cordialement
jpbbricole

Bonjour jpbbricole

Merci beaucoup pour votre soutien

Rebonjour jpbbricole

Je viens de tester ton programme, il fonctionne à merveille, excellent mais j'aimerais te demander si ca sera possible d'avoir la possibilité d'allumer d'autres LEDS même s'il y a une allumée, au lieu d'attendre une LED s'éteint pour allumer une autre.

Merci infiniment pour ton temps et pour ton assistance.

Bonjour pathy2023

Oui, c'est la prochaine étape, ce sera dans le courant de l'après-midi :wink:

A+
Cordialement
jpbbricole

est-ce un projet scolaire ?

Bonjour pathy2023

Voilà une version où toutes les LED sont indépendantes. Tu peux en allumer plusieurs à la fois.
Pour arrêter une LED en cours, il faut introduire son numéro et 0 comme paramètre de temps

Dans la console (ATTENTION maintenant à 115200), tu peux voir fonctionner le programme :

LED = 8 Minutes = 8
LED = 1 Minutes = 1
LED = 1 FIN
LED = 7 Minutes = 5
LED = 8 FIN
LED = 3 Minutes = 3
LED = 7 FIN
LED = 3 FIN
LED = 2 Minutes = 5
LED = 2 FIN

L'indépendance des LED est réglée par ces 2 tableaux:

unsigned long ledOnTempo[ledNombre];     // Temps d'allumage des LED
unsigned long ledOnMillis[ledNombre];     // Temps d'allumage des LED chronométrage

ledOnTempo contient la durée d'allumage et ledOnMillis le chronométrage.
Le tout est "orchestré" ici:

	//--------------------------------- Allumage temporaire des LED
	for (int l = 0; l < ledNombre; l ++)
	{
		if (ledOnMillis[l] != 0 && (millis() - ledOnMillis[l] >= ledOnTempo[l]))     // Si LED en cours et son temps échu

La prochaine étape pourrait être de pouvoir allumer des LED dont le numéro est > 9 et les minutes > 9 également, qu’en penses tu ?

Le programme :

/*
	Name:       ARDFR_pathy2023_DonneesSeriePh4.ino
	Created:	26.07.2023
	Author:     jpbbricole / pathy2023

	Phase 4
	Toutes les LED indépendantes.
	Pour arrêter une temporisation mettre 0 dans le temps, pour arrêter la LED 4: commande 40
*/

String mensaj;
String data;
int led;
unsigned long mins;

const int ledPin[] = {1, 2, 3, 4, 5, 6, 7, 8};
const int ledNombre = sizeof(ledPin) / sizeof(ledPin[0]);     // CVompte le nombre de LED
const int ledEtatOn = HIGH;     // Etat pour allumer la LED

unsigned long ledOnTempo[ledNombre];     // Temps d'allumage des LED
unsigned long ledOnMillis[ledNombre];     // Temps d'allumage des LED chronométrage

long delaisMinute = 1000;  // 60000     // Delais pour une minute, a diminuer pour accélérer l'attente pendant le développement

void setup()
{
	Serial.begin(115200);
	
	for (int l = 0; l < ledNombre; l ++)
	{
		pinMode(ledPin[l], OUTPUT);
		digitalWrite(ledPin[l],!ledEtatOn);     // Eteindre la LED
		ledOnMillis[l] = 0;
	}
}

void loop()
{
	if (Serial.available())
	{
		String mensaj=Serial.readStringUntil('\n');     // https://reference.arduino.cc/reference/fr/language/functions/communication/serial/readstringuntil
		mensaj.trim();     // Pour nettoyer mensaj  https://docs.arduino.cc/built-in-examples/strings/StringLengthTrim?
		data=mensaj;

		led=data.substring(0,1).toInt();
		mins=data.substring(1,3).toInt();
		ledAllumerMinutes(led, mins);
	}

	//--------------------------------- Allumage temporaire des LED
	for (int l = 0; l < ledNombre; l ++)
	{
		if (ledOnMillis[l] != 0 && (millis() - ledOnMillis[l] >= ledOnTempo[l]))     // Si LED en cours et son temps échu
		{
			ledOnMillis[l] = 0;
			digitalWrite(ledPin[l],!ledEtatOn);     // Eteindre la LED, -1 parce que indice de tableau démarre à 0
		
			Serial.println("LED = " + String(l+1) + " FIN");
		}
		else
		{
			if (ledOnMillis[l] != 0)     // Si temporisation en cours pour cette led
			{
				digitalWrite(ledPin[l],ledEtatOn);     // Allumer la LED
			}
		}
	}
}

void ledAllumerMinutes(int ledNum, unsigned long minutes)
{
	Serial.print("LED = " + String(ledNum));
	Serial.println("\t Minutes = " + String(minutes));
	
	ledOnTempo[ledNum -1] = minutes*delaisMinute;
	ledOnMillis[ledNum -1] = millis();     // Démarrage du chrono de la LED ledNum
}

A+
Cordialement
jpbbricole

Pour voir une autre approche, voici une version sans String et sans accumulation de la commande d'entrée (analyse à la volée de l'entrée de l'utilisateur)

Comme le N° de led tient sur un seul caractère on peut se permettre ce type de gestion sans séparateur la commande prend la forme N° d'index de la broche (0 à 9) suivi d'une durée en secondes (ou rien du tout ou 0 pour éteindre) avant la validation. La durée se fabrique au fil de l'eau aussi en construisant au fur et à mesure de la réception des caractères le nombre représentant la durée.

par exemple

  • si vous tapez 2156return alors la troisième LED s'allume pour 156 secondes.

  • si vous tapez 20return ou juste 2return alors la led s'éteint

le wokwi pour tester

le code:

struct Led {
  const byte broche;
  byte etat;
  unsigned long debut;
  unsigned long attente;
};

Led lesLeds[] = {
  {2, LOW, 0, 0},
  {3, LOW, 0, 0},
  {4, LOW, 0, 0},
  {5, LOW, 0, 0},
  {6, LOW, 0, 0},
  {7, LOW, 0, 0},
  {8, LOW, 0, 0},
  {9, LOW, 0, 0},
  {10, LOW, 0, 0},
  {11, LOW, 0, 0},
};

const byte numLeds = 10;

// gestion commande série
enum {ATTENTE_BROCHE, ATTENTE_DUREE} etat;
byte indexLed;
unsigned long duree;

void setup() {
  Serial.begin(115200);
  // état initial
  for (Led& l : lesLeds) {
    pinMode(l.broche, OUTPUT);
    digitalWrite(l.broche, l.etat);
  }
  Serial.println(F("Entrez une commandes N° Led suivi de la durée en secondes"));
}

void loop() {
  // gestion commande série
  if (Serial.available()) {
    char recu = Serial.read();
    switch (etat) {
      case ATTENTE_BROCHE:
        if (recu >= '0' && recu <= '9') { // choix du N° de la LED
          indexLed = recu - '0';
          etat = ATTENTE_DUREE;
        }
        break;

      case ATTENTE_DUREE:
        if (recu == '\n') { // fin de la durée
          lesLeds[indexLed].etat = (duree == 0) ? LOW : HIGH;
          lesLeds[indexLed].attente = duree * 1000ul;
          lesLeds[indexLed].debut = millis();
          digitalWrite(lesLeds[indexLed].broche, lesLeds[indexLed].etat );

          // ------ info de debug -----
          Serial.print(F("Led N°"));
          Serial.print(indexLed);
          Serial.print(F(" sur la broche #"));
          Serial.print(lesLeds[indexLed].broche);
          Serial.print(F(" mise à "));
          Serial.print(lesLeds[indexLed].etat == HIGH ? "HIGH" : "LOW");
          if (lesLeds[indexLed].etat == HIGH) {
            Serial.print(F(" pour "));
            Serial.print(duree);
            Serial.println(F(" s"));
          } else Serial.println();
          // ---------------------------

          indexLed = 0;
          duree = 0;
          etat = ATTENTE_BROCHE;
        } else {
          if (recu >= '0' && recu <= '9') {
            duree = duree * 10 + (recu - '0');
          }
        }
        break;
    }
  }

  // gestion de l'extinction automatique
  for (Led& l : lesLeds) {
    if (l.etat == HIGH)
      if (millis() - l.debut >= l.attente) {
        l.etat = LOW;
        digitalWrite(l.broche, LOW);
        l.attente = 0;
      }
  }

}

bien sûr il n'y a pas la gestion des entrées incorrectes