Forum: Mikrocontroller und Digitale Elektronik Arduino: Wo Variable deklarieren und initalisieren?


von neuling (Gast)


Lesenswert?

hallo Leute,

//////////////////////////////////////////////////////////////////////
void setup() {
  pinMode(10,OUTPUT);
  pinMode(12,INPUT);

}

void loop() {

    int anzahl=0;

    anzahl++;
}

//////////////////////////////////////////////////////////////////////

mein Problem: Bei obigem Code geht das Programm jedes mal wieder in die 
loop und setzt Anzahl immer wieder auf 0. Ich möchte anzahl aber immer 
weiter hochzählen lasse, wo muss ich die Variable dann aber deklarieren 
und initalisieren?

Bei setup habe ich es mal versucht, hat aber nicht geklappt. Dort werden 
also nur die Ports definiert?

von Wolfgang (Gast)


Lesenswert?

neuling schrieb:
> Ich möchte anzahl aber immer
> weiter hochzählen lasse, wo muss ich die Variable dann aber deklarieren
> und initalisieren?

Versuchs mal mit static

von Ulrich F. (Gast)


Lesenswert?

Wolfgang schrieb:
> Versuchs mal mit static
Dann doch lieber global.
Oder?

neuling schrieb:
> Bei obigem Code geht das Programm jedes mal wieder in die
> loop
Ja, das tut es, darum heißt es auch loop.

neuling schrieb:
> Dort werden
> also nur die Ports definiert?
Da kann man noch viel mehr tun.
Aber im Gültigkeitsbereich von setup() definierte Variablen sind in 
loop() unsichtbar. Das hast du richtig erkannt.

von Frickelfritze (Gast)


Lesenswert?

neuling schrieb:
> wo muss ich die Variable dann aber *deklarieren*

Oberhalb von setup()

neuling schrieb:
> wo muss ich die Variable dann aber .... und initalisieren?

In setup()

von Wolfgang (Gast)


Lesenswert?

Frickelfritze schrieb:
> Oberhalb von setup()

Und was soll eine globale Variable, wenn sie (bisher) nur lokal in 
loop() verwendet wird?

So wie das Programm aussieht, wird der Compiler die Variable aber 
sowieso weg optimieren.

von neuling (Gast)


Lesenswert?

ich habe sie jetzt global verwendet, also über setup:

int anzahl=0;

und das funktioniert.

Wolfgang schrieb:
> Und was soll eine globale Variable, wenn sie (bisher) nur lokal in
> loop() verwendet wird?
>
> So wie das Programm aussieht, wird der Compiler die Variable aber
> sowieso weg optimieren.

Warum hältst du nichts von dieser Methode?

Und wenn ihr schon so freundlich seid, hätte ich direkt noch eine Frage 
zum seriellen Monitor:

/////////////////////////////////////////////////////////
if(Serial.available()>0){
  Serial.println(anzahl,DEC);
    }
/////////////////////////////////////////////////////////

Diesen Code habe ich so gefunden, um den seriellen Monitor zu benutzen, 
allerdings muss ich immer zuerst irgendein Zeichen eingeben, damit mir 
was angezeigt wird. Wie kann ich das beheben?

Und was sagt mir if(Serial.available()>0) ???

von Wolfgang (Gast)


Lesenswert?

neuling schrieb:
> Warum hältst du nichts von dieser Methode?

Weil die Variable anscheinend nur lokal in loop() benötigt wird (oder 
auch nicht) und dann jegliche weitere Sichtbarkeit eine möglichst engen 
Kapselung widerspricht.

von Frickelfritze (Gast)


Lesenswert?

neuling schrieb:
> Und was sagt mir if(Serial.available()>0) ???

Verwende beim Posten von Code-Schnipseln die Deklaration
von C-Code wie es beim den Hinweisen angegeben ist.

(--> Formatierung (mehr Informationen...)

von Michael U. (amiga)


Lesenswert?

Hallo,

if(Serial.available()>0) schaut nach, ob Zeichen an der seriellen 
Schnittstelle angekommen sind.
Wenn ja ist die Bedingung erfüllt und Du gibst 
mitSerial.println(anzahl,DEC); was aus.
Wenn nicht, dann passiert eben nichts und es wird weiter gewartet.

Du solltest Dir noch ein paar Graundlagen anlesen, auch beim Arduino.
Wenn Du was über die serielle senden willst dann eben nur mit 
Serial.println(anzahl,DEC); ausgeben.

Gruß aus Berlin
Michael

von Frickelfritze (Gast)


Lesenswert?

neuling schrieb:
> Und was sagt mir if(Serial.available()>0) ???

Sagt dir das magische Wort google etwas?
Und die Hilfe Funktion der Arduino Site?

https://www.arduino.cc/en/Serial/Available

von neuling (Gast)


Lesenswert?

ok. Habe dort aber auch keine Erklärung dafür gefunden, dass ich immer 
zuerst ein Zeichen eingeben muss, beziehungsweise wie das automatisch 
geht

von Wolfgang (Gast)


Lesenswert?

neuling schrieb:
> ok. Habe dort aber auch keine Erklärung dafür gefunden, dass ich immer
> zuerst ein Zeichen eingeben muss, beziehungsweise wie das automatisch
> geht

Dazu zwingt dich auch keiner und du musst es nicht. Aber wenn du es 
trotzdem tust, wird daraufhin der aktuelle Wert von Anzahl in 
Dezimaldarstellung ausgegeben.

von Ulrich F. (Gast)


Lesenswert?

Wolfgang schrieb:
> Und was soll eine globale Variable, wenn sie (bisher) nur lokal in
> loop() verwendet wird?
Bisher...

Wolfgang schrieb:
> und dann jegliche weitere Sichtbarkeit eine möglichst engen
> Kapselung widerspricht.
Arduino... C++
Wenn kapseln, dann ordentlich in einem Objekt.
Ok, für eine einfache Zählvariable ist das vielleicht arg übertrieben...


Aber grundsätzlich gilt:
Globale Variablen/Dinge sind böse.
Statische Variablen in Funktionen sind böse.
Goto ist böse.
Und das was sonst noch alles böse ist.....

In der Realität wird man sich nach der Decke strecken müssen, und auch 
die schwarze Seite der Macht akzeptieren dürfen.


Und wenn ich schon zwischen Strick und Kugel unterscheiden muss:
Mir persönlich sind meist globale Variablen sympathischer, als lokale 
statische.

von chris_ (Gast)


Lesenswert?

>Statische Variablen in Funktionen sind böse.

Wieso dieses?

von Ulrich F. (Gast)


Lesenswert?

chris_ schrieb:
>>Statische Variablen in Funktionen sind böse.
>
> Wieso dieses?
Es entspricht dem "Prinzip der geringsten Verwunderung", wenn sich 
Funktionen bei jedem Aufruf gleich/reproduzierbar verhalten. Das tun sie 
nicht mehr, wenn sie auf globale oder lokale statische Variablen 
zurückgreifen.

Den unbeabsichtigten Seiteneffekten wird damit u.U. Tür und Tor 
geöffnet.

von avr (Gast)


Lesenswert?

Ulrich F. schrieb:
> Es entspricht dem "Prinzip der geringsten Verwunderung", wenn sich
> Funktionen bei jedem Aufruf gleich/reproduzierbar verhalten. Das tun sie
> nicht mehr, wenn sie auf globale oder lokale statische Variablen
> zurückgreifen.
>
> Den unbeabsichtigten Seiteneffekten wird damit u.U. Tür und Tor
> geöffnet.

Das hat nichts mit Seiteneffekten zu tun. Variablen, welche nur in einer 
Funktion benutzt werden, gehören auch in dieser deklariert. Nur weil das 
nicht der OOP-Ansatz ist, ist es deswegen nicht schlecht! C++ ist eine 
Multiparadigma-Sprache und wenn man mit C++ programmiert, heißt das 
nicht, dass man OO programmieren muss (wie beispielsweise in Java).

Im Übrigen ist es egal wie du es umschreibst. Am Ende wird es immer eine 
Funktion loop geben, die entweder auf statische, globale oder 
Klassenvariablen zugreift.

von Ulrich F. (Gast)


Lesenswert?

Dann mache ich mal den Priester für dich ...

Unbekannt schrieb:
> Wer einmal verstanden hat, wie ein Hammer
> funktioniert, für den sieht die ganze Welt
> plötzlich wie ein Nagel aus.

Eine ordentliche echte, schöne, Funktion hat Parameter. Von mir aus auch 
in Form von Zeigern oder Referenzen. Und sie hat einen Rückgabewert.
So ist schön....
So ist gut zu debuggen und fein wiederverwendbar.

Und was davon abweicht, ist nicht so schön, z.B. die Verwendung von 
globalen und statischen Variablen.

von avr (Gast)


Lesenswert?

Verstehst du es nicht oder willst du es nicht verstehen?

Du kannst das Arduino Grundgerüst nicht ändern. Mach doch selbst mal 
einen Vorschlag für Variablen in der loop Funktion.

Ulrich F. schrieb:
> Eine ordentliche echte, schöne, Funktion hat Parameter. Von mir aus auch
> in Form von Zeigern oder Referenzen. Und sie hat einen Rückgabewert.
> So ist schön....

Warum sollte sie Parameter und Rückgabewerte haben? bei Get und Set 
Funktionen ist oft nur eins von beiden sinnvoll.

> So ist gut zu debuggen und fein wiederverwendbar.

ja, allerdings steht in der loop Funktion das Programm. Das 
wiederzuverwenden ist nicht sinnvoll.

> Und was davon abweicht, ist nicht so schön, z.B. die Verwendung von
> globalen und statischen Variablen.

Das geht halt nicht immer. Findest du Interrupts unschön?

Du kannst sagen dass die Arduino-Software-Architektur schrott ist. Aber 
was ich nicht hören kann ist, dass statische Variablen grundsätzlich 
böse sind. Es gibt eben Funktionen die sind statisch und man kann sie 
auch nicht objektorientiert machen (Wenn dir das nicht passt, solltest 
du Java programmieren). Und genau dann ist static die richtige Lösung. 
Beispiele dafür sind main und Interrupts, sowie die Arduino Funktion 
loop. Genauso gibt es für goto Einsatzzwecke (z.B. als Abbruch bei 
verschachtelten Schleifen - alles andere ist mMn unübersichtlich).

von Ulrich F. (Gast)


Lesenswert?

avr schrieb:
> Verstehst du es nicht oder willst du es nicht verstehen?
Eine Tüte "Lesen und verstehen" würde dir auch gut zu Gesichte stehen...
Fange doch nochmal von vorne an...

Wenn du nicht  willst, brauchst du mir ja nicht zu glauben...
Aber allen anderen kann ich nur den Rat geben, den Einsatz von globalen 
und statischen Dingen zu minimieren.

avr schrieb:
> Das geht halt nicht immer.
Da!
Jetzt hat er doch was gemerkt!
Jetzt sagt er "immer"!
Das kleine "immer", oder das große "immer"?
Oder gar das schwachsinnige "immer", das fehlgeleitete?

Tut mir leid das jetzt sagen zu müssen, aber wer "immer und "nie" ins 
Spiel bringt, hat meist sowieso schon verloren. Ende der Argumente 
erreicht. Auch wenn es noch nicht in der Großhirnrinde angekommen ist.

avr schrieb:
> Mach doch selbst mal
> einen Vorschlag für Variablen in der loop Funktion.
Vergessen, was ich vorher geschrieben habe, bevor du den "static" 
Prieser raus hängen lassen musstest?
Ich wiederhole es gerne nochmal:
Ulrich F. schrieb:
> Und wenn ich schon zwischen Strick und Kugel unterscheiden muss:
> Mir persönlich sind meist globale Variablen sympathischer, als lokale
> statische.

avr schrieb:
> Genauso gibt es für goto Einsatzzwecke (z.B. als Abbruch bei
> verschachtelten Schleifen
Auch hier agitierst du so, als hätte ich "nie" gesagt. Warum?
Sind meine Texte zu schwer zu verstehen?
Oder stehst du einfach nur auf krawall?
Erstmal die Wiederholung, denn hochscrollen und dann zu lesen scheint ja 
zu viel für dich zu sein...
Ulrich F. schrieb:
> In der Realität wird man sich nach der Decke strecken müssen, und auch
> die schwarze Seite der Macht akzeptieren dürfen.

Ich übersetze es dir mal:
Jede vermiedene statische Variable ist eine gute Variable.
Jede vermiedene globale Variable ist eine gute Variable.
Jedes vermiedenes Goto ist eine gutes Goto.

Und ich finde, wenn man eins der bösen 3 einsetzt, sollte man sich 
darüber klar sein, dass man da einen Kompromiss (mit dem Teufel) 
eingegangen ist. Die 3 als die ultimativen Heilsbringer verkaufen zu 
wollen ist irgendwie absurd, aus meiner Sicht.
OK, ich sehe ja ein, dass meine Ansichten bei jemandem der diese Dinge 
inflationär einsetzt, sauer aufstoßen. Denn es ist ja weitverbreitete 
Praxis, ja, vollkommen menschlich, dass man sich den Mist den man 
tagtäglich baut schön redet.


Und jetzt, mein Sohn, ist das Spielchen hier (für mich) zu Ende.
2 Priester, 2 unterschiedliche Religionen, aber der gleiche Gott.
Da passiert nicht mehr viel..... außer Fronten verhärten...
Sinnfrei...

von avr (Gast)


Lesenswert?

Ulrich F. schrieb:
> Ich wiederhole es gerne nochmal:
> Ulrich F. schrieb:
>> Und wenn ich schon zwischen Strick und Kugel unterscheiden muss:
>> Mir persönlich sind meist globale Variablen sympathischer, als lokale
>> statische.

Und genau das ist der Punkt der mich stört. Nach deinem "Prinzip der 
geringsten Verwunderung" gehört da eindeutig eine lokal statische 
Variable hin. Du rätst allerdings zu einer Globalen.

von chris_ (Gast)


Lesenswert?

Den Ausdruck "Prinzip der geringsten Verwunderung" finde ich sehr 
lustig. Ich werde diesen Ausdruck in meinen Wortschatz übernehmen ;-)

Aber zurück zu den statischen Variablen: Das "gotos" meistens böse sind, 
enverstanden. Die sind auch in den Misra Rules explizit untersagt.

Aber statische Variablen? So ein richtig stichhaltiges Argument scheint 
es mir da nicht zu geben.

von Ulrich F. (Gast)


Lesenswert?

Das einzige stichhaltige Argument, welches ich habe, ist:
Funktionen sollten sich immer gleich verhalten.



Mal ein Beispiel:
strtok() in jedem C/C++ Handbuch zu finden...
Das kann einem gemeine Fallen stellen, wenn man es an mehreren Orten in 
einem Programm verwendet. z.B. im Rahmen von Kooperativem Multitasking, 
in ISRs usw.

Und das ist das böse an statischen/globalen Variablen.

Vielleicht sollte man konsequent strtok_r() verwenden.....

von avr (Gast)


Lesenswert?

chris_ schrieb:
> Aber zurück zu den statischen Variablen: Das "gotos" meistens böse sind,
> enverstanden. Die sind auch in den Misra Rules explizit untersagt.

U.a. damit man verschachtelte Schleifen elegant abbrechen kann, ist goto 
ab Misra 2008 wieder erlaubt. Es soll vermieden werden, aber für Sprünge 
nach vorne ist es ok.

von avr (Gast)


Lesenswert?

Ulrich F. schrieb:
> Das einzige stichhaltige Argument, welches ich habe, ist:
> Funktionen sollten sich immer gleich verhalten.

Das wird aber mit globalen Variablen nicht besser. Das ist kein Argument 
gegen statische Variablen in Funktionen. Wenn man globale Variablen in 
Funktionen braucht und diese nur in der Funktion genutzt werden, gehören 
sie auch in die Funktion.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.