code C++ ecriture boucle

Salut ,

y aurait-il une jolie facon de " concatener " ces 2 fonctions proprement svp ?

j ' y arrive pas :confused:

void activeRelaisTable (byte startPin , byte endPin ) {
		for ( byte i = startPin; i < endPin; i++ ) {
			tableau_Etat_Relais [ i ] = LOW; //on affiche le nouvel état du relais
			digitalWrite ( tableau_Pin_Relais [ i ] , LOW ); //on effectue la mise à jour du pin
			if ( i  < RELAY_NUMBER_V )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
			else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
			else if (i >= RELAY_NUMBER_A ) {}
		}
}

et

void activeRelais (byte i ) {
		tableau_Etat_Relais[i] = !tableau_Etat_Relais[i]; //on affiche le nouvel état du relais
		digitalWrite(tableau_Pin_Relais[i], tableau_Etat_Relais[i]); //on effectue la mise à jour du pin
		
		if ( i  < RELAY_NUMBER_V )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
		else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
		else if (i >= RELAY_NUMBER_A ) {}

}

Comme ça par exemple ?

void activeRelaisTable (byte startPin , byte endPin ) {
 for ( byte i = startPin; i < endPin; i++ ) {
   tableau_Etat_Relais [ i ] = activeRelais (i , LOW); //on affiche le nouvel état du relais
 }
}

bool activeRelais (byte i , bool level) {
 newlevel = !level; //on affiche le nouvel état du relais
 digitalWrite(tableau_Pin_Relais[i], newlevel); //on effectue la mise à jour du pin
 if ( i  < RELAY_NUMBER_V )  gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
 else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A ) gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
 else if (i >= RELAY_NUMBER_A ) {}
 return newlevel;
}

est ce que je peux faire ça ?

void activeRelaisTable (byte startPin , byte endPin ) {
	if ( startPin == endPin ) endPin = endPin +1;
	for ( byte i = startPin; i < endPin; i++ ) {
		tableau_Etat_Relais[i] = !tableau_Etat_Relais[i]; //on affiche le nouvel état du relais
		digitalWrite(tableau_Pin_Relais[i], tableau_Etat_Relais[i]); //on effectue la mise à jour du pin
		
		if ( i  < RELAY_NUMBER_V )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
		else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
		else if (i >= RELAY_NUMBER_A ) {}
	}
}

lesept:
Comme ça par exemple ?

void activeRelaisTable (byte startPin , byte endPin ) {

for ( byte i = startPin; i < endPin; i++ ) {
  tableau_Etat_Relais [ i ] = activeRelais (i , LOW); //on affiche le nouvel état du relais
}
}

bool activeRelais (byte i , bool level) {
newlevel = !level; //on affiche le nouvel état du relais
digitalWrite(tableau_Pin_Relais[i], newlevel); //on effectue la mise à jour du pin
if ( i  < RELAY_NUMBER_V )  gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A ) gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
else if (i >= RELAY_NUMBER_A ) {}
return newlevel;
}

Salut lesept et merci pour la reponse .

ce que je voudrais faire c ' est n ' avoir qu ' une seule fonction . si ca n ' est pas trop galere .

est ce que je peux considerer que !tableau_Etat_Relais c ' est pareil que LOW , je sais bien que normalement non , puisque ca fait aussi dans l' autre sens , mais vu qu ' on est dans une fonction d' activation ...

je suis obligé de garder le ! dans la partie pour un seul relais .

je vais quand meme tester voir ce que ca donne .

en tout cas vous pouvez déjà dégager ce bout de code qui ne sert à rien :slight_smile:

else if (i >= RELAY_NUMBER_A ) {}

J-M-L:
en tout cas vous pouvez déjà dégager ce bout de code qui ne sert à rien :slight_smile:

else if (i >= RELAY_NUMBER_A ) {}

Salut J-M-L , vous avez tout a fait raison , pour le moment il ne sert a rien :smiley:

Mais un jour il servira quand j ' implementerai le reste des relais de mon installation .

Sinon , la fonction que j ' ai poster avant a l ' air de faire le taff pour du single et du multi . j ' ai un parametre inutile dans certains cas , mais plus qu ' une fonction dans le code .

je sais pas ce qui est mieux niveau perf , mais niveau code , ca fait de la place , il commencait a y avoir trop de fonctions !! et trop de lignes presque 1000.

je suis a 850 maintenant lol !

si vous ne voulez qu'une seule fonction il suffit de l'appeler avec startPin = endPin... dans ce cas la boucle for ne traite qu'une seule valeur qui serait celle de votre pin
EDIT: Attention à votre < cependant dans la boucle for... ça ne devrait pas être <= afin de bien prendre en compte le N° de la pin de fin dans la boucle for ?? (sinon mon hack ne marche pas)

une autre option c'est de rendre la seconde pin facultative, avec comme valeur par défaut 255 (une pin qui n'existe pas). et de tester cette valeur pour faire la boucle for quand vous avez une vraie valeur lors de l'appel et sinon si le paramètre est omis (donc on voit 255) on établit comme borne de la boucle for la même startPin.

void activeRelaisTable (byte startPin , byte endPin = 255 ) {
  byte pinFin = (endPin == 255) ? startPin : endPin;

  for ( byte i = startPin; i <= pinFin; i++ ) {
    tableau_Etat_Relais [i] = LOW; //on affiche le nouvel état du relais
    digitalWrite( tableau_Pin_Relais[i] , LOW ); //on effectue la mise à jour du pin
    if ( i  < RELAY_NUMBER_V )  gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
    else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A ) gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
    else if (i >= RELAY_NUMBER_A ) {}
  }
}

donc si vous ne voulez qu'une seule pin vous appelez activeRelaisTable(3); par exemple

Attention à votre < cependant dans la boucle for... ça ne devrait pas être <= afin de bien prendre en compte le N° de la pin de fin dans la boucle for ?? (sinon mon hack ne marche pas)

J-M-L:
si vous ne voulez qu'une seule fonction il suffit de l'appeler avec startPin = endPin... dans ce cas la boucle for ne traite qu'une seule valeur qui serait celle de votre pin
EDIT: Attention à votre < cependant dans la boucle for... ça ne devrait pas être <= afin de bien prendre en compte le N° de la pin de fin dans la boucle for ?? (sinon mon hack ne marche pas)

une autre option c'est de rendre la seconde pin facultative, avec comme valeur par défaut 255 (une pin qui n'existe pas). et de tester cette valeur pour faire la boucle for quand vous avez une vraie valeur lors de l'appel et sinon si le paramètre est omis (donc on voit 255) on établit comme borne de la boucle for la même startPin.

void activeRelaisTable (byte startPin , byte endPin = 255 ) {

byte pinFin = (endPin == 255) ? startPin : endPin;

for ( byte i = startPin; i <= pinFin; i++ ) {
    tableau_Etat_Relais [i] = LOW; //on affiche le nouvel état du relais
    digitalWrite( tableau_Pin_Relais[i] , LOW ); //on effectue la mise à jour du pin
    if ( i  < RELAY_NUMBER_V )  gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
    else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A ) gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
    else if (i >= RELAY_NUMBER_A ) {}
  }
}




donc si vous ne voulez qu'une seule pin vous appelez `activeRelaisTable(3);` par exemple

c ' est ce que j' ai fais , votre premiere option , tout en conservant le " < " sans le egal en mettant cette ligne :

if ( startPin == endPin ) endPin = endPin +1;

votre 2eme option ne peut pas marcher , car j ' ai un seul tableau de pins pour plusieurs utilisations .
d' ou la fin de ma fonction :

 if ( i  < RELAY_NUMBER_V )  gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );
    else if ( i >= RELAY_NUMBER_V && i < RELAY_NUMBER_A ) gestionnaireDeTache.registerAsyncCommand( i, TIMER_A, resetTimer );
    else if (i >= RELAY_NUMBER_A ) {}

et donc je ne peut n ' y mettre le egal , ni mettre 255 comme valeur par defaut pour endPin .

Au debut ca me semblait bien de faire de la sorte . je me demande si avec les ajouts futurs ca ne va pas me donner envie de changer ! ( ca me titille deja :stuck_out_tongue: )

OK - oui le +1 fonctionne aussi. ça fait un peu bizarre mais du moment que vous savez que la dernière pins n'est pas comprise dans le processus, pourquoi pas

ça marche pareil avec le param en valeur par défaut:

void activeRelaisTable (byte startPin , byte endPin = 255 ) {
  byte pinFin = (endPin == 255) ? startPin+1 : endPin;

ah j'avais pas vu que dans la fonction à 1 param vous faitestableau_Etat_Relais[i] = !tableau_Etat_Relais[i]; //on affiche le nouvel état du relaisalors que dans l'autre c'esttableau_Etat_Relais [ i ] = LOW; //on affiche le nouvel état du relais

donc les deux ne sont pas vraiment identiques, celle avec la boucle for force à LOW alors que l'autre inverse la valeur

oui , c ' etait justement la cause de la difficulté de ne faire plus qu ' une fonction .

j ' est tenté de garder les 2 cas , bien sur j ' y suis arrivé , mais ca donnait un truc pas beau du tout :grin: :grin:

j ' ai aussi essayé de faire ++i dans le for , a la place de i++ , mais je n' ai pas vu ce que ca change .

lorsque je clique sur le bouton pour activer ma centralisation de volets ( ca fait chouette de dire ca ! 8) ) , ca marche sans probleme aussi bien qu ' avec un simple volet le tout grace a votre classe , avant j etais obligé par un forçage a LOW car y avait pas la meme gestion .

c ' est vraiment trop la classe votre classe gestionnaire async :stuck_out_tongue: .

j ' ai fait les modifs partout dans le code , la ca ressemble vraiment a quelquechose .

il reste encore un point qui me titille un switch case dans ma fonction d' arrosage autonome qui ne me plait pas des masses , il me semble que je pourrais le supprimer , mais je n' ai pas encore eu le tilt sur la façon de proceder .

Avec l’approche du paramètre optionnel si on reconnaît 255 on pourrait inverser sinon mettre LOW... mais pas bcp d’intérêt intellectuel je pense qu’il vaut mieux garder deux fonctions.

Je changerais le nom cependant de void activeRelais (byte i ) {En void inverseRelais (byte i ) {

c ' est fait , mais , il inverse uniquement quand le timer n ' a pas été reset :

if ( i  < RELAY_NUMBER_V )	gestionnaireDeTache.registerAsyncCommand( i, TIMER_V, resetTimer );

une fois le temps ecoulé , il active a nouveau :stuck_out_tongue: