Go Down

Topic: Interrupt lässt Relais wild und schnell schalten. (Read 339 times) previous topic - next topic

ghostship

Hallo Gemeinde

Ich sitze gerade an einem Problem.
Ich beschäftige mich erst seit einigen Stunden mit meinem Wemos D1.
Nun versuche ich einen Pumpensteuerung für meine Sprinkler im Garten zu realisieren.

Durch zeitweisen Grundwassermangel bin ich gezwungen eines der Relais von meinem Relaisshield einmal alle ca. 3 Stunden für eine Minute laufen zu lassen damit der Wasserspiegel nicht abfällt.

Ich hatte also folgendes vor und benutze dazu ArduBlock in Version 2.

Mit einer falls/sonst Schleife frage ich einen Taster ab.
Wenn dieser gedrückt wird soll das Programm für die Magnetventile über ein Relaisshield abgearbeitet werden. Ist der Taster nicht gedrückt öffnet ein bestimmtes Ventil alle 3 Stunden für 60 sek.

Die Abfrage des Tasters läuft aber nur wenn der Wemos nicht beim Warten ist.
Das ist völlig unbrauchbar.
Code: [Select]
void setup() {
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(15, INPUT);
  digitalWrite( 4 , HIGH );

  digitalWrite( 5 , HIGH );

  digitalWrite( 12 , HIGH );

  digitalWrite( 13 , HIGH );

}

void loop() {
  if (digitalRead(15)) {
    digitalWrite( 4 , LOW );
    delay( 1000 );
    digitalWrite( 4 , HIGH );
    delay( 1000 );
    digitalWrite( 5 , LOW );
    delay( 1000 );
    digitalWrite( 5 , HIGH );
    delay( 1000 );
    digitalWrite( 12 , LOW );
    delay( 1000 );
    digitalWrite( 12 , HIGH );
    delay( 1000 );
    digitalWrite( 13 , LOW );
    delay( 1000 );
    digitalWrite( 13 , HIGH );
    delay( 1000 );
  }
  else {
    digitalWrite( 13 , LOW );
    delay( 1000 );
    digitalWrite( 13 , HIGH );
    delay( 5000 );
  }
}



Jetzt habe ich versucht dies über eine separate Interrupt-Schleife abzuhandeln.
Leider schalten die Relais nach hochladen auf den Wemos alle an und die BuildIn LED schaltet wie wild hin und her. Es gibt auch keine Reaktion auf den Tasterdruck.

Ich habe gelesen das ich jeden Eingang (bis auf GIO16) am Wemos als Interrupt verwenden kann.
Kann mir jemand verraten wo mein Problem liegt?

Code: [Select]
void interrupt();


void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  attachInterrupt(0, interrupt, CHANGE);

  digitalRead(2);

  digitalWrite( 4 , HIGH );

  digitalWrite( 5 , HIGH );

  digitalWrite( 12 , HIGH );

  digitalWrite( 13 , HIGH );

}

void loop() {
  digitalWrite( 13 , LOW );
  delay( 1000 );
  digitalWrite( 13 , HIGH );
  delay( 5000 );
}

void interrupt() {
  digitalWrite( 4 , LOW );
  delay( 1000 );
  digitalWrite( 4 , HIGH );
  delay( 1000 );
  digitalWrite( 5 , LOW );
  delay( 1000 );
  digitalWrite( 5 , HIGH );
  delay( 1000 );
  digitalWrite( 12 , LOW );
  delay( 1000 );
  digitalWrite( 12 , HIGH );
  delay( 1000 );
  digitalWrite( 13 , LOW );
  delay( 1000 );
  digitalWrite( 13 , HIGH );
  delay( 1000 );
}


HotSystems

#1
May 23, 2020, 04:26 pm Last Edit: May 23, 2020, 04:30 pm by HotSystems
Du brauchst für deine Relaissteuerung keinen Interrupt.
So zeitkritisch ist deine Steuerung nicht.

Mach es ganz normal in der Loop.
Dazu musst du natürlich deine kompletten delays() entfernen und durch eine Funktion mit millis ersetzen.
Sieh dir dazu das Beispiel BlinkWithoutDelay in der IDE an.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Serenifly

Interrupts sind für Dinge die sehr schnell und/oder sehr regelmäßig stattfinden müssen.

Entsprechend sollten Interrupts auch so kurz wie möglich sein. Sie sind kein Ersatz für regulären Programmfluss. delay() hat darin nichts verloren und geht auch gar nicht.

ghostship

Vielen Dank für die schnellen Antworten.

Das Problem ist aber das in der falls/sonst Variante das Programm ja diese ca. 3 Stunden in Warteposition steht bevor das Ventil eben für die besagte Minute öffnet. In dieser Zeit kann ich den Taster aber nicht abfragen oder gibt es da noch eine andere Variante?

HotSystems

Vielen Dank für die schnellen Antworten.

Das Problem ist aber das in der falls/sonst Variante das Programm ja diese ca. 3 Stunden in Warteposition steht bevor das Ventil eben für die besagte Minute öffnet. In dieser Zeit kann ich den Taster aber nicht abfragen oder gibt es da noch eine andere Variante?
Dann lies bitte meinen kompletten Post.

Du musst die delays ersetzen.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

michael_x

Quote
gibt es da noch eine andere Variante?
Ja. Bei BlinkWithoutDelay geht es nicht um Blinken, sondern um WithoutDelay.

MicroBahner

Alternativ könntest Du den MoToTimer aus den MobaTools verwenden. Damit ist es vielleicht etwas einfacher ;) . Das Grundprinzip ist aber dasselbe - die delay müssen raus. Ein Beispiel ist auch dabei.
Gruß, Franz-Peter

gregorss

... In dieser Zeit kann ich den Taster aber nicht abfragen oder gibt es da noch eine andere Variante?
Die Anderen haben ja schon erwähnt, dass BlinkWithoutDelay das Prinzip zeigt. Wenn es darum geht, mehrere Sachen quasi gleichzeitig zu erledigen, strickst Du Dir am besten einen Endlichen Automaten. Das Strickmuster ist z.B. hier, hieroder hier erklärt. Im Wesentlichen geht es darum die „warte"-Denke durch die „es ist Zeit für"-Denke zu ersetzen.

Gruß

Gregor
Mir wird übel. (Uwe)

ghostship

#8
May 23, 2020, 07:30 pm Last Edit: May 23, 2020, 07:42 pm by ghostship
Hallo Leute

Jetzt habe ich nach ein wenig hin und her verstanden was man mit mills macht.
Schaue mir gleich die Beispiele der letzten 2 Kommentare an aber hier mal mein Code mit dem es jetzt wunderbar funktioniert.

Vielen Dank für eure Hilfe

Code: [Select]

long Steuerung = 0L;
int Zeit = 0;
void Unterprogramm();


void setup() {
  pinMode(15, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(15, INPUT);
  digitalRead(15);

  digitalWrite( 4 , HIGH );

  digitalWrite( 5 , HIGH );

  digitalWrite( 12 , HIGH );

  digitalWrite( 13 , HIGH );

}

void loop() {
  Steuerung = millis();
  while(Steuerung + 1000L >= millis()) {
      Unterprogramm();
    }
  Zeit = ( Zeit + 1 );
  if (( Zeit == 50 )) {
    digitalWrite( 12 , LOW );
  }
  if (( Zeit == 60 )) {
    digitalWrite( 12 , HIGH );
    Zeit = 0;
  }
}

//Pumpensteuerung
void Unterprogramm() {
  if (digitalRead(15)) {
    digitalWrite( 5 , HIGH );
    digitalWrite( 12 , HIGH );
    digitalWrite( 13 , HIGH );
    digitalWrite( 4 , LOW );
    delay( 10000 );
    digitalWrite( 4 , HIGH );
    delay( 2000 );
    digitalWrite( 5 , LOW );
    delay( 10000 );
    digitalWrite( 5 , HIGH );
    delay( 2000 );
    digitalWrite( 12 , LOW );
    delay( 10000 );
    digitalWrite( 12 , HIGH );
    delay( 2000 );
    Zeit = 0;
  }
}

HotSystems

Das mit den Code-Tags konntest du doch schon.
Warum hier nicht mehr ?
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

gregorss

... hier mal mein Code mit dem es jetzt wunderbar funktioniert. ...
Schön, dass Du Dich nochmal meldest. Gib Dir noch ein bisschen Mühe, Deinen Code lesefreundlicher zu gestalten und mit Kommentaren zu versehen - z.B. was an welchen Pin angeschlossen ist. Du weißt nicht, was dieses Wochenende noch auf Dich zukommt :-)

Gruß

Gregor
Mir wird übel. (Uwe)

ghostship

Schön, dass Du Dich nochmal meldest. Gib Dir noch ein bisschen Mühe, Deinen Code lesefreundlicher zu gestalten und mit Kommentaren zu versehen - z.B. was an welchen Pin angeschlossen ist. Du weißt nicht, was dieses Wochenende noch auf Dich zukommt :-)

Gruß

Gregor

Was meinst du mit "was auf dich zukommt"?

Jetzt funktioniert es wirklich gut.
Auch schön das es die Delays gibt, denn ich will das der Taster nicht abgefragt wird solange sich das Modul im Sprinklerbetrieb befindet und nicht im Leerlauf.

Wie füge ich denn Kommentare hinzu?
Ich habe vermutlich das Pferd von hinten aufgezäumt aber das ist schon immer meine Art.

postmaster-ino

#12
May 23, 2020, 08:08 pm Last Edit: May 23, 2020, 08:11 pm by postmaster-ino
Hi
Ich hatte also folgendes vor und benutze dazu ArduBlock in Version 2.
Befürchte, sowohl die 'magic numbers' wie die fehlenden Kommentare sind der Programmier-Art geschuldet.

Bin mir nicht sicher, ob diese 'Einsteigerfreundlichen Systeme' nicht doch die falsche Richtung ist - ob man aus den zusammen gepuzzelten Blöcken in drei Wochen noch mehr herleiten kann, als ein Häh?

MfG

PS: Wenn Du etwas nur zu bestimmten Zeiten abfargen willst, dann mach Das doch auch so - delay() ist der falsche Weg - Du verbaust Dir somit sämtliche Möglichkeiten, Deinen Sketch zu erweitern - weil Alles einfach nur blockiert.
Das wirst Du erkennen, wenn Du Dir die Links in #7 reingezogen hast.
Die MoBaTools aus #6 gehen ebenfalls diese Richtung und bei Fragen dazu ist der MicroBahner (ist ja Seine Lib) auch nicht weit weg.
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

HotSystems

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Serenifly

Auch schön das es die Delays gibt, denn ich will das der Taster nicht abgefragt wird solange sich das Modul im Sprinklerbetrieb befindet und nicht im Leerlauf.
Dazu braucht man doch kein Delay

Go Up