Zähler bleibt nicht stehen

OP #4919098
Lesenswert?

Nabend

Eigentlich habe ich nicht gedacht, dass ich bei dieser Aufgabe ein 
Problem bekommen werde.

Das Ganze ist die Steuerung für meine Aquarium Beleuchtung.
Mittels ESP, welcher eine KSQ mittels PWM ansteuert, welche die LED 
betreiben.

Hier mal der Code:
1
void setup()
2
{
3
  Serial.begin(115200);
4
  pinMode(Pin_Kanal_4, OUTPUT);
5
  digitalWrite(Pin_Kanal_4, LOW);
6
  pinMode(Pin_Kanal_1, OUTPUT);
7
  digitalWrite(Pin_Kanal_1, LOW);
8
  pinMode(Pin_Kanal_2, OUTPUT);
9
  digitalWrite(Pin_Kanal_2, LOW);
10
  pinMode(Pin_Kanal_3, OUTPUT);
11
  digitalWrite(Pin_Kanal_3, LOW);
12
  analogWriteFreq(50000);
13
  WiFi.begin(ssid, password);
14
  Serial.println("");
15
  while (WiFi.status() != WL_CONNECTED) {
16
    delay(50);
17
    Serial.print(".");
18
  }
19
  Serial.println(".");
20
  Serial.println(WiFi.localIP());
21
  server.on("/", handleRoot);
22
  server.on("/ein/", state_ein);
23
  server.on("/aus/", state_aus);
24
  server.begin();
25

26
  currentTime = millis();
27
  loopTime = currentTime;
28
}
29

30

31
//////////////////////////////////////////         Loop            //////////////////////////////////////////
32
void loop()
33
{
34
  server.handleClient();
35

36

37
  if (state == 0)
38
  {
39
    ausschalten();
40
  }
41

42
  if (state == 1)
43
  {
44
    einschalten();
45
  }
46

47

48
}
49
//////////////////////////////////////////     Funktionen     //////////////////////////////////////////
50

51

52
void state_ein()
53
{
54
  state = 1;
55
}
56
void state_aus()
57
{
58
  state = 0;
59
}
60

61

62
void einschalten()
63
{
64
  currentTime = millis();
65
  if (currentTime >= (loopTime + 10))
66
  {
67
    brightness = brightness + fadeAmount;
68
    analogWrite(12, brightness);
69
    analogWrite(14, brightness);
70
    analogWrite(4, brightness);
71
    analogWrite(5, brightness);
72
    Serial.print(state * 100);
73
    Serial.print(" ");
74
    Serial.println(brightness);
75

76
    if (brightness == 1020)
77
    {
78
      state = 3;
79
      Serial.print("hell");
80
    }
81
    loopTime = currentTime;
82
  }
83
}
84

85

86

87
void ausschalten()
88
{
89
  currentTime = millis();
90
  if (currentTime >= (loopTime + 10))
91
  {
92
    brightness = brightness - fadeAmount;
93
    analogWrite(12, brightness);
94
    analogWrite(14, brightness);
95
    analogWrite(4, brightness);
96
    analogWrite(5, brightness);
97
    Serial.print(state * 100);
98
    Serial.print(" ");
99
    Serial.println(brightness);
100
    if (brightness == 0)
101
    {
102
      Serial.print("dunkel");
103
      state = 3;
104
    }
105
    loopTime = currentTime;
106
  }
107
}

Das Problem ist, dass wenn die Url: IP/ein/ aufgerufen wird, der Zähler 
"brightness" nicht bei 1020 aufhört,
sondern weiterzählt.

Der Fall aus funktioniert hingegen.

Warum?

Danke für eure Hilfe

Kolja
Gast #4919125
Lesenswert?

Kolja L. schrieb:
> brightness = brightness - fadeAmount;

Kann es sein, dass "brightness = brightness - fadeAmount;" den Wert 1020 
nicht trifft (schreibe da besser >=, und dann ebenso <= 0 beim 
Ausschalten).

Ansonsten würde ich noch vorschlagen, bei Programmieren gloabale 
Variablen zu vermeiden - Code ist besser zu verstehen, wenn Funktionen 
nur auf Variablen und Strukturen arbeiten, die im Funktionskopf 
übergeben werden.
OP #4919129
Lesenswert?

Oh, sorry zu früh abgeschnitten:

int brightness = 0;
int fadeAmount = 1;
int state = 3;
unsigned long currentTime;
unsigned long loopTime;


und doch, die 1020 werden getroffen:

100 1018
100 1019
100 1020
hell100 1021
100 1022
100 1023
100 1024
100 1025


Deshalb finde ich es ja so merkwürdig.
OP #4919139
Lesenswert?

So, dann hier noch mal Strg+A Strg+V
1
#include <ESP8266WiFi.h>
2
#include <WiFiClient.h>
3
#include <ESP8266WebServer.h>
4
#include <ESP8266mDNS.h>
5

6
//////////////////////////////////////////     Initalisierung     //////////////////////////////////////////
7
int Pin_Kanal_1        = 12;
8
int Pin_Kanal_2        = 14;
9
int Pin_Kanal_3        = 4;
10
int Pin_Kanal_4        = 5;
11
int brightness = 0;
12
int fadeAmount = 1;
13
int state = 3;
14
unsigned long currentTime;
15
unsigned long loopTime;
16
const char* ssid      = "PRISM";
17
const char* password  = "12345678";
18
ESP8266WebServer server(80);
19

20
//////////////////////////////////////////        Setup           //////////////////////////////////////////
21
void setup()
22
{
23
  Serial.begin(115200);
24
  pinMode(Pin_Kanal_4, OUTPUT);
25
  digitalWrite(Pin_Kanal_4, LOW);
26
  pinMode(Pin_Kanal_1, OUTPUT);
27
  digitalWrite(Pin_Kanal_1, LOW);
28
  pinMode(Pin_Kanal_2, OUTPUT);
29
  digitalWrite(Pin_Kanal_2, LOW);
30
  pinMode(Pin_Kanal_3, OUTPUT);
31
  digitalWrite(Pin_Kanal_3, LOW);
32
  analogWriteFreq(50000);
33
  WiFi.begin(ssid, password);
34
  Serial.println("");
35
  while (WiFi.status() != WL_CONNECTED) {
36
    delay(50);
37
    Serial.print(".");
38
  }
39
  Serial.println(".");
40
  Serial.println(WiFi.localIP());
41
  server.on("/", handleRoot);
42
  server.on("/ein/", state_ein);
43
  server.on("/aus/", state_aus);
44
  server.begin();
45

46
  currentTime = millis();
47
  loopTime = currentTime;
48
}
49

50

51
//////////////////////////////////////////         Loop            //////////////////////////////////////////
52
void loop()
53
{
54
  server.handleClient();
55

56

57
  if (state == 0)
58
  {
59
    ausschalten();
60
  }
61

62
  if (state == 1)
63
  {
64
    einschalten();
65
  }
66

67

68
}
69
//////////////////////////////////////////     Funktionen     //////////////////////////////////////////
70

71

72
void state_ein()
73
{
74
  state = 1;
75
}
76
void state_aus()
77
{
78
  state = 0;
79
}
80

81

82
void einschalten()
83
{
84
  currentTime = millis();
85
  if (currentTime >= (loopTime + 10))
86
  {
87
    brightness = brightness + fadeAmount;
88
    analogWrite(12, brightness);
89
    analogWrite(14, brightness);
90
    analogWrite(4, brightness);
91
    analogWrite(5, brightness);
92
    Serial.print(state * 100);
93
    Serial.print(" ");
94
    Serial.println(brightness);
95

96
    if (brightness == 1020)
97
    {
98
      state = 3;
99
      Serial.print("hell");
100
    }
101
    loopTime = currentTime;
102
  }
103
}
104

105

106

107
void ausschalten()
108
{
109
  currentTime = millis();
110
  if (currentTime >= (loopTime + 10))
111
  {
112
    brightness = brightness - fadeAmount;
113
    analogWrite(12, brightness);
114
    analogWrite(14, brightness);
115
    analogWrite(4, brightness);
116
    analogWrite(5, brightness);
117
    Serial.print(state * 100);
118
    Serial.print(" ");
119
    Serial.println(brightness);
120
    if (brightness == 0)
121
    {
122
      Serial.print("dunkel");
123
      state = 3;
124
    }
125
    loopTime = currentTime;
126
  }
127
}

Sorry, sollte schon beim ersten Mal komplett sein.
OP #4919194
Lesenswert?

dlchnr schrieb:
> Ansonsten würde ich noch vorschlagen, bei Programmieren gloabale
> Variablen zu vermeiden - Code ist besser zu verstehen, wenn Funktionen
> nur auf Variablen und Strukturen arbeiten, die im Funktionskopf
> übergeben werden.

Ja, da gebe ich dir Recht.
Für mich als Anfänger ist es so (leider) erstmal einfacher.
Und viel mehr Code wird es nicht.

Joe F. schrieb:
> Sieht so aus als ob "server.handleClient()" den state, nachdem er von
> "einschalten()" oder "ausschalten()" auf 3 gesetzt wurde sofort wieder
> auf 0 oder 1 setzt.

Das würde zumindest das "Überzählen" erklären.
Wie könnte ich es anders machen?
#4919209
Lesenswert?

Kolja L. schrieb:
> Wie könnte ich es anders machen?

z.B. so:
1
int brightness_set = 0;
2
int brightness     = 1;
3

4
void loop()
5
{
6
  server.handleClient();
7

8
  currentTime = millis();
9
  if (currentTime >= (loopTime + 10))
10
  {
11
    if (brightness_set > brightness)
12
    {
13
      brightness++;
14
      update_brightness();
15
    }
16
    
17
    if (brightness_set < brightness)
18
    {
19
      brightness--;
20
      update_brightness();
21
    }
22
    
23
    loopTime = current_time;
24
  }
25
}
26

27

28
void state_ein()
29
{
30
  brightness_set = 1020;
31
}
32

33
void state_aus()
34
{
35
  brightness_set = 0;
36
}
37

38
void update_brightness()
39
{
40
  analogWrite(12, brightness);  
41
  analogWrite(14, brightness);
42
  analogWrite( 4, brightness);
43
  analogWrite( 5, brightness);
44
//  Serial.println(brightness);
45
}
OP #4919292
Lesenswert?

Joe F. schrieb:
> z.B. so:

Ähh, Dankeschön :-)

Der Code ist nur halb so lang,
funktioniert aber deutlich besser als mein Konstrukt.

Ich verstehe auch, was er (der Code) macht.
Soll jetzt nicht komisch klingen, aber so anspruchsvoll ist es ja auch 
nicht.

Nur, warum komme ich nicht auf solche einfachen Lösungen?


Vielen Dank auf jeden Fall!

P.S.
Der Code ist ja auch so "flexibel" damit kann ich die Helligkeitswerte 
auch dynamisch übergeben.
Also über die URL.
Das war auch mein ursprüngliches Vorhaben,
wovon ich aber, mangels Erfolg, Abstand genommen habe.

P.P.S.
Wie wäre denn der Ansatz (nicht die Lösung),
wenn ich die 4 LED nicht alle zeitgleich dimmen möchte?
Also erst 12 und 14 langsam hochfahren
und dann (auch wenn 12 und 14 noch nicht ganz an sind)
4 und 5 hochfahren.
Die LED-Reihen haben andere Lichtfarben,
12 und 14 sind warm und 4 und 5 kaltweiß.
#4919387
Lesenswert?

Kolja L. schrieb:
> Wie wäre denn der Ansatz (nicht die Lösung),
> wenn ich die 4 LED nicht alle zeitgleich dimmen möchte?
1
int brightness_set[4] = { 0, 0, 0, 0 };
2
int brightness[4]     = { 1, 1, 1, 1 };
3
int i;
4

5
void loop()
6
{
7
  server.handleClient();
8

9
  currentTime = millis();
10
  if (currentTime >= (loopTime + 10))
11
  {
12
    for (i=0; i<4; i++)
13
    {
14
      if (brightness_set[i] > brightness[i])
15
      {
16
        brightness[i]++;
17
        update_brightness(i, brightness[i]);
18
      }
19
      else if (brightness_set[i] < brightness[i])
20
      {
21
        brightness[i]--;
22
        update_brightness(i, brightness[i]);
23
      }
24
    }
25
    loopTime = current_time;
26
  }
27
}
28

29
void update_brightness(int led_nr, int b)
30
{
31
  const int output_map[4] = {12, 14, 4, 5};
32
  analogWrite(output_map[led_nr], b);  
33
}
34

35
void set_led(int led_nr, int b)
36
{
37
  brightness_set[led_nr] = b;
38
}


Statt state_ein() und state_aus() musst du es irgendwie schaffen 
set_led() als Server Callback einzubinden, und zwar mit Parametern - 
LED-Nummer (von 0 bis 3) und Helligkeit.
Wie man das macht weiss ich nicht, das wäre jetzt deine Aufgabe.

PS:
Kolja L. schrieb:
> Nur, warum komme ich nicht auf solche einfachen Lösungen?

Aller Anfang ist schwer, man beisst sich buchstäblich die Zähne aus.
Wenn es dann irgendwann mal Klick gemacht hat - so nach dem 20. Mal - 
wird es zur Fingerübung ;-)
Nicht aufgeben. Genau an solchen Projekten lernt man.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren