ich habe eine Funktion, die die dauer eines Tastendrucks auswertet und daraufhin etwas tut. Das Problem ist jetzt, wenn ich z.B. den Taster 5 Sekunde gedückt halte werden bei meinem Code auch alle anderen dinge getan, die bei 1 - 4 Sekunden gedückten Taster passieren sollen. Jetzt will ich aber natürlich, dass nur die eine Funktion ausgeführt werden soll. Ich hab überlegt, dass ich erst eine gewisse Zeit warte und dann erst die entsprechenden Befehle ausführe. Finde aber ich eher unschön, wenn ich jetzt Beispielsweise den Taster 1 Sekunde drücke und dann erst 10 Sekunden warte, bevor ich das passiert, was bei 1 Sekunde gedückten Taster passieren soll.
Hat jemand da eine Idee, wie ich das lösen kann?
Mfg
int8_t Taster_alt;
#define TASTER_GEDRUECKT 1
#define TASTER_NICHT_GEDRUECKT 2
#define TASTER_LOSGELASSEN 3
#define TASTER_1SEK_GEDRUECKT 4
#define TASTER_2SEK_GEDRUECKT 5
#define TASTER_3SEK_GEDRUECKT 6
#define TASTER_4SEK_GEDRUECKT 7
#define TASTER_5SEK_GEDRUECKT 8
void Tasterabfrage()
{
// == Tasterauswertung ==
byte Bla = Taster();
if (Taster_alt != Bla)
{
if (Bla == 5) // tu was
if (Bla == 6) // tu was
if (Bla == 7) // tu was
if (Bla == 8) // tu was
}
Taster_alt = Bla; // Aktuellen Wert abspeichern
}
byte Taster() //== Tasterabfrage ==
{
static unsigned long startzeit;
static bool Taster_status;
bool Taster_gedrueckt = !digitalRead(D4); // Taster nach GND geschaltet
if ((Taster_gedrueckt) && (! Taster_status))
{
startzeit = millis();
Taster_status = true;
delay(5); // entprellen
return TASTER_GEDRUECKT;
}
if ((Taster_gedrueckt) && (Taster_status))
{
if (((millis() - startzeit) >= 1000) && ((millis() - startzeit) <= 2000))
return TASTER_1SEK_GEDRUECKT;
else if (((millis() - startzeit) >= 2000) && ((millis() - startzeit) <= 3000))
return TASTER_2SEK_GEDRUECKT;
else if (((millis() - startzeit) >= 3000) && ((millis() - startzeit) <= 4000))
return TASTER_3SEK_GEDRUECKT;
else if (((millis() - startzeit) >= 4000) && ((millis() - startzeit) <= 5000))
return TASTER_4SEK_GEDRUECKT;
else if (((millis() - startzeit) >= 5000) && ((millis() - startzeit) <= 6000))
return TASTER_5SEK_GEDRUECKT;
else
return false;
}
if ((!Taster_gedrueckt && Taster_status))
{
Taster_status = false;
delay(5);
return TASTER_LOSGELASSEN;
}
return TASTER_NICHT_GEDRUECKT;
}
Du hast nicht nur ein Problem.
Warum machst Du das:
void Tasterabfrage()
{
// == Tasterauswertung ==
byte Bla = Taster();
if (Taster_alt != Bla)
{
if (Bla == 5) // tu was
if (Bla == 6) // tu was
if (Bla == 7) // tu was
if (Bla == 8) // tu was
}
Taster_alt = Bla; // Aktuellen Wert abspeichern
}
neu:
if (Taster_alt != Bla)
{
switch (bla)
{
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
default:
break:
}
Taster_alt = Bla; // Aktuellen Wert abspeichern
}
Hallo,
ich habe deinen Sketch als Pseudocode angenommen und einen gestesten Sketch erstellt. Probier mal aus ob diese Lösung zu deinem Projekt passt.
// timer für die Tasterabfrage
struct TIMER {
unsigned long stamp;
unsigned long duration;
};
TIMER buttonScan {0, 20}; // alle 20 msec wird auf eine Änderung geschaut
// Datenstruktur für den Taster
struct INPUT_ {
int pin;
int state;
unsigned long time01;
};
INPUT_ button {A0, 0, 0};
void setup() {
pinMode (button.pin, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
Tasterabfrage();
}
void Tasterabfrage() {
if (millis() - buttonScan.stamp >= buttonScan.duration) {
buttonScan.stamp = millis();
// ist der Taster gedrückt worden?
bool state = !digitalRead(button.pin);
if (button.state != state) {
// den aktuellen Status speichern
button.state = state;
// wenn der Taster losgelassen worden ist, dann mit der Zeitdifferenz in die Auswertung
if (!state) makeTime(((int)millis() - button.time01) / 100);
// wenn der Taster gedrückt worden ist, dann die Zeit speichern
else button.time01 = millis();
}
}
}
void makeTime (int time) {
switch (time) {
case 0 ... 9: Serial.println(F("1. Sekunde")); break;
case 10 ... 19: Serial.println(F("2. Sekunde")); break;
case 20 ... 29: Serial.println(F("3. Sekunde")); break;
case 30 ... 39: Serial.println(F("4. Sekunde")); break;
case 40 ... 49: Serial.println(F("5. Sekunde")); break;
case 50 ... 59: Serial.println(F("6. Sekunde")); break;
case 60 ... 69: Serial.println(F("7. Sekunde")); break;
default: Serial.println(F("größer als 7 Sekunden")); break;
}
}
Der Code krankt auch sonst - Es war nur ein gut gemeinter Hinweis.
Ungehört. Nu gut...
Hier gehört ein Byte rein für den PIN und ein bool für den state.
zu dem int:
makeTime(((int)millis() - button.time01) / 100);
Das halte ich für kreuzgefährlich, denn mit jedem Mal, wo millis() am int überläuft, kommt es zu einem negativen Vorzeichen....
Probier es aus:
unsigned long x = 0;
int y=0;
void setup() {
Serial.begin(115200);
Serial.println(F("Start..."));
for (uint8_t i=0; i<10; i++)
{
x+=32767;
y=(int)x;
Serial.print(x);
Serial.print("\t");
Serial.println(y);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
Was darüber hinaus passiert, las ich mal so stehen,...
Das macht er ja eigentlich.
Das casten auf (signed) int ist falsch und an der Stelle wo es jetzt steht auch.
Man könnte jetzt drüber nachdenken, ob die Typumwandlung nach der Subtraktion und vor der Division oder erst nach der Division erfolgen soll.
Ich würde definitiv zu letzterem tendieren.
Mit der expliziten Typumwandlung soll ja der Bereich fürs case abgedeckt werden. Das geht auch. nur eben nicht da