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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht 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:
void setup()
{
  Serial.begin(115200);
  pinMode(Pin_Kanal_4, OUTPUT);
  digitalWrite(Pin_Kanal_4, LOW);
  pinMode(Pin_Kanal_1, OUTPUT);
  digitalWrite(Pin_Kanal_1, LOW);
  pinMode(Pin_Kanal_2, OUTPUT);
  digitalWrite(Pin_Kanal_2, LOW);
  pinMode(Pin_Kanal_3, OUTPUT);
  digitalWrite(Pin_Kanal_3, LOW);
  analogWriteFreq(50000);
  WiFi.begin(ssid, password);
  Serial.println("");
  while (WiFi.status() != WL_CONNECTED) {
    delay(50);
    Serial.print(".");
  }
  Serial.println(".");
  Serial.println(WiFi.localIP());
  server.on("/", handleRoot);
  server.on("/ein/", state_ein);
  server.on("/aus/", state_aus);
  server.begin();

  currentTime = millis();
  loopTime = currentTime;
}


//////////////////////////////////////////         Loop            //////////////////////////////////////////
void loop()
{
  server.handleClient();


  if (state == 0)
  {
    ausschalten();
  }

  if (state == 1)
  {
    einschalten();
  }


}
//////////////////////////////////////////     Funktionen     //////////////////////////////////////////


void state_ein()
{
  state = 1;
}
void state_aus()
{
  state = 0;
}


void einschalten()
{
  currentTime = millis();
  if (currentTime >= (loopTime + 10))
  {
    brightness = brightness + fadeAmount;
    analogWrite(12, brightness);
    analogWrite(14, brightness);
    analogWrite(4, brightness);
    analogWrite(5, brightness);
    Serial.print(state * 100);
    Serial.print(" ");
    Serial.println(brightness);

    if (brightness == 1020)
    {
      state = 3;
      Serial.print("hell");
    }
    loopTime = currentTime;
  }
}



void ausschalten()
{
  currentTime = millis();
  if (currentTime >= (loopTime + 10))
  {
    brightness = brightness - fadeAmount;
    analogWrite(12, brightness);
    analogWrite(14, brightness);
    analogWrite(4, brightness);
    analogWrite(5, brightness);
    Serial.print(state * 100);
    Serial.print(" ");
    Serial.println(brightness);
    if (brightness == 0)
    {
      Serial.print("dunkel");
      state = 3;
    }
    loopTime = currentTime;
  }
}

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)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

Sascha

von dlchnr (Gast)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht lesenswert
So, dann hier noch mal Strg+A Strg+V
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

//////////////////////////////////////////     Initalisierung     //////////////////////////////////////////
int Pin_Kanal_1        = 12;
int Pin_Kanal_2        = 14;
int Pin_Kanal_3        = 4;
int Pin_Kanal_4        = 5;
int brightness = 0;
int fadeAmount = 1;
int state = 3;
unsigned long currentTime;
unsigned long loopTime;
const char* ssid      = "PRISM";
const char* password  = "12345678";
ESP8266WebServer server(80);

//////////////////////////////////////////        Setup           //////////////////////////////////////////
void setup()
{
  Serial.begin(115200);
  pinMode(Pin_Kanal_4, OUTPUT);
  digitalWrite(Pin_Kanal_4, LOW);
  pinMode(Pin_Kanal_1, OUTPUT);
  digitalWrite(Pin_Kanal_1, LOW);
  pinMode(Pin_Kanal_2, OUTPUT);
  digitalWrite(Pin_Kanal_2, LOW);
  pinMode(Pin_Kanal_3, OUTPUT);
  digitalWrite(Pin_Kanal_3, LOW);
  analogWriteFreq(50000);
  WiFi.begin(ssid, password);
  Serial.println("");
  while (WiFi.status() != WL_CONNECTED) {
    delay(50);
    Serial.print(".");
  }
  Serial.println(".");
  Serial.println(WiFi.localIP());
  server.on("/", handleRoot);
  server.on("/ein/", state_ein);
  server.on("/aus/", state_aus);
  server.begin();

  currentTime = millis();
  loopTime = currentTime;
}


//////////////////////////////////////////         Loop            //////////////////////////////////////////
void loop()
{
  server.handleClient();


  if (state == 0)
  {
    ausschalten();
  }

  if (state == 1)
  {
    einschalten();
  }


}
//////////////////////////////////////////     Funktionen     //////////////////////////////////////////


void state_ein()
{
  state = 1;
}
void state_aus()
{
  state = 0;
}


void einschalten()
{
  currentTime = millis();
  if (currentTime >= (loopTime + 10))
  {
    brightness = brightness + fadeAmount;
    analogWrite(12, brightness);
    analogWrite(14, brightness);
    analogWrite(4, brightness);
    analogWrite(5, brightness);
    Serial.print(state * 100);
    Serial.print(" ");
    Serial.println(brightness);

    if (brightness == 1020)
    {
      state = 3;
      Serial.print("hell");
    }
    loopTime = currentTime;
  }
}



void ausschalten()
{
  currentTime = millis();
  if (currentTime >= (loopTime + 10))
  {
    brightness = brightness - fadeAmount;
    analogWrite(12, brightness);
    analogWrite(14, brightness);
    analogWrite(4, brightness);
    analogWrite(5, brightness);
    Serial.print(state * 100);
    Serial.print(" ");
    Serial.println(brightness);
    if (brightness == 0)
    {
      Serial.print("dunkel");
      state = 3;
    }
    loopTime = currentTime;
  }
}

Sorry, sollte schon beim ersten Mal komplett sein.

von Teo D. (teoderix)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Kolja L. schrieb:
> Wie könnte ich es anders machen?

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

void loop()
{
  server.handleClient();

  currentTime = millis();
  if (currentTime >= (loopTime + 10))
  {
    if (brightness_set > brightness)
    {
      brightness++;
      update_brightness();
    }
    
    if (brightness_set < brightness)
    {
      brightness--;
      update_brightness();
    }
    
    loopTime = current_time;
  }
}


void state_ein()
{
  brightness_set = 1020;
}

void state_aus()
{
  brightness_set = 0;
}

void update_brightness()
{
  analogWrite(12, brightness);  
  analogWrite(14, brightness);
  analogWrite( 4, brightness);
  analogWrite( 5, brightness);
//  Serial.println(brightness);
}

: Bearbeitet durch User
von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG

von Kolja L. (kolja82)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG

von Joe F. (easylife)


Bewertung
0 lesenswert
nicht 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?
int brightness_set[4] = { 0, 0, 0, 0 };
int brightness[4]     = { 1, 1, 1, 1 };
int i;

void loop()
{
  server.handleClient();

  currentTime = millis();
  if (currentTime >= (loopTime + 10))
  {
    for (i=0; i<4; i++)
    {
      if (brightness_set[i] > brightness[i])
      {
        brightness[i]++;
        update_brightness(i, brightness[i]);
      }
      else if (brightness_set[i] < brightness[i])
      {
        brightness[i]--;
        update_brightness(i, brightness[i]);
      }
    }
    loopTime = current_time;
  }
}

void update_brightness(int led_nr, int b)
{
  const int output_map[4] = {12, 14, 4, 5};
  analogWrite(output_map[led_nr], b);  
}

void set_led(int led_nr, int b)
{
  brightness_set[led_nr] = b;
}


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)


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

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.