LCD Zeile mit One_Button löschen

guten Abend meine Lieben,
können wir gemeinsam ein vermutlich recht banales Problem lösen?
ok, Aufgabenstellung:
Anzeige von Text nach Tastendruck auf dem LCD Display.
Löschen vom Text nach erneuten Tastendruck.
Testaufbau mit Taster, Widerstand und LEDs fluppt hervorragend.
Erste Hürde quasi geschfft.
Nun kommt die Schwiriegkeit.
Nach dem ersten Tastendruck erscheint tatsächlich der Text, verschwindet allerdings wohl aufgrund einer
von mir angewandten Anweisung im Sketch.
Ziel soll sein, das der Text erst beim zweiten Tastendruck überschrieben werden soll (hier mit Space/ Leerzeichen).
kriegt man das sauber gelöst?
um ne Menge zus. Text zu vermeiden sind statt Millis Delay Anweisungen drin :o

 /* die zur Zeit verwendete Delay Anweisungen werden nach erfolgreicher
  * Testläufe durch Millis() ersetzt. 
  */
 
 #include "OneButton.h"
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
const int buttonPin = 12;
const int ledPin2 = 2;
const int ledPin3 = 3; 
const int ledPin4 = 4;
OneButton button(buttonPin, false);
 
int ledState1 = LOW;
int ledState2 = HIGH; 

void setup()
{
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(buttonPin, INPUT);
 
 button.attachClick(clickedIt);
 lcd.init(); 
 lcd.backlight();
}

 void loop() {
 button.tick();
  delay(10);
}

void clickedIt()
{
 ledState1 = !ledState1;
 digitalWrite(ledPin2, ledState1);
 digitalWrite(ledPin4,ledState1);
 lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
 lcd.print("Erste Zeile 12345678");
 delay(1000);
 digitalWrite(ledPin2, LOW);
 ledState2 = !ledState2;
 digitalWrite(ledPin3, ledState2);
 delay(1000);
 digitalWrite(ledPin3, LOW);
 lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
 lcd.print("                    ");// Zeileninhalt löschen/ überschreiben
}

Wenn Du etwas abhängig von bestimmten Bedingungen erledigen / nicht erledigen willst, dann solltest Du diese Bedingungen abfragen. Was Du suchst ist if.

Edit: Nach über 70 Postings wird es wohl an der Zeit sein, mal mit dem Lernen der Grundlagen zu beginnen.

Gruß Tommy

Wenn du dein Problem für banal hältst, verstehe ich nicht, warum du es nicht selbst lösen kannst.
Auch kommt mir deine Äusserung delays statt millis einzusetzen unüberlegt vor.

Mit delay blockierst du deinen Sketch zusätzlich, sodass dieser während des delay keine Tastendrücke mehr annehmen kann.

Hi

Wenn Du dem Arduino sagst
'Schreib was auf's Display, warte 10 Sekunden, mach das Licht an, warte 10 Sekunden, mach das Licht aus'
... warum wunderst Du Dich, daß Das genau so gemacht wird?

Ich wundere mich, warum Du diese Status nicht in loop() abarbeitest und jeweils nach der Wartezeit einen Status weiter springst.
Wäre dann nämlich eine State-Maschine - und der Arduino hätte noch massig Zeit, anderes Zeug zu tun.

MfG

moin,
vielen Dank für die Anschubser.
Wenn man nicht die hellste Kerze am Baum ist, brauchst halt mal ein Denkanstoß.

Hallo zusammen,
kurz mitgeteilt:
um zu verhindern, dass meine Servos für die zu stellenden Weichenstrassen beim "fahren" unterbrochen werden, muss ich im Sketch zwingend wohl Delays einsetzen.
Quasi als Bremse für übereilte Tastendrücken.

Oder gibt es eine elegantere Lösung?

Schönen Grillabend zusammen ( hier sind 27 Grad, kein Wind).

Floetzinger:
Oder gibt es eine elegantere Lösung?

ja millis()

...meine Versuche sind fehlgeschlagen, also muss ich wohl weiter probieren.
Ziel ist, zu verhindern das während der Laufzeit der Servos ein weiterer Befehl/ Tastendruck abgearbeitet wird.

Floetzinger:
um zu verhindern, dass meine Servos für die zu stellenden Weichenstrassen beim "fahren" unterbrochen werden, muss ich im Sketch zwingend wohl Delays einsetzen.

Nein, das brauchst Du nicht. Was meinst Du überhaupt mit 'unterbrochen werden' ? Ich denke es geht darum, dass die Weichen nicht umgestellt werden, wenn ein Zug darüber fährt?. Dann darfst Du während dieser Zeit die Tasten einfach nicht mehr abfragen. Dazu braucht es kein delay(). Du musst nur wissen, wenn ein Zug drüber fährt. Da braucht's aber ein paar mehr Informationen, wie das bei dir funktionieren soll. Allerdings ist mir nicht klar, was das mit deiner Frage hier in dem Sketch zu tun hat.

Hallo zusammen, wieder zurück v.d. Tournee (morgens Zirkus, abends Theater :slight_smile: )
ich habe dann mal einen neuen Versuch unternommen, mein millis Problem zu lösen.
Ohne erfolg.
eine Fingerübung, ob ich überhaupt das Prizip verstanden habe, habe ich aus einen Sketch von agmue und der Nachtwächterbeschreibung erstellt. Läuft, ist komisch aber läuft.
Das einfügen in meinen Sketch allerdings klappt nicht.
könntet ihr einmal drüberschauen und den richtigen Tipp geben?
geändert habe ich die Zeilen:
18, 19 69,70,71.
Aktuell schaltet Pin 2 nicht nach 3 sec. aus/low, sondern bleibt high.

/* Weichenstrasse stellen und auflösen durch Tastendruck (Flip/Flop) 
  * 
 */
 #include "OneButton.h"
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
const int buttonPin = 12;// Taster ein/ aus
const int ledPin2 = 2;// Anzeige Tastendruck Weichenstrasse stellen
const int ledPin3 = 3;// Anzeige Tastendruck Weichenstrasse aufgelöst 
const int ledPin4 = 4;// Anzeige Anlassung Relais
OneButton button(buttonPin, false);
 
int ledState1 = LOW;
int ledState2 = HIGH; 
// ****
//byte ledPin2 = 2;
unsigned long aktuelleMillis = 0; // hier richtig eingefügt?
unsigned long Intervall = 3000;// hier richtig eingefügt?
//******
void setup()
{
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(buttonPin, INPUT);
  Serial.begin(9600);
 button.attachClick(clickedIt);
 lcd.init(); 
 lcd.backlight();
 
}
 void loop()
{
 button.tick();
  delay(10);
}

void clickedIt()
{

 ledState1 = !ledState1;
 digitalWrite(ledPin2, ledState1);
 digitalWrite(ledPin4,ledState1);
   if(ledState1 == LOW){
//   Serial.println("aufgelöst");// Testausgabe  Monitor
    lcd.setCursor (0,0);
    lcd.print("Weichenstrasse ");
    lcd.setCursor(0,1);
    lcd.print("Gleis 64 aufgeloest   ");
    lcd.setCursor(0,2);
    lcd.print ("Weichen 15,16,4 auf ");
    lcd.setCursor(0,3);
    lcd.print ("Geradefahrt gestellt"); 
   }   
    else if(ledState1 == HIGH)
    {
//    Serial.println("gestellt");// Testausgabe  Monitor
    lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
    lcd.print("Weichenstrasse ");
    lcd.setCursor(0,1);
    lcd.print("Gleis 64 gestellt  ");
    lcd.setCursor(0,2);
    lcd.print ("Weichen 15,16,4 auf");
    lcd.setCursor(0,3);
    lcd.print ("Abzweig gestellt    "); 
    }
{
aktuelleMillis=millis();
if (millis() - aktuelleMillis == Intervall){
digitalWrite (5,LOW);
}

//delay(2000); deaktiviert, Test mit milliis()
 //digitalWrite(ledPin2, LOW);//deaktiviert , Test mit millis()
 ledState2 = !ledState2;
 digitalWrite(ledPin3, ledState2);
 
delay(2000);
digitalWrite(ledPin3, LOW);

}
}

Schau Dir mal diese beiden unsinnigen Zeilen aus Deinem Code an:

aktuelleMillis=millis();
if (millis() - aktuelleMillis == Intervall)

Das wird nie erfüllt. Wirf nochmal einen verstehenden Blick in BlinkWithoutDelay. So wird das dort nicht gemacht.

Gruß Tommy

Hallo Tommy56,
mmh, in der Reihenfolge der Zeilen aus Blink without... die Zeilen in den Sketch getragen, nö, läuft nicht.
An welcher Stelle lieg ich falsch? ist es die Stelle im Sketch?
Vergesse ich was wichtiges?
Kein Wunder, das ich nicht den Kopierer im Büro benutzen soll, so vernagelt ich manchmal bin :grin:
Nähere ich mich denn überhaupt der Lösung oder renn ich weiter im Kreis durch den Wald der Dinge?
Danke schon mal fürs helfen...
wbr. Flötzinger

/* Weichenstrasse stellen und auflösen durch Tastendruck (Flip/Flop) 
  * 
 */
 #include "OneButton.h"
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
const int buttonPin = 12;// Taster ein/ aus
const int ledPin2 = 2;// Anzeige Tastendruck Weichenstrasse stellen
const int ledPin3 = 3;// Anzeige Tastendruck Weichenstrasse aufgelöst 
const int ledPin4 = 4;// Anzeige Anlassung Relais
OneButton button(buttonPin, false);
 
int ledState1 = LOW;
int ledState2 = HIGH; 
//*** Test mit millis()
unsigned long previousMillis = 0;
const long Interval = 2000;
// ***
void setup()
{
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(buttonPin, INPUT);
  Serial.begin(9600);
 button.attachClick(clickedIt);
 lcd.init(); 
 lcd.backlight();
}
 void loop()
{
 button.tick();
  delay(10);
}

void clickedIt()
{

 ledState1 = !ledState1;
 digitalWrite(ledPin2, ledState1);
 digitalWrite(ledPin4,ledState1);
   if(ledState1 == LOW){
//   Serial.println("aufgelöst");// Testausgabe  Monitor
    lcd.setCursor (0,0);
    lcd.print("Weichenstrasse ");
    lcd.setCursor(0,1);
    lcd.print("Gleis 64 aufgeloest   ");
    lcd.setCursor(0,2);
    lcd.print ("Weichen 15,16,4 auf ");
    lcd.setCursor(0,3);
    lcd.print ("Geradefahrt gestellt"); 
   }   
    else if(ledState1 == HIGH)
    {
//    Serial.println("gestellt");// Testausgabe  Monitor
    lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
    lcd.print("Weichenstrasse ");
    lcd.setCursor(0,1);
    lcd.print("Gleis 64 gestellt  ");
    lcd.setCursor(0,2);
    lcd.print ("Weichen 15,16,4 auf");
    lcd.setCursor(0,3);
    lcd.print ("Abzweig gestellt    "); 
    }
//*** Test mit millis()
unsigned long currentMillis = millis();
if (currentMillis -previousMillis >= Interval){
previousMillis = currentMillis;  
}
//***
//delay(2000);
 digitalWrite(ledPin2, LOW);
 ledState2 = !ledState2;
 digitalWrite(ledPin3, ledState2);
 
delay(2000);
digitalWrite(ledPin3, LOW);

}

Das mit dem Kopierer kann ich verstehen.

if (currentMillis -previousMillis >= Interval){
  previousMillis = currentMillis; 
  // <------ Hier musst Du das tun, was Du nach Intervall tun willst
}

Und das Delay(2000) raus.

Gruß Tommy

....das Delay kommt raus, wenn ich den Kram vorher verstanden habe. Dank dir!
Versuch macht irgendwann auch kluch (fragt sich nur wen :slight_smile: )

Empfehlung von Tommy56 ausgeführt.
Ergebnis:
Pin ist sehr kurz high,Anzeige LED blitzt quasi nur kurz auf.
scheinbar bin ich aber auf denrichtigen Weg...
Ich werde das Gefühl nicht los, da ist noch ein weitere Fehler im Sketch (?)

/* Weichenstrasse stellen und auflösen durch Tastendruck (Flip/Flop) 
  * 
 */
 #include "OneButton.h"
 #include <Wire.h> 
 #include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
const int buttonPin = 12;// Taster ein/ aus
const int ledPin2 = 2;// Anzeige Tastendruck Weichenstrasse stellen
const int ledPin3 = 3;// Anzeige Tastendruck Weichenstrasse aufgelöst 
const int ledPin4 = 4;// Anzeige Anlassung Relais
OneButton button(buttonPin, false);
 
int ledState1 = LOW;
int ledState2 = HIGH; 
//*** Test mit millis()
unsigned long previousMillis = 0;
const long Interval = 3000;
// ***
void setup()
{
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(buttonPin, INPUT);
  Serial.begin(9600);
 button.attachClick(clickedIt);
 lcd.init(); 
 lcd.backlight();
}
 void loop()
{
 button.tick();
  delay(10);
}

void clickedIt()
{

 ledState1 = !ledState1;
 digitalWrite(ledPin2, ledState1);
 digitalWrite(ledPin4,ledState1);
   if(ledState1 == LOW){
//   Serial.println("aufgelöst");// Testausgabe  Monitor
    lcd.setCursor (0,0);
    lcd.print("Weichenstrasse ");
    lcd.setCursor(0,1);
    lcd.print("Gleis 64 aufgeloest   ");
    lcd.setCursor(0,2);
    lcd.print ("Weichen 15,16,4 auf ");
    lcd.setCursor(0,3);
    lcd.print ("Geradefahrt gestellt"); 
   }   
    else if(ledState1 == HIGH)
    {
//    Serial.println("gestellt");// Testausgabe  Monitor
    lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
    lcd.print("Weichenstrasse ");
    lcd.setCursor(0,1);
    lcd.print("Gleis 64 gestellt  ");
    lcd.setCursor(0,2);
    lcd.print ("Weichen 15,16,4 auf");
    lcd.setCursor(0,3);
    lcd.print ("Abzweig gestellt    "); 
    }
//*** Test mit millis()
unsigned long currentMillis = millis();
if(currentMillis -previousMillis >= Interval){
previousMillis = currentMillis; 
digitalWrite(ledPin2,LOW);
ledState2 = !ledState2;
digitalWrite(ledPin3, ledState2);
}
//***
//delay(2000);
 
 
delay(2000);
digitalWrite(ledPin3, LOW);

}

Du hast 2 LED. Um welche geht es denn?

Gruß Tommy

Hi

clickit ist ein INTERRUPT - darin hat weder delay() noch irgendwelche länger dauernden Arbeiten was drin verloren (LCD voll schrieben ect.pp. - und wohl auch nicht die millis()-ABfrage, da Du hier nUR rein kommst, wenn Du GERADE JETZT den Button drückst - danach erst wieder, wenn DU ERNEUT drückst.

Was hindert Dich daran, in Deiner loop() die millis-Abfrage einzubauen und dort eben darauf zu reagieren, daß die Zeit um ist?
In der ISR wird 'sich nur gemerkt, daß ein Knopf gedrückt wurde' - ob man dafür eine ISR braucht, sei auch Mal dahin gestellt.

Ein Interrupt ist wirklich nur für zeitkritische Dinge nötig (oder, wenn man wieder wach werden will - dann vom Wachhund oder PinChange).

Dein 'Ist Knopf gedrückt, dann mache A ... B ... C ... D ... E ... warte 10 Sekunden ... F ... fertig' machst Du in loop() mit einer State-Maschine.
Pro 'Knopf' eine eigene State-Maschine, schreibe Dir die Aufgaben in der zeitlichen Reihenfolge auf - kann ja auch sein, daß eine Aufgabe erst beendet ist, wenn ein Pin den Zustand ändert (Endtaster), oder eben, wenn eine gewisse Zeit um ist - dann 'machst Du halt Nichts', bis diese Bedingung(en) erfüllt sind und Du zum nächsten Status wechselst.

MfG

Edit
Habe mich von dem attach blenden lassen, der Rest zum Interrupt ist aber trotzdem so.

Schönen Sonntag,
bis bischen in Zeitnot, werde mich immer mal Häppchenweise an euren Empfehlungen halten, zus. noch einen kleinen Abriß schreiben, wie das Ganze entstanden ist und was das Ziel sein soll.
kurz noch gefragt:
wo hätte ich lesen/ erkenn können, dass ClickIt eine Interupt Nummer ist? wo ist mir was entgangen?
Danke und schönen Abend noch zusammen

Floetzinger:
wo hätte ich lesen/ erkenn können, dass ClickIt eine Interupt Nummer ist? wo ist mir was entgangen?

button.attachClick(clickedIt);

Dieses Entwurfsmuster wo man mit einer attach-Methode eine Callback-Funktion übergibt die dann von der Library automatisch aufgerufen wird

Nachtrag:
das deutet oft auf Interrupts hin, aber in diesem Fall ist es keiner. Das sieht man wenn man sich den Quelltext der Library anschaut. Die Callbacks dienen nur dazu dass man der Library mitteilt was sie in bestimmten Fällen machen soll.
Delays hebeln da aber trotzdem die Funktionalität der Library aus wenn man mehrere Knöpfe hat

Hallo zusammen,
bevor ich jetzt (oder genauer in den nächsten Tagen) anfange den Sketch neu zu schtreiben, hätte ich ein paar grundsätzliche Dinge erfragt.
Die Buchstaben in den Klammern wären meine Reihenfolge im Aufbau.
der Sketch besteht aus einer Sektion(A) mit:
#Include...
const int...
int led...
usw.
Nächste Sektion(B) Void Setup() mit:
pinMode...
buton.attach...
usw.
die dritte Sektion(C) ist Void Loo(), gefolgt von ClickIt().
Frage:
kann diese Reihenfolge so bleiben, und kann ich dann eine weitere Voidxxx(D) mit der
LCD Anzeige, den symbolischen LEDs (später ja dann als Ausgang zum Eingang ULN28xxTrieber)
einfach so dran hägen?
Oder laufe ich in Gefahr, dann keine Tasterabfrage und kein Pin Wechsel von High/ Low
mehr zu bekommen?
Es wäre für mich zum Verständnis einfacher, wenn ich die logische Abfolge kennen würde.
Die Zeit, an denen ich mehr Zeit habe kommt erst in 92 wochen, 4 Tage und ein paar Stunden...

Danke euch.
Flötzinger