Come l'IDE organizza le cose
Per prima cosa, ecco come l'IDE organizza il tuo "schizzo":
- Il
.ino
file principale è lo stesso nome della cartella in cui si trova. Quindi, per foobar.ino
nella foobar
cartella - il file principale è foobar.ino.
- Tutti gli altri
.ino
file in quella cartella vengono concatenati insieme, in ordine alfabetico, alla fine del file principale (indipendentemente da dove si trova il file principale, in ordine alfabetico).
- Questo file concatenato diventa un
.cpp
file (ad es. foobar.cpp
) - viene inserito in una cartella di compilazione temporanea.
- Il preprocessore "utile" genera prototipi di funzioni per le funzioni che trova in quel file.
- Il file principale è sottoposto a scansione per le
#include <libraryname>
direttive. Questo innesca l'IDE per copiare anche tutti i file rilevanti da ciascuna libreria (menzionata) nella cartella temporanea e generare istruzioni per compilarli.
- Eventuali
.c
, .cpp
o .asm
file nella cartella bozza vengono aggiunti al processo di compilazione come unità di compilazione distinte (che è, sono compilati nel modo usuale come file separati)
- Tutti i
.h
file vengono anche copiati nella cartella di compilazione temporanea, quindi possono essere indicati dai file .c o .cpp.
- Il compilatore aggiunge ai file standard del processo di compilazione (come
main.cpp
)
- Il processo di compilazione quindi compila tutti i file sopra in file oggetto.
- Se la fase di compilazione ha esito positivo, vengono collegati tra loro con le librerie standard AVR (ad es. Dandoti
strcpy
ecc.)
Un effetto collaterale di tutto ciò è che puoi considerare lo schizzo principale (i file .ino) come C ++ a tutti gli effetti. La generazione del prototipo di funzione, tuttavia, può portare a oscuri messaggi di errore se non si presta attenzione.
Evitare le stranezze del pre-processore
Il modo più semplice per evitare queste idiosincrasie è lasciare vuoto lo schizzo principale (e non utilizzare altri .ino
file). Quindi crea un'altra scheda (un .cpp
file) e inserisci le tue cose in questo modo:
#include <Arduino.h>
// put your sketch here ...
void setup ()
{
} // end of setup
void loop ()
{
} // end of loop
Si noti che è necessario includere Arduino.h
. L'IDE lo fa automaticamente per lo schizzo principale, ma per altre unità di compilazione, devi farlo. Altrimenti non conoscerà cose come String, i registri hardware, ecc.
Evitare il paradigma di installazione / principale
Non devi correre con il concetto di setup / loop. Ad esempio, il tuo file .cpp può essere:
#include <Arduino.h>
int main ()
{
init (); // initialize timers
Serial.begin (115200);
Serial.println ("Hello, world");
Serial.flush (); // let serial printing finish
} // end of main
Forza l'inclusione della libreria
Se si esegue con il concetto di "schizzo vuoto" è comunque necessario includere le librerie utilizzate altrove nel progetto, ad esempio nel .ino
file principale :
#include <Wire.h>
#include <SPI.h>
#include <EEPROM.h>
Questo perché l'IDE esegue la scansione del file principale solo per l'utilizzo della libreria. In effetti è possibile considerare il file principale come un file di "progetto" che nomina quali librerie esterne sono in uso.
Problemi di denominazione
Non nominare il tuo schizzo principale "main.cpp" - l'IDE include il proprio main.cpp, quindi avrai un duplicato se lo fai.
Non nominare il tuo file .cpp con lo stesso nome del tuo file .ino principale. Poiché il file .ino diventa effettivamente un file .cpp, anche questo ti darebbe uno scontro di nomi.
Dichiarare una classe in stile C ++ nello stesso singolo file .ino (ne hai sentito parlare, ma non l'hai mai visto funzionare - è persino possibile?);
Sì, questo viene compilato OK:
class foo {
public:
};
foo bar;
void setup () { }
void loop () { }
Tuttavia, probabilmente è meglio seguire la normale pratica: inserire le dichiarazioni in .h
file e le definizioni (implementazioni) in .cpp
(o .c
) file.
Perché "probabilmente"?
Come mostra il mio esempio, puoi mettere tutto in un unico file. Per progetti più grandi è meglio essere più organizzati. Alla fine si sale sul palco in un progetto di medie e grandi dimensioni in cui si desidera separare le cose in "scatole nere", ovvero una classe che fa una cosa, la fa bene, viene testata ed è indipendente ( per quanto possibile).
Se questa classe viene quindi utilizzata in più altri file nel progetto, è qui .h
che .cpp
entrano in gioco i file separati e i file.
Il .h
file dichiara la classe, ovvero fornisce dettagli sufficienti per consentire ad altri file di sapere cosa fa, quali funzioni ha e come vengono chiamati.
Il .cpp
file definisce (implementa) la classe, ovvero fornisce effettivamente le funzioni e i membri statici della classe che fanno sì che la classe faccia il suo lavoro. Dal momento che si desidera implementarlo solo una volta, questo è in un file separato.
Il .h
file è ciò che viene incluso in altri file. Il .cpp
file viene compilato una volta dall'IDE per implementare le funzioni di classe.
biblioteche
Se segui questo paradigma, allora sei pronto a spostare l'intera classe (i file .h
e .cpp
) in una libreria molto facilmente. Quindi può essere condiviso tra più progetti. Tutto ciò che serve è creare una cartella (ad es. myLibrary
) E inserire i file .h
e .cpp
(ad es. myLibrary.h
E myLibrary.cpp
) e quindi inserire questa cartella nella libraries
cartella nella cartella in cui sono conservati gli schizzi (la cartella dello sketchbook).
Riavvia l'IDE e ora conosce questa libreria. Questo è davvero banalmente semplice e ora puoi condividere questa libreria su più progetti. Lo faccio molto.
Un po 'più di dettagli qui .