Fragen zum Timer bei MobaTools

Hallo liebe Community,
Ich bin ganz neu dabei und versuche mir alles so gut wie es geht beizubringen.
Leider habe ich ein Problem mit meinem Code.
Ich möchte gerne, wenn ich buttonPin1 oder buttonPin2 drücke, dass LedPin und LedPin2 gleichzeitig angehen und nach dem "Timer" wieder ausgehen. Besonders bei buttonPin1 soll auch das Display in der Zeit, in der der "Timer" läuft, etwas anderes anzeigen. Leider geht nur LedPin immer rechtzeitig aus. LedPin2 und auch das Display reagieren oft nicht auf den Timer und bleiben an und nur selten gehen sie gleichzeitig mit LedPin aus.
Bestimmt habe ich nur massiv etwas falsch gemacht und finde den Fehler nicht.
Ich bin sehr dankbar für jeden Hilfe.

#include <MobaTools.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int buttonPin1 = 12;
const int buttonPin2 = 4;
const int ledPin = 2;
const int ledPin2 = 7;

MoToTimer Blinkzeit1;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin2, OUTPUT);

  lcd.init();
  lcd.backlight();
  lcd.print("NeuerTest");
  lcd.setCursor(0,1);
  lcd.print("Test123");
  delay(10000);
  lcd.clear();
  lcd.print("");
  lcd.setCursor(0,1);
  lcd.print("Halloichbin");

}

void loop() {
  if (digitalRead(buttonPin1) == LOW) {
    digitalWrite(ledPin, HIGH);
    lcd.clear();
    lcd.print("TEST123");
    Blinkzeit1.setTime( 2000L );
  }

  if ( Blinkzeit1.expired() )
  {
   digitalWrite(ledPin, LOW);
    lcd.clear();
    lcd.print("");
    lcd.setCursor(0,1);
    lcd.print("Text");
 }
  if (digitalRead(buttonPin2) == LOW) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, HIGH);
    Blinkzeit1.setTime( random(100,500) );
  }

  if ( Blinkzeit1.expired() )
  {
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
  }
  

}

Du kannst nicht an 2 verschiedenen Stellen auf das gleiche Ereignis warten und unterschiedliche Dinge auslösen. 'expired' ist als Ereignis programmiert. Sobald Du das nach dem Timerablauf einmal abgefragt hast, ist das Ereignis gelöscht.
Du mussst dir für deine beiden unterschiedlichen Aktionen auch 2 Timer Objekte anlegen. Oder Du musst dir merken, welche Taste gedrückt wurde, damit Du beim Ablauf des Timers entsprechend unterschiedliche Aktionen auslösen kannst. So ganz habe ich deine Anforderung noch nicht verstanden. Was soll z.B. passieren, wenn eine der Tasten während des Zeitablaufes gedrückt wird?

machaase:
Ich möchte gerne, wenn ich buttonPin1 oder buttonPin2 drücke, dass LedPin und LedPin2 gleichzeitig angehen und nach dem "Timer" wieder ausgehen. Besonders bei buttonPin1 soll auch das Display in der Zeit, in der der "Timer" läuft, etwas anderes anzeigen. Leider geht nur LedPin immer rechtzeitig aus. LedPin2 und auch das Display reagieren oft nicht auf den Timer und bleiben an und nur selten gehen sie gleichzeitig mit LedPin aus.

Das ist eine sehr unbestimmte Aufgabe. Was ist "Besonders". Was ist "Time"? Davon hast Du mehrere.
Ich denke, das Du zwei Instanzen brauchst, aber nur eine initialisierst.
Auch denke ich, das Du Dir beim Einsatz der lib was gedacht hast, mit dem hier vorgestellten aber WEIT! über das Ziel hinaus schiesst und später da noch was kommt....
Also bitte erkläre vollständig was Du willst.

Abstract:

// KEIN CODE!
if (buttonPin1==gedrückt)
{
ledPin1=an;
ledPin2=an;
display=zeigeBesondersAn;
timerzeit1=millis();
}

if (buttonPin2==gedrückt)
{
ledPin1=an;
ledPin2=an;
timerzeit2=millis();
//display ist nicht involviert!
timerzeit2=millis();
}

if (millis()-timerzeit1>Ablaufzeit1)
{
display=zeigeBesondersAus;
}

if ((millis()-timerzeit1>Ablaufzeit1) && (millis()-timerzeit2>Ablaufzeit2))
{
ledPin1=aus;
ledPin2=aus;
}

[Zusatz]
Ich habe jetzt 6(!) Minuten auf das preview der Forensoftware gewartet, nachdem ich endlich meinen Text mit dem Pseudocode fertig hatte.
Microbahner nimms mir nicht übel, ich schreibs trotzdem :wink:
[/Zusatz]

my_xy_projekt:
Microbahner nimms mir nicht übel, ich schreibs trotzdem :wink:

Ich weis, dass hier viele der Ansicht sind, man muss unbedingt mit millis() selbst hantieren. Ich bin da anderer Ansicht. Ich sag ja auch keinem dgitalWrite() ist Mist, Du musst unbedingt lernen wie man die Ports direkt beschreibt :wink: :smiley: .

Außerdem geht es in diesem Fall nicht so einfach. Bei einem digitalen Ausgang ist es egal, ob er nach dem Überschreiten der Zeit bei jedem loop erneut rückgesetzt wird. Bei einem LC-Display sollte man das aber nicht machen. Da bräucht man dann noch einen Merker, dass man bereits geschrieben hat. Mit der expired() Methode kann man sich das sparen, die wird nach dem Zeitablauf genau einmal wahr. Und so wird auch nur 1x auf das LCD geschrieben.

MicroBahner:
Bei einem LC-Display sollte man das aber nicht machen. Da bräucht man dann noch einen Merker, dass man bereits geschrieben hat. Mit der expired() Methode kann man sich das sparen, die wird nach dem Zeitablauf genau einmal wahr.

Ja.
Ja.
Ja.
Aehm.... hab ich was vergessen?
Nein :wink:

Bitte meinen Ansatz nicht falsch verstehen...

Vielen dank für die Antworten. Jetzt habe ich den Fehler schon mal sehr gut verstanden.

Es gibt Taster 1 und Taster 2 und 2 Leds.
Wenn ich auf Taster 1 drücke, sollen beide Leds für zb 10sek leuchten und der Display soll in dieser Zeit einen anderen Text zeigen. Nach den 10 sek sollen die Leds ausgehen und der Display wieder den Text vom Anfang anzeigen.
Das selbe sollte auch bei Taster 2 passieren. Nur halt zb 5sek.

Das ist noch alles Neuland für mich und ich versuche es zu lernen.
Ich hatte eben noch versucht mit millis() zu arbeiten. Es klappt schon mal besser aber jetzt wirken aber die Leds deutlich schwächer
und ich kann die "Aktion" nicht mehr abbrechen bzw ich habe noch keine Lösung gefunden wie
oder kann man den Code so verwenden ?

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int buttonPin1 = 12;
const int buttonPin2 = 4;
const int ledPin = 2;
const int ledPin2 = 7;

unsigned long lastMillis1;
unsigned long lastMillis2;


void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin2, OUTPUT);
  
  lastMillis1 = millis();
  lastMillis2 = millis();
  

  lcd.init();
  lcd.backlight();
  lcd.print("HALLO");
  lcd.setCursor(0,1);
  lcd.print("TEST");
  delay(10000);
  lcd.clear();
  lcd.print("");
  lcd.setCursor(0,1);
  lcd.print("JETZT");

}

void loop() {
  if (!digitalRead(buttonPin1)) {
    lastMillis1 = millis();
 }
    if (millis() - lastMillis1 <= 8000) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, HIGH);
    lcd.clear();
    lcd.print("122345");
    
    
  }
  else {
   digitalWrite(ledPin, LOW);
   digitalWrite(ledPin2, LOW);
   lcd.clear();
   lcd.print("JETZT");
   
 }

 if (!digitalRead(buttonPin2)) {
    lastMillis2 = millis();

    }
    if (millis() - lastMillis2 <= 2000) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, HIGH);
    lcd.clear();
    lcd.print("122345");
    
     }
  else {
   digitalWrite(ledPin, LOW);
   digitalWrite(ledPin2, LOW);
   lcd.clear();
   lcd.print("JETZT");
   
   }
   
 }

machaase:
Es gibt Taster 1 und Taster 2 und 2 Leds.
Wenn ich auf Taster 1 drücke, sollen beide Leds für zb 10sek leuchten und der Display soll in dieser Zeit einen anderen Text zeigen. Nach den 10 sek sollen die Leds ausgehen und der Display wieder den Text vom Anfang anzeigen.
Das selbe sollte auch bei Taster 2 passieren. Nur halt zb 5sek.

Dann programmier das halt so :wink:

#include <MobaTools.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int buttonPin1 = 12;
const int buttonPin2 = 14;
const int ledPin = 2;
const int ledPin2 = 7;

MoToTimer Blinkzeit1;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(ledPin2, OUTPUT);

  lcd.init();
  lcd.backlight();
  lcd.print("NeuerTest");
  lcd.setCursor(0, 1);
  lcd.print("Test123");
  delay(10000);
  lcd.clear();
  lcd.print("");
  lcd.setCursor(0, 1);
  lcd.print("Halloichbin");

}

void loop() {
  if (digitalRead(buttonPin1) == LOW && !Blinkzeit1.running() ) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, HIGH);
    lcd.clear();
    lcd.print("Taster1");
    Blinkzeit1.setTime( 10000L );
  }

  if (digitalRead(buttonPin2) == LOW && !Blinkzeit1.running()) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, HIGH);
    lcd.clear();
    lcd.print("Taster2");
    Blinkzeit1.setTime( random(1000, 5000) );
  }

  if ( Blinkzeit1.expired() )
  { // Zeit abgelaufen: Leds aus und alter Text
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Halloichbin");
  }


}

Ich hab's jetzt noch so gemacht, dass die Taster während der Timer-Laufzeit gesperrt sind. Ansonsten solltest Du die noch entprellen ( oder MoToButtons verwenden :wink: ).

my_xy_projekt:
Bitte meinen Ansatz nicht falsch verstehen...

Nö, ich hab' nur meine Ansicht dazu dargelegt. Das Arduino-System bietet ja grundsätzlich schon eine ganze Reihe 'Komfortfunktionen', die das Leben erleichtern. Ich finde eben nichts schlechtes dabei, wenn man dem noch welche hinzufügt, und die auch nutzt ( ohne sich tiefer um die darunterliegenden Details kümmern zu müssen ).
Die Geschichte mit den millis() scheint da eine Glaubensfrage zu sein :smiley: :smiley:

MicroBahner:
Dann programmier das halt so :wink:

Vielen Dank,
Ich werde es heute Abend mal probieren. Ich verstehe so langsam immer mehr was ich falsch gemacht habe. DANKE!

MicroBahner:
Ich hab's jetzt noch so gemacht, dass die Taster während der Timer-Laufzeit gesperrt sind. Ansonsten solltest Du die noch entprellen ( oder MoToButtons verwenden :wink: ).

Vielen Vielen dank es geht! Mit dem entprellen oder MoToButtons muss ich noch einiges lernen :smiley: das habe ich noch nicht geschafft. Aber habe jetzt schon einiges gelernt!

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