ich bin ein newbie in Arduino - Programmierung und habe im Moment ein Problem was sich durch Googlen nicht lösen läßt. Also wäre die Erste Frage - geht das eigentlich was ich vorhabe?
Was ich vor habe:
Zu Übersichtlichkeit möchte ich mein Arduino Projekt in mehrere *.h + *.cpp Librarys packen. Auf dieser Seite gibts dazu auch ein tolles Beispiel. Jetzt würde ich gerne Variablen deklarieren, die in den verschiedenen *.cpp Unterprogrammen (public-class) verwendet werden können.
Welche IDE nutzt du? Mit der Arduino IDE kannst du neue Tabs anlegen. Diese erstellen im gleichen Ordner neue .h Dateien die automatisch mit eingebunden werden (kein #include <.h> nötig)
Wenn du GlobalVars in den einzelnen Tabs anlegst, sollten die für das ganze Programm gelten. Frage, ob du soviele GlobalVars überhaupt brauchst.
Mit dem "extern" Schlüsselwort. Damit sagst du dass die Variable irgendwo anders existiert, aber musst sie nicht initialisieren:
Eine andere Möglichkeit wäre einen Header zu erstellen wie "Constants.h" und diesen in den anderen Headern zu inkludieren. Eventuell include guards einbauen, wenn du Probleme mit Mehrfach-Inkludierungen bekommst. Manche Compiler unterstützen auch #pragma once. Die Arduino IDE meckert da nicht, aber ob er es wirklich korrekt umsetzt weiß ich nicht.
Ich habe mein Projekt in mehrere .ino Dateien aufgeteilt, statt Klassen und mache es so (der Header mit den Konstanten wird dann in der Hauptdatei als aller erstes inkludiert). Hat den Nachteil, dass diese alphabetisch zusammengefügt werden und man damit Teile nicht unbedingt überall sichtbar sind. Und die Zeilennummern stimmen nicht mehr, da die IDE das in eine cpp Datei packt. Aber man kommt zurecht ohne dass man gleich mit Klassen anfangen muss.
Es macht nur Sinn dein Projekt in Klassen zu zerlegen, wenn du die Klassen später in anderen Projekten weiterverwenden kannst. Wenn diese nur speziell für deine Anwendung existieren, dann macht eine Klasse kaum einen Sinn.
Das sind ja schon ne Menge Antworten. Also vielleicht sollte ich erstmal sagen was ich vor habe:
Ich habe ein Arduino 2560 mit Ethernet Shield + SD-Slot. Ich möchte eine mehrkanalige Zeitschaltuhr programmieren, die über HTML- Seiten im Netzwerk konfiguriert werden kann. Die HTML Seiten sind auf SD- Karte abgelegt. Ebenso soll sich eine Initialisierungsdatei auf der SD- Karte befinden, wo Netzwerkparameter abgelegt sind (ip, Port ...). Da ich kein Uhrzeitmodul habe wird die interne Uhr, aus dem Systemtakt, mit einem NTP- Server synchronisiert. Dank der Beispiele auf arduino.cc funktionieren die einzelnen Unterprogramme auch schon.
Aus meiner Sicht macht es Sinn verschiedene Unterprogramme zu erstellen die z.B. das Auslesen der SD- Karte, den WebServer oder die Uhrzeitberechnung und synchronisierung übernehmen.
@sschultewolter -> Ich benutze die Arduino Version 1.05. Wenn ich neue Tabs anlege, dann werden diese als *.ino angelegt (wenn ich nichts anderes angebe). Mit den verschiedenen *.ino funktioniert das so wie du es beschrieben hast.
@serenifly -> Wenn ich z.B. in einem Global.h eine Variable deklariere (nicht initialisiere), dann ist diese nur in der *.cpp sichtbar, wo diese Global.h includiert wurde. Includiere ich diese in mehreren *.cpp bekomme ich die Fehlermeldung der Mehrfachdeklarierung. Verstehe ich das mit dem Include vielleicht falsch? Deklaration als extern ändert daran nichts.
@jomelo -> Die Klassen würde ich dann gerne später für ähnliche Projekte verwenden. Gibts da andere Möglichkeiten?
Um Mehrfach-Inkludierungen zu verhindern, gibt es wie gesagt include guards:
Das Problem tritt auf wenn du in Klasse A einen Header inkludiertst, Klasse A dann in Klasse B inkludierst und versuchst den Header auch in B zu inkludieren.
Das #ifdef Präprozessor Makro ist der klassische Ansatz in C. Du kannst auch mal versuchen ob #pragma once im Header funktioniert.
#pragma once
sollte genausogut funktionieren, auch wenn bei arduino lieber mit
#ifndef GLOBAL_H
#define GLOBAL_H
// ... hier die eigentlichen Deklarationen
#endif
gewerkelt wird.
Wenn ich z.B. in einem Global.h eine Variable deklariere (nicht initialisiere), dann ist diese nur in der *.cpp sichtbar, wo diese Global.h includiert wurde. Includiere ich diese in mehreren *.cpp bekomme ich die Fehlermeldung der Mehrfachdeklarierung. .. Deklaration als extern ändert daran nichts.
Verstehe ich das mit dem Include vielleicht falsch?
Auch wenn du nicht mit Klassen arbeitest, steht in der include - Datei global.h nur die Deklaration
[b]extern[/b] int myGlobalVariable;
und in genau einer .cpp Datei ist dann Definition ( oder Initialisierung, wie du es nennst )
int myGlobalVariable;
Alle anderen .cpp Dateien die #include "global.h"
verwenden, können dann im Code auf myGlobalVariable zugreifen.
Wenn du dich nicht entscheiden kannst, welches die "Heimat" - .cpp deiner Variable ist, mach eine Extra Datei global.cpp
(oder nimm die Datei, in der sie geschrieben wird -- das ist meist nur eine --, oder die Datei die setup und loop enthält)
#include "global.h"
// hier werden alle globalen Variablen initialisiert
int myGlobalVariable;
Die Arduino IDE mit .ino Dateien pfuschelt etwas dazwischen, so als ob für alle globalen Variablen eine global.h mit extern Deklarationen angelegt würde und diese in allen aus den .ino erzeugten .cpp hinzugefügt würde.
Man könnte sich mal ansehen, was im temp Ordner an .cpp erzeugt wird...