Go Down

Topic: [Résolu]Fonction avec fonction en parametre (Read 994 times) previous topic - next topic

cutprod

Aug 31, 2012, 07:35 pm Last Edit: Aug 31, 2012, 08:34 pm by cutprod Reason: 1
Bonjour a tous,
j'ai besoin d' appeler une fonction a intervalle régulier (2 ou 3 sec)
Pour cela j' insert dans ma boucle une fonction avec 2 paramètres (l'intervalle de temps en ms et la fameuse fonction a appeler).
Pour le temps pas de problème mais c'est pour la fonction a appeler que je bloque... J'ai fais pas mal de tests et j'ai des erreurs a la compile...
Code: [Select]
long time_x = 0;
long time_y;

void setup()
{
  Serial.begin(9600);
  Serial.println ("go...");
}

void loop()
{
  timer(1000,func_test)
}

//########################################################

void timer(long timer_tick, func_to_call)
{
 time_y = millis();
 
 if(time_y - time_x > timer_tick)
 {
   time_x = time_y;
   func_to_call();
 }
 
}//fin timer()

void func_test()
{
  Serial.println ("ok!");
}

Quelqu'un pour m'aider?
Ps = Peut être existe t il un moyen plus simple ou meilleur qui me serait passé sous le nez ?! ce serait fort possible :~
Merci d'avance.

barbudor

Bonjour

On ne passe pas une fonction en paramètre mais un pointeur de fonction.
le nom de la fonction est ce pointeur


Code: [Select]

long time_x = 0;
long time_y;

void setup()
{
   Serial.begin(9600);
   Serial.println ("go...");
}

void timer(long timer_tick, void (*func_to_call)() );

void loop()
{
   timer(1000,func_test);
}

//########################################################

void timer(long timer_tick, void (*func_to_call)() )
{
  time_y = millis();
 
  if(time_y - time_x > timer_tick)
  {
    time_x = time_y;
    (*func_to_call)();
  }
 
}//fin timer()

void func_test()
{
   Serial.println ("ok!");
}

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

skywodd

Bonjour,


Ps = Peut être existe t il un moyen plus simple ou meilleur qui me serait passé sous le nez ?! ce serait fort possible :~

Il n'existe qu'une seule méthode pour passer une fonction en paramètre 'd'une autre fonction ;)
-> Utiliser un pointeur sur fonction

Tutoriel :
http://www.siteduzero.com/tutoriel-3-314203-les-pointeurs-sur-fonctions.html

--

Pour faire simple, tu prends le prototype de ta fonction.
Exemple :
Code: [Select]
void toto(int plop);

Tu changes un peu le nom pour montrer qu'il s'agit d'un pointeur
Exemple :
Code: [Select]
void fnc_toto_ptr(int plop);

Remarque :
fnc = abréviation de fonction
ptr = abréviation de pointeur
Ainsi tu sais de suite de quoi il s'agit ;)

Tu ajoutes des parenthèses et une étoile devant le nom de la fonction.
Exemple :
Code: [Select]
void (*fnc_toto_ptr)(int plop);

Tu mets le tout dans un typedef.
Exemple :
Code: [Select]
typedef void (*fnc_toto_ptr)(int plop);

Et c'est cuit ! :smiley-mr-green:

Exemple :
Code: [Select]
typedef void (*fnc_toto_ptr)(int plop);

void loop() {
 // ...
 mon_toto(super_toto);
}

void mon_toto(fnc_toto_ptr toto) {
 int val = 42;
 // ...
 toto(val);
}

void super_toto(int plop) {
 // ...
}


Edit: Zut alors, je me suis fait grilled par Barbudor :smiley-mr-green:
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

barbudor

Skywodd à raison, le typedef rend généralement plus lisible
Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

skywodd


Skywodd à raison, le typedef rend généralement plus lisible

Ça rend le code plus lisible et surtout réutilisable si tu as plusieurs fonctions utilisant le même type de pointeur sur fonction ;)
Bonus: en cas de modification tu as juste à changer le typedef.

Par contre il y a gros point négatif (bug de qualité, conception 100% "made in italy" de notre chère team arduino) :
L'ide arduino ne place pas les typedef (struct, union, ...) avant les prototypes de fonction mais âpres.
Du coup lors de la compilation le compilateur ne sait pas ce qu'est le type en question et c'est le drame "error at line x-y: machintruc not defined".

Solution : placer le typedef dans un fichier .h situé dans le même dossier que le .ino (ou .pde).
Il suffit ensuite d'inclure le fichier .h avec #include "monfichier.h" en haut du sketch.
(les includes sont toujours situé avant les prototypes, donc lors de la compilation le compilateur connait les typedef au moment où il rencontre les prototypes)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

cutprod

Aie! Aie! Aie!  :smiley-eek:
Précision, rapidité, efficacité...
Vous êtes trop bon!!
Merci a tous les deux pour votre aide.

Go Up