INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Mein Skript macht nicht das was es soll ;(
16.03.2017, 12:47
Beitrag #1
Mein Skript macht nicht das was es soll ;(
Hallo,

leider macht mein Skript nicht das was es soll, zumindest nicht ganz. Grundlegend möchte ich einfach nur eine LED Leiste dimmen. Der Dimmvorgang soll um eine bestimmte Uhrzeit starten und die eingegebene Dauer durchlaufen. Gleiches dann Abends nur umgekehrt.

Und genau hier liegt mein Problem. Die Startdimmung wird wie erwartet durchlaufen und die LED Leiste auf die volle Helligkeit hochgedimmt.

Aber beim ausschalten, bleibt das Skript dann irgendwo hängen. jedenfalls geht das Licht nicht aus. Wenn ich die Stromzufuhr kappe und wieder einschalte geht das Licht durch meine Abfrage aus.

Könnte bitte mal einer von euch cracks mal drüber schauen?
Code:
#include <DS1307RTC.h> // Importiert die benannte Bibliothek
#include <Time.h> // Importiert die benannte Bibliothek
#include <TimeLib.h>  // Importiert die benannte Bibliothek
#include <Wire.h> // Importiert die benannte Bibliothek

byte Dimmung; unsigned long MyMilliSec; byte Leiste; byte PinNum; // Deklaration von im skript verwendeten Variablen
tmElements_t tm; // Dient als Variable
//##################### Bitte in diesem Bereich die gewuenschten Zeiten eingeben. #####################\\

// Mit dem Arduino Nano koennen maximal 6 Leisten angesteuert werden, da dieser ueber 6 Dimmbare Ports verfuegt.
byte AL  = 0; // Bitte hier die gewuenschte Anzahl der Leisten eintragen.ACHTUNG BEGINNEND MIT 0 fuer die erste Leiste. 1 Leiste =0| 2 Leisten =1| 3 Leisten=2 usw. Bitte auch auf den richtigen Anschluss der Leisen auf dem Arduino achten. Leiste 0 = Pin 3, Leiste 1 = Pin 5, Leiste 2 = Pin 6|9|10|11 Die Zuweisung der Ports erfolgt durch das Skript.
byte AusDim = 255; // ganz aus! Alle zur Verfuegung stehenden Dimmstufen des Arduino werden genutzt. Es kann sein, dass nicht alle Stufen von der Leiste unterstuetzt werden.
byte AnDim  = 0; // ganz an! Alle zur Verfuegung stehenden Dimmstufen des Arduino werden genutzt. Es kann sein, dass nicht alle Stufen von der Leiste unterstuetzt werden.
byte DEBUG = 1; // Erweiterte Serial Ausgaben zur Fehlerbereinigung/Test. 0 = DEBUG aus|1 = DEBUG ein

// Bitte darauf achten das sich die Start-/Dimm-/Stopzeiten nicht ueberschneiden!
// Bitte die Startzeiten fuer morgens eingeben.
byte StartMorgens[6][2] = {{16, 0}, // Leiste 1 Start um Stunde, Minute --- Initialisiert das benannte Array mit 6 Zeilen zu je 2 Werten (fuer die Uhrzeit stunde,minute,OHNE sekunden) ---
  {0, 0}, // Leiste 2 Start um Stunde, Minute
  {0, 0}, // Leiste 3 Start um Stunde, Minute
  {0, 0}, // Leiste 4 Start um Stunde, Minute
  {0, 0}, // Leiste 5 Start um Stunde, Minute
  {0, 0}  // Leiste 6 Start um Stunde, Minute
}; // Schliesst das Array
byte StartMorgensDimOn = 60; // Anzahl der Minuten die fuer den kompletten Dimmvorgang einer Leiste genutzt werden soll.

// Bitte die Startzeiten fuer Nachtruhe eingeben.
byte StopAbend[6][2] = {{20, 0}, // Leiste 1 Stop um Stunde, Minute --- Initialisiert das benannte Array mit 6 Zeilen zu je 2 Werten (fuer die Uhrzeit stunde,minute,OHNE sekunden) ---
  {0, 0}, // Leiste 2 Stop um Stunde, Minute
  {0, 0}, // Leiste 3 Stop um Stunde, Minute
  {0, 0}, // Leiste 4 Stop um Stunde, Minute
  {0, 0}, // Leiste 5 Start um Stunde, Minute
  {0, 0}  // Leiste 6 Start um Stunde, Minute
}; // Schliesst das Array
byte StopAbendDimOff  = 120; // Anzahl der Minuten die fuer den kompletten Dimmvorgang einer Leiste genutzt werden soll.

//############################  Keine Aenderungen nach dieser Zeile noetig. ############################\\

void setup() {  // Ausfuehrung nur bei Initialisierung (Start) des Arduino
  Serial.begin(9600); // Startet Serielle Schnittstelle mit 9600 Baud
  while (!Serial) ; // Wartet auf Serielle Schnittstelle
  delay(200); // 200 Millisekunen verzoegerung, damit die Schnittstelle korrekt initiert werden kann.
  zeit(); // Gehe in die Funktion Zeit um die aktuelle Uhrzeit zu holen.
  for (Leiste = 0; Leiste <= AL; Leiste ++) {   // Schleife zum durchlaufen jeder inzelnen Leiste. Beginnend bei 0. 0 ist die erste Leiste.
    if ((tm.Hour >= StartMorgens[Leiste][0]) && (tm.Hour <= StopAbend[Leiste][0])) {
      pzul(); // Gehe in die Funktion PinzuLeiste damit die entsprechenden Pins den Leisten zugeordnet werden koennen.
      Dimmung  = 0; // Belege die angegebene Variable mit 255 um das Licht der Leisten komplett aus zu machen.
      lichtAnAus(); // Gehe in die Funktion LichtAnAUS damit die entsprechenden Leisten ausgeschaltet werden koennen.
      Serial.println("");
      Serial.print("Nummer der Leiste ");
      Serial.print(Leiste);
      Serial.print(". Nachbau der Ausfallabfrage: Wenn die aktuelle Stunde ");
      Serial.print(tm.Hour);
      Serial.print(" >= als die angegebene Stunde ");
      Serial.print(StartMorgens[Leiste][0]);
      Serial.print(" zum starten des Licht UND die aktuelle Stunde ");
      Serial.print(tm.Hour);
      Serial.print(" <= als die angegebene Stunde ");
      Serial.print(StopAbend[Leiste][0]);
      Serial.println(" zum ausschalten des Licht ist. Dann mache das Licht an.");
    } else if ((tm.Hour <= StartMorgens[Leiste][0]) || (tm.Hour >= StopAbend[Leiste][0]))  {
        pzul(); // Gehe in die Funktion PinzuLeiste damit die entsprechenden Pins den Leisten zugeordnet werden koennen.
        Dimmung  = 255; // Belege die angegebene Variable mit 255 um das Licht der Leisten komplett aus zu machen.
        lichtAnAus(); // Gehe in die Funktion LichtAnAUS damit die entsprechenden Leisten ausgeschaltet werden koennen.
        Serial.println("");
        Serial.print("Nummer der Leiste ");
        Serial.print(Leiste);
        Serial.print(". Nachbau der Ausfallabfrage: Wenn die aktuelle Stunde ");
        Serial.print(tm.Hour);
        Serial.print(" <= als die angegebene Stunde ");
        Serial.print(StartMorgens[Leiste][0]);
        Serial.print(" zum starten des Licht ODER die aktuelle Stunde ");
        Serial.print(tm.Hour);
        Serial.print(" >= als die angegebene Stunde ");
        Serial.print(StopAbend[Leiste][0]);
        Serial.println(" zum ausschalten des Licht ist. Dann mache das Licht aus.");
    }   // Schliesst die IF Debug Abfrage.
  }   // Schliesst die Schleife.
}   // Schliesst void setup.

void loop() {
  zeit(); // Gehe in die Funktion Zeit um die aktuelle Uhrzeit zu holen.
  for (Leiste = 0; Leiste <= AL; Leiste ++) {   // Schleife zum durchlaufen jeder inzelnen Leiste. Beginnend bei 0
    if ((tm.Hour == StartMorgens[Leiste][0]) && (tm.Minute == StartMorgens[Leiste][1])) { // Wenn es die angegebene Uhrzeit ist,
      dimmHochMorgens(); // gehe in den benannten Bereich
    } // Schliesst die IF Abfrage.
    if ((tm.Hour == StopAbend[Leiste][0]) && (tm.Minute == StopAbend[Leiste][1])) { // Wenn es die angegebene Uhrzeit ist,
      dimmRunterAbends(); // gehe in den benannten Bereich
    }   // Schliesst die IF Abfrage.
  }   // Schliesst die Schleife.
}   // Schliesst void Loop.

void dimmHochMorgens() { // Dieser Bereich (Scope) dimmt morgens zur definierten Uhrzeit das Licht an
  for (Dimmung = AusDim; Dimmung >= AnDim; Dimmung --) {  // Dazu wird der Variable "Dimmung" der Wert aus Zeile 10 zugewiesen und solange reduziert bis dieser auf dem Wert welcher in der Zeile 11 steht erreicht ist.
    Serial.print("Befinden uns in der Funktion dimmHochMorgens. ");
    Serial.print("Wert der Variable Dimmung ");
    Serial.print(Dimmung);
    Serial.print(" Aktuelle Systemzeit ");
    Serial.print(tm.Hour);
    Serial.print(":");
    Serial.print(tm.Minute);
    Serial.print(":");
    Serial.print(tm.Second);
    Serial.println(""); //Standard Log
    pzul(); // Gehe in die Funktion PinzuLeiste damit die entsprechenden Pins den Leisten zugeordnet werden koennen.
    lichtAnAus(); // Gehe in die Funktion LichtAUS damit die entsprechenden Leisten ausgeschaltet werden koennen.
    MyMilliSec = StartMorgensDimOn  * 60UL * 1000 / AusDim; // Formel zum berechnen der benoetigten Millisekunden per Dimmvorgang (Eingegebene Minuten multipiziert mal 60 (nun haben wir die Sekunen) multipiziert mal 1000 (nun haben wir die Millisekunen) geteilt durch wert aus Variable AusDim (Anzahl der Dimmspruenge)
    delay(MyMilliSec); // Regelt die Schleifendauer, hierdurch bestimmt ihr wie lange es dauert bis fertig gedimmt ist. Die Zeit wird dabei in millisek angegeben. Dieser Dimmvorgang dauert somit 255*7 Sekunden. Hier koennt ihr eure eigene Wunschdauer reinschreiben, das koennt ihr bei allen delay(..) machen*/
  }   // Schliesst die Schleife.
}   // Schliesst void dimmHochMorgens.

void dimmRunterAbends() { // Diese Funktion dimmt Abends zur definierten Uhrzeit das Licht aus
  for (Dimmung = AnDim; Dimmung <= AusDim; Dimmung ++) {  // Dazu wird der Variable "Dimmung" der Wert aus Zeile 11 zugewiesen und solange erhoeht bis dieser auf dem Wert welcher in der Zeile 10 steht erreicht ist.
    pzul(); // Gehe in die Funktion PinzuLeiste damit die entsprechenden Pins den Leisten zugeordnet werden koennen.
    Serial.print("Befinden uns in der Funktion dimmRunterAbends");
    Serial.print("DEBUG Modus --->  "); //Extra Ausgabe fuer DEBUG
    Serial.print("Nummer der Leiste: ");
    Serial.print(Leiste);
    Serial.print(" Nummer des zugewiesenen Ports: ");
    Serial.print(PinNum);
    Serial.println("");
    lichtAnAus(); // Gehe in die Funktion LichtAUS damit die entsprechenden Leisten ausgeschaltet werden koennen.#
    MyMilliSec = StopAbendDimOff * 60UL * 1000 / AusDim; // Formel zum berechnen der benoetigten Millisekunden pr Dimmvorgang (Eingegebene Minuten multipiziert mal 60 (nun haben wir die Sekunen) multipiziert mal 1000 (nun haben wir die Millisekunen) geteilt durch wert aus Variable AusDim (Anzahl der Dimmspruenge)
    delay(MyMilliSec); // Regelt die Schleifendauer, hierdurch bestimmt ihr wie lange es dauert bis fertig gedimmt ist. Die Zeit wird dabei in millisek angegeben. Dieser Dimmvorgang dauert somit wert aus Variable AusDim*7 Sekunden. Hier koennt ihr eure eigene Wunschdauer reinschreiben, das koennt ihr bei allen delay(..) machen*/
  }   // Schliesst die Schleife.
}   // Schliesst void dimmRunterAbends.

void zeit() {
  setSyncProvider(RTC.get); // Bezieht die aktuelle Uhrzeit vom RTC Modul
  if (RTC.read(tm)) {  // Wenn die aktuelle Uhrzeit ausgelesen werden kann
  } else {  // Oder Statement.
    Serial.print("Die aktuelle Uhrzeit kann nicht gelesen werden, bitte pruefen Sie die Uhr!");
    Serial.println(""); // Standard Log
  }   // Schliesst die Schleife
}   // Schliesst void Zeit.

void pzul() {
  switch (Leiste) { // Dem Switch Statement wird der aktuell verwendete Wert der Variable "Leiste" uebergeben
    case 0: // Wenn "Leise" den Wert angegeben Wert enthält
      PinNum = 3; // dann wird die entsprechende Pin Nummer gesetzt.
      break; // Verlässt das Switch Statement
    case 1: // Wenn "Leise" den Wert angegeben Wert enthält
      PinNum = 5; // dann wird die entsprechende Pin Nummer gesetzt.
      break; // Verlässt das Switch Statement
    case 2: // Wenn "Leise" den Wert angegeben Wert enthält
      PinNum = 6; // dann wird die entsprechende Pin Nummer gesetzt.
      break; // Verlässt das Switch Statement
    case 3: // Wenn "Leise" den Wert angegeben Wert enthält
      PinNum = 9; // dann wird die entsprechende Pin Nummer gesetzt.
      break; // Verlässt das Switch Statement
    case 4: // Wenn "Leise" den Wert angegeben Wert enthält
      PinNum = 10; // dann wird die entsprechende Pin Nummer gesetzt.
      break; // Verlässt das Switch Statement
    case 5: // Wenn "Leise" den Wert angegeben Wert enthält
      PinNum = 11; // dann wird die entsprechende Pin Nummer gesetzt.
      break; // Verlässt das Switch Statement
  } // Schliesst switch
} // Schliesst void pzul.

void lichtAnAus() {
  if (DEBUG) {
    Serial.println("DEBUG Modus --->  Befinden uns in der Funktion LichtANAUS"); //Extra Ausgabe fuer DEBUG
  }
  pinMode(PinNum, OUTPUT); // Setzt den entsprechenden Pin auf "Ausgang"
  digitalWrite(PinNum, LOW); // Setzt den entsprechenden Pin auf "GND/LOW bzw. AUS" (HIGH = 5V!!!)
  analogWrite(PinNum, Dimmung); // Schreibt auf 255, bedeutet 0% Beleuchtung auf den Ausgang
  Serial.print(tm.Hour);
  Serial.print(":");
  Serial.print(tm.Minute);
  Serial.print(":");
  Serial.print(tm.Second);
  Serial.print(" Stelle Beleuchtung auf Port: ");
  Serial.print(PinNum);
  Serial.print(" der Leiste: ");
  Serial.print(Leiste);
  Serial.print(" auf den Wert: ");
  Serial.print(Dimmung);
  Serial.println(""); // Standard Log
} // Schliesst Funktion void lichtAnAus
[/code]

Dankeschön
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
16.03.2017, 14:23
Beitrag #2
RE: Mein Skript macht nicht das was es soll ;(
Da ich die passende HW nicht habe, kann ich den Sketch nicht testen.
Aber diese Schleife in 'dimmHochMorgens()' komnmt nie zum Ende:
Code:
for (Dimmung = AusDim; Dimmung >= AnDim; Dimmung --) {  // Dazu wird der Variable "Dimmung" der Wert aus Zeile 10 zugewiesen und solange reduziert bis dieser auf dem Wert welcher in der Zeile 11 steht erreicht ist.
Dimmung ist als byte defniert, und hat damit den Wertebereich 0..255. Die Endebedingung 'Dimmung >= AnDim' wird nie erreicht ( == false ), da AnDim 0 ist, und Dimmung damit IMMER >= AnDim ist.
Dein Sketch wird auch niemals für mehr als eine Leiste funktionieren, da Du mit delay() arbeitest, und der Arduino damit während der gesamten Dimzeit sich für andere Leisten nicht mehr interessiert.

P.S. hast Du dich schonmal mit dem Thema 'Parameterübergabe an Funktionen' beschäftigt? - solltest Du tun.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
16.03.2017, 15:56 (Dieser Beitrag wurde zuletzt bearbeitet: 16.03.2017 16:09 von DerMatze79.)
Beitrag #3
RE: Mein Skript macht nicht das was es soll ;(
Hallo Mirco,

Du hast Recht. Das ist auch mein eigentliches Problem. Die Schleife beginnt immer wieder von vorne ohne diese zu verlassen.

Blöd!

Naja, zumindest weis ich nun wo der Fehler liegt. Ich habe Byte nun gegen Int ausgetauscht und die Schleife wird nun verlassen. Danke (Y)
Auch hast du in dem Punkt Recht, dass die anderen Leisten, wenn Sie denn genutzt werden nicht berücksichtigt werden.

Noch blöder.....!

Und nun habe ich gar keine Idee wie ich das/die Probleme angehen könnte. Dein letzter Satz ist leider nicht hilfreich für mich.

LG
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
16.03.2017, 16:33
Beitrag #4
RE: Mein Skript macht nicht das was es soll ;(
(16.03.2017 15:56)DerMatze79 schrieb:  Und nun habe ich gar keine Idee wie ich das/die Probleme angehen könnte. Dein letzter Satz ist leider nicht hilfreich für mich.
Es sind 2 Sachen, die MicroBahner angesprochen hat.
1. Delay(): Während dieser Zeit macht der Prozessor nichts, außer Warten. Deshalb kannst Du nicht mehrere Lichtleisten ansprechen. Die Lösung liegt darin millis() zu verwenden. Dazu mußt Du Dir BlinkWithoutDelay anschauen und verstehen. Beim Verstehen kann Dir die Nachtwächtererklärung helfen.

2. Funktionen: Du arbeitest (fast) ausschließlich mit globalen Variablen. Du kannst einer Funktion aber auch direkt Werte übergeben. Dadurch kannst Du Deinen Sketch übersichtlicher gestalten. Hier gibt es Grundlagenliteratur.

3. Noch eine Anmerkung von mir: Sketche Kommentieren ist sehr wichtig. Wenn man aber für die gleiche Sache den gleichen Kommentar immer wieder hintereinander schreibt und dieser dann auch noch die Variable falsch schreibt, dann verringert das eher die Übersichtlichkeit und Lesbarkeit:
z.B.
Zitat: switch (Leiste) { // Dem Switch Statement wird der aktuell verwendete Wert der Variable "Leiste" uebergeben
case 0: // Wenn "Leise" den Wert angegeben Wert enthält
PinNum = 3; // dann wird die entsprechende Pin Nummer gesetzt.
break; // Verlässt das Switch Statement
Das muß man dann nicht noch 4 Mal wiederholen.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
16.03.2017, 22:19
Beitrag #5
RE: Mein Skript macht nicht das was es soll ;(
(16.03.2017 15:56)DerMatze79 schrieb:  Und nun habe ich gar keine Idee wie ich das/die Probleme angehen könnte.
Tommy hat ja schon einiges dazu geschrieben.
Wenn man mit dem Arduino mehrere Dinge gleichzeitig machen will, gilt folgendes Prinzip:
Im loop niemals WARTEN, bis etwas zu tun ist, sondern immer nur PRÜFEN ob etwas zu tun ist. Wenn ja, dann tue es, wenn nicht wird die entsprechende Aktion übersprungen, und mit der nächste Aufgabe weitergemacht. Hängt die Aktion von der Zeit ab ( wie bei dir ) so kann man über die millis() prüfen, ob der Zeitpunkt für die Aktion erreicht ist. Da das Programm im loop ja immer wieder im Kreis läuft, wird auch die Prüfung immer wieder ausgeführt, bis der Zeitpunkt 'zum Handeln' gekommen ist.
Dieses Prinzip wird im BlinkWithoutDelay in einem einfachen Beispiel angewendet, und die 'Nachtwächtererklärung' ist eine Analogie, die dieses Prinzip im menschlichen Handeln verdeutlicht.

Für die einfache Bearbeitung deiner 6 Leisten solltest Du auch mehr mit Arrays arbeiten. Für die Startzeiten machst Du das ja schon.
Genauso kannst Du dir ein Array für die PWM-Pins der Leisten anlegen und ein Array in dem Du die jeweiligen Zeiten für die nächsten Aktionen hinterlegst. Dann kannst Du - wie schon jetzt bei den Startzeiten - mit der Leistennummer als Index den richtigen PWM-Pin ansprechen und die Zeitprüfung für den nächsten PWM-Schritt machen. Zur Übung kannst Du auch mal das BlinkWithoutDelay von Arne auf Arrays und for-Schleife umstellen - das ist dann ein ähnliches Prinzip wie Du bei deinen Leisten einsetzen kannst.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Bootloader lässt sich nicht brennen?? dobermann145 10 207 21.11.2017 22:58
Letzter Beitrag: hotsystems
Sad Nano - nicht genug Speicher torsten_156 10 525 30.10.2017 21:40
Letzter Beitrag: MicroBahner
  NeoPixels: Sketch will nicht - Problem mit delay? Zabsi 5 424 22.08.2017 15:17
Letzter Beitrag: Tommy56
  BME280 - Luftdruckoffset nicht einstellbar ? Stargazer 17 1.160 13.08.2017 15:38
Letzter Beitrag: hotsystems
  Ich komme mit millis nicht weiter !!! Gonmaus 8 862 09.07.2017 21:24
Letzter Beitrag: Tommy56
  Led soll zeitversetzt ausgehen Affenbrot 33 8.058 22.06.2017 18:36
Letzter Beitrag: hotsystems
  WEMOS Motorshield funzt nicht Rumpl-X 8 698 07.06.2017 21:10
Letzter Beitrag: Tommy56
  LCD geht nicht - keine Ahnung warum?? DL1AKP 12 947 15.05.2017 13:17
Letzter Beitrag: DL1AKP
  [Mega2560 und Marlin]Was soll diese Fehlermeldung? ManniP 3 486 11.05.2017 14:03
Letzter Beitrag: Tommy56
  433mHz Funkmodule senden/empfangen nicht metzgefa 2 823 06.05.2017 13:30
Letzter Beitrag: metzgefa

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste