Dynamischer Variablenname in Scheife hochzählen

Gast #5251751
Hallo zusammen,

ich würde gern meine Treppe beleuchte und jede Stufe einzeln ansteuern 
und je nachdem ob die Treppe von oben oder unten betreten wird, soll von 
unten nach oben oder oben nach unten die Beleuchtung verzögert an oder 
aus gehen.
Ohne Schleifen, läuft es schon. Es muss doch auch mit einer Schleife 
gehen.

Hier mal einen Ausschnitt aus dem Programm:

  // Variablendeklaration

int Melder_unten = 22;     // Input  Bewegungsmelder unten
int Melder_oben  = 23;     // Input  Bewegungsmelder oben
int LED1         = 24;     // Output RGB-Leiste Stufe  1
int LED2         = 25;     // Output RGB-Leiste Stufe  2
int LED3         = 26;     // Output RGB-Leiste Stufe  3
int LED4         = 27;     // Output RGB-Leiste Stufe  4
int LED5         = 28;     // Output RGB-Leiste Stufe  5
int LED6         = 29;     // Output RGB-Leiste Stufe  6
int LED7         = 30;     // Output RGB-Leiste Stufe  7
int LED8         = 31;     // Output RGB-Leiste Stufe  8
int LED9         = 32;     // Output RGB-Leiste Stufe  9
int LED10        = 33;     // Output RGB-Leiste Stufe 10
int LED11        = 34;     // Output RGB-Leiste Stufe 11
int LED12        = 35;     // Output RGB-Leiste Stufe 12
int LED13        = 36;     // Output RGB-Leiste Stufe 13
int LED14        = 37;     // Output RGB-Leiste Stufe 14
int LED15        = 38;     // Output RGB-Leiste Stufe 15

int LEDblau      = 3;      // Farbe blau an Pin 3
int LEDrot       = 5;      // Farbe rot an Pin 5
int LEDgruen     = 6;      // Farbe gruen an Pin 6
int brightness1a = 150;    // Zahlenwert zwischen 0 und 255 – gibt die 
Leuchtstärke der einzelnen Farbe an
int brightness1b = 150;    // Zahlenwert zwischen 0 und 255 – gibt die 
Leuchtstärke der einzelnen Farbe an
int brightness1c = 150;    // Zahlenwert zwischen 0 und 255 – gibt die 
Leuchtstärke der einzelnen Farbe an
int dunkel       = 0;      // Zahlenwert 0 bedeutet Spannung 0V – also 
LED aus
int VZ           = 250;    // Verzögung Ansteuerung der Stufen
int Dauer        = 60000;  // Leuchtdauer wenn alle Stufen angesteuert 
sind
int Sperrzeit    = 120000; // Sperrzeit bevor die Scheife beendet wird 
und die anderen Laufen kann

bool Sperrbit, LED00;      // Temporärevariable
int n;                     // Temporärevariable für Scheifenzähler

void setup()
{
  // Konfiguration

pinMode(Melder_unten,INPUT );
pinMode(Melder_oben, INPUT );
pinMode(LED1,       OUTPUT);
pinMode(LED2,       OUTPUT);
pinMode(LED3,       OUTPUT);
pinMode(LED4,       OUTPUT);
pinMode(LED5,       OUTPUT);
pinMode(LED6,       OUTPUT);
pinMode(LED7,       OUTPUT);
pinMode(LED8,       OUTPUT);
pinMode(LED9,       OUTPUT);
pinMode(LED10,       OUTPUT);
pinMode(LED11,       OUTPUT);
pinMode(LED12,       OUTPUT);
pinMode(LED13,       OUTPUT);
pinMode(LED14,       OUTPUT);
pinMode(LED15,       OUTPUT);

pinMode(LEDblau,     OUTPUT);
pinMode(LEDgruen,    OUTPUT);
pinMode(LEDrot,      OUTPUT);


}

void loop() // Hauptprogramm
{

   if (digitalRead(Melder_unten)==HIGH)
   {

   // Ansteuern der RGB LEDs
   analogWrite(LEDblau,  brightness1a); // blau einschalten
   analogWrite(LEDrot,   brightness1b); // rot einschalten
   analogWrite(LEDgruen, brightness1c); // gruen einschalten

   // Einschalten der Treppenbeleuchtung von unten nach oben mit je VZ 
ms Verzögerung von Stufe zu Stufe

***Das hier ist mein Problem**********
   for (int i=0; 15; i++)
    {
      digitalWrite(LED[i],HIGH); // LED
      delay(VZ);
    }

*****************+++

Vielen Dank für eure Hilfe.
Daniel
Gast #5251760
Daniel schrieb:
> ***Das hier ist mein Problem**********

WO ? zu erkennen dass Du von LED1=24 bis LED15=38 rauf bzw. runter 
zählen willst? Nimm einfach die Konstanten als Start- bzw. Endwert der 
Schleife (anstatt 0 und 15)

Micha
Gast #5251764
Ich versteh ehrlich gesagt das Problem nicht. Defniere doch alle LEDs 
als array. Die Reihenfolge kannst du einfach mit einem if(oben/unten ?) 
und einer vor-/rückwärts zählenden Schleife realisieren.
Gast #5251769
auron schrieb:
> Ich versteh ehrlich gesagt das Problem nicht. Defniere doch alle
> LEDs
> als array. Die Reihenfolge kannst du einfach mit einem if(oben/unten ?)
> und einer vor-/rückwärts zählenden Schleife realisieren.

Das stimmt. Das wäre der richtige und universell anwendbare Weg.
Hier in diesem Fall müßte er nur in der Schleife das i nicht von 0 bis 
15 laufen lassen, sondern von 24 bis 38 und dann

> digitalWrite(LED[i],HIGH);

ersetzen durch

> digitalWrite(i,HIGH);
Gast #5251775
Wie auch immer...
Alles ist besser, als Variablen durchzunummerieren!
Denn das ist (fast) IMMER eine dumme Idee.

> int LED1         = 24;
byte LED1         = 24;
Halbiert den RAM Verbrauch pro Pin

> byte LED1         = 24;
const byte LED1         = 24;
Senkt den RAM Verbrauch auf Null, pro Pin

npn schrieb:
> sondern von 24 bis 38
Kann einem auf die Füße fallen, wenn man dann doch irgendwelche 
Sonderfunktionen der Pins braucht, und damit die fortlaufende 
Nummerierung gestört wird.

Ich würde ja das Array im Flash bevorzugen...
Gast #5251798
Arduino F. schrieb:
> Kann einem auf die Füße fallen, wenn man dann doch irgendwelche
> Sonderfunktionen der Pins braucht, und damit die fortlaufende
> Nummerierung gestört wird.
>
> Ich würde ja das Array im Flash bevorzugen...

Klar, ich auch.
Deshalb schrieb ich bezüglich des Arrays:
npn schrieb:
> Das stimmt. Das wäre der richtige und universell anwendbare Weg.
#5269569
Hallo zusammen,

die Treppe ist nun mit den LEDs und der Steuerung ausgestattet.
Nur leider funktioniert es nun nicht mehr so wie in der Werkstatt?
Es läuft direkt nach dem zuschalten der Spannung einmal los und dann tut 
sich nichts mehr.
Nach dem neuladen des Arduino kann ich über den Bewegungsmelder die 
Beleuchtung einmal ansteuern und dann wenn sie wieder aus ist reagiert 
der Arduino nicht mehr. Könntet ihr euch mal das Programm ansehen ob ich 
doch einen fehler habe?

Besten Dank im vorraus.
1
#include <Adafruit_NeoPixel.h>
2
#ifdef __AVR__
3
#include <avr/power.h>
4
#endif
5
  
6
  //Variablendeklaration
7

8
int Melder_unten = 22;      // Input  Bewegungsmelder unten
9
int Melder_oben  = 23;      // Input  Bewegungsmelder oben
10
int Nanopixel    = 6;       // Output für NanoPixel LEDs
11
int VZ           = 15;      // Verzögung Ansteuerung der Stufen
12
int Dauer        = 30000;   // Leuchtdauer wenn alle Stufen angesteuert sind
13
int Sperrzeit    = 120000;  // Sperrzeit bevor die Scheife beendet wird und die anderen Laufen kann
14

15
#define NUMPIXELS      394  // Anzahl der Nanopixel-LEDs
16

17
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, Nanopixel, NEO_GRB + NEO_KHZ800);
18

19

20
void setup() 
21
{
22
  //Konfiguration 
23

24
pinMode(Melder_unten,INPUT );
25
pinMode(Melder_oben, INPUT );
26
pinMode(Nanopixel,   OUTPUT);
27

28

29
#if defined (__AVR_ATtiny85__)
30
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
31
#endif
32
  // End of trinket special code
33
pixels.begin(); // This initializes the NeoPixel library.
34
}
35

36

37
void loop() 
38
{
39
Nanopixel = 0;
40

41
  // put your main code here, to run repeatedly:
42
   if (digitalRead(Melder_unten)==HIGH)
43
   {
44
   // Einschalten der Treppenbeleuchtung von unten nach oben mit je VZ ms Verzögerung von Stufe zu Stufe 
45
   for(int i=0;i<NUMPIXELS;i++)
46
     {
47

48
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
49
    pixels.setPixelColor(i, pixels.Color(0,0,250)); // Moderately bright green color.
50

51
    pixels.show(); // This sends the updated pixel color to the hardware.
52

53
    delay(VZ); // Verzögerung der Pixel
54

55
     }
56
   
57
   
58
   
59
   
60
   // Leuchtdauer aller Stufen vor dem Schrittweisen abschalten der Stufen
61
   delay(Dauer);             // Leuchtdauer
62
   
63
   //Abschalten der Treppenbeleuchtung von unten nach oben mit je VZ ms Verzögerung von Stufe zu Stufe 
64
  
65
   for(int i=0;i<NUMPIXELS;i++)
66
     {
67

68
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
69
    pixels.setPixelColor(i, pixels.Color(0,0,0)); // Moderately bright green color.
70

71
    pixels.show(); // This sends the updated pixel color to the hardware.
72
    delay(VZ); // Verzögerung der Pixel
73

74
     }
75

76
   delay(Sperrzeit);              // Sperrzeit
77
   }
78

79
  if (digitalRead(Melder_oben)==HIGH)
80
   {
81
   
82
   
83
   // Einschalten der Treppenbeleuchtung von oben nach unten mit je VZ ms Verzögerung von Stufe zu Stufe 
84
     for(int i=NUMPIXELS;i>=0;i--)
85
     
86
     {
87
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
88
    pixels.setPixelColor(i, pixels.Color(250,0,0)); // Moderately bright green color.
89

90
    pixels.show(); // This sends the updated pixel color to the hardware.
91

92
    delay(VZ); // Verzögerung der Pixel
93

94
    }
95
   
96
   // Ausschalten der Treppenbeleuchtung von oben nach unten mit je VZ ms Verzögerung von Stufe zu Stufe 
97
   
98
   
99
   // Leuchtdauer aller Stufen vor dem Schrittweisen abschalten der Stufen
100
   delay(Dauer);             // Leuchtdauer
101
   
102
   //Abschalten der Treppenbeleuchtung von unten nach oben mit je VZ ms Verzögerung von Stufe zu Stufe 
103
    
104
   for(int i=NUMPIXELS;i>=0;i--)
105
    {
106

107
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
108
    pixels.setPixelColor(i, pixels.Color(0,0,0)); // Moderately bright green color.
109

110
    pixels.show(); // This sends the updated pixel color to the hardware.
111
    delay(VZ); // Verzögerung der Pixel
112

113
    }
114

115
   delay(Sperrzeit);              // Sperrzeit
116
   }
117
}
#5269826
@ Daniel Muscheika (hasenbeinmh)

>Nach dem neuladen des Arduino kann ich über den Bewegungsmelder die
>Beleuchtung einmal ansteuern

Da sollte ein Reset reichen.

>Besten Dank im vorraus.

Lange Quelltexte gehören in den Anhang.

Die Einrückung des Quelltextes ist nicht sonderlich gut, man sieht die 
Ebenen nur sehr schlecht.

Das Prgramm sieht OK aus. Aber wie sehen deine Meldereingänge aus? Sind 
das einfache Taster? Hast du dort Pull-Up oder Pull-Down Widerstände 
dran?

https://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen
Angehängte Dateien:
#5270518
Genau, denn wenn du einmal hast
1
for(int i=0;i<NUMPIXELS;i++)

und einmal
1
for(int i=NUMPIXELS;i>=0;i--)

Dann kann das nicht klappen, denn es wird nicht das selbe durchgezählt.
Ist NUMPIXELS z.B. 3, dann ergibt die obige Schleife:
0, 1, 2
und die untere Schleife ergibt:
3, 2, 1, 0

Wenn das Array 3 Elemente enthält, dann gibt es array[3] nicht, denn man 
zählt ja von 0 an. Folglich, Absturz.


Glückwunsch zu deiner ersten Berührung mit dem Off-by-One Fehler ;)
https://de.wikipedia.org/wiki/Off-by-one-Error

Um den zu vermeiden empfiehlt es sich, For schleifen immer nach dem 
selben Muster aufzubauen, damit man nicht im Kopf mehrere Varianten 
behalten muss.

Wenn du wirklich mal rückwärts zählen musst, und dafür keine Subtraktion 
in der Schleife haben willst, dann eben
1
int i = NUMPIXELS-1;
#5270699
Guten Morgen,

Also das wie folgt machen?
1
if (int i>= 0)
2
{
3
int i = Numpixels-1;
4

5
Dann der Rest
6
}

Aber in der Werkstatt hat es funktioniert und er stürzt nach der beiden 
ersten fortwährtsscheifen ab? ?

Die Rückwährtsscheifen habe ich noch nicht an der Treppe getestet.
#5271042
Hallo zusammen,

der Controller beibt in der Sperrzeit hängen.
Im Anhang der aktuelle Code und hier die Monitorausgabe:

Warte auf Bewegung
Analogwert für Nanopixel:284.00
Melder_unten:1
Von unten nach oben
Sperrzeit für von unten nach oben läuft

Der Analogwert für die Nanopixel schwankt vor dem einer 
Bewegungserkennung.
Eine TXT mit der gesamten Ausgabe findet ihr im Anhang.
Vielleicht hat jemand eine Idee.

Beste Grüße
Daniel
Angehängte Dateien:
Gast #5271065
Daniel M. schrieb:
> Hallo,
>
> ich habe die Sperrzeit verkürzt und lasse sie vier mal hintereinander
> ablaufen. Dann funktioniert alles.

Womit du einen Flicken auf einen Bug geklebt hast, ohne die Ursache zu 
erkennen!
> int Sperrzeit    = 60000;
Lass dir die Zeile doch noch ein paar mal durchs Gemüt fegen...
Vielleicht hilfts ja.

Auch ist der Arraygrenzenbug weiterhin unverändert existent.
#5271071
@ Daniel Muscheika (hasenbeinmh)

>der Controller beibt in der Sperrzeit hängen.

Sehr merkwürdig. Wie sieht deine Stromversorgung aus? Was für ein 
Netzteil speist deinen Aufbau?

>Im Anhang der aktuelle Code und hier die Monitorausgabe:

Die Einrückung ist schon wieder/immer noch Mist.
Gast #5271081
Falk B. schrieb:
> unsigned long Sperrzeit    = 60000;
Das ist die richtige Richtung...
Dann klappts auch mit dem Delay.

Die vollständige, korrekte, Notation wäre:
> const unsigned long Sperrzeit    = 60000UL;
Die lässt dann keine Fragen mehr offen.
#5271180
Hallo,

nein, eine Warnug gab es nicht. Stimmt int reicht nicht bei so großen 
Zahlen. Hätte mir auch direkt auffallen können. Danke.
Und das mit dem Array funktioniert es so wie es ist. Versuche ich aber 
noch zu ändern.

Wie so ist das einrücken immer noch mist?
#5271191
@Daniel Muscheika (hasenbeinmh)

>Wie so ist das einrücken immer noch mist?

Siehts du das nicht selber?

Hmm, ich sehe gerade, irgendwie ist die Einrückung bei meinem Beispiel 
flöten gegangen??!? Liegt wahrscheinlich an dem komischen 
Arduino-Editor.

Siehe Anhang, so sollte das aussehen.
Angehängte Dateien:
#5271213
Falk B. schrieb:
> Gibt's da keine Warnung

Bei Arduino werden Compilerwarnungen grundsätzlich abgeschaltet, damit 
sie den Benutzer nicht überfordern.

> Fehlermeldung vom Compiler?

Es ist C(++), also ist alles erlaubt :D


Ich empfehle an dieser Stelle mal Platformio anstatt des 
Arduino-Editors. Da gibt es Autovervollständigung, vernünftige 
Einrückung, Linting, etc. und es ist nicht sooo viel komplizierter als 
mit der Arduino-IDE.
http://platformio.org/platformio-ide
Gast #5271221
Christopher J. schrieb:
> Falk B. schrieb:
>> Gibt's da keine Warnung
>
> Bei Arduino werden Compilerwarnungen grundsätzlich abgeschaltet, damit
> sie den Benutzer nicht überfordern.

Und ich vermute, weil das Framework selbst jede Menge davon generiert - 
ich hab alle angeschaltet finde die Warnungen aus meinem Code kaum noch, 
zumindest bei ESP8266.

MfG, Arno
#5271263
Arno schrieb:
>> Bei Arduino werden Compilerwarnungen grundsätzlich abgeschaltet, damit
>> sie den Benutzer nicht überfordern.
>
> Und ich vermute, weil das Framework selbst jede Menge davon generiert -
> ich hab alle angeschaltet finde die Warnungen aus meinem Code kaum noch,
> zumindest bei ESP8266.

Gut möglich. Platformio lädt die Abhängigen Bibliotheken tatsächlich als 
statische Library (.a), womit die Warnungen des Frameworks entfallen.

Ich habe mir mal den Spaß gemacht und das Treppenlicht-"Projekt" in 
Platformio importiert. Wenn ich dann in Atom die "Build-Konsole" öffne 
bekomme ich genau eine Warnung:
1
src/Treppenlicht.ino:13:17: warning: overflow in implicit constant conversion [-Woverflow]
2
int Sperrzeit    = 120000;  // Sperrzeit bevor die Scheife beendet wird und die anderen Laufen kann

So Compilerwarnungen sind schon etwas tolles ;)
Gast #5271275
> Bei Arduino werden Compilerwarnungen grundsätzlich abgeschaltet, damit
> sie den Benutzer nicht überfordern.

Das stimmt doch gar nicht.

> Und ich vermute, weil das Framework selbst jede Menge davon generiert

Tut es nicht. Der ESP8266 Core generiert Warnungen, aber nicht die 
"originalen" Cores die zum Lieferumfang gehören.

Auf jeden Fall halte ich es für eine gute Idee, alle Warnungen 
einzuschalten und zu hinterfragen. Auch wenn das Zeit kostet. Antworten 
zu unklaren Fehlermeldungen habe ich bisher immer entweder mit Google 
gefunden oder mir wurde hier im Forum prima geholfen.

PS: Ich bin trotzdem kein Fan von Arduino, insbesondere finde ich den 
Editor eine schlechte Zumutung.
Gast #5271312
Stefan U. schrieb:
> aber nicht die "originalen" Cores
> die zum Lieferumfang gehören.

Ach, das interessiert doch keinen.
Hier ist wieder das Arduino Bashing in vollem Gange, und da kommts auf 
ein bisschen verfälschen und übertreiben nicht so an, wenn es denn der 
Sache dienlich ist.

Also weiter so...
Gast #5271341
Stefan U. schrieb:
>> Und ich vermute, weil das Framework selbst jede Menge davon generiert
>
> Tut es nicht. Der ESP8266 Core generiert Warnungen, aber nicht die
> "originalen" Cores die zum Lieferumfang gehören.

Du merkst, ich hab den Unterschied nichtmal erkannt, was ja für die 
gelungene Integration spricht :)

MfG, Arno
Gast #5271399
Arduino F. schrieb:
> Daniel schrieb:
>> Kann ich den pinMode auch über das Array machen oder muss ich hier
>> die
>> Pins dann einzeln konfigurieren?
> byte leds[] = {3,4,5,6};
>
> void setup()
> {
>    for(byte led:leds) pinMode(led,OUTPUT);
> }

okaaay - witzich. Das hätte ich so niemals geschrieben, danke!
lG
Äxl

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.