Monoflop: Nachtriggern verhindern

Hallo zusammen,
ich möchte ein Monoflop ohne Nachtriggern verwenden. In meinem Beispielcode wird das Monoflop durch einen zweiten Tastendruck wieder angestoßen. Wie kann ich das verhindern?

/*
   Monoflop - nachtriggerbar
   OK mit Eingabe von Taste
   10.04.2022
   Quelle: https://forum.arduino.cc/t/impuls-ausgeben-ohne-delay/348015/11
*/

bool triggered;
unsigned long previousMillis;

void setup()
{
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  pinMode(2, INPUT_PULLUP);
}

void loop()
{
  /*
    if (Serial.available())
    {
      char c = Serial.read();

      if (c == 'x')
        trigger();
    }
  */

  if (digitalRead(2) == LOW)
  {
    trigger();
  }
  if (triggered && (millis() - previousMillis > 500))
  {
    digitalWrite(3, LOW);
    triggered = false;
  }
}

void trigger()
{
  digitalWrite(3, HIGH);
  triggered = true;
  previousMillis = millis();
}

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Sorry! War mein Fehler.

Vielleicht so?

Ne. Funktioniert leider nicht. Wenn ich die Taste festhalte, bleibt die LED dauerhaft an.

Dann sollte das Monoflop flankengetriggert sein, siehe StateChangeDetection Beispiel.

ein nicht nachtriggerbares Monoflop

/*
  https://forum.arduino.cc/t/monoflop-nachtriggern-verhindern/979444
*/

#include <Noiasca_led.h>               // download library from http://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <Noiasca_button.h>            // some tools to read buttons
                                       
PulsePin pulseLed {3};                // any output pin
Button button {2};                    // button connects pin with GND, "active LOW"

void setup() {
  Serial.begin(115200);
  pulseLed.begin();   // you have to call the .begin() method for the LED pair
  pulseLed.on();      // you can switch the LED on

  pulseLed.setOnInterval(500);         // you can modify the delay time for the pulsing. Default value is 50.
  button.begin();   // you have to call the .begin() method for each button
}

void loop() {
  // read the buttons
  if (button.wasPressed())
  {
    Serial.println(F("button was pressed, switch ON LED"));
    pulseLed.on();  // switch on LED
  }
  pulseLed.update();   // you have to call update() for the LED
}

ich verwende dazu meine Library von:
https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
(kommt mit den notwendigen LED Effekten und einem einfachen Button)

1 Like

Danke für den Hinweis. Habe den erwähnten Code leider nicht anpassen können, weil ich nicht genau durchblicke.

Vielen Dank. Der Code funktioniert einwandfrei. Ich versuche noch, ein zweites Monoflop einzubauen.
Hintergrund meines Projektes:
Mit dem Arduino will ich eine Batteriespannung überwachen und bei weniger als 11,5 Volt über ein GSM-Modul eine SMS zur Info versenden. WLAN scheidet aufgrund der Entfernung zur Batterie (ca 100 Meter) aus. Den Spannungsmesser habe ich fertig und es fehlte nur noch der Triggerimpuls zum Versand der SMS. Eine andere Überlegung wäre, den Spannungswert (11,5 Volt) direkt zum Triggern des SMS-Versandes zu nutzen. Zunächst versuche ich es hiermit.

eine zweite LED (dritte, vierte...) würde ich einfach als Array anlegen und dann in For Schleifen durchgehen:

/*
  https://forum.arduino.cc/t/monoflop-nachtriggern-verhindern/979444
*/

#include <Noiasca_led.h>               // download library from http://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <Noiasca_button.h>            // some tools to read buttons

PulsePin pulseLed[] {13, 6};                // any output pin
Button button[] {A0, A1};                   // button connects pin with GND, "active LOW"

void setup() {
  Serial.begin(115200);
  for (auto &obj : pulseLed)
  {
    obj.begin();   // you have to call the .begin() method for the LED pair
    obj.setOnInterval(500);         // you can modify the delay time for the pulsing. Default value is 50.
  }
  for (auto &obj : button ) obj.begin();   // you have to call the .begin() method for each button
}

void loop() {
  for (size_t i = 0; i < sizeof(button) / sizeof(button[0]); i++)
  {
    if (button[i].wasPressed())
    {
      Serial.print(F("button was pressed, switch ON LED ")); Serial.println(i);
      pulseLed[i].on();  // switch on LED
    }
    pulseLed[i].update();   // you have to call update() for the LED
  }
}

oder wenn man will, könnte man auch sagen, eine LED und ein Button bilden eine Einheit, eine Gruppe.
Also machen wir uns eine eigene Klasse mit einer LED und einem Button und brauchen nur je eine auto range based for loop in setup und loop

#include <Noiasca_led.h>               // download library from http://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <Noiasca_button.h>            // some tools to read buttons

class MyGroup                            // eine Gruppe besteht aus
{
  public:
    PulsePin pulseLed;                   // einer LED
    Button button;                       // einem einschalt-Button
};
MyGroup group[]
{
  {13, A0},     // LEDPin, ButtonPin
  {6, A1}
};

void setup() {
  Serial.begin(115200);
  for (auto &obj : group)
  {
    obj.pulseLed.begin();                // you have to call the .begin() method for the LED pair
    obj.pulseLed.setOnInterval(500);     // you can modify the delay time for the pulsing. Default value is 50.
    obj.button.begin();                  // you have to call the .begin() method for each button
  }
}

void loop() {
  for (auto &obj : group)
  {
    if (obj.button.wasPressed())
    {
      Serial.println(F("a button was pressed, switch ON LED "));
      obj.pulseLed.on();  // switch on LED
    }
    obj.pulseLed.update();   // you have to call update() for the LED
  }
}

Vielen Dank. Probiere ich später aus.

Wie definiere ich unterschiedliche Laufzeiten? MF 1 hat 1 sec; MF 2 soll 5 min. laufen.
Ansonsten funktioniert dieses Beispiel gut.

in setup() aber außerhalb einer for schleife:

 pulseLed[0].setOnInterval(1000);
 pulseLed[1].setOnInterval(5*60*1000UL);

PS: Wir fangen bei 0 zum zählen an!

Habe den Code eingebaut, aber die Zeit für das Monoflop 2 (5 min.) stimmt nicht. Es läuft nur etwa eine Minute. Wo liegt mein Fehler?
Hier der gesamte Code:

/*
  https://forum.arduino.cc/t/monoflop-nachtriggern-verhindern/979444
*/

#include <Noiasca_led.h>               // download library from http://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <Noiasca_button.h>            // some tools to read buttons

PulsePin pulseLed[] {3, 6};                // any output pin
Button button[] {2, 5};                   // button connects pin with GND, "active LOW"

void setup() {
  Serial.begin(9600);
  pulseLed[0].setOnInterval(1000);
  pulseLed[1].setOnInterval(5*60*1000UL);
  for (auto &obj : pulseLed)
  {
    obj.begin();   // you have to call the .begin() method for the LED pair
    //    obj.setOnInterval(1000);         // you can modify the delay time for the pulsing. Default value is 50.
  }
  for (auto &obj : button ) obj.begin();   // you have to call the .begin() method for each button
}

void loop() {
  for (size_t i = 0; i < sizeof(button) / sizeof(button[0]); i++)
  {
    if (button[i].wasPressed())
    {
      Serial.print(F("button was pressed, switch ON LED ")); Serial.println(i);
      pulseLed[i].on();  // switch on LED
    }
    pulseLed[i].update();   // you have to call update() for the LED
  }
}

oha.
Hab nicht damit gerechnet dass da jemand 300.000 braucht ^^

geht aktuell als uint16_t nicht weit genug hoch.

Bessere ich am Abend aus.
oder wenn du selber ran willst, in der Datei src/Noiasca_led.h ... ca Zeile 1081

uint32_t onInterval = 500;

aber auch im setter ca Zeile 1098

void setOnInterval(uint32_t _onInterval)

edit:
habs nachgebessert. Du kannst die neue Version von meiner HP unter dem gleichen Link runterladen.

PS, so aus dem Bauch raus, würde ich die Intervalle erst nach der begin() Funktion aufrufen:

  Serial.begin(9600);
  for (auto &obj : pulseLed)
  {
    obj.begin();  
  }
  pulseLed[0].setOnInterval(1000);    // you can modify the delay time for the pulsing. Default value is 50.
  pulseLed[1].setOnInterval(5 * 60 * 1000UL);
1 Like

Jetzt funktionieren die Monoflops wie gewünscht. Es gibt durchaus Anwendungen für längere Laufzeiten. In meinem Fall schaltet das Monoflop einen Wechselrichter für 5 Minuten ein (Garagentorantrieb).
Deinen Code verstehe ich (bisher) nur teilweise, kann aber kleine Änderungen daran selbst vornehmen.
Herzlichen Dank für die Hilfe!

Nachfrage:
Anstelle eines Tasters soll das erste Monoflop (pulseLed 8) durch einen L- bzw. H-Pegel von D9 getriggert werden. Wie kann ich das ändern?

Meinst du folgendes:
Du legst den Eingang D9 mit einem pulldown Widerstand auf LOW.
Wird dieser Eingang auf HIGH gezogen und dann soll der Pulse Timer starten?!?

Also die Logik dieses Buttons soll umgekehrt werden?
Wenn ja, dann verweise ich gern auf meine Beschreibung:
https://werner.rothschopf.net/microcontroller/202203_tools_button_en.htm

du kannst für den Button angeben ob dieser HIGH oder LOW active ist.
Default ist LOW active (mit internal Pullup).
Aber so kannst du den Button auch HIGH active machen:

Button buttonA {A0, HIGH}; // active HIGH: button connects pin with GND, external pull down resistor

umgelegt auf dein Array mit Buttons schreibst also


Button button[] {
  {9, HIGH},  // button ist HIGH active (braucht externen pulldown)
  {5, LOW}   // button ist LOW active (nutzt internen Pullup)
};
1 Like

Vielen Dank.
Das klappt für mein Projekt ausgezeichnet. Nebenbei habe ich auch mit deiner Lib eine weitere Taste entprellt und die bisher verwendete Lib entfernt.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.