Forum: Mikrocontroller und Digitale Elektronik Zähler bleibt nicht stehen


von Kolja L. (kolja82)


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

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

wie ist brightness und fadeAmount definiert?
Man schreibt bei so was lieber  >=1020

Sascha

von dlchnr (Gast)


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.

von Teo D. (teoderix)


Lesenswert?

Sascha W. schrieb:
> wie ist brightness und fadeAmount definiert?
> Man schreibt bei so was lieber  >=1020

Bloß nich, dann musste den gesamten Code, nach solchen Misst 
durchsuchen.
Lieber den Gesamten Code Posten!

von Kolja L. (kolja82)


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.

von Tom W. (Gast)


Lesenswert?

Bloß nicht den gesamten Code posten. Der Fehler könnte gefunden werden.

von Kolja L. (kolja82)


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.

von Teo D. (teoderix)


Lesenswert?

Sascha W. schrieb:
> Man schreibt bei so was lieber  >=1020

Sorry, hab erst jetzt gerafft was Du meintest.

Für Heute lass ich's lieber, find ja nich mal die Loop. Das Rattert für 
mich einfach so durch :/

von Joe F. (easylife)


Lesenswert?

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.

von Kolja L. (kolja82)


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?

von Joe F. (easylife)


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
}

: Bearbeitet durch User
von Kolja L. (kolja82)


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ß.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

4 Werte übergeben und im Programm einzeln abarbeiten - wäre mein 
Vorschlag.

MfG

von Kolja L. (kolja82)


Lesenswert?

4 Werte alleine reichen ja nicht.

Ein Szenario wäre z.B.:

4 langsam hochfahren (dauert 60s)
ab Sekunde 30 5 hochfahren (also noch während 4 hochfährt)
ab Sekunde 120 12 hochfahren
ab Sekunde 180 14 hochfahren

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Dann sind die in sich geschlossenen Schleifen aber blöd - Stichwort 
könnte State-Machine sein.

MfG

von Joe F. (easylife)


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.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

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

Weil man sowas unter "Erfahrung" verbucht. :-)

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.