Go Down

Topic: Question sur INCLUDE (Read 1 time) previous topic - next topic

jmatgou

Bonjour à tous,

Mon fichier .pde commence à être bien rempli, j'ai déclarer plusieurs fonctions que j'utilise dans la partie "setup" et la parti "loop".
Afin de faire un peu de ménage et de rendre mon code plus propre et plus lisible, je souhaiterais faire un fichier de fonction pour ne laisser que le corps du programme dans le .pde
Je n'aurais plus qu'à "includer" ce fichier.

Mais je ne connais pas la syntaxe. Je ne cherche pas à faire une classe avec un .h et un .cpp, mais juste un fichier de fonction à coté de mon programme principale.

Je ne sais pas si c'est faisable.

Merci aux personnes qui pourront m'aider.
Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

Super_Cinci

Dans ton IDE, tu peux cliquer sur la flèche en haut tout à droite, puis "new tab". Tu mets un nom dans la case jaune qui apparaît en dessous, puis OK.

Cela aura pour effet de t'ouvrir un second fichier pde dans le même répertoire que ton pde principal.

Colles-y tout le code que tu veux "cacher", à la compilation, les deux fichiers seront regroupés.

Inconvénient : il se peut que le compilateur ne retrouve pas tous ses petits (surtout les variables globales), je ne sais pas dans quel ordre il met les fichiers pour compiler, mais ça peut aider à gagner en ménage... à tester

SesechXP

Salut,

Si tu ne veux pas créer de classe, tu peux néanmoins créer une bibliothèque. Pour ce faire, il te faut créer deux fichiers :

- le fichier d'entête, par exemple "MyLibrary.h" :
Code: [Select]

// Protection contre les inclusions multiples.
#ifndef h_MyLibrary_h
#define h_MyLibrary_h

// Prototype de ta fonction.
void MyLibrary__print();

#endif /* h_MyLibrary_h */


- le fichier source, par exemple "MyLibrary.cpp" :
Code: [Select]

#include "MyLibrary.h"

void MyLibrary__print()
{
    // Corps de la fonction.
}
Julien - www.idreammicro.com

skywodd

Bonjour,

Alors au choix :

Soit tu fait autant de .pde qu'il te faut (dans le même dossier), à la compilation il seront tous réunis en un seule "gros" .pde, attention les variables "globals" doivent être déclaré dans le .pde principal (celui portant le nom du dossier du sketch).
-> permet de faire des sous fonctions rélié matériellement au reste des .pde sans ce casser la tête, soit tu crée les .pde à la main sous tu ouvre un nouvel onglet avec la petite fléche sur la droite de l'ide et tu rentre lenomdetonpde.pde

Soit tu fait des .h et .cpp, les .cpp doivent ce trouvé IMPÉRATIVEMENT dans le même dossier que le sketch principal pour être compilé, il seront compilé séparément en .o, donc chaque cpp doit être indépendant au niveau des variables, fonctions, ... sinon au moment de la compilation il y aura une erreur de lien.
Pour utiliser un .cpp, il faut crée un .h contenant les prototypes des fonctions du .cpp car les .cpp ne sont pas "lu" par l'ide arduino pour générer automatique les prototypes, de plus pour utiliser des fonctions "arduino" dans un cpp il faut ajouter #include <WProgram.h>.
Pour éviter les conflits de déclaration de fonctions il faut aussi faire un "include guard" sur chaque .h comme ceci :
Code: [Select]
#ifndef nomdufichier_h
#define nomdufichier_h
// les prototypes de fonctions
#endif


D'un point de vu général,
- pour les inclusions de librairies "classique" :
Code: [Select]
#include <nomdelalibrairie.h> // bien noter l'utilisation de <>
- pour les inclusions de header (.h) local  :
Code: [Select]
#include "nomduheader.h" // bien noter l'utilisation de ""


Personnellement je te conseille de découper ton code en fonction puis de les placer dans des pde, l'ide arduino s'occupera du reste ;)
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

jmatgou

Bonjour et merci à tous.
J'ai opté pour la solution de Super_Cinci qui m'a parut plus simple dans l'immédiat et qui fonctionne très bien (pas de problème de variable globale)

Je pense tout de même que plus tard je me ferais une librairie de fonction bien propre avec un .h et un .cpp (solution plus portable)

Merci encore !
Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

68tjs

A chaque onglet correspond un fichier.
Le premier onglet sera toujours celui que tu as créé au départ du projet il ne pose pas de problème.
Pour les onglets suivants l'IDE les range automatiquement dans l'ordre alphabétique. Le compilateur les prends aussi dans l'ordre alphabétique.

Si tu crée un onglet pour "setup" et un autre "avance"  "avance" sera pris en charge avant "setup" et tu auras des erreurs de compilation.

La seule solution que j'ai trouvé pour imposer l'ordre, que je veux, avec les nom d'onglets, que je veux, c'est de préfacer les noms d'onglets avec une lettre, exemple :
a_setup   et b_avance

skywodd


A chaque onglet correspond un fichier.
Le premier onglet sera toujours celui que tu as créé au départ du projet il ne pose pas de problème.
Pour les onglets suivants l'IDE les range automatiquement dans l'ordre alphabétique. Le compilateur les prends aussi dans l'ordre alphabétique.

Si tu crée un onglet pour "setup" et un autre "avance"  "avance" sera pris en charge avant "setup" et tu auras des erreurs de compilation.

La seule solution que j'ai trouvé pour imposer l'ordre, que je veux, avec les nom d'onglets, que je veux, c'est de préfacer les noms d'onglets avec une lettre, exemple :
a_setup   et b_avance

C'est justement à cause de cette particularité qu'il faut mettre toute les variables global dans le pde principal, de même si vous voulez faire le test, il est impossible de déclarer une structure dans un pde puis de l'utiliser en tant que variable de retour (ou d'argument) d'une fonction d'un autre pde.
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

68tjs

Quote
C'est justement à cause de cette particularité qu'il faut mettre toute les variables global dans le pde principal

Pas obligé.
J'ai fais un essais avec le programme principal, c'est à dire le premier onglet, ne comportant que des commentaires et rien d'autre et ça marche.

Avec plusieurs onglets ce qui est impératif c'est de respecter le même ordre que celui qu'on aurait avec un seul onglet.
Dans un seul onglet on déclare les variables globales, les prototypes de fonction, ensuite on écrit la fonction setup et bien là c'est pareil.
onglet principal  : mon_prog.pde
premier onglet   :  a_var_glob   variables globales et prototypes de fonction
deuxieme ongle :  b_setup
3émme             :  c_fonction machin
4 ème               :  d_fonction truc
etc

En préfixant les noms d'onglets avec des lettres (les chiffres cela ne marche pas) on maîtrise totalement l'ordre à la compilation.

jmatgou

Merci pour cette précision concernant l'ordre des onglets.
Arduino Mega 2560 R2
Shield Ethernet + SD
Arduino 1.0

Super_Cinci

Je comprends mieux maintenant, pourquoi quand j'avais voulu découper un programme de 2000 lignes en onglets "LCD", "Keypad"... ben ça marche pas, car j'avais des variables globales pour le LCD, d'autres pour le keypad, etc, et je trouvais ça sympa de séparer les "pages".

Bon, je me rabattrai sur des librairies alors!

+1 pour le coup des lettres, fallait le savoir!

68tjs

Quote
+1 pour le coup des lettres, fallait le savoir!


Non ça a juste été "C'est pas moi qui céderais le premier" et c'est l'IDE qui a fini par céder.

Par contre j'ai essayé avec Code::Blocks ou Eclipse, avec des librairies qui ne font appel qu'à du  C pur c'est bon, mais avec celle qui font appel à du C++ c'est toujours les IDE qui gagnent pour le moment (pas moyen d'optimiser à la compilation : un Serial.begin() coûte 16 koctets !) et pourtant j'en ai lu des articles qui présentaient des optimisations qui devaient fonctionner.
Mais bon je ne suis pas un spécialiste j'ai pas du tout comprendre.

Super_Cinci


pas moyen d'optimiser à la compilation : un Serial.begin() coûte 16 koctets !) et pourtant j'en ai lu des articles qui présentaient des optimisations qui devaient fonctionner.
Mais bon je ne suis pas un spécialiste j'ai pas du tout comprendre.

16Ko??? moi j'ai trouvé 1372 (bare minimum + Serial.begin(9600)) - 450 (bare minimum vide) = 922 octets (461 instructions, mais c'est déjà bien trop)... rajouter à ça un buffer série bien souvent surdimensionné en RAM. (un Serial.print('N') me coûte 470 octets)

on démarre un port série en 3 ou 4 instructions sur les registres, suffit de se plonger dans le datasheet...

On a du taff en effet dans l'optimisation du code! (mais bon, c'est pas le sujet ici, pardon...)

Go Up