Comment l'IDE organise les choses
Tout d'abord, voici comment l'IDE organise votre "sketch":
- Le
.ino
fichier principal est celui du même nom que le dossier dans lequel il se trouve. Donc, pour foobar.ino
dans le foobar
dossier - le fichier principal est foobar.ino.
- Tous les autres
.ino
fichiers de ce dossier sont concaténés ensemble, par ordre alphabétique, à la fin du fichier principal (indépendamment de l'endroit où se trouve le fichier principal, par ordre alphabétique).
- Ce fichier concaténé devient un
.cpp
fichier (par exemple. foobar.cpp
) - il est placé dans un dossier de compilation temporaire.
- Le préprocesseur génère "utilement" des prototypes de fonction pour les fonctions qu'il trouve dans ce fichier.
- Le fichier principal est analysé pour les
#include <libraryname>
directives. Cela déclenche l'IDE pour copier également tous les fichiers pertinents de chaque bibliothèque (mentionnée) dans le dossier temporaire et générer des instructions pour les compiler.
- Tous les
.c
, .cpp
ou les .asm
fichiers dans le dossier d' esquisse sont ajoutés au processus de construction d'unités de compilation séparée (qui est, ils sont compilés de la manière habituelle sous forme de fichiers séparés)
- Tous les
.h
fichiers sont également copiés dans le dossier de compilation temporaire, afin qu'ils puissent être référencés par vos fichiers .c ou .cpp.
- Le compilateur ajoute dans le processus de construction des fichiers standard (comme
main.cpp
)
- Le processus de génération compile ensuite tous les fichiers ci-dessus dans des fichiers objets.
- Si la phase de compilation réussit, ils sont liés entre eux avec les bibliothèques standard AVR (par exemple, vous donner,
strcpy
etc.)
Un effet secondaire de tout cela est que vous pouvez considérer l'esquisse principale (les fichiers .ino) comme C ++ à toutes fins utiles. La génération du prototype de fonction peut cependant conduire à des messages d'erreur obscurs si vous ne faites pas attention.
Éviter les bizarreries du pré-processeur
Le moyen le plus simple d'éviter ces idiosyncrasies est de laisser votre esquisse principale vierge (et de ne pas utiliser d'autres .ino
fichiers). Ensuite, créez un autre onglet (un .cpp
fichier) et mettez-y vos trucs comme ceci:
#include <Arduino.h>
// put your sketch here ...
void setup ()
{
} // end of setup
void loop ()
{
} // end of loop
Notez que vous devez inclure Arduino.h
. L'IDE le fait automatiquement pour l'esquisse principale, mais pour les autres unités de compilation, vous devez le faire. Sinon, il ne connaîtra pas des choses comme String, les registres matériels, etc.
Éviter le paradigme de configuration / principal
Vous n'avez pas à exécuter le concept de configuration / boucle. Par exemple, votre fichier .cpp peut être:
#include <Arduino.h>
int main ()
{
init (); // initialize timers
Serial.begin (115200);
Serial.println ("Hello, world");
Serial.flush (); // let serial printing finish
} // end of main
Forcer l'inclusion de bibliothèque
Si vous utilisez le concept de "croquis vide", vous devez toujours inclure les bibliothèques utilisées ailleurs dans le projet, par exemple dans votre .ino
fichier principal :
#include <Wire.h>
#include <SPI.h>
#include <EEPROM.h>
En effet, l'EDI analyse uniquement le fichier principal pour l'utilisation de la bibliothèque. En effet, vous pouvez considérer le fichier principal comme un fichier "projet" qui désigne les bibliothèques externes utilisées.
Problèmes de dénomination
Ne nommez pas votre croquis principal "main.cpp" - l'EDI inclut son propre main.cpp, vous en aurez donc un double si vous le faites.
Ne nommez pas votre fichier .cpp avec le même nom que votre fichier .ino principal. Étant donné que le fichier .ino devient effectivement un fichier .cpp, cela vous donnera également un conflit de noms.
Déclarer une classe de style C ++ dans le même fichier .ino unique (a entendu parler, mais n'a jamais vu de travail - est-ce même possible?);
Oui, cela compile OK:
class foo {
public:
};
foo bar;
void setup () { }
void loop () { }
Cependant, il est probablement préférable de suivre la pratique normale: Mettez vos déclarations dans des .h
fichiers et vos définitions (implémentations) dans des fichiers .cpp
(ou .c
).
Pourquoi "probablement"?
Comme mon exemple le montre, vous pouvez tout rassembler dans un seul fichier. Pour les grands projets, il vaut mieux être plus organisé. Finalement, vous arrivez sur scène dans un projet de taille moyenne à grande où vous voulez séparer les choses en "boîtes noires" - c'est-à-dire une classe qui fait une chose, le fait bien, est testée et est autonome ( le plus loin possible).
Si cette classe est ensuite utilisée dans plusieurs autres fichiers de votre projet, c'est là que les fichiers séparés .h
et .cpp
entrent en jeu.
Le .h
fichier déclare la classe - c'est-à-dire qu'il fournit suffisamment de détails pour que les autres fichiers sachent ce qu'il fait, quelles fonctions il a et comment ils sont appelés.
Le .cpp
fichier définit (implémente) la classe - c'est-à-dire qu'il fournit en fait les fonctions et les membres statiques de la classe qui font que la classe fait son travail. Comme vous ne voulez l'implémenter qu'une seule fois, cela se trouve dans un fichier séparé.
Le .h
fichier est ce qui est inclus dans les autres fichiers. Le .cpp
fichier est compilé une fois par l'IDE pour implémenter les fonctions de classe.
Bibliothèques
Si vous suivez ce paradigme, vous êtes prêt à déplacer très facilement toute la classe (les fichiers .h
et .cpp
) dans une bibliothèque. Il peut ensuite être partagé entre plusieurs projets. Tout ce qui est nécessaire est de créer un dossier (par exemple. myLibrary
) Et d'y placer les fichiers .h
et .cpp
(par exemple. myLibrary.h
Et myLibrary.cpp
), puis de placer ce dossier dans votre libraries
dossier dans le dossier où sont conservés vos croquis (le dossier du carnet de croquis).
Redémarrez l'IDE et il connaît maintenant cette bibliothèque. C'est vraiment très simple, et maintenant vous pouvez partager cette bibliothèque sur plusieurs projets. Je le fais beaucoup.
Un peu plus de détails ici .