Pages: [1] 2   Go Down
Author Topic: Création de librairie & fonctions: problème pour trouver delay() [résolu]  (Read 2253 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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 smiley
« Last Edit: September 03, 2011, 01:13:48 pm by schizophrene » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

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

++
Logged


Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: August 28, 2011, 01:02:22 pm by schizophrene » Logged

Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
#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.
« Last Edit: August 28, 2011, 01:12:23 pm by schizophrene » Logged

Made in Belgium
Offline Offline
God Member
*****
Karma: 1
Posts: 756
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

essaie plutôt ?

Code:
#include "WProgram.h"
Logged


Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley

En attendant, je suis toujours ouvert à toute suggestion.
« Last Edit: August 29, 2011, 11:20:40 am by schizophrene » Logged

Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
#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 smiley-kiss
« Last Edit: August 29, 2011, 01:09:51 pm by schizophrene » Logged

Forum Moderator
Toulouse / France
Offline Offline
Full Member
*****
Karma: 5
Posts: 241
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

- Distributeur officiel Arduino - France

Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley

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 smiley-kiss ).

Voilà tout, merci encore.
Logged

Forum Moderator
Toulouse / France
Offline Offline
Full Member
*****
Karma: 5
Posts: 241
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

- Distributeur officiel Arduino - France

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
void loop(){
    static int i = 0;
    // ...
}

++
Logged


Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
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... smiley-kiss
« Last Edit: September 01, 2011, 12:35:15 pm by schizophrene » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

++
Logged


Offline Offline
Sr. Member
****
Karma: 2
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Forum Moderator
Toulouse / France
Offline Offline
Full Member
*****
Karma: 5
Posts: 241
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: September 02, 2011, 04:02:45 am by Snootlab » Logged

- Distributeur officiel Arduino - France

Pages: [1] 2   Go Up
Jump to: