ich habe eine binäruhr die mir sekunden.minuten und stunden anzeigt. Das habe ich mittels 3 schieberegister gelöst, das läuft.
Nun möchte ich aber während des laufenden betriebs die uhrzeit umstellen.
Dafür habe ich 2 Taster (schwarz und grün). Wird einer der Taster grückt wird eine interrupt ausgelöst, der mir dann wiederrum Flags setzt.
Wird der Taster schwarz 1x gedrückt, wechselt das Programm vom Normalbetrieb(statusBlack = 0) in den Stundenmodus.(statusBlack = 1) Nun kann mit dem grünen Taster duch drücken die gewünschte stunde eingestellt werden. Erneutes drücken von schwarz wechselt in den Minutenmodus(statusBlack = 2) und mit dem grünen Taster kann die gewünschte Minute eingestellt werden. Erneutes Drücken von Schwarz "speichert " die neue Zeit und wechselt in den Normalmodus(statusBlack = 0) und die Uhr läuft mit dieser Zeit nun weiter. wird im Normalmodus grün gedrückt passiert gar nichts.
soweit so gut
Mein Programmtechnisches Problem ist nun aber...
befindet sich mein programm nicht im normalmodus also statusBlack = 1 oder statusBlack = 2, dann soll er in den Normalmodus zurückkehren, wenn entweder statusBlack = 0 passiert oder 5 Sekunden lang keine Taste gedrückt wurde. und mit diesen 5 Sekunden habe ich ein problem, wie kann ich es programmiertechnisch umsetzten zu überprüfen ob zwischen 2 interrupts mehr als 5 sekunden vergangen sind. Denn wenn ja, dann soll er nicht die neue Zeit speichern sonder wieder in den Normalmodus wechseln und mit der alten Zeit weiterzählen.
int greenPin = 2;
int blackPin = 3;
int interruptNumberGreen = 0;
int interruptNumberBlack = 0;
volatile int statusBlack = 0;
volatile int statusGreen = 0;
void setup() {
//Pin-modus Eingang
pinMode(greenPin, INPUT);
pinMode(blackPin, INPUT);
//Interrupts
attachInterrupt(interruptNumberGreen, interruptGreen, RISING); // RISING FALLING CHANGE LOW
attachInterrupt(interruptNumberBlack, interruptBlack, RISING);
}
void interruptGreen(){
}
/*
statusBlack
0=normalbetrieb
1=Modus stunde einstellen
2=Modus Minute einstellen
*/
void interruptBlack(){
if (statusBlack==0){
statusBlack = 1;
}
if (statusBlack==1){
statusBlack = 2;
}
if (statusBlack==2){
statusBlack = 0;
}
}
void loop()
{
if (statusBlack!=0)
{
zeitBlackDavor=millis();
/*
Hier liegt mein Problem, der Code hier ist noch nicht fertig
*/
while ((abs(zeitBlackJetzt-zeitBlackDavor)<(sekunde*5))/* oder....*/)
{
zeitBlackJetzt=millis();
Serial.println("jo");
}
statusBlack=0;
}
// problem ende
if (statusBlack==0)
{
// uhrzeit berechnung und ausgabe jede sekunde (mit millis())
}
}
darkangel1208:
Dafür habe ich 2 Taster (schwarz und grün). Wird einer der Taster grückt wird eine interrupt ausgelöst, der mir dann wiederrum Flags setzt.
Warum vergeht alleine im deutschsprachigen Teil des Forums keine Woche, in der nicht gleich mehrere Programmieranfänger der Meinung sind, dass man zusätzliche selbst programmierte "Interrupts" in einem Sketch braucht, um so langsame Signale wie manuell gedrückte Tastschalter auszuwerten und zu verarbeiten?
Das ist doch absolut nervig, wenn Anfänger immer wieder komplizierte Programme "mit Interrupts" schreiben wollen, wo ein einfaches Programm "ohne Interrupts" viel eher angebracht wäre. Du bist doch diese Woche bereits der Dritte oder so, der mit demselben Quatsch "Interrupts zur Tasterabfrage" hier aufschlägt.
jurs:
Warum vergeht alleine im deutschsprachigen Teil des Forums keine Woche, in der nicht gleich mehrere Programmieranfänger der Meinung sind, dass man zusätzliche selbst programmierte "Interrupts" in einem Sketch braucht, um so langsame Signale wie manuell gedrückte Tastschalter auszuwerten und zu verarbeiten?
Das ist doch absolut nervig, wenn Anfänger immer wieder komplizierte Programme "mit Interrupts" schreiben wollen, wo ein einfaches Programm "ohne Interrupts" viel eher angebracht wäre. Du bist doch diese Woche bereits der Dritte oder so, der mit demselben Quatsch "Interrupts zur Tasterabfrage" hier aufschlägt.
Vieleicht sollte man delay() aus allen Tutorials verbannen und dadurch würde millis() besser erklährt und verstanden. Dadurch würden Anfänger sofort auf die richtige Spur geschickt.
uwefed:
Vieleicht sollte man delay() aus allen Tutorials verbannen und dadurch würde millis() besser erklährt und verstanden. Dadurch würden Anfänger sofort auf die richtige Spur geschickt.
Vielleicht sollte man "delay()" auch aus allen Beispielprogrmamen verbannen, die zur IDE mitgeliefert werden?
Ich wäre sofort dabei, neue Beispielprogramme für "Files - Examples" zu schreiben, damit diese vollständig
blockierungsfrei ohne "delay()" funktionieren
und
mit nullterminierten C-Strings statt mit String-Objekten arbeiten
wenn ich das von uwe verwende, wäre das ganze dann so
void loop() {
if( modus ==0 && (zeitBlackJetzt-zeitBlackDavor)>(sekunde*5)) // zeitanzeigemodus
{ neue Zeit ausgeben}
if(digitalread(blackPin)==HIGH) //1. mal drücken
modus = 1 // zeiteinstellmodus
if(digitalread(blackPin)==HIGH) //2. mal drücken
modus = 2 // zeiteinstellmodus
if(digitalread(blackPin)==HIGH) //3. mal drücken
modus = 0 // zurück zu normal
}
naja das geht ja nicht, dann etwas anders halt
void loop() {
if( modus ==0 && (zeitBlackJetzt-zeitBlackDavor)>(sekunde*5)) // zeitanzeigemodus
{ neue Zeit ausgeben}
if(digitalread(blackPin)==HIGH) //1. mal drücken
{
if(modus == 0)
modus = 1 // zeiteinstellmodus stunde
if(modus == 1)
modus = 2 // zeiteinstellmodus minute
if(modus == 2)
modus = 0 // zurück zu normal
}
}
hmm was mach ich jetzt wenn da jemand mal etwas länger auf den knopf drückt als wie das programm von der einen if(modus == 0) bis zur nächsten if(modus == 1) gekommen ist, also der user bis dahin den knopf nicht wieder losgelassen hat?
ohne interput wüsste ich es nicht zu lösen und inwiefern habe ich millis() falsch benutzt??
Du mußt den Taster nicht auf HIGH kontrollieren, sondern ob er das erste mal gedrückt wurde und ein kleines delay(10) hier darf man das!! einfügen zum Entprellen.
delay() ist Mist, das ist klar.
Wird aber nicht durch millis() ersetzt, wennschon durch if (millis() - startzeit > WARTEZEIT) !
Statt dessen muss die Zustandsführung sehr gut überlegt werden. Und dazu gehört bei Tastern, ob ein Taster gerade neu betätigt (oder losgelassen) wurde und ob diese Änderung schon verarbeitet ist.
Das wichtigste ist generell die Definition der Variablen zur Zustandsführung und die Bedeutung jedes Werts.
if (modus == 0) ist z.B. sehr nichtssagend, auch für den Ersteller selbst, nach einem Monat. enum {NORMAL, MINUTESTELLEN, STUNDESTELLEN} modus; ist die Variablendefinition und damit das, worauf es ankommt. Und kommt so sogar ohne Kommentartext aus.
Dazu brauchst du noch ein bool alterTasterZustand, um zu erkennen, dass der Taster neu betätigt wurde und du z.B. von modus==NORMAL auf modus=MINUTESTELLEN umschalten sollst.
if(digitalread(blackPin)==HIGH) //1. mal drücken
{
if(modus == 0)
modus = 1 // zeiteinstellmodus stunde
if(modus == 1)
modus = 2 // zeiteinstellmodus minute
if(modus == 2)
modus = 0 // zurück zu normal
}
kommt natürlich IMMER modus=0 raus, das solltest du unbedingt anders lösen!