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:
  • 1 Bewertungen - 2 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Sich wiederholende Intervalle ohne Delay Verzweiflung
11.12.2019, 22:57
Beitrag #17
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
(11.12.2019 22:50)RobertLeRopp schrieb:  aber bekomme die Pause absolut nicht ordentlich zum laufen
Was funktioniert denn nicht?

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.12.2019, 23:10 (Dieser Beitrag wurde zuletzt bearbeitet: 12.12.2019 01:55 von RobertLeRopp.)
Beitrag #18
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
(11.12.2019 22:57)MicroBahner schrieb:  
(11.12.2019 22:50)RobertLeRopp schrieb:  aber bekomme die Pause absolut nicht ordentlich zum laufen
Was funktioniert denn nicht?

Ich verstehe die 255 als "pausen pin" wie kann ich die Länge der Pause definieren ?

des weiteren bleibt der Ablauf aktuell beim 4ten Relai stehen, es bleibt dauerhaft an und die Abfolge läuft nicht weiter.

Code:
const byte relPin[] = {2, 255, 3, 4, 5};
const byte relZahl = sizeof(relPin);
unsigned long previousMillis;
unsigned long aktIntervall;
int interval[] = {3000, 3000, 3000, 3000};
byte schrittNr = relZahl - 1;

void setup() {

  Serial.begin(9600);
  for (int i = 0; i < relZahl; i++) {
    pinMode(relPin[i], OUTPUT);
  }
}

void loop() {
  if (millis() - previousMillis >= aktIntervall) {
    previousMillis = millis();
    byte neuerSchritt = schrittNr + 1;
    if ( neuerSchritt >= relZahl ) neuerSchritt = 0;
  

    if ( relPin[schrittNr] < 255  ) {

      digitalWrite( relPin[schrittNr], LOW );
      Serial.print( "Relais "); Serial.print(relPin[neuerSchritt]); Serial.println(" AUS");
      Serial.println("");
    }
    if ( relPin[neuerSchritt] < 255 ) {

      digitalWrite( relPin[neuerSchritt], HIGH );
      Serial.print( "Relais "); Serial.print(relPin[neuerSchritt]); Serial.println(" EIN");
      Serial.println("");
    } else {

    }
    schrittNr = neuerSchritt;
    aktIntervall = interval[schrittNr];
  }
}

Zum Thema Tag und Nacht Schaltung kenne ich diesen weg, habe bis jetzt aber noch nichts eingetragen bekommen was mir den Intervall ändert.

Code:
const int schwellwert = 500;

void setup() {
//
}

void loop() {
  int sensorValue = analogRead(A0);

  if (sensorValue > 500) {
   // Tages Intervall
  }
  else {
    // Nacht Intervall
  }
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2019, 09:13
Beitrag #19
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
Schau dir nochmal gemau meinen Sketch an. Das Problem liegt in diesen Zeilen:
Code:
const byte relPin[] = {2, 255, 3, 4, 5};
...
int interval[] = {3000, 3000, 3000, 3000};
Für jeden Eintrag im Array relPin brauchst Du auch einen entsprechenden Eintrag im Array 'interval', der die Länge des jeweiligen Schrittes festlegt. Ist in relPin an der Stelle eine Pin-Nummer, dann ist das die Dauer für 'Relais an', steht dort eine 255, dann ist es die Pausendauer. Willst Du z.B. zwischen jedem Relaisschalten eine Pause von 1sec, dann sähe das so aus:
Code:
const byte relPin[] = {2, 255, 3, 255, 4, 255, 5, 255};
...
int interval[] = {3000, 1000, 3000, 1000, 3000, 1000, 3000, 1000};
Beide Arrays müssen immer die gleiche Zahl von Elementen haben.
Vielleicht hätte ich beim 2. Array
Code:
int interval[schrittZahl] = {3000, 1000, 3000, 1000, 3000, 1000, 3000, 1000};
schreiben sollen, um das deutlicher zu machen.

Zur Tag/Nacht Umschaltung:
In deiner Abfrage des Lichtsensors setzt Du nur einen Merker, der dann angibt, ob es Tag oder Nacht ist. Berücksichtige aber auch den Hinweis von Tommy auf die Hysterese, das ist wichtig.
Diesen Merker kannst Du dann in dem else-Block in der Schrittkette abfragen. Entweder Du schaltest dann bei 'Tag' dort die Schrittkette gleich eins weiter ( also das, was am Anfang des Schrittkettenblocks auch schon gemacht wurde ). Oder Du überschreibst die Zeit für die Pause und setzt sie auf 0, so dass beim nächsten loop-Durchlauf gleich auf den nächsten Schritt geschaltet wird.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2019, 11:18
Beitrag #20
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
Hallo RobertLeRob,

ergänzent zu den anderen guten Vorschlägen die schon gemacht wurden, würde ich Dir auch einmal empfehlen das Konzept der StateMachine anzuschauen.

Ich habe Dir mal ein Beispiel vorbereitet, das Du Dann für Deinen Fall verwenden und ausbauen könntest:
Code:
#include <Arduino.h>
#define INTERVALL 5000    // Dauer eines Anschaltzeitraumes in Millisekunden hier zur Demo nur 5 Sekunden
enum State_enum
{
  RELAIS1,
  RELAIS2,
  RELAIS3,
  RELAIS4
}; // Hier werden alle möglichen Zustände aufgelistet

State_enum state = RELAIS1;

unsigned long previousMillis;

void stateMachine();

void setup()
{
  Serial.begin(9600);
  delay(2000);
  previousMillis = millis();
}

void loop()
{
  stateMachine();
  delay(1000);  // habe ich nur für die Demo eingebaut, wird nicht benötigt
}


void stateMachine()
{
  switch (state)
  {
  case RELAIS1:
    Serial.println("Relais1 an");
    if (millis() - previousMillis >= INTERVALL){
      // Zeitraum für den ersten State abgelaufen
      state = RELAIS2;  // nächsten State setzen
      previousMillis = millis();
    }
    break;

  case RELAIS2:
    Serial.println("Relais2 an");
    if (millis() - previousMillis >= INTERVALL)
    {
      state = RELAIS3;
      previousMillis = millis();
    }
    break;

  case RELAIS3:
    Serial.println("Relais3 an");
    if (millis() - previousMillis >= INTERVALL)
    {
      state = RELAIS4;
      previousMillis = millis();
    }
    break;
  case RELAIS4:
    Serial.println("Relais4 an");
    if (millis() - previousMillis >= INTERVALL)
    {
      state = RELAIS1;
      previousMillis = millis();
    }
    break;
  }
}

Bei dem Codebeispiel wird nicht auf Tag und Nacht eingegangen, das kannst du aber in einem State hinterlegen.
Dann gibt es noch zwei Möglichkeiten mit den Zusänden der Nacht umzugehen.
Entweder machst Du für jedes Relais einen eigenen Nachtzustand und ergänzt die neuen States im Code, oder aber du verwendest weiterhin nur die vier States und verwendest dann ein Array für die verschiedenen Intervalldaueren für Tagesintervalle und Nachtintervalle.

Viel Erfolg

Roland
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2019, 11:35
Beitrag #21
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
Entschuldige, ich hatte es heute Nacht dann auch noch gesehen, warum die Pausen nicht funktionieren können.

Ich habe mehrere Versuche durch, die Tag/Nacht unterscheide auf diese Art zu realisieren aber ohne Erfolg.
Ich habe versucht den Pauenschritt im Tage-Fall zu überspringen.
Irgend ein Fehler tritt dann immer auf, egal wie ich es drehe, aktuell ist es: "'neuerSchritt' was not declared in this scope"

Code:
if (sensorValue < 500) {
      byte neuerSchritt = schrittNr + 1;
    }
    else {
      byte neuerSchritt = schrittNr + 2;
    }


Hier der ganze Code:

Code:
const int schwellwert = 500;
const byte relPin[] = {2, 255, 3, 255, 4, 255, 5, 255};
const byte relZahl = sizeof(relPin);
unsigned long previousMillis;
unsigned long aktIntervall;
int interval[] = {3000, 6000, 3000, 6000, 3000, 6000, 3000, 6000};
byte schrittNr = relZahl - 1;

void setup() {

  Serial.begin(9600);
  for (int i = 0; i < relZahl; i++) {
    pinMode(relPin[i], OUTPUT);
  }
}

void loop() {
  
int sensorValue = analogRead(A0);
  
  if (millis() - previousMillis >= aktIntervall) {
    previousMillis = millis();
    
  if (sensorValue < 500) {
      byte neuerSchritt = schrittNr + 1;
    }
    else {
      byte neuerSchritt = schrittNr + 2;
    }
    
    if ( neuerSchritt >= relZahl ) neuerSchritt = 0;
  

    if ( relPin[schrittNr] < 255  ) {

      digitalWrite( relPin[schrittNr], LOW );
      Serial.print( "Relais "); Serial.print(relPin[neuerSchritt]); Serial.println(" AUS");
      Serial.println("");
    }
    if ( relPin[neuerSchritt] < 255 ) {

      digitalWrite( relPin[neuerSchritt], HIGH );
      Serial.print( "Relais "); Serial.print(relPin[neuerSchritt]); Serial.println(" EIN");
      Serial.println("");
    } else {

    }
    schrittNr = neuerSchritt;
    aktIntervall = interval[schrittNr];
  }
}

Mein größtes Problem ist aktuell aber, das es mir nicht möglich ist Intervallzeiten länger als 90000 Millisekunden zu machen, alles was darüber geht bleibt einfach stehen und schaltet nicht weiter.

Es sollen später aber Intervalle von mindestens 3 Minuten an und 10 Minuten Pause sein. Also 180.000 und 600.000 Millisekunden.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2019, 11:50 (Dieser Beitrag wurde zuletzt bearbeitet: 12.12.2019 11:54 von RolandF.)
Beitrag #22
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
Hallo ObertLeRopp,

Du musst natürlich darauf achten, dass Du die Intervalle dann als unsigned long ablegst.
Mit int Intervallen (also max +-32000) kommst Du mit millis nicht weit.

PS:Und wenn das ganze komplizierter wird lohnt sich wirklich noch einmal ein Blick auf das Konzept der StateMachine, da kannst Du jeden Zustand getrennt betrachten und entscheiden was abhängig vom aktuellen Zustand als nächstes passieren soll ;-)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2019, 14:11 (Dieser Beitrag wurde zuletzt bearbeitet: 12.12.2019 14:34 von MicroBahner.)
Beitrag #23
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
Hallo,
Du musst das Überspringen der Pause wie gesagt auch in dem else-Zweig innerhalb der Schrittkette machen. Denn da ist erst erkannt, dass es gerade um eine Pause geht.

(12.12.2019 11:35)RobertLeRopp schrieb:  
Code:
if (sensorValue < 500) {
      byte neuerSchritt = schrittNr + 1;
    }
    else {
      byte neuerSchritt = schrittNr + 2;
    }
durch das 'byte' definierst Du hier immer wieder eine neue Variable. Das willst Du aber garnicht, Du willst die vorhanden Variable neuerSchritt' nurtzen. So einfach geht das aber nicht, da Du bei jedem incrementieren überprüfen musst, ob das Ende des Arrays erreicht ist. Deshalb ist es einfacher, beim 'Tag' einfach die Pausenlänge zu 0 zu setzen. Dann ist sie ja praktisch nicht mehr vorhanden.

Was die Zeiten angeht. Da Du nur rel. große Zeiten benötigst, kannst Du im Array auch die Zeiten in Sekunden angeben, und im loop dann einfach mit 1000 multiplizieren. Das spart Ram, und ist auch übersichtlicher als so riesige Zahlen. Sinnvoll wäre evtl. noch das Array als 'unsigned int' zu definieren. Dann kannst Du Zeiten bis 65000 Sekunden d.h. gut 18 Stunden definieren.

Versuch's mal hiermit:
Code:
// Schritte der Schrittkette mit der Pinnummern des angezogenen Relais, oder
// 255 wenn kein Relais aktiv ist ( Pausenschritt )
const byte relPin[] = {2, 255, 3, 4, 5, 255};
const byte schrittZahl = sizeof(relPin); // so einfach möglich, da relPin als byte definiert ist
// Zeitdauer des jeweiligen Schrittes
const int interval[ schrittZahl] = {3, 1, 2, 2, 5, 2};
byte schrittNr = schrittZahl - 1;   // Nummer des aktiven Schrittes ans Ende setzen
// beim ersten Start von loop wird dann auf den ersten Schritt (Index 0 )
// umgeschaltet
boolean istTag = true;   //  Merker ob es gerade hell oder dunkel ist

// Variable für die Zeitsteuerung
unsigned long previousMillis = 0;
unsigned long aktIntervall = 0;

void setup() {
  Serial.begin(115200 );
  while (!Serial);
  for (int i = 0; i < schrittZahl; i++) {
    pinMode(relPin[i], OUTPUT);
  }
}

void loop() {
  // vvvvvvvvvvvvvv  zeitgesteuerte Schrittkette  vvvvvvvvvvvvvvv
  if (millis() - previousMillis >= aktIntervall) {
    // Zeitdauer des aktuellen Schrittes ist abgelaufen
    previousMillis = millis();
    // Index des nächsten Schrittes berechnen, bei Überlauf wieder von vorn
    byte neuerSchritt = schrittNr + 1;
    if ( neuerSchritt >= schrittZahl ) neuerSchritt = 0;
    aktIntervall = 1000L * interval[neuerSchritt]; // Zeit für nächsten Schritt setzen

    if ( relPin[schrittNr] < 255  ) {
      //im aktuellen Schritt ist eine Relais an: -> ausschalten
      digitalWrite( relPin[schrittNr], LOW );
      //Serial.print( "Relais "); Serial.print( relPin[schrittNr] ); Serial.println(" AUS");
    }
    if ( relPin[neuerSchritt] < 255 ) {
      // im Folgeschritt soll ein Relais eingeschaltet werden
      digitalWrite( relPin[neuerSchritt], HIGH );
      Serial.print( "Relais "); Serial.print( relPin[neuerSchritt] ); Serial.println(" EIN");
    } else {
      // im Folgeschritt ist KEIN Relais eingetragen ( Pause )
      // hier kann gegebenenfalls geprüft werden, ob der Schritt übersprungen werden soll
      // ( Tag/Nacht Umschaltung )
      if ( istTag ) {
        // keine Pause
        aktIntervall = 0;
        Serial.println( "keine Pause");
      } else {
        Serial.println( "Pause");
      }
    }
    schrittNr = neuerSchritt;           // Schrittnummer aktualisieren

  } // ^^^^^^^^^^^^^^^ Ende Schrittkette ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  // Prüfen ob es hell oder dunkel ist, und das Flag 'istTag' entsprechend setzen
  int sensorValue = analogRead(A0);
  // Für einen sauberen Schaltpunkt in der Dämmerung, den
  // Sensor mit Hystere auswerten:
  if (sensorValue < 500) {
    istTag = true;
  }
  else if (sensorValue > 550) {
    istTag = false;
  }

}

Edit: Die Zeit für den nächsten Schritt wird jetzt in 'aktIntervall' gespeichert bevor die Auswertung auf 'Pause' gemacht wird. Dann kann man sie dort gegebenenfalls ainfach wieder zu 0 setzen um die Pause zu überspringen.


Eine 'komplette' Statemachine lohnt eigentlich nur, wenn in jedem Zustand wirklich unterscheidliche Dinge gemacht werden sollen, und wenn auch auf unterschiedliche Ereignisse reagiert werden soll.
Eine Schrittkette ist eine abgespeckte Variante davon, die hier vollkommen ausreicht.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2019, 16:24 (Dieser Beitrag wurde zuletzt bearbeitet: 12.12.2019 16:25 von RolandF.)
Beitrag #24
RE: Sich wiederholende Intervalle ohne Delay Verzweiflung
(12.12.2019 11:35)MicroBahner schrieb:  Eine 'komplette' Statemachine lohnt eigentlich nur, wenn in jedem Zustand wirklich unterscheidliche Dinge gemacht werden sollen, und wenn auch auf unterschiedliche Ereignisse reagiert werden soll.
Eine Schrittkette ist eine abgespeckte Variante davon, die hier vollkommen ausreicht.
Da hast Du natürlich Recht solange nicht mehr Aktionen in den einzelnen Zuständen hinzukommen.
Ich mache das aber lieber schon etwas früher so, dann bin ich bei späteren Änderungen schneller.
Solange die Zustände ähnlich abläufe haben steht dann in jedem Zustand nur eine Funktionsaufruf mit Parameter.
Aber hier ist das wie Du schon richtig festgestellt hast nicht unbedingt nötig.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Nextion an Arduino und umgekehrt ohne Bibliothek night022 23 327 17.09.2020 04:59
Letzter Beitrag: night022
  Fehler bei delay über 32767 Kleingärtner 5 592 07.05.2020 18:51
Letzter Beitrag: Kleingärtner
Question Sketch compilieren und testen ohne hochladen? Triax16 18 1.656 02.05.2020 12:48
Letzter Beitrag: Bitklopfer
  SoftwareSerial.h und SD.h vertragen sich nicht sowerum 25 2.054 25.04.2020 10:46
Letzter Beitrag: hotsystems
  Wie bekomme ich DIESES Delay weg. DO3GE 9 943 18.04.2020 12:44
Letzter Beitrag: Fips
  delay-millis()-while-Sensorenabfrage RCudino 22 2.011 01.04.2020 06:46
Letzter Beitrag: RCudino
  Denkanstoß gesucht - in Schrittkette delay() ersetzen SpaghettiCode 19 1.484 31.03.2020 21:31
Letzter Beitrag: MicroBahner
  for-schleife, delay, millis, interrupt Harry 8 978 31.03.2020 21:02
Letzter Beitrag: Harry
  Menu funktioniert ohne Serial.println nicht GSA1150 7 728 30.03.2020 18:26
Letzter Beitrag: Tommy56
  Stepper Motor mit zwei Taster bedienen / Fehler ohne Fehlermeldung Milano 6 817 21.03.2020 16:06
Letzter Beitrag: MicroBahner

Gehe zu:


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