calcul d' un temps precis

Salut , je voulais savoir si on peut creer une fonction qui calcule un temps en ms a partir d’ un unsigned long converti en float pour la precision du calcul puis qui retourne un unsigned long en faisant comme ca :

unsigned long calculTimer_V (uint8_t identifier) {

	float timer_volet = TIMER_V; // calculer a partir d' un float donne des resultats + precis
	//unsigned long timer_volet = TIMER_V;
	uint8_t hauteur_V = 210; 
	
	
	if ( ( (identifier > 3) && (identifier < NUMBER_NAME_RELAY_V) ) || ( (identifier > 11) && (identifier < 16) ) ) {
		hauteur_V= 105;
	}
	else if ( (identifier == 1) || (identifier == 2) || (identifier == 1 + NUMBER_NAME_RELAY_V) || (identifier == 2 + NUMBER_NAME_RELAY_V) ) {  
		hauteur_V= 210;
	}
	else { 
		hauteur_V= 97;
	}
	
	timer_volet = timer_volet / 210 * hauteur_V;
	if ( DEBUG ) {
		Serial.print (F("Le relais numero "));
		Serial.print (identifier);
		Serial.print (F(" vient d' etre active pour "));
		Serial.print (timer_volet);
		Serial.println (F(" millisecondes"));
	}
	return (timer_volet);
}

qu ’ en pensez vous,ca ne risque pas de poser de problemes , ou c ’ est pas comme ca qu il faut faire ?

Si tu fais ce calcul en entier, tu auras une assez mauvaise précision car tu fais la division en premier

timer_volet = timer_volet / 210 * hauteur_V;

Si tu fais le calcul dans ce sens

timer_volet = timer_volet * hauteur_V / 210;

tu auras une précision bien meilleur.

Après, il faut voir le besoin.

fdufnews:
Si tu fais ce calcul en entier, tu auras une assez mauvaise précision car tu fais la division en premier

timer_volet = timer_volet / 210 * hauteur_V;

Si tu fais le calcul dans ce sens

timer_volet = timer_volet * hauteur_V / 210;

tu auras une précision bien meilleur.

Après, il faut voir le besoin.

effectivement , tu as raison , je n' avais pas pensé a cela !

c ' est juste pour arreter le moteur de mes volets roulants . donc pas besoin d ' etre precis au 1/1000 de seconde , mais bon j ' aimerais ne pas me retouver avec une demi seconde d' ecart !

dans la fonction , rien de choquant ? declaration d' un float et return d' un float qui est signalé a l'' origine comme unsigned long comme je l' ai fais , pas genant ?

j ’ ai modifié la fonction de calcul comme suit :

unsigned long calculTimer_V (uint8_t identifier) {
	if ( identifier < RELAY_NUMBER_V ) {
		unsigned long timer_volet = TIMER_V;
		uint8_t hauteur_V = 210;
		if ( ( (identifier > 3) && (identifier < NUMBER_NAME_RELAY_V) ) || ( (identifier > 11) && (identifier < 16) ) ) {
			hauteur_V= 105; //  nuit : 15 sec
		}
		else if ( (identifier == 1) || (identifier == 2) || (identifier == 1 + NUMBER_NAME_RELAY_V) || (identifier == 2 + NUMBER_NAME_RELAY_V) ) { // salle a manger ou salon
			hauteur_V= 210;
		}
		else { // si on est cuisine ou salle TV => hauteur = 95 cm
			hauteur_V= 100;
		}
		timer_volet = timer_volet * hauteur_V / 210; // pour plus de precision , il est preferable de finir par la division .
		
		if (DEBUG) {
			Serial.print (F("calculTimer_V => tache numero "));
			Serial.print (identifier);
			Serial.print (F(" active pour "));
			Serial.print (timer_volet);
			Serial.println (F(" millisecondes"));
		}
	return timer_volet;
	}
}

Mais ca ne plait pas l ’ IDE :

/home/iznobe/Arduino/SKETCH/serveur volets/serveur_volet_arrosage_V_A_P_R_IA_RTC_NTP.UDP_6.300/serveur_volet_arrosage_V_A_P_R_IA_RTC_NTP.UDP_6.300.ino: In function 'long unsigned int calculTimer_V(uint8_t)':
/home/iznobe/Arduino/SKETCH/serveur volets/serveur_volet_arrosage_V_A_P_R_IA_RTC_NTP.UDP_6.300/serveur_volet_arrosage_V_A_P_R_IA_RTC_NTP.UDP_6.300.ino:1044:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

comment corriger cela svp ?

meme en faisant ca , il ne veut pas : >:(

unsigned long calculTimer_V (unsigned long identifier) {

	if ( identifier < RELAY_NUMBER_V ) {
		unsigned long timer_volet = TIMER_V;
		unsigned long hauteur_V;

		if ( ( (identifier > 3) && (identifier < NUMBER_NAME_RELAY_V) ) || ( (identifier > 11) && (identifier < 16) ) ) {
			hauteur_V= 105UL; //  nuit : 15 sec
		}
		else if ( (identifier == 1) || (identifier == 2) || (identifier == 1 + NUMBER_NAME_RELAY_V) || (identifier == 2 + NUMBER_NAME_RELAY_V) ) { // salle a manger ou salon
			hauteur_V= 210UL;
		}
		else { // si on est cuisine ou salle TV => hauteur = 95 cm
			hauteur_V= 100UL;
		}
		timer_volet = timer_volet * hauteur_V / 210UL; // pour plus de precision , il est preferable de finir par la division .
		
		if (DEBUG) {
			Serial.print (F("calculTimer_V => tache numero "));
			Serial.print (identifier);
			Serial.print (F(" active pour "));
			Serial.print (timer_volet);
			Serial.println (F(" millisecondes"));
		}
	return timer_volet;
	}
}

hello

et comme ça: ?

//déclaration en portée globale
unsigned long timer_volet = 0;
setup()
loop()
unsigned long calculTimer_V (uint8_t identifier) {
  if ( identifier < RELAY_NUMBER_V ) {
    timer_volet = TIMER_V;
    uint8_t hauteur_V = 210;
    if ( ( (identifier > 3) && (identifier < NUMBER_NAME_RELAY_V) ) || ( (identifier > 11) && (identifier < 16) ) ) {
      hauteur_V = 105; //  nuit : 15 sec
    }
    else if ( (identifier == 1) || (identifier == 2) || (identifier == 1 + NUMBER_NAME_RELAY_V) || (identifier == 2 + NUMBER_NAME_RELAY_V) ) { // salle a manger ou salon
      hauteur_V = 210;
    }
    else { // si on est cuisine ou salle TV => hauteur = 95 cm
      hauteur_V = 100;
    }
    timer_volet = timer_volet * hauteur_V / 210; // pour plus de precision , il est preferable de finir par la division .

    if (DEBUG) {
      Serial.print (F("calculTimer_V => tache numero "));
      Serial.print (identifier);
      Serial.print (F(" active pour "));
      Serial.print (timer_volet);
      Serial.println (F(" millisecondes"));
    }
  }
  return timer_volet;
}

Salut ,

meme en declarant la variable globale , il me met la meme erreur ...

j ' ai essayé avec des floats => idem
j 'ai essayé de convertir avec ca aussi :

float vIn = 0.0;
unsigned long vOut = (unsigned long)vIn;

j ' ai aussi essayé d ' initialiser et declarer directement en faisant :

unsigned long timer_volet = TIMER_V * hauteur_V / 210; // pour plus de precision , il est preferable de finir par la division .

mais ca veut toujours pas , je suis vraiment a court d' idees :grin:

pourtant sur le moniteur serie , ca parait etre bon :

13:27:13.598 -> calculTimer_V => tache numero 0 active pour 14285 millisecondes
13:27:13.631 -> activResetTimer => tache 0 enregistrée pour dans 14285
13:27:13.631 -> activeRelaisTable => numero 0 active

si je fais comme ca apres 2 heures de recherche pour rien , ca marche :

unsigned long calculTimer_V (uint8_t pin) {
	unsigned long timer_volet = TIMER_V; // calculer a partir d' un float donne des resultats + precis

	if ( pin < RELAY_NUMBER_V ) {
		uint8_t hauteur_V= 100;
		if ( ( (pin > 3) && (pin < NUMBER_NAME_RELAY_V) ) || ( (pin > + NUMBER_NAME_RELAY_V) && (pin < RELAY_NUMBER) ) ) hauteur_V = 105; //  nuit : 15 sec
		else if ( (pin == 1) || (pin == 2) || (pin == 1 + NUMBER_NAME_RELAY_V) || (pin == 2 + NUMBER_NAME_RELAY_V) ) hauteur_V = 210; // salle a manger ou salon
		//else hauteur_V = 100; // si on est cuisine ou salle TV => hauteur = 95 cm

		timer_volet = timer_volet / 210 * hauteur_V; // pour plus de precision , il est preferable de finir par la division .

		if (DEBUG) {
			Serial.print (F("calculTimer_V => tache numero "));
			Serial.print (pin);
			Serial.print (F(" active pour "));
			Serial.print (timer_volet);
			Serial.println (F(" millisecondes"));
		}
	}
	return timer_volet;
}

principalement l ’ emplacement du return est en cause … enfin j ’ ai l’ impression .

je comprends pas pourquoi , il ne veut pas genre :

int mafonction () {
  if (un_truc) {
    return ma_valeur;
  }
}

quelqu ’ un aurait une explication svp ?

iznobe:
je comprends pas pourquoi , il ne veut pas genre :

int mafonction () {

if (un_truc) {
    return ma_valeur;
  }
}




quelqu ' un aurait une explication svp ?

parce que vous avez promis au compilateur de retourner un entier et si un_truc est faux vous ne retournez rien…

le plus propre c’est de faire comme cela

int mafonction () {
  int maValeur = -1;
  if (un_truc) {
    // on bricole et modifie maValeur
  }
  return maValeur;
}

sinon si c’est des if imbriqués et compliqué de sortir en milieu de code et que vous voulez faire un return dans le if, rajoutez un return à la fin avec une valeur par défaut

int mafonction () {
  if (un_truc) {
      // on bricole et modifie maValeur
      return maValeur;
  }
  return -1; // ou ce que vous voulez quand le calcul n'a pas eu lieu
}

ca ressemble a la valeur par defaut d ' un switch case de la sorte .

c ' est ce que je pensais avoir fait dans la fonction du #3 .

je m' assure juste avant que la valeur transmise en parametre soit dans le bon creneau avec la premire condition globale .

et donc de retourner un truc que quand la condition est vrai , pfff il pourrait etre plus clair sur l ' erreur , on comprend rien a ce qu ' il raconte dans son erreur .

si il disait , le retour risque de ne pas comporter de valeur , on comprendrait et je n' aurais pas perdu 2 heures !

En tout cas merci pour cette explication @J-M-L :wink:

le warning est assez parlant quand même je trouve

[color=orange] warning: control reaches end of non-void function [-Wreturn-type][/color]

ça vous dit bien que vous arrivez à la fin d'une fonction qui ne retourne pas rien (non void) et que vous n'avez pas le bon type de retour (return-type)

en #3 vous êtes bien dans ce cas où il y a un chemin possible pour aller à la fin de la fonction sans faire de return. le compilateur vous dit donc que vous n'avez pas respecté votre promesse et il est très tatillon sur le sujet :slight_smile:

:slight_smile:

Serial.println (F(" millisecondes"));
}
}
return timer_volet;
}

La variable timer_volet est est déclarée dans le if elle est locale à ce bloc.

oui, mais je faisais référence à ma réponse en #5
en début, je précisais une déclaration en globale.

je suppose que notre ami a fait la modif sur son code

alors qu’il aurait du tester avec le code complet que je lui proposait.
il aurait vu la modif rappelée dans le post ci dessus.

bref, cela n’a pas d’importance

dfgh:
oui, mais je faisais référence à ma réponse en #5
en début, je précisais une déclaration en globale.

je suppose que notre ami a fait la modif sur son code

alors qu'il aurait du tester avec le code complet que je lui proposait.
il aurait vu la modif rappelée dans le post ci dessus.

bref, cela n'a pas d'importance

oui exact , je n ' ai compris qu ' apres , qu il fallait mettre en global de la fonction .
je l ' avais mis en global dans mon code mais ca ne changeait rien , le probleme etait lié au fait que le return etait soumis à condition comme l' a souligné@J-M-L .

avec les 2 modifs que tu dis ca marche !
et c ' est ce que j ' ai fini par faire .
Merci a vous tous :smiley: