Go Down

Topic: Création de librairie & fonctions: problème pour trouver delay() [résolu] (Read 2421 times) previous topic - next topic

schizophrene

Bonjour à tous,

Je souhaite créer une librairie contenant des tableaux et des fonctions.

Je crée une fonction lireAniSimple(...) faisant appel à des fonctions de la librairie Tlc5940.h (pas de problème ici, je l'ai mise en #include) ainsi qu'à l'instruction delay().

Le problème, quand j'essaie de compiler mon sketch d'essai, j'obtiens le message suivant:

Code: [Select]

In file included from sketch_aug28b.cpp:1:
C:\Program Files (x86)\Arduino 22\libraries\TLC5940/animations.h: In function 'void lireAniSimple(int, int, int, int, int)':
C:\Program Files (x86)\Arduino 22\libraries\TLC5940/animations.h:16: error: 'delay' was not declared in this scope


J'obtenais, avant d'inclure la libraire du TLC5940, une ligne de plus dans le message d'erreur, comme quoi 'Tlc' n'était pas déclaré - problème résolu donc, par l'inclusion de la librairie Tlc5940.h.

J'ai essayé de trouver la libraire contenant delay(), sans succès.

Une idée pour résoudre mon problème?

D'avance, je vous remercie :)

SesechXP

Salut,

Pour delay et de nombreuses autres fonctions des bibliothèques Arduino il faut inclure WProgram.h

++
Julien - www.idreammicro.com

schizophrene

#2
Aug 28, 2011, 07:24 pm Last Edit: Aug 28, 2011, 08:02 pm by schizophrene Reason: 1
Salut SesechXP et merci pour ta réponse, mais ça ne fonctionne pas!

J'ai aussi essayé d'inclure delay.h et delay_basic.h, sans plus de succès...

Une autre idée?

EDIT: Ok, j'ai rien dit, cela fonctionne très bien!

Je n'avais pas mis le #include dans mon .h  smiley-kiss

Merci pour ton aide du coup smiley

schizophrene

#3
Aug 28, 2011, 07:41 pm Last Edit: Aug 28, 2011, 08:12 pm by schizophrene Reason: 1
Par contre, mon programme n'a pas l'air de sortir de la fonction.

En gros, j'utilise un TLC5940 pour multiplier les sorties PWM.
Pour commencer très simple, j'active toutes les sorties du TLC5940 une par une (la led au bout de chaque sortie s'allume), puis j'éteins chaque led les unes après les autres dans le même ordre.

Sans utiliser de fonction, j'arrive très bien à le faire. Mais une fois mes fonctions créées avec 'void' dans mon .h, mes leds s'allument les unes après les autres, mais ne s'éteignent pas.

J'utilise un flag 'i', pour savoir si mon animation a été écrite ou effacée (ça fonctionnait très bien sans utiliser de fonctions). Quand i = 0, l'animation est lue; quand i = 1, l'animation est effacée.

Code Arduino:

Code: [Select]
#include <animations.h>
#include <Tlc5940.h>

const int zero = 0;
const int plein = 4095;
const int tempo = 500;

int i = 0;
int sortie = 0;
int animation = 0;

void setup()
{
  Tlc.init();
}

void loop()
{
  if (i == 0)
  {
    lireAniSimple(animation,sortie,plein,tempo,i);
  }
 
  if (i == 1)
  {
    effaceAniSimple(animation,sortie,zero,tempo,i);
  }
}


Code animation.h:

Code: [Select]
#include <Tlc5940.h>
#include <WProgram.h>

unsigned int ani_simple[][15] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
{4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 14, 13, 12, 11, 10},
{10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}
};

void lireAniSimple(int animation, int sortie, int plein, int tempo, int i)
{
for (sortie = 0; sortie < 15; sortie++)
{
Tlc.set(ani_simple[animation][sortie],plein);
Tlc.update();
delay(tempo);
}
i = 1;
sortie = 0;
}

void effaceAniSimple(int animation, int sortie, int zero, int tempo, int i)
{
for (sortie = 0; sortie < 15; sortie++)
{
Tlc.set(ani_simple[animation][sortie],zero);
Tlc.update();
delay(tempo);
}
i = 0;
sortie = 0;
}


Désolé pour le code non commenté, c'est vraiment à titre d'essai.
Si vous galérez à le comprendre, je le commenterai.

Merci d'avance pour toute aide.


schizophrene

#5
Aug 28, 2011, 09:51 pm Last Edit: Aug 29, 2011, 06:20 pm by schizophrene Reason: 1
Salut, et merci pour ta réponse.

Je ne pourrais pas tester ce soir, seulement demain.

Mais, comme WProgram.h ne me sert que pour delay() dans animation.h, et que delay() fonctionne correctement jusqu'à ce que toutes les leds soient allumées, je ne suis pas sûr que ça vienne de là.
L'expérimention, demain, nous le dira :)

En attendant, je suis toujours ouvert à toute suggestion.

schizophrene

#6
Aug 29, 2011, 08:00 pm Last Edit: Aug 29, 2011, 08:09 pm by schizophrene Reason: 1
Bonjour à tous,

J'ai testé de mettre des guillemets sur tous les #include du sketch et dans mon .h: cela n'a rien changé.

Du coup, j'ai décidé de changer les fonctions: avant elles ne renvoyaient rien, maintenant elles renvoient la valeur de i avec return. Et ça fonctionne!

Code du sketch:

Code: [Select]
#include "animations.h"
#include "Tlc5940.h"

const int zero = 0;
const int plein = 4095;
const int tempo = 500;

int sortie = 0;
int i = 0;
int animation = 0;

void setup()
{
 Tlc.init();
}

void loop()
{
 if (i == 0)
 {
   i = lireAniSimple(animation, sortie, plein, tempo, i);
 }
 
 if (i == 1)
 {
   i = effaceAniSimple(animation, sortie, zero, tempo, i);
 }
 
}


Code animations.h:

Code: [Select]
#include "Tlc5940.h"
#include "WProgram.h"

unsigned int ani_simple[][15] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
{4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 14, 13, 12, 11, 10},
{10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}
};

int lireAniSimple(int animation, int sortie, int plein, int tempo, int i)
//void lireAniSimple(int animation, int sortie, int plein, int tempo, int i)
{
for (sortie = 0; sortie < 15; sortie++)
{
Tlc.set(ani_simple[animation][sortie],plein);
Tlc.update();
delay(tempo);
}
i = 1;
sortie = 0;
return i;
}

int effaceAniSimple(int animation, int sortie, int zero, int tempo, int i)
//void effaceAniSimple(int animation, int sortie, int zero, int tempo, int i)
{
for (sortie = 0; sortie < 15; sortie++)
{
Tlc.set(ani_simple[animation][sortie],zero);
Tlc.update();
delay(tempo);
}
i = 0;
sortie = 0;
return i;
}


Par contre, mon UNO réinitialise aléatoirement en lisant ce programme. L'intensité de la led de mise sous tension varie légèrement quand ça se produit. J'alimente, pour mes tests, la platine avec l'USB.
Est-ce une cause?

Je testerai demain avec un bloc secteur.

PS: encore désolé pour le code non commenté, flemme quand tu nous tiens :*

Snootlab

Bonjour,

Pour les #include, ce qu'il faut savoir, c'est que lorsque l'on fait un #include "foo.bar", il va chercher dans l'annuaire du fichier source, puis dans les chemins normalisés, atteignables par ton compilateur (Winavr\avr\include ... et d'autres).
Lorsque tu fais par contre un #include <foo.bar>, il ne va chercher que dans les chemins normalisés, et pas dans le répertoire de ton fichier source.
Donc, dans le cas du Wprogram.h, cela ne change rien, étant donné qu'il est dans les répertoires normalisés.

Par contre, ce qui peut poser problème, c'est d'avoir trois variables différentes appellées "i", "animation" ou "sortie", une dans ton main, et une dans la définition de lireAni et effaceAni. C'est quelque chose à ne jamais faire. En effet, dans certains cas, cela passera, dans d'autres (le plus souvent), cela sera source de conflits.

Ensuite, je ne comprends pas l'intérêt de passer "animation" en paramètre, car il semble ne pas changer et égaler toujours 0.

En espérant t'avoir aidé,

Bonne journée.

-----
Stéphane
- Distributeur officiel Arduino - France

schizophrene

Bonjour Snootlab, et merci pour ta réponse.

Je comprend maintenant la différence entre "..." et <...> pour les include, merci.

Pour la double définition des variables, j'en conclue que cela peut-être une cause de reset intempestif de la platine?
Je remédirai à cela ce soir :)

Quant à 'animation' passée en paramètre, effectivement la variable ne change pas - pour l'instant, car à terme elle changera automatiquement ou manuellement, selon un mode de fonctionnement défini par l'utilisateur (moi :* ).

Voilà tout, merci encore.

Snootlab

Bonjour,

Pour le reset intempestif, je n'ai pas assez d'informations pour savoir à quoi il est dû. Peut-être que renommer correctement tes variables ne réglera pas le problème, mais ce qui est sûr, c'est qu'il ne faut jamais avoir deux variables du même nom, cela fait partie des règles communes de codage "propre", et souvent, cela peut générer des problèmes ou des dysfonctionnements.

Bonne journée.

-----
Stéphane
- Distributeur officiel Arduino - France

SesechXP

Salut,

Je suis d'accord avec Snootlab concernant le nom des variables. Par contre on n'a parfois pas le choix et deux variables ont le même nom. Dans ce cas il faut réduire leur portée à l'aide du mot clé static à défaut de pouvoir les mettre en private dans le sketch. Par exemple :
Code: [Select]
static int i = 0;

Dans ton exemple, il est même possible de pousser plus loin puisque la variable i n'est utilisée que dans la fonction loop :
Code: [Select]

void loop(){
    static int i = 0;
    // ...
}


++
Julien - www.idreammicro.com

schizophrene

#11
Sep 01, 2011, 07:26 pm Last Edit: Sep 01, 2011, 07:35 pm by schizophrene Reason: 1
Bonjour, et merci une fois de plus pour vos réponses.

Ok pour la double déclaration de variable, j'ai résolu en mettant un 'H' devant chaque déclaration dans animations.h:

Code: [Select]
#include "Tlc5940.h"
#include "WProgram.h"

unsigned int ani_simple[][15] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
{4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 14, 13, 12, 11, 10},
{10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}
};

int lireAniSimple(int Hanimation, int Hsortie, int Hplein, int Htempo, int Hi)
{
for (Hsortie = 0; Hsortie < 15; Hsortie++)
{
Tlc.set(ani_simple[Hanimation][Hsortie],Hplein);
Tlc.update();
delay(Htempo);
}
Hi = 1;
Hsortie = 0;
return Hi;
}

int effaceAniSimple(int Hanimation, int Hsortie, int Hzero, int Htempo, int Hi)
{
for (Hsortie = 0; Hsortie < 15; Hsortie++)
{
Tlc.set(ani_simple[Hanimation][Hsortie],Hzero);
Tlc.update();
delay(Htempo);
}
Hi = 0;
Hsortie = 0;
return Hi;
}


J'ai essayé de les mettre en static, mais j'obtenais ce message:
Code: [Select]
C:\Program Files (x86)\Arduino 22\libraries\TLC5940/animations.h:11: error: storage class specifiers invalid in parameter declarations
C:\Program Files (x86)\Arduino 22\libraries\TLC5940/animations.h:11: error: storage class specified for parameter 'Hanimation'


Par contre, dans mon .h, je déclare quand même 2 fois chaque variable, une fois pour chaque fonction: les variables de fonctions sont-elles détruites à la fin de la fonction?

PS: le problème de reset intempestif venait d'un port USB défectueux... :*

SesechXP

Quelles variables as-tu essayé de mettre en static ? Les arguments de ta fonction ? Je pensais à celles déclarées dans ton sketch...

Par contre je crois comprendre que tu as des implémentations de fonctions dans animations.h !? Si oui c'est à proscrire : le fichier d'entête (*.h) constitue l'API de ta bibliothèque (prototypes de fonctions, etc) alors que le fichier source (*.c ou *.cpp) en contient l'implémentation.

++
Julien - www.idreammicro.com

schizophrene

Hello,

J'ai essayé de mettre les variables des fonctions en static, celles du sketch seront en volatile (utilisation d'une interruption).

Que veux-tu dire par implémentation de fonction?

Snootlab

#14
Sep 02, 2011, 11:01 am Last Edit: Sep 02, 2011, 11:02 am by Snootlab Reason: 1
Bonjour,

Ce qu'il veut dire c'est que dans ton .h tu mettras ça :

int lireAniSimple(int , int , int , int , int );

et dans ton .c tu mettras ceci :

int lireAniSimple(int Hanimation, int Hsortie, int Hplein, int Htempo, int Hi)
{
      //ta fonction
}


Bonne journée,

-----
Stéphane
- Distributeur officiel Arduino - France

Go Up