Variablendeklaration in Unterprogrammen

Hi,
ist wohl wieder eine Anfängerfrage, aber ich zähl mich immer noch dazu. :roll_eyes:

wenn ein Sketch aus mehreren Unterprogrammen (*.ino's) besteht, wie sieht es dann mit der Variablendeklaration aus?

Ich habs bisher nur geschafft, eine Variable in zwei Unterprogrammen zu verwenden, wenn ich diese im Hauptprogramm definiert habe.
Wenn ich eine Variable in einem Unterprogramm definiert habe, und diese dann in einem anderen Unterprogramm verwenden will, dann hat der Compiler immer gemault, daß er sie nicht kennt.
Mit Unterprogramm meine ich eine zweite *.ino, die mit dem rechten Pfeil als "neuer Tab" erzeugt werden kann.
Gibts da so was wie eine public oder private Deklaration?

Gruß/hk007

Hi,
ja wir Anfänger haben es nicht leicht. Aber wenn du eine Variable global definierst, kann diese von jeder Funktion genutzt werden.

int x = 0;

setup{}
loop
{
Serial.println(x);
extra_funktion();
Serial.println(x);
extra_funktion_klappe_die_zweite();
Serial.println(x);
}
void extra_funktion
{
x++;
}
void extra_funktion_klappe_die_zweite
{
x=2*x;
}

so kannst du die Variable in jeder Funktion anfassen.
mfg
Balli

Das ist richtig, mit Globalen variablen muss/sollte man allerdings aufpassen, schnell ist diese überschrieben ohne das du das wolltest da sie ja global ist und damit überall gültig ist.
Definierst du in Funktionen neue Variablen brauchst du dir keine Sorgen zu machen da sie nur in ihrem Gültigkeitsbereich gültig ist .

void machewas()
{ 
/* Das hier ist der Gültigkeitsbereich*/
}

Wenn du in Unterprogrammen eine variablen verwenden willst, di nicht global definiert sind musst du die entsprechend übergeben. Ließ dir mal das durch:

Prinzipiel läuft das so:

Hauptprogramm:
int x;
int y;
int z;
x =2;
y=x+3;

z = Unterprogramm(x, y);

int Unterprogramm(int a, int b):
int c
a=a+3;
c = a*b;
return c;

Bei der Deklaration deines Unterprogramms musst du also festlegen welche Werte es beim Aufruf erwartet. Diese sind dann Lokal deklariert und können verwendet werden. Beim Aufruf im Hauptprogramm übergibst du die entsprechenden Werte. Veränderungen im Unterprogramm haben dann keinen Einfluss auf die Variable im Hauptprogramm.

Das eine hat doch mit dem anderen nicht zu tun. Du sprichst von Subroutinen, hk007 von der Unterteilung des Programms in mehrere Dateien, die anschließend beim compilieren wieder zusammengefasst werden.

Das eine hat doch mit dem anderen nicht zu tun. Du sprichst von Subroutinen, hk007 von der Unterteilung des Programms in mehrere Dateien, die anschließend beim compilieren wieder zusammengefasst werden.

Genau, du hast es erfasst, was ich meine. Subroutinen, oder nennen wir es einfach Tabs? Glaub das trifft es am ehesten.

Mal ein Beispiel:
Mein Programm (und auch der erste Tab) heisst "Main". Dann erstelle ich noch 2 Tabs mit den Namen "Sub1" und "Sub2".
Wenn ich jetzt eine Variable in Main definiere, dann kann ich sie auch in Sub1 und Sub2 verwenden.
Wenn ich eine Variable in Sub1 definiere, dann kann ich sie in Sub2 nicht verwenden.
-->Fehlermeldung beim kompilieren: ... was not declared in this scope.
Wundert mich etwas, weil ich dachte, daß die Tabs beim compilieren in ein scope zusammengezogen werden.

gruß/hk007

Nein nein, es wird nur zu einer Datei zusammengefasst, der scope ist der Gültigkeitsbereich den ich angesprochen habe. Entweder die variable ist Global und somit überall gültig, oder du musst die explizit deklarieren.

Entweder die variable ist Global und somit überall gültig, oder du musst die explizit deklarieren.

Kann ich das so verstehen:
Global definiert ist die Variable, wenn sie in "Main" definiert wird?
Gibts dann auch ne Möglichkeit die Variable in einem der Subs so zu definieren, daß sie global ist?

Global ist eine Variable dann wenn die vor der setup() funktion deklariert wird.
Da die verschiedenen Tabs, also deine main und deine sub1 und sub2 ja eh zu einer Datei werden sollten globale variablen auch dort gültig sein.Variablen die du Global haben willst also vor die setup() funktion packen, und dann sollte das gehen.

OK,

aber die Frage ist jetzt, kann ich die Variable auch in einer der Subs global definieren?
Ich kann in den Subs keine void setup() verwenden, damit ich die Variable davor definieren kann. Das nimmt mir der Compiler krumm.

Ja richtig, es wird ja 1 Datei, und damit wäre void setup() ja doppelt vorhanden. Wenn du in deiner main deine variablen vor die setup() packst dann sind sie ja "überall Global", da es später 1 datei wird... für den compiler keinen unterschied ob es 1 tab ist oder 10 es wird zu einer Datei :wink:

Ja, das ist jetzt klar.
Aber ich finde es in meinem Fall etwas unübersichtlich alle Variablen in die Main zu werfen.
Da dachte ich, daß ich die Variable in einer Sub definiere, wo sie logisch dazu gehört.
Wenn das nicht geht, dann muss halt alles in die Main vor void setup()

Ich verstehe genau was Du meinst. Das nützt Dir aber nichts da ich es jetzt auch nicht weiß. :slight_smile:
Was ich aber weiß ist das ich auch Variablen in einem zweiten Tab deklariere ausserhalb von Funktionen.
Allerdings nutze ich diese dann auch nur in diesem Tab.

Ps: Habs gerade mal ausprobiert. Scheint aber zu gehen. Wenn du die Variablen im zweiten Tab ausserhalb einer Funktion deklarierst scheint sie global zu sein.
Darf halt nicht in einer Funktion passieren.

Wenn du die Variablen im zweiten Tab ausserhalb einer Funktion deklarierst scheint sie global zu sein.

ja, kann ich jetzt nach einigen Versuchen und auch mit der Hilfe von Shufty bestätigen.
Allerdings muss man da etwas aufpassen.
Die Neben-Tabs werden in der IDE in alphabetischer Reihenfolge angezeigt. Und so werden sie auch beim compilieren abgearbeitet.
Also muss der Tab, in dem die Variable definiert wird, alphabetisch vor den Tabs stehen, in denen die Variable verwendet wird.
Und wie MueThoS geschrieben hat, muss die Variable in dem Nebentab vor der Funktion definiert werden.

Hallo, das Thema ist zwar schon etwas älter, aber ich habe das gleiche Problem.
Ich wollte alle meine globalen Variablen in einem Tab ablegen, weil ich das übersichtlicher finde.
Leider haben alle vorangegangenen Tipps nicht geholfen.
Ich habe als test das Blink.ino - Beispiel genommen und die Deklaration int led = 13; in einen neuen Tab AA_Globale_Variablen.ino verschoben und der Compiler meckert, dass er led jetzt nicht mehr kennt.
Kann das jemand nachvollziehen, bzw. kennt jemand Abhilfe für dieses Problem?
Achso, Arduino IDE: 1.0.5
Danke
Sascha

hk007:
Da dachte ich, daß ich die Variable in einer Sub definiere, wo sie logisch dazu gehört.

Das funktioniert aber leider nicht, weil die "globale Variable" die einem Sub-Tab definiert ist eben auch in allen nachfolgenden gilt

hk007:
Aber ich finde es in meinem Fall etwas unübersichtlich alle Variablen in die Main zu werfen.

Ich mache es inzischem bei umfangreicheren Projekten so:
der erste Tab (der ja auch immer so heißt wie das Projekt) enthält aussschliesslich alle globale Definitionen.
Hat den Vorteil, dass man auch weiß, wo man suchen muß.
der zweite Tab enthält setup() und loop(), die folgenden dann Funktionen.
Zwischenablage01.jpg

Ein weiterer "Trick" ist

[b]extern[/b] int x;  // ist in Tab2 definiert, und soll hier verwendet werden

Man sollte allerdings aufpassen, dass man sich das Leben nicht selber schwer macht.
Der Grundsatz, alle Globalen Vairiablen im "Haupt-ino" zu definieren, hat den Vorteil, dass man sie auch als Mensch findet, nicht nur der Compiler, der darin von der Arduino - IDE unterstützt wird.

Variable als Parameter zu übergeben (statt zig Globale Variable zu verwenden) ist auch ein guter Ansatz, um nicht den Überblick zu verlieren.

Arduino C++ kennt auch Klassen ...