ich baue momentan einen Kameraslider, der in verschiedenen verschwindigkeiten fahren soll. Angetrieben über einen Schrittmotor.
Die Geschwindigkeit kann man über zwei Taster einstellen, plus und minus.
Momentan habe ich für das Abfragen der Buttons das "Debounce" Scatch benutzt, das als Beisipel in der IDE enthalten ist. Momentan muss man für jede Änderung ein mal drücken.
Da ich nun aber 50 verschiedene Geschwindigkeiten habe, würde ich gerne eine Möglichkeit haben, den Taster entweder ein mal kurz zu drücken (+ oder - 1) oder, wenn ich ihn z.b. für länger als eine Sekunde gedrückt halte, soll z.b. alle 0,5 Sekunden der Geschwindigkeitswert um eins erhöht werden.
Leider habe ich keine Ahnung wie ich sowas angehen kann
Wie würde man sowas programmieren, ohne mit delay gleich den ganzen Ablauf aufzuhalten?
Wenn der gleichzeitig mit einem der beiden anderen gedrückt wird,
verwendest/toggelst du den 2. Modus ("alle 0,5 Sekunden der Geschwindigkeitswert um eins erhöhen").
Nicht direkt im Arduino-Stil geschrieben. Entweder portierst du das ganze selber, oder aber du wartest. Der ein oder andere hat sich die vielleicht für Arduino schon angepasst
Die Timerteil muss nich übernommen werden. Wenn man alle 10ms die Funktion in der loop aufruft, reicht das.
michael_x:
Schon imposant, die Assembler - Routine für 8 Taster gleichzeitig.
Gibt allerdings viele "Wege, die dran vorbei führen", auch in deinem gelinkten Artikel und in den dort aufgeführten Links
Mir ging es eigentlich um die C Komfortroutine, aber die asm ist auch bekannt. Nur braucht es die Performance echt nicht
Du könntest es auch mit einer Variablen lösen, die bei gedrücktem button über millis() und modulo hochzählt oder so eine Funktion aufgerufen wird, die den Geschwindigkeitswert ändert.
Etwas spät, aber ich wollte mal meine letzliche Lösung vorstellen, für den fall dass mal jemand über diesen Thread stößt
War am ende eigentlich recht einfach, habe es über millis gelöst und keine anderen library bemüht.
Basis dafür war das Debounce Beispiel aus der Arduino IDE. Ich habe den Sketch dann etwas erweitert, und jetzt führt er ein mal beim Runter drücken des Buttons ein mal code aus, wartet dann x millis und führt ab dann so lange alle y millis einen Code aus, bis man den Button wieder los lässt.
Ideal um z.b. Zähler hoch zählen zu lassen, wie bei mir für Geschwindigkeiten eines Motors oder für Lautstärken oder sonst was, wo es viele Optionen gibt, wie man mit einem Taster hoch und runter zählen lassen will.
int inPin1 = 6; //Input Pin
int buttonState1; //Wird fuer Debounce Benoetigt. Aus dem Beispielsketch
int lastButtonState1 = LOW; //Wird fuer Debounce Benoetigt. Aus dem Beispielsketch
long lastDebounceTime1 = 0; //Wird fuer Debounce Benoetigt. Aus dem Beispielsketch
long debounceDelay = 50; //Wird fuer Debounce Benoetigt. Aus dem Beispielsketch
long startLow1; //Speichert Millis sobald der Button runter gedrückt wird
long startLowEachPlus1; //Speichert Zeit (Millis) wann das nächste mal automatisch erhöht werden soll
int zaehler = 0; //Dient nur Testzwecken. Dieser Zähler wird ein mal beim runter drücken hoch gezählt und dann nach einer Sekunde alle 300 millis ein mal
boolean checkLongPress = false; //Damit der Code für automatisches Hochzählen nur ausgeführt wird, wenn der Button runter gedrückt wird. Ist entweder true oder false
int waitMillisTillLong = 1500; //Wie lange nach runter drücken gewartet werden soll, bis automatisches hochzählen beginnt
int waitMillisAfterEach = 200; //Alle wie viel Millis automatisch hochgezählt wird
void setup() {
Serial.begin(9600);
pinMode(inPin1, INPUT);
}
void loop() {
int reading1 = digitalRead(inPin1); //Debounce
if (reading1 != lastButtonState1) { //Debounce
lastDebounceTime1 = millis(); //Debounce
}
if ((millis() - lastDebounceTime1) > debounceDelay) { //Debounce
if (reading1 != buttonState1) { //Debounce
buttonState1 = reading1; //Debounce
if (buttonState1 == LOW) { //Debounce. LOW wenn Pull-Up genutzt wird. Bei Pull-Down muss es auf HIGH geändert werden
startLow1 = millis(); //Millis zum Zeitpunkt, wenn der Button runter gedrückt wird
startLowEachPlus1 = (millis() + waitMillisTillLong); //Millis, wann das erste mal automatisch hochgezählt werden soll
checkLongPress = true; //Schaltet den "Modus" ein, so dass geprüft wird, ob der Button länger als x millis gedrückt wurde
//Hier kommt der Code hin, der ein mal beim runter drücken ausgeführt werden soll, zb die nächsten beiden Zeilen
zaehler++; //Test zähler schon mal hoch zählen
Serial.println(zaehler); //und ausgeben
}
if (buttonState1 == HIGH) {
checkLongPress = false; //Modus zum prüfen ob lange gedrückt wurde wieder ausschalten
}
}
}
lastButtonState1 = reading1; //Debounce
if (checkLongPress == true) { //wenn der Button runter gedrückt wurde, wird angefangen zu prüfen
if (millis() - startLow1 > waitMillisTillLong) { //Nach der eingestellten Zeit wird wird etwas erstmals ausgeführt
if (millis() - startLowEachPlus1 > waitMillisAfterEach) { //Nach eingestellter Zeit für automatisches Hochzählen wird das hier ausgeführt
startLowEachPlus1 = startLowEachPlus1 + waitMillisAfterEach; //Zeit hochsetzen für nächtes Automatisches erhöhen
//Hier kommt der Code hin, der alle x millis automatisch ausgeführt werden soll wie zb die nächsten beiden zeilen
zaehler++; //Zähler automatisch hochsetzen
Serial.println(zaehler); //und ausgeben
}
}
}
}
Ich hoffe, dass das in Zukunft mal jemandem helfen kann