INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
mehrere Taster abfragen
08.09.2014, 13:14
Beitrag #1
mehrere Taster abfragen
Hallo,

bin noch in der "Anfänger-Phase" mit ARDUINO. Habe hier mal ein Problem mit Tasterabfrage. Ich möchte permanent auf mehrere Taster reagieren können und das Programm dann was anderes machen lassen. In dem Fall ein Lauflicht-Beispiel.

Aber da der (im Moment noch eine) Taster im Hauptprogramm abgefragt wird, läuft erst das Unterprogramm zu Ende ehe darauf reagiert wird.
Das ist das erste Problem - es soll ja sofort abgebrochen werden. muss ich da die Abfrage in jedem Unterprogramm wiederholen?

Wenn ich jetzt 5 Tasten hätte: Wie kann ich auf alle diese Tasten mit unterschiedlichen Unterprogrammen reagieren? Und wie gesagt, sofort und nicht erst wenn ein Unterprogramm abgearbeitet ist....

Hier mein Code mit nur einem Taster (Bitte nicht über die möglicherweise unsinnigen Komentare wundern. Bin wie gesagt Anfänger und will das verstehen können)
Code:
/*    
Timer1-Interrupt zur Erzeugung von Zeiten benutzen.
Hier Blitzen einer LED.
Im Hauptprogramm Lauflicht UNABHAENGIG vom Interrupt-Blitzen!!
*/

// Initialisierungen
#include <TimerOne.h>  //Library einbinden

const int LED = 13;    //LED an Pin 13
const int BUTTON = 10;  //Taster an Pin 10
int msek = 0;  //Variable fuer Zaehler in ISR, initialisieren mit Wert=0
int timer = 30;           // 30msek als Timer für Lauflicht
int timer_blinken = 60;  // 60msek als Timer fuer Blinken



/// -------------------------------------------------------------
///              Setup (wird NUR EINMAL durchlaufen)
/// -------------------------------------------------------------
void setup()
{
pinMode(LED, OUTPUT);  //Pin13 als Ausgang  
pinMode(BUTTON, INPUT);  // Taster als Eingang
Timer1.initialize(10000); // setzen Timer auf 10000µsek = 10msek
Timer1.attachInterrupt( timerIsr ); // Interrupt-Routine hier
  // use a for loop to initialize each pin as an output:
for (int thisPin = 2; thisPin < 10; thisPin++)  {
pinMode(thisPin, OUTPUT);      
}
}


/// -------------------------------------------------------------
///                 Hauptprogramm (Endlosschleife)
/// -------------------------------------------------------------
void loop(){

  
if (BUTTON == LOW){    // wenn Taster gedrueckt
Blinken();    //Funktion (Unterprogramm) Blinken aufrufen
}  

Lauflicht();  //Funktion (Unterprogramm) Lauflicht aufrufen

}//**************** Ende Hauptprogramm ***************************



/// -------------------------------------------------------------
///                 Unterprogramm Lauflicht
/// -------------------------------------------------------------
void Lauflicht(){
for (int i = 0; i < 11; i++){
// loop from the lowest pin to the highest:
for (int thisPin = 2; thisPin < 10; thisPin++) {
// turn the pin on:
digitalWrite(thisPin, HIGH);  
delay(timer);   // Pause 30msek (Prozessor kann NICHTS anderes tun!!!!)              
// turn the pin off:
digitalWrite(thisPin, LOW);    
}

// loop from the highest pin to the lowest:
for (int thisPin = 9; thisPin >= 2; thisPin--) {
// turn the pin on:
digitalWrite(thisPin, HIGH);
delay(timer);  // Pause 30msek (Prozessor kann NICHTS anderes tun!!!!)
// turn the pin off:
digitalWrite(thisPin, LOW);
}
}
}//**************** Ende Unterprogramm ******************************



/// -------------------------------------------------------------
///                 Unterprogramm Blinken
/// -------------------------------------------------------------
void Blinken(){
for (int i = 0; i < 20; i++){    //20 mal Schleife durchlaufen zum Blinken aller LED's

for (int thisPin = 2; thisPin < 10; thisPin++) { //der Reihe nach alle Pins auf HIGH
digitalWrite(thisPin, HIGH);
}
delay(timer_blinken);    // 60msek warten
for (int thisPin = 2; thisPin < 10; thisPin++) { //der Reihe nach alle Pins auf LOW
digitalWrite(thisPin, LOW);
}
delay(timer_blinken);    // 60 msek warten
}
}//********************** Ende Unterprogramm ***********************



/// -------------------------------------------------------------
///                      ISR Timer Routine
/// -------------------------------------------------------------
void timerIsr()
{
msek = msek++;  //Variable um eins erhoehen

switch (msek)    // Auswahl treffen, anhand des Wertes von msek
{
case 1:        // wenn msek = 1 ist dann tue...
digitalWrite (LED, HIGH);    // das hier!!
break;        // stop, hier abbrechen. Nichts weiter tun.

case 3:      // siehe oben, dito
digitalWrite (LED, LOW);
break;

case 100:  //nach 1 sekunde
msek = 0;  //msek zuruecksetzen
break;
}   // Switch-Anweisung endet hier...

}
//******************  Ende ISR *******************************
Den Timer-Interrupt habe ich zum Testen eingebunden mit einer Blitz-LED.

Sorry, falls alles ziemlich trivial klingt, habe aber im Moment keine Idee, wie ich hier weiterkommen kann.

Gruß, Andreas
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2014, 15:51
Beitrag #2
RE: mehrere Taster abfragen
Interrupts sind da ein Stichwort: AttachInterrupt
Desweiteren solltest du die delay() Funktion loswerden: BlinkWithoutDelay
Damit könntest du auch auf Interrupts verzichten.

gruß lorenz
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.09.2014, 03:48 (Dieser Beitrag wurde zuletzt bearbeitet: 09.09.2014 04:40 von Corvus.)
Beitrag #3
RE: mehrere Taster abfragen
Hab deinen Code mal modifiziert, so dass sofort auf den Tastendruck reagiert wird:
Zitat:
/*    
Timer1-Interrupt zur Erzeugung von Zeiten benutzen.
Hier Blitzen einer LED.
Im Hauptprogramm Lauflicht UNABHAENGIG vom Interrupt-Blitzen!!
*/

// Initialisierungen
#include <TimerOne.h>  //Library einbinden

const int LED = 13; //LED an Pin 13
const int BUTTON = 10; //Taster an Pin 10

int msek = 0; //Variable fuer Zaehler in ISR, initialisieren mit Wert=0
int timer = 30; // 30msek als Timer für Lauflicht
int timer_blinken = 60; // 60msek als Timer fuer Blinken
int LauflichtPin = 2; // Startpin für Lauflicht
int LauflichtRichtung = -1; //Richtung des Lauflichts
boolean LauflichtAktiv = true; //wird erst benötigt, wenn Blinken() angepasst wurde
unsigned long nextEventTimer = 0;



/// -------------------------------------------------------------
///              Setup (wird NUR EINMAL durchlaufen)
/// -------------------------------------------------------------
void setup(){
  pinMode(LED, OUTPUT); //Pin13 als Ausgang
  pinMode(BUTTON, INPUT); // Taster als Eingang
  Timer1.initialize(10000); // setzen Timer auf 10000µsek = 10msek
  Timer1.attachInterrupt( timerIsr ); // Interrupt-Routine hier
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 2; thisPin < 10; thisPin++){
    pinMode(thisPin, OUTPUT);
  }
  



/// -------------------------------------------------------------
///                 Hauptprogramm (Endlosschleife)
/// -------------------------------------------------------------
void loop(){
  if (BUTTON == LOW){ // wenn Taster gedrueckt
    Blinken();    //Funktion (Unterprogramm) Blinken aufrufen
    // Lauflicht wieder auf Anfang setzen damit es nach dem Blinken nicht da weiter macht, wo es aufgehört hatte:
    LauflichtPin = 2;      
    LauflichtRichtung = -1;
  }  
  Lauflicht();  //Funktion (Unterprogramm) Lauflicht aufrufen
}//**************** Ende Hauptprogramm ***************************



/// -------------------------------------------------------------
///                 Unterprogramm Lauflicht
/// -------------------------------------------------------------

void Lauflicht(){
  if (LauflichtAktiv) { //Nur etwas tun, wenn Lauflicht aktiviert ist
    if (nextEventTimer<=millis()){ //Nur etwas tun, wenn der Timer für das nächste Ereignis abgelaufen ist
      nextEventTimer=millis()+timer; //setze den Timer 30ms weiter
      digitalWrite(LauflichtPin-LauflichtRichtung,LOW); //Letzte Diode abschalten
      digitalWrite(LauflichtPin,HIGH); //Aktuelle Diode einschalten
      if (LauflichtPin==2 || LauflichtPin==9) //Wenn erste oder letzte Diode erreicht sind, dann...
        LauflichtRichtung*=-1;                             //...ändere die Richtung
      LauflichtPin+=LauflichtRichtung;                   //Nächsten Pin in Laufrichtung wählen
    }
  }
//**************** Ende Unterprogramm ******************************



/// -------------------------------------------------------------
///                 Unterprogramm Blinken
/// -------------------------------------------------------------
void Blinken(){
for (int i = 0; i < 20; i++){ //20 mal Schleife durchlaufen zum Blinken aller LED's

for (int thisPin = 2; thisPin < 10; thisPin++) { //der Reihe nach alle Pins auf HIGH
digitalWrite(thisPin, HIGH);
}
delay(timer_blinken); // 60msek warten
for (int thisPin = 2; thisPin < 10; thisPin++) { //der Reihe nach alle Pins auf LOW
digitalWrite(thisPin, LOW);
}
delay(timer_blinken); // 60 msek warten

}//********************** Ende Unterprogramm ***********************



/// -------------------------------------------------------------
///                      ISR Timer Routine
/// -------------------------------------------------------------
void timerIsr()
{
msek = msek++;  //Variable um eins erhoehen

switch (msek) // Auswahl treffen, anhand des Wertes von msek
{
case 1: // wenn msek = 1 ist dann tue...
digitalWrite (LED, HIGH); // das hier!!
break; // stop, hier abbrechen. Nichts weiter tun.

case 3: // siehe oben, dito
digitalWrite (LED, LOW);
break;

case 100: //nach 1 sekunde
msek = 0;  //msek zuruecksetzen
break;
}   // Switch-Anweisung endet hier...

}
//******************  Ende ISR *******************************
(ungetestet)

Die Blinken() Funktion hab ich mal so gelassen, damit du auch noch was zu tun hast Wink

Ist in deinem Fall zwar noch irrelevant, aber generell ist es nicht verkehrt einen Taster zu entprellen. Dazu kannst du dir das Debounce Beispiel mal angucken.

gruß lorenz

PS: Alternativ könntest du auch Hardwareseitig jeden Taster zusätzlich mit einem Interrupt-Pin verbinden (z.B. mit Hilfe einer Diode) und in der ISR dann überprüfen welcher der Buttons gedrückt wurde. Um damit dann die entsprechende Aktion auszulosen. Aber solange es sich wie oben vermeiden lässt, würde ich von Interrupts abraten.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.09.2014, 14:21
Beitrag #4
RE: mehrere Taster abfragen
Hallo Lorenz,

danke für den Code - schaue ich mir heute abend an.
Wegen entprellen: Habe ich mit RC-Glied und 7414 gelöst. Geht gut.

Ja, ich WILL ja auch selbst machen. Aber manchmal braucht man einen Denkanstoss in die richtige Richtung.
Die Delays sind eine andere Baustelle... Sollen dann auch noch weg.

Gruss, Andreas
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.09.2014, 18:34
Beitrag #5
RE: mehrere Taster abfragen
(09.09.2014 14:21)DL1AKP schrieb:  Die Delays sind eine andere Baustelle... Sollen dann auch noch weg.
Gerade die Delays sind die Baustelle.

gruß lorenz
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
04.11.2014, 14:37
Beitrag #6
RE: mehrere Taster abfragen
Hallo Corvus,

ich schnall's nicht... Hab alles versucht, aber irgend wie geht es einfach nicht.
Es reagiert einfach nicht auf meine Tastendrücke...

Allein hier geht es schon nicht:
Code:
if (digitalRead(BUTTON_PIN) == HIGH){ // wenn Taster gedrueckt
    LauflichtAktiv = !LauflichtAktiv;    // invertieren
    delay(50);    //kurz warten
    Serial.println(LauflichtAktiv);
  }
Es wird immer "0" auf dem seriellen Monitor angezeigt. Eigentlich war meine Intention, die Boolean zu togglen....

Das gesamte Programm sieht so aus:
Code:
// Initialisierungen
const int LED = 13; //LED an Pin 13
const int BUTTON_PIN = 10; //Taster an Pin 10

int msek = 0; //Variable fuer Zaehler in ISR, initialisieren mit Wert=0
int timer = 30; // 30msek als Timer für Lauflicht
int timer_blinken = 60; // 60msek als Timer fuer Blinken
int LauflichtPin = 2; // Startpin für Lauflicht
int LauflichtRichtung = -1; //Richtung des Lauflichts
boolean LauflichtAktiv = true; //wird erst benötigt, wenn Blinken() angepasst wurde
unsigned long nextEventTimer = 0;


void setup(){
Serial.begin(9600);        // seriellen Port öffnen    
  pinMode(LED, OUTPUT); //Pin13 als Ausgang
  pinMode(BUTTON_PIN, INPUT); // Taster als Eingang
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 2; thisPin < 10; thisPin++){
    pinMode(thisPin, OUTPUT);
  }
  
}

void loop(){
    
  if (digitalRead(BUTTON_PIN) == HIGH){ // wenn Taster gedrueckt
    LauflichtAktiv = !LauflichtAktiv;    // invertieren
    delay(50);    //kurz warten
    Serial.println(LauflichtAktiv);
  }
    
  //Blinken();    //Funktion (Unterprogramm) Blinken aufrufen
  Lauflicht();  //Funktion (Unterprogramm) Lauflicht aufrufen
}

void Lauflicht(){
  if (LauflichtAktiv = true) { //Nur etwas tun, wenn Lauflicht aktiviert ist
        if (nextEventTimer<=millis()){ //Nur etwas tun, wenn der Timer für das nächste Ereignis abgelaufen ist
          nextEventTimer=millis()+timer; //setze den Timer 30ms weiter
          digitalWrite(LauflichtPin-LauflichtRichtung,LOW); //Letzte Diode abschalten
          digitalWrite(LauflichtPin,HIGH); //Aktuelle Diode einschalten
            if (LauflichtPin==2 || LauflichtPin==9) //Wenn erste oder letzte Diode erreicht sind, dann...
              LauflichtRichtung*=-1;                             //...ändere die Richtung
              LauflichtPin+=LauflichtRichtung;                   //Nächsten Pin in Laufrichtung wählen
    }
  }
}


void Blinken(){

// Lauflicht wieder auf Anfang setzen damit es nach dem Blinken nicht da weiter macht, wo es aufgehört hatte:
LauflichtPin = 2;
LauflichtRichtung = -1;

if (LauflichtAktiv = false) { //Nur etwas tun, wenn Lauflicht NICHT aktiviert ist
    if (nextEventTimer<=millis()){ //Nur etwas tun, wenn der Timer für das nächste Ereignis abgelaufen ist
        nextEventTimer=millis()+timer; //setze den Timer 30ms weiter
        for (int thisPin = 2; thisPin < 10; thisPin++) { //der Reihe nach alle Pins auf HIGH
            digitalWrite(thisPin, !digitalRead(thisPin));    // Pin invertieren (togglen)
        }
    }
}
}

Entschuldigung, falls da irgendwas komplett dummes steht. Aber es geht mir einfach nicht ein... Hoffentlich geht aus meinem Code hervor, wie es wirklich funktionieren soll? Also ein Tastendruck soll (sofort) jeweils von Lauflicht nach Blinken umschalten, und umgekehrt. Eigentlich sollte es nur ein Beispiel sein, um das Prinzip der delay-freien Programmierung zu erkennen. Hätte nie gedacht, das ein simples Lauflicht so schwierig ist...

Könnte ich da noch mal etwas Hilfe bekommen? Möglicherweise ist es nur etwas kleines... Compilieren geht ohne Fehlermeldungen.

Gruß, Andreas
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
04.11.2014, 17:54 (Dieser Beitrag wurde zuletzt bearbeitet: 04.11.2014 17:55 von Corvus.)
Beitrag #7
RE: mehrere Taster abfragen
hier steckt der Fehler:
Code:
if (LauflichtAktiv = false)
if (LauflichtAktiv = true)

Ein einzelnes '=' ist ein Zuweisungsoperator.
Du brauchst hier aber einen komparativen Operator, also '==':

Code:
if (LauflichtAktiv == false)
if (LauflichtAktiv == true)

ich würde allerdings folgendes vorziehen:
Code:
if (!LauflichtAktiv)
if (LauflichtAktiv)
das ist dann eher eine Stilfrage.
gruß lorenz
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
04.11.2014, 17:59
Beitrag #8
RE: mehrere Taster abfragen
Mhhh... wie dumm von mir... Angry
Ja, danke - ist wohl ein Anfängerfehler..

Genau, jetzt steht im seriellen Monitor das richtige.
Hoffe den Rest kriege ich jetzt auch noch hin.
Im Moment erst mal kein Blinken, es leuchtet nur eine LEDHuh

Schaue es mir morgen mal an.
Vielen Dank erst mal.

Grüße
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  LED Zustand abfragen Nafetz 35 807 Gestern 10:09
Letzter Beitrag: hotsystems
  mehrere Taster entprellen Kitt 15 489 24.10.2016 21:17
Letzter Beitrag: georg01
  Byte Shiften und Bit abfragen.... comfan 4 201 02.09.2016 20:30
Letzter Beitrag: comfan
  Taster für mehrere Funktionen matthias3579 5 345 16.08.2016 16:00
Letzter Beitrag: StephanBuerger
  Steuern von 4 Servo mittels eines Taster und eines Potis Jackie09 17 748 16.07.2016 11:43
Letzter Beitrag: Binatone
  Mehrere Wertabfragen blebbens 5 370 18.06.2016 22:58
Letzter Beitrag: Scheams
  2 und mehrere Led´s mit Fernbedienung AN / AUS + Blinkfunktion Golffahrer 22 932 07.06.2016 11:31
Letzter Beitrag: hotsystems
  Schwellwert mit Taster ändern malsehen 16 1.410 12.04.2016 20:11
Letzter Beitrag: malsehen
  Mehrere Abläufe gleichteitig mit "Millis" MarkusSpielt 3 652 11.04.2016 18:23
Letzter Beitrag: MarkusSpielt
  3 Schrittmotoren, 2 LED's 1 Taster cichla 0 388 31.03.2016 15:21
Letzter Beitrag: cichla

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste