Hallo,
ich suche einen timer der ohne die millis() Methode funktioniert.
Es geht darum ich habe ein Projekt dort will ich eine Zeit auf einem Segmentdisplay ausgeben. Die Zeit wird mit einem Button bei gedrückt halten gestartet und beim loslassen angehalten. Nun ist es auch so dass diese Zeit über einen längeren Zeitraum gespeichert werden soll.
Mit der millis() würde ich ja immer nur die Zeit seit dem Boardstart haben, und ich wüsste auch nicht wie ich das realisieren sollte.
Hier ist mal mein momentaner Sketch:
#include "SevSeg.h"
SevSeg sevseg;
int button = 2; //Button pull up
int buttonSig = 0; //Button pull up
long myTimer = 0;
long myTimeout = 1000;
int min=0;
void setup() {
byte digitPins[]={3,4,5};
byte segmentPins[]={6,7,8,9,10,11,12,13};
bool updateWithDelays = false; // Default 'false' is Recommended
bool disableDecPoint = true;
sevseg.begin(COMMON_ANODE,2,digitPins,segmentPins,updateWithDelays,disableDecPoint);
sevseg.setBrightness(90);
pinMode(button, INPUT); //Button pull up
digitalWrite(button, HIGH); //Button pull up
Serial.begin(9600);
}
void loop() {
buttonSig = digitalRead(button);
if (millis() > myTimeout + myTimer && buttonSig == LOW) {
myTimer = millis();
min+=1;
sevseg.setNumber(min);
Serial.print("Botton: ");
Serial.println(buttonSig);
Serial.print("Minuten: ");
Serial.println(min);
}
sevseg.refreshDisplay();
}
Mit der millis() würde ich ja immer nur die Zeit seit dem Boardstart haben, und ich wüsste auch nicht wie ich das realisieren sollte.
dann merk die die aktuellen millis() in einer Variable wenn du deine Taste drückst, dann kannst du immer wieder deine Variable befragen, wann du die Taste gedrückt hast.
auch wenn millis() schon weiter ist.
Wie kannst Du feststellen, wie lange Du zum Brötchenholen die Wohnung verläßt? Deine Armbanduhr kannst Du vergessen, denn die zeigt ja nur die Zeit seit Mitternacht an, also unbrauchbar.
Oder?
Genauso wie mit Deiner Armbanduhr (Zeit Ankunft - Zeit Weggehen) machst Du das auch mit millis().
Deine analoge Armbanduhr läuft nach 12 Stunden "über", millis() nach ca. 49 Tagen, da muß man dann nochmal genauer überlegen.
Hallo,
danke für eure Tipps. Ich habe das Ganze jetzt mal wie bei BlinkWithoutDelay umgeschrieben.
Aber ich muss sagen ich komme nicht drauf. Nehmen wir mal an ich speichere den Wert in einer Variablen und er beträgt beim loslassen des Buttons 50.000 und beim erneuten drücken sind die millis() auf 100.000 weitergelaufen.
So wie bringe ich nun wieder in den richtigen "Rhythmus", ohne dass mir was verloren geht? Intervall = 60.000.
#include "SevSeg.h"
SevSeg sevseg;
int button = 2; //Button pull up
int buttonSig = 0; //Button pull up
unsigned long previousMillis = 0;
const long interval = 60000;
int min=0;
void setup() {
byte digitPins[]={3,4};
byte segmentPins[]={6,7,8,9,10,11,12,13};
bool updateWithDelays = false; // Default 'false' is Recommended
bool disableDecPoint = true;
sevseg.begin(COMMON_ANODE,2,digitPins,segmentPins,updateWithDelays,disableDecPoint);
sevseg.setBrightness(90);
pinMode(button, INPUT); //Button pull up
digitalWrite(button, HIGH); //Button pull up
Serial.begin(9600);
}
void loop() {
buttonSig = digitalRead(button);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval && buttonSig == LOW) {
previousMillis = currentMillis;
min+=1;
sevseg.setNumber(min);
Serial.print("Botton: ");
Serial.println(buttonSig);
Serial.print("Minuten: ");
Serial.println(min);
}
sevseg.refreshDisplay();
}
Hallo,
ich habe versucht Deinen Eingangstext zuverstehen:
Du suchst eine Stoppuhr, die beim drücken des Tasters die Zeitmessung startet, beim losLassen stoppt und die Zeitdifferenz zur Anzeige auf dem 7-Segement bringt?
also das Prinzip ist nicht so ein Mirakel. Aufpassen halt wegen Debounce und stateChangeDetection. Aber dafür gibt es auch schöne Beispiele in der IDE.
Du suchst eine Stoppuhr, die beim drücken des Tasters die Zeitmessung startet, beim losLassen stoppt und die Zeitdifferenz zur Anzeige auf dem 7-Segement bringt?
Ja so könnte man es auch sagen. Also die Differenz zwischen drücken und loslassen. ALSO es soll sich wären dessen ändern. Wie ein counter
mastershredder:
ich suche einen timer der ohne die millis() Methode funktioniert.
Ich denke eher nicht.
Eigentlich schöne Schrittkette - warten - auslösen - zählen - stoppen
Geht aber auch mit Schachteln.
Zusammengebastelt, also ungetestet und nur mal zum probieren, ob es das ist, was Du meinst.
Deine loop() damit ersetzen ...
[edit] noch ne Variable vergessenn..[/edit]
void loop() {
static bool laststate = HIGH;
static unsigned long startmillis = 0;
static int lastmin = min;
buttonSig = LOW;
if (buttonSig == LOW) // Taste gedrückt?
{
if (laststate == HIGH) // Vorher nicht gedrückt?
{
laststate = LOW; // Setze Startzustand
startmillis = millis();
min = 0;
}
if ((millis() - startmillis) % 1000 == 0) // Zeit läuft?
{
if (lastmin != min) {
min += 1;
lastmin = min;
sevseg.setNumber(min);
}
Serial.print("Botton: ");
Serial.println(buttonSig);
Serial.print("Minuten: ");
Serial.println(min);
}
else
{
lastmin = -1;
}
}
else // Taste nicht gedrückt?
{
laststate = HIGH; // Beende Startzustand
}
sevseg.refreshDisplay();
}
ich suche einen timer der ohne die millis() Methode funktioniert.
Das ist nicht dein Problem.
Ganz im Gegenteil.
Es geht darum ich habe ein Projekt dort will ich eine Zeit auf einem Segmentdisplay ausgeben. Die Zeit wird mit einem Button bei gedrückt halten gestartet und beim loslassen angehalten. Nun ist es auch so dass diese Zeit über einen längeren Zeitraum gespeichert werden soll.
Das hört sich doch nach einer klassischen Stoppuhr an....
Eine Stoppuhr aus meiner Wühlkiste:
(leicht für diese Anforderungen angepasst)
Taster an 2 losgelassen, die Uhr steht
Taste an 2 gedrückt, die Uhr läuft weiter.
Die Uhr zählt also nur die ms, wie lange der Knopf gedrückt wurde.
Maximaler Zeitraum: 49,x Tage.
Aber jetzt erst mal erkläre ich mal mein ganzes Projekt dass man versteht was ich will:
Also ich habe einen Staubsauger der einen ziemlich kleinen Akku hat, und keinerlei Anzeige dafür. Ich weiß das er ca. 25min hält aber jach. Es gibt so ein Phänomen dass immer wenn ich was größeres saugen will das Ding nur noch 5min Saft hat >:( sehr ärgerlich. Ich habe mir jetzt gedacht wenn ich hingehe und immer wenn ich den Staubsauger anmache, einen Button mit drücke und dann die Zeit(in Minuten) wie ich sauge hoch zählt und ich sie auf einem Segmentdisplay angezeigt bekomme wäre das doch schon eine coole Sache.
Dann habe ich wenigstens eine kleine Orientierung
Wenn der Akku dann leer ist und wieder vollgeladen, einfach reset und fertig.
Dass heißt dann auch das der Microcontroller an einer Batterie hängt. Display kann man noch sehen dass man dies noch abschalten kann.
mastershredder:
Wirklich interessante Vorschläge. my_xy_projekt: Deiner geht noch nicht so ganz.
Dochdoch, der geht. ganz.
Jede Sekunde zählt der min++ - Das war Absicht!
Wenn Du jetzt nicht sekunde sondern min haben willst, musst Du da *60 nehmen.
Dann hier mal die Variante in kurz
void loop() {
static bool laststate = HIGH;
const unsigned long intervall = 10; // Zeit in ms
static unsigned long startmillis = 0; // Merker
static unsigned long tik = 0; // yo...
buttonSig = digitalRead(button);
if (buttonSig == LOW) // Taste gedrückt?
{
if (laststate == HIGH) // Vorher nicht gedrückt?
{
laststate = LOW; // Setze Startzustand
startmillis = millis();
min = 0;
}
if (millis() - startmillis > tik) // Zeit läuft?
{ tik += intervall;
min++;
}
Serial.print("Botton: ");
Serial.println(buttonSig);
Serial.print("Minuten: ");
Serial.println(min);
}
else // Taste nicht gedrückt?
{
laststate = HIGH; // Beende Startzustand
}
}
Die Zeit wird mit einem Button bei gedrückt halten gestartet und beim loslassen angehalten. Nun ist es auch so dass diese Zeit über einen längeren Zeitraum gespeichert werden soll.
Hm. Hab ich doch den zweiten Satz überlesen...
Na nichts leichter als das:
Lösche doch einfach das rücksetzen der min!
min = 0;
Zeile gelöscht und schon aufaddiert.
[edit]
mastershredder:
Wenn der Akku dann leer ist und wieder vollgeladen, einfach reset und fertig.
Ich frag mich grad, ob es nicht besser wäre einfach den Akku abzufragen.
Angezeigt wird dann mit einer RGB-LED whatever und das nur, solange button == pressed....
Aber Vorsicht - das ginge wohlmöglich ohne ARDUINO; da fehlt dann das schöpferische...
Hallo
ich habe auch noch eine Stoppuhr in der Sketch Restekiste gefunden, den du ganz einfach an deine 7-Segment Ausgabe anpassen kannst. Dieser Sketch arbeitet allerdings mit der millis() Funktion, wenn es dich nicht stört .
t // Forum: Suche timer ohne millis()
// Autor: paulpaulson
// Sketch aus der Restekiste
struct ENTPRELLEN {
unsigned long zeitStempel;
unsigned long zeitDauer = 20;
};
ENTPRELLEN entprellen;
struct TASTER {
int pin = 2;
bool status = HIGH;
};
TASTER taste;
void setup()
{
pinMode(taste.pin, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.print(F("und los geht´s mit Taster an Pin ")), Serial.println(taste.pin);
}
void loop()
{
static unsigned long jetztZeit;
static unsigned long startZeit;
static bool anzeige;
jetztZeit = millis();
digitalWrite(LED_BUILTIN,jetztZeit/500%2);
bool buttonGelesen = digitalRead(taste.pin);
if (jetztZeit - entprellen.zeitStempel >= entprellen.zeitDauer) {
entprellen.zeitStempel = jetztZeit;
if (taste.status != buttonGelesen) taste.status = buttonGelesen;
if (!taste.status) {
if (!anzeige) anzeige = true, startZeit = jetztZeit;
} else {
if (anzeige) anzeige = false, Serial.print((jetztZeit - startZeit)/60000), Serial.println(" min");
}
}
}
Ich frag mich grad, ob es nicht besser wäre einfach den Akku abzufragen.
Aber Vorsicht - das ginge wohlmöglich ohne ARDUINO; da fehlt dann das schöpferisch
Also ich bleibe lieber jetzt mal bei der Methode. Habe auch noch nicht so viel Ahnung davon.
Aber jach also my_xy_projekt deine Methode hab ich nun mal rein kopiert. Die könnte fast funktionieren.
Da ist nur eine Sache: Ich drücke den Button es zählt hoch, wunderbar. Dann beim zweiten Mal sind es unterschiedliche ZEITEN wo NICHTS passiert bis es weiter läuft. Also es hängt mal kurz mal lang. Ich habe auch noch was als Kommentar in den Sketch geschrieben.
#include "SevSeg.h"
SevSeg sevseg;
int button = 2; //Button pull up
int buttonSig = 0; //Button pull up
//unsigned long previousMillis = 0;
//const long interval = 1000;
int min=0;
//int startmillis;
void setup() {
byte digitPins[]={3,4};
byte segmentPins[]={6,7,8,9,10,11,12,13};
bool updateWithDelays = false; // Default 'false' is Recommended
bool disableDecPoint = true;
sevseg.begin(COMMON_ANODE,2,digitPins,segmentPins,updateWithDelays,disableDecPoint);
sevseg.setBrightness(90);
pinMode(button, INPUT); //Button pull up
digitalWrite(button, HIGH); //Button pull up
Serial.begin(9600);
}
void loop() {
static bool laststate = HIGH;
const unsigned long intervall = 1000; // Zeit in ms
static unsigned long startmillis = 0; // Merker
static unsigned long tik = 0; // yo...
buttonSig = digitalRead(button);
if (buttonSig == LOW) // Taste gedrückt?
{
if (laststate == HIGH) // Vorher nicht gedrückt?
{
laststate = LOW; // Setze Startzustand
startmillis = millis();
} // Haben diese beiden millis bzw startmilis und millis() nicht den genau gleichen Wert, und heben sich so gegenseitig wieder auf?
if (millis() - startmillis > tik) // Zeit läuft?
{ tik += intervall;
min++;
sevseg.setNumber(min);
}
Serial.print("Botton: ");
Serial.println(buttonSig);
Serial.print("Minuten: ");
Serial.println(min);
}
else // Taste nicht gedrückt?
{
laststate = HIGH; // Beende Startzustand
}
sevseg.refreshDisplay();
}
paulpaulson Der Sketch aus deiner Restekiste sieht auch interessant aus. Aber da hätte ich ein paar Fragen. Habe sie als Kommentar in den Sketch geschrieben.
t // Forum: Suche timer ohne millis()
// Autor: paulpaulson
// Sketch aus der Restekiste
struct ENTPRELLEN {
unsigned long zeitStempel;
unsigned long zeitDauer = 20;
};
ENTPRELLEN entprellen;
struct TASTER {
int pin = 2;
bool status = HIGH;
};
TASTER taste;
void setup() {
pinMode(taste.pin, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.print(F("und los geht´s mit Taster an Pin ")), Serial.println(taste.pin);
}
void loop() {
static unsigned long jetztZeit;
static unsigned long startZeit;
static bool anzeige;
jetztZeit = millis();
// Was übergiebst du da für einen Wert du Teilst doch da durch 0 oder nicht?
digitalWrite(LED_BUILTIN,jetztZeit/500%2);
bool buttonGelesen = digitalRead(taste.pin);
if (jetztZeit - entprellen.zeitStempel >= entprellen.zeitDauer) {
entprellen.zeitStempel = jetztZeit;
if (taste.status != buttonGelesen) taste.status = buttonGelesen;
if (!taste.status) {
if (!anzeige) anzeige = true, startZeit = jetztZeit; }
// Zu welchem if Block gehört dieses else, zum obersten?
else {
if (anzeige) anzeige = false, Serial.print((jetztZeit - startZeit)/60000), Serial.println(" min");
}
}
}