LCD Zeile mit One_Button löschen

Hi

Floetzinger:
Die Zeit, an denen ich mehr Zeit habe kommt erst in 92 Wochen, 4 Tage und ein paar Stunden...

Und DAS ohne Count-Down-Uhr?? :o
... ich könnte Dir ein Forum empfehlen ... :slight_smile:
(Einen Renten-Countdown wurde schon Mal vor Jahren in einem Forum angefragt - wollte ich eigentlich auch schon gebaut haben ... aber ich habe ja noch (wesentlich) mehr Zeit dafür ... man muß halt auch Mal Glück haben können!)

MfG

Kann ein 8-bitter Deine riesige Restzeit verarbeiten? :wink:

Gruß Tommy

Ich bin selber Anfänger aber wenn ich die Richtig verstanden habe willst du mit dem ersten Buttondruck den Text ausgeben und mit dem zweiten den Text löschen. Die anderen Prozesse sollen davon unberührt bleiben? Warum arbeitets du denn nicht mit Markern. IMeine Lösung sehe ungefähr so aus:

 /* 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;
int Flag==1;                            //EDIT: Setzten der Flag Variabel auf 1
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);
 if (Flag==1){                                                    //Wenn Flagge =1 dann diese Schleife
  lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
 
 lcd.print("Erste Zeile 12345678");
 Flag+=1;
delay (500);                                                          //Jetzt wird der Flaggenwert um 1 erhöht
 }
 if (Flag==2){                                                     //Jetzt läuft diese Schleife da Flag =2                    
  clear.lcd(); // oder lcd.print("                    ");
 Flag-=1; 
delay(500);                                                          //Flag wird um eins reduziert und das Spiel fängt 
 }                                                                     //wieder von vorne an mit der ersten Schleife
 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
}

Hi

Tommy56:
Kann ein 8-bitter Deine riesige Restzeit verarbeiten? :wink:

Gruß Tommy

Zur Not in Software in 64 Bit - Das sollte reichen

So, genug OT :o

Hast mit dem OT ja recht. Aber Du bringst manches Mal so schöne Steilvorlagen, da muss man reagieren :wink:

Gruß Tommy

Es wäre für mich zum Verständnis einfacher, wenn ich die logische Abfolge kennen würde.

Die logische Abfolge ist: Man kann nur verwenden, was bekannt ist. ( Von oben nach unten )

Dabei hilft die Arduino IDE, indem sie das für Funktionsdefinitionen aushebelt und Funktions-Deklarationen vor den eigentlichen Code stellt: Funktionen (das was du fälschlich Void nennst) können in beliebiger Reihenfolge definiert werden.

Außerdem steuert die IDE einen Rahmen bei, der setup() und danach immer wieder loop() aufruft.

Globale Variable und Konstanten, die in diesen Funktionen verwendet werden, müssen schon bekannt sein, also oberhalb stehen.

Off Topic:
Postmaster-ino schrieb:
„Und DAS ohne Count-Down-Uhr??
... ich könnte Dir ein Forum empfehlen ...
(Einen Renten-Countdown wurde schon Mal vor Jahren in einem Forum angefragt - wollte ich eigentlich auch schon gebaut haben ... aber ich habe ja noch (wesentlich) mehr Zeit dafür ... man muß halt auch Mal Glück haben können!)“
Und Tommy56 meinete:
„Kann ein 8-bitter Deine riesige Restzeit verarbeiten? “
Daraufhin meinte Postmaster-ino:
„Zur Not in Software in 64 Bit - Das sollte reichen“

So, um das Ganze kurz aufzulösen, meine herzallerliebsten Kolleginnen und Kollegen
haben keine Mühen gescheut und ein unter zu Hilfenahme von Wissenschafter von der UUAP (1)
(Unseen University of Ankh-Morpork) ein deutsches Äquivalenz zum sehr, sehr großen Deep Thought(2)
zu schaffen.
Unter Berücksichtigung der Umlaufbahn von Merkur und Saturn, der Lohnzahlungen an die Mütter von Clarence Ashley und Gwen Foster(3) wurden Algorithmen entwickelt, die , beeinflusst von Murphy und Schrödiger Gesetzen, zu einen beeindruckenden Ergebnis führten:
Der ResttageausrechnerbiszurRente Kalender.

1: Terry Pratchetts Scheibenwelt
2: Douglas Adams Hitchhikers Guide to the Galaxy
3: eigentlich bekannter durch The Animals „ House of the Rising Sun“

hi there,
kurzer Zwischenbericht, bevor mich die Arbeit einholt.Dank eurer Hinweise und Anregungen, habe ich zum Switch Case Szenario gewechselt. Und tatsächlich, ich kann eindeutig erkennen und was grad passiert und steuern.
Nachdem ich also diese Hürde geschafft habe, werde ich nun die Millis() in den Sketch einbauen (zumindest versuch ich das mal).
Verstehensfrage:
wann merk ich mir die zeit zum "laufgehen"? direkt am Sketchanfang oder wenn der Nachtwächter losgeht?
und dann:
der Vergleich auf Ablauf der Zeit vor der "Aktion, wie High/ low der Pins?

bis später.
und denkt dran, manche haben diese Woche Do frei :grin:

...egal, ob ich die Zeile previuosMillis = millis(); in Zeile 47 oder Zeile 55 einfüge,
der Pin wechselt nicht von High auf Low.
Kopf >Tisch
Könnte mir jemand mal den Kopf richten?

find den flaschen Vähler nicht.

//***** was man alles braucht**** 
#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;
const int Stellzeit = 2000;
unsigned long previuosMillis ;
unsigned long interval = 2000;
OneButton button(buttonPin, false);

int ledState1 = LOW;
int ledState2 = HIGH;
enum Zustand {Abzweig, Geradeaus}; 
//byte Zustand = ledState1;
int a ;
// ******                       
void setup()
{
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(buttonPin, INPUT);
button.attachClick(clickedIt);
lcd.init();
lcd.backlight();
}
void loop()
{
Serial.begin(9600);

button.tick();
delay(10);
}
void clickedIt()
{
ledState1 = !ledState1; 
a= ledState1;
switch (a)
{
  case 1:
 previuosMillis = millis(); 
  digitalWrite(ledPin2,HIGH);
 //Platzhalter:  hier weitere Pins aktivieren 
  digitalWrite(ledPin3,LOW);
  Serial.println ("Case 1");
  Serial.println(ledState1);    
     if (millis()-previuosMillis>= 2000) {
     digitalWrite (ledPin2, LOW);

  break; 
    case 0:   
    Serial.println("Case 0"); 
    Serial.println (a);
    digitalWrite(ledPin3, HIGH);
    digitalWrite(ledPin2,LOW); 
    break;   
//default:
}
} 
}

Hi

Auch an Dich der Tip(p):
MALE Dir auf, was wann passieren soll.
Mit Pfeilen dazwischen, von welchem Zustand zu Welchem gewechselt werden soll.
An die Pfeile schreibst Du die Bedingung, bei Der 'dieser Pfeil gegangen wird'.

In Deinem aktuellen Sketch prüfst Du immer noch in clickit(), ob die Zeit abgelaufen ist.
WIE willst Du nach dem Klick wieder nach clickit() kommen??
Selbst wenn, merkst Du Dir dort am Anfang die aktuelle Zeit - womit die Endprüfung nicht erfüllt ist (da die Laufzeit noch nicht vorbei ist).

Durch das Klicken merkst Du Dir NUR, daß Da Wer geklickt hat - nicht mehr, nicht weniger.
In loop() prüfst Du JEDES MAL, ob da 'Wer geklickt hat' - wenn JA, merkst Du Dir die Zeit und fängst an, den Nachtwächter los zu schicken.
Hier wird jetzt in JEDEM loop()-Durchlauf geprüft, ob für den aktuellen Status die Weiter-Schalt-Bedingung erfüllt ist - wenn JA, gehst Du zum nächsten Status - so lange, bis Du fertig bist.
Dann läuft loop() zwar immer noch mit rasender Geschwindigkeit im Kreis, hat aber gerade Nichts zu tun - erst beim nächsten Klick ist wieder die Bedingung erfüllt, daß der erste Status angesprungen wird.
Der typische Nachtwächter, wie Er leibt und im KReis rennt.

MfG

Guten Tag an alle, die heute nicht werkeln müssen. Alle anderen auch einen schönen Tage heute.
ich habe nun erstmal den sketch umgrstellt,den anregungen folgen nicht im ClickIt() hängen zubleiben.
Nun komm ich nicht in die Switch Case Abfrage.
Bevor ich das nicht klar habee, werde ich keine millis Nummer einfügen (Probleme nicht anhäufen Modus).
Habe ich da immer noch was falsch verstanden?
Muss ich die Switch Case Abfragen anders einfügen oder eigenständig machen?
Meine Versuche mit
void Weichenstellung();
Switch Case Gedöns einfügen und im Void Loop dann Weichensteuerung() aufrufen hat auch nicht geklappt.

hier der aktuelle Fehlschlag Sketch:

#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;
const int Stellzeit = 2000;
unsigned long previuosMillis = 0;
unsigned long interval = 2000;
OneButton button(buttonPin, false);

int ledState1 = LOW;
int ledState2 = HIGH;
enum Zustand {Abzweig, Geradeaus}; 
//byte Zustand = ledState1;
int a ;
 // ******                       
void setup(){
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(buttonPin, INPUT);
 button.attachClick(clickedIt);
 lcd.init();
 lcd.backlight();
}
void loop(){
 Serial.begin(9600);
 button.tick();
 delay(10);
 switch (a) {
      case 1:
     digitalWrite(ledPin2,HIGH);
     Serial.println ("komisch1");
     Serial.println(ledState1);    
       ledState2 =!ledState2;
     break;     
     case 0:   
     Serial.println("Case 0"); 
     Serial.println (a);
     digitalWrite(ledPin3, HIGH);
     digitalWrite (ledPin2,LOW); 
     break;   
}
}
 void clickedIt(){
 ledState1 = !ledState1; 
 a= ledState1;
 Serial.println(ledState1);
}

Danke undschönen Tag!

Flötzinger

Guten Abend zusammen,
gefühlt viel Zeit verplempert, ohne Erfoge zu erzielen.
Um die MillisNummere zumindest für mich nachvollziehbar zu machen, habe ich ein Sketch mit 2 Taster zur Zustandsänderung gemacht. Die Dauer der HIGH Phase ist auf 2 sec. eingestellt. Wird nach Tastendruck erfülllt, also bei den Tastern.
Sketch zur freundlichen Ansicht:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
const int Taster1 = 11;
const int Taster2 = 12;
const int Taster3 = 10;
const int Taster4 = 9;
const int ledPin2 = 2;
const int ledPin3 = 3;
const int ledPin4 = 4;
const int ledPin5 = 5;
unsigned long Startzeit1 =0;
unsigned long Startzeit2 =0;

void setup(){
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(ledPin5, OUTPUT);
 pinMode(Taster1,INPUT);
 pinMode(Taster2,INPUT);
  pinMode(Taster3,INPUT);
 pinMode(Taster4,INPUT);
 lcd.init(); 
 lcd.backlight();
}

void loop(){
if (digitalRead(Taster1)==HIGH){
    digitalWrite(ledPin2,HIGH);
      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    ");  
      Startzeit1=millis(); 
}  
else if (millis()-Startzeit1>=2000){
       digitalWrite(ledPin2,LOW); 
}
     
if (digitalRead(Taster2)==HIGH){
    digitalWrite(ledPin3,HIGH);
      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 ("Geradefahrt gestellt");  
      Startzeit1=millis(); 
}
else if (millis()-Startzeit1>=2000){
       digitalWrite(ledPin3,LOW);
}
if (digitalRead(Taster3)==HIGH){
    digitalWrite(ledPin4,HIGH);
      lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
      lcd.print("Weichenstrasse ");
      lcd.setCursor(0,1);
      lcd.print("Gleis xx gestellt  ");
      lcd.setCursor(0,2);
      lcd.print ("Weichen 15,16,4 auf");
      lcd.setCursor(0,3);
      lcd.print ("Abzweig gestellt    ");  
      Startzeit1=millis(); 
}  
else if (millis()-Startzeit1>=2000){
       digitalWrite(ledPin4,LOW); 
}       
if (digitalRead(Taster4)==HIGH){
    digitalWrite(ledPin5,HIGH);
      lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
      lcd.print("Weichenstrasse ");
      lcd.setCursor(0,1);
      lcd.print("Gleis xx gestellt  ");
      lcd.setCursor(0,2);
      lcd.print ("Weichen 15,16,4 auf");
      lcd.setCursor(0,3);
      lcd.print ("Geradefahrt gestellt");  
      Startzeit1=millis(); 
}  
else if (millis()-Startzeit1>=2000){
       digitalWrite(ledPin5,LOW); 
}
  

}

In der abgespeckten Version mit OneButton funktioniert wider meiner Erwartung die millis() Geschichte nicht.
Und ums Verrecken ich kann ers mir nicht erklären, warum. Alle möglichen Varianten (die mir so einfielen)
ausprobiert.
Weiß jemand eine Rat/ Tipp?
Sketch:

//***** was man alles braucht**** 
#include "OneButton.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
const int buttonPin = 11;
const int ledPin2 = 2;
const int ledPin3 = 3;
const int ledPin4 = 4;
unsigned long Startzeit1 =0;

OneButton button(buttonPin, false);

int ledState1 = LOW;
int ledState2 = HIGH;
enum Zustand {Abzweig, Geradeaus}; 
//byte Zustand = ledState1;
int a ;
 // ******                       
void setup(){
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(buttonPin, INPUT);
 button.attachClick(clickedIt);
 //lcd.init();
// lcd.backlight();
}
void loop(){ 
 Serial.begin(9600);
 button.tick();
 delay(10);
if (digitalRead(ledState1)==HIGH){
    digitalWrite(ledPin2,HIGH);
    Startzeit1=millis();
}    
 else if (millis()-Startzeit1>=1000){
          digitalWrite(ledPin2,LOW); 
          Serial.println(ledState1);
}
}

void clickedIt(){
 ledState1 = !ledState1;
 a=ledState1; 
  
Serial.println("A");
Serial.println(ledState1); 
Serial.println("E");
}

Danke.
lieben Gruß Flötzinger

Hi

if (digitalRead(ledState1)==HIGH){

Das soll so?
Damit fragst Du die Pins 0 und 1 ab - Die werden allerdings für die USB-Kommunikation benutzt - denke, Du machst hier einen Fehler.
Wenn die Abfrage wieder auf einen Taster-Pin umgebogen ist, sehe ich nicht, wieso millis() hier den Dienst verweigern sollte.

MfG

öh, eigentlich ist doch ledState1 mein Merker für den Zustand.
Wäre also entweder eine Namensänderung richtig oder Pin? Der Pin kommt allerdings über OneButton als ledState1 ins Spiel.

"Damit fragst Du die Pins 0 und 1 ab" noch ein öhh, wo lern/ les ich das denn wieder?

@postmaster-ino:
in den Zeilen 49,50 und 51 lasse ich mir den Statuswechsel im Monitor anzeigen.
Jeder Tastendruck ändert den Zustand von ledState1 von 1 zu 0 resp. von 0 zu 1.

ist verwirrt

Hi

Ja, status ist boolean und kann somit nur true (!=0) oder false (0) annehmen.
Da Du digitalRead aber den Status als Pinnummer mitgibst, fragst Du bei false den Status von Pin 0, bei true den Status von Pin 1 ab.
Aaaahh - jetzt dämmert's mir:
Du willst je nach state die LED an/ausschalten - in der Abfrage möchtest Du also NUR

if (state==high) {
  //mache was, wenn state high ist
}else{
  //mache was, wenn state false ist
}

state abfragen und nicht das Level eines Pin mit der Nummer, Die status vorgibt.

MfG
Edit
true/false korrigiert - klar ist's, wie Tommy56 in #36 schreibt ... da habe ich mich irgendwie verhaspelt.

Arduino-Referenz:
false: bedeutet immer 0 (Null)
true: bedeutet 1, ABER: auch jeder andere Wert außer Null ist true.

Der Download zur Arduino-Referenz (in Deutsch) ist nur einen Klick entfernt.

postmaster-ino:
somit nur true (==1) oder false (alles Andere, hier aber 0) annehmen.

Das ist falsch formuliert. Es gibt in C/C++ eine klare Festlegung: 0 (oder NULL bei Pointern) ist FALSE, alles andere ist TRUE.

Gruß Tommy

Hallo zusammen,
jetzt habe ich das Ganze noch mal von Vorn angefangen.
Dabei habe ich mich auf das Video https://www.vimore.org/watch/B5AbaAGCbQ8/arduino-tutorial-kapitel-3-2-2-die-onebutton-library// gestützt und Step by Step abgearbeitet.
Dann mein Versuch die angesteuerte LED nach 2 Sec. wieder auf LOW zusetzen.
Erwartungsgemäß klappt es nicht. Kurz bei meinen andrern, lauffähigen Versuch nachgeschaut, sieht gleich aus.
Um wenigstens nach zuvollziehen, wann was passiert,, habe ich Serial.print eingesetzt.
Scheint so, als wenn die Abfrage nach der vergangenen Zeit nicht erreicht wird bzw. überschritten wird.

Was funktioniert:

  1. Tastendruck Pin High
    2.Tastendruck Pin low
    Anzeige im LCD Display einwandfrei
    für spätere Zwecke ist noch ein zweiter Taster vorgesehen. Das Erkennen klappt übrigens auch.

Könntet ihr mir ein Stück weit weiterhelfen?

// OneButton Lib lernen
// millis() zum Abschalten ledPin xx nach 2 sec.


#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // Datenleitungen an 27/ 28
#include <OneButton.h>
const int ledPin2 = 2;
const int ledPin3 = 3; 
//const int ledPin4 = 4; Reserve
int ButtonPin1 = 11;
int ButtonPin2 = 12;
int m;
unsigned long Startzeit1 = 0;
OneButton Button1 = OneButton(ButtonPin1,false); //Taster > externer Widerstand
OneButton Button2 = OneButton(ButtonPin2,false);

void setup(){
  Serial.begin(9600);
  while(!Serial); // Programm Start nach Öffnen des Monitors
  Serial.println(" Programmstart");
  lcd.init(); 
lcd.backlight();
    Button1.attachClick(ein_Click1);  
    Button2.attachClick(ein_Click2);  
    pinMode(ledPin2, OUTPUT);
    pinMode(ledPin3, OUTPUT);
}
void loop(){
Button1.tick();
Button2.tick();
delay(10);
}
void ein_Click1(){
Serial.println(" ein Klick 1.Taster");
Serial.println(m);
static int m = LOW; // mit 0 starten
Serial.println(m);  // welchen Wert hat m?
if((m)==HIGH){
  digitalWrite(ledPin2,HIGH);
  lcd.setCursor(0,0); // Cursorpos 0, Zeile 1
  lcd.print("Weichenstrasse ");
  lcd.setCursor(0,1);
  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    ");   
  Startzeit1=millis();
}    
 else if (millis()-Startzeit1>=2000){
  Serial.println(Startzeit1);
         digitalWrite(ledPin2,LOW); // Pin nach 2 sec. auf low; klappt nicht.Fehler liegt wo?
} 
m = !m; // umkehren

}
//**** Vorbereitung für 2. Taster
void ein_Click2(){
  Serial.println(" ein Klick 2.Taster");
}

guten Abend zusammen,
mich beschleicht ja so langsam das Gefühl, dass OneButton und millis() nicht so wirklich zusammen passen resp. zusammen arbeiten wollen.
Wer hat denn ähnliches erlebt und eine Lösung gefunden?

Vielen für eure Mühen...

OneButton arbeitet perfekt mit millis() zusammen - wenn es das nicht macht - machst du etwas falsch.

Ohne jetzt 3 Seiten durchzulesen:
Was soll dein Minisketch genau machen. Beschreibe exakt welche Aktion welche Wirkung erzielen soll bzw was per Zeit geschehen soll.
So dass es ein Entchen versteht.
Oder zeichne einen Programmablaufplan. Kariertes Papier ist super für solche Sachen :wink: