Wie die IDE die Dinge organisiert
Das erste ist, wie die IDE Ihre "Skizze" organisiert:
- Die
.ino
Hauptdatei ist diejenige , mit dem gleichen Namen wie der Ordner ist es in. Also, für foobar.ino
infoobar
Ordner - die Hauptdatei foobar.ino ist.
- Jede andere
.ino
Dateien in diesem Ordner werden am Ende der Hauptdatei in alphabetischer Reihenfolge miteinander verknüpft (unabhängig davon, wo sich die Hauptdatei in alphabetischer Reihenfolge befindet).
- Diese verkettete Datei wird zu einer
.cpp
Datei (zB foobar.cpp
) - sie wird in einem temporären Zusammenstellungsordner abgelegt.
- Der Präprozessor generiert "hilfreich" Funktionsprototypen für Funktionen, die er in dieser Datei findet.
- Die Hauptdatei wird gesucht
#include <libraryname>
Direktiven . Dadurch kopiert die IDE auch alle relevanten Dateien aus jeder (genannten) Bibliothek in den temporären Ordner und generiert Anweisungen zum Kompilieren.
- Beliebig
.c
, .cpp
oder.asm
Dateien in der Skizze Ordnern hinzugefügt werden, um den Build - Prozess als separate Kompilierungseinheiten (das heißt, sie werden in der üblichen Art und Weise zusammengestellt als separate Dateien)
- Irgendein
.h
Dateien werden auch in den temporären Kompilierungsordner kopiert, sodass Ihre C- oder CPP-Dateien auf sie verweisen können.
- Der Compiler fügt dem Buildprozess Standarddateien hinzu (like
main.cpp
)
- Der Erstellungsprozess kompiliert dann alle oben genannten Dateien in Objektdateien.
- Wenn die Kompilierungsphase erfolgreich ist, werden sie zusammen mit den AVR-Standardbibliotheken verknüpft (z. B. geben Sie
strcpy
usw.).
Ein Nebeneffekt all dessen ist, dass Sie die Hauptskizze (die .ino-Dateien) in jeder Hinsicht als C ++ betrachten können. Die Generierung von Funktionsprototypen kann jedoch zu undurchsichtigen Fehlermeldungen führen, wenn Sie nicht vorsichtig sind.
Vermeiden Sie die Macken des Vorprozessors
Die einfachste Möglichkeit, diese Eigenheiten zu vermeiden, besteht darin, die Hauptskizze leer zu lassen (und keine anderen .ino
Dateien zu verwenden). Dann mache einen weiteren Tab (eine .cpp
Datei) und füge deine Sachen so ein:
#include <Arduino.h>
// put your sketch here ...
void setup ()
{
} // end of setup
void loop ()
{
} // end of loop
Beachten Sie, dass Sie einschließen müssen Arduino.h
. Die IDE macht das automatisch für die Hauptskizze, aber für andere Kompilierungseinheiten müssen Sie es tun. Andernfalls werden Dinge wie String, die Hardware-Register usw. nicht bekannt.
Vermeidung des Setup- / Hauptparadigmas
Sie müssen nicht mit dem Setup / Loop-Konzept arbeiten. Beispielsweise kann Ihre CPP-Datei sein:
#include <Arduino.h>
int main ()
{
init (); // initialize timers
Serial.begin (115200);
Serial.println ("Hello, world");
Serial.flush (); // let serial printing finish
} // end of main
Bibliothekseinschluss erzwingen
Wenn Sie mit dem Konzept "Leere Skizze" arbeiten, müssen Sie die an anderer Stelle im Projekt verwendeten Bibliotheken einbeziehen, beispielsweise in Ihre Hauptdatei .ino
:
#include <Wire.h>
#include <SPI.h>
#include <EEPROM.h>
Dies liegt daran, dass die IDE nur die Hauptdatei auf Bibliotheksnutzung überprüft. Tatsächlich können Sie die Hauptdatei als "Projekt" -Datei betrachten, die angibt, welche externen Bibliotheken verwendet werden.
Probleme beim Benennen
Nennen Sie Ihre Hauptskizze nicht "main.cpp" - die IDE enthält ihre eigene main.cpp, sodass Sie in diesem Fall ein Duplikat erhalten.
Benennen Sie Ihre CPP-Datei nicht mit demselben Namen wie Ihre Haupt-INO-Datei. Da die .ino-Datei effektiv zu einer .cpp-Datei wird, erhalten Sie auch einen Namenskonflikt.
Deklarieren einer Klasse im C ++ - Stil in derselben einzelnen .ino-Datei (habe von funktionierenden Klassen gehört, diese aber noch nie gesehen - ist das überhaupt möglich?);
Ja, dies wird in Ordnung kompiliert:
class foo {
public:
};
foo bar;
void setup () { }
void loop () { }
Es ist jedoch wahrscheinlich am besten, wenn Sie der normalen Praxis folgen: Schreiben Sie Ihre Deklarationen in .h
Dateien und Ihre Definitionen (Implementierungen) in .cpp
(oder .c
) Dateien.
Warum "wahrscheinlich"?
Wie mein Beispiel zeigt, können Sie alles in einer Datei zusammenfassen. Für größere Projekte ist es besser, organisierter zu sein. Schließlich kommen Sie in einem mittleren bis großen Projekt auf die Bühne, in dem Sie Dinge in "Black Boxes" aufteilen möchten - eine Klasse, die eines tut, es gut macht, getestet wird und in sich geschlossen ist ( so weit wie möglich).
Wenn diese Klasse dann in mehreren anderen Dateien in Ihrem Projekt verwendet wird, kommen hier die separaten .h
und .cpp
Dateien ins Spiel.
Die .h
Datei deklariert die Klasse - das heißt, sie enthält genügend Details, damit andere Dateien wissen, was sie tut, welche Funktionen sie hat und wie sie aufgerufen werden.
Die .cpp
Datei definiert (implementiert) die Klasse - das heißt, sie stellt tatsächlich die Funktionen und statischen Klassenmitglieder bereit, die die Klasse dazu bringen, ihre Sache zu tun. Da Sie es nur einmal implementieren möchten, befindet es sich in einer separaten Datei.
Die .h
Datei ist das, was in anderen Dateien enthalten ist. Die .cpp
Datei wird einmal von der IDE kompiliert, um die Klassenfunktionen zu implementieren.
Bibliotheken
Wenn Sie diesem Paradigma folgen, können Sie die gesamte Klasse (die .h
und .cpp
Dateien) ganz einfach in eine Bibliothek verschieben. Dann kann es zwischen mehreren Projekten geteilt werden. Alles , was erforderlich ist , um einen Ordner zu machen (z. B. myLibrary
) und die setzt .h
und .cpp
Dateien hinein (z. B. myLibrary.h
und myLibrary.cpp
) und stellen Sie diesen Ordner in Ihrem dann libraries
in dem Ordner Ordner , in dem Sie Ihre Skizzen (das Skizzenbuch Ordner) gehalten werden.
Starten Sie die IDE neu und sie kennt diese Bibliothek jetzt. Dies ist ganz einfach, und jetzt können Sie diese Bibliothek für mehrere Projekte freigeben. Ich mache das oft.
Ein bisschen mehr Details hier .