ARDUINO - Schalter während einem Programm dauerhaft abfragen?

3 Antworten

bool boSchalterGedrueckt = False;

void loop(void)
{
  
  if(Schalter == Gedrückt)
    boSchalterGedrueckt = True;

  /* Do some stuff */

}

Sowas?

Debouncing sollte berücksichtig werden, entweder hardwareseitig (Kondensatorschaltung oder über GPIO-Funktionen des Pins), oder über Software (Button muss z.B. 5x als gedrückt erkannt werden, dass er als gedrückt erkannt wird).

Woher ich das weiß:Studium / Ausbildung – Masterstudium Elektrotechnik - Schwerpunkt Embedded Systems
griepie 
Fragesteller
 22.09.2020, 10:26

Jein - das Programm sollte ja im void loop was ausführen (mit delays) und der Schalter sollte einfach immer überprüft werden und dann den bool ändern - sprich unabhängig vom loop agieren

0
Gehilfling  22.09.2020, 10:35
@griepie

Delays würde ich nicht verwenden, die nutzen im Arduino "busy waiting". Nimm lieber Timer. Oder du liest deinen Schalter über einen GPIO-Interrupt ein.

0

Du widersprichst dich. Zuerst schreibst Du:

Ich würde in einem Programm gerne einen Schalter immer abfragen. Das ganze soll aber passieren während der Arduino eben seine void loop() Schleife "abarbeitet".

Der Schalterzustand soll also immer in der "loop" abgefragt werden. Das nennt man Polling. Nachteil: Wird der Schalter schnell wieder ausgeschaltet während der Ausführung des Restprogramms oder der Schalter "Prellt" geht die Information verloren.

Dann schreibst aber im Kommentar:

das Programm sollte ja im void loop was ausführen (mit delays) und der Schalter sollte einfach immer überprüft werden und dann den bool ändern - sprich unabhängig vom loop agieren

Schalter "einfach immer überprüfen" geht in dem Fall wo das Programm etwas anderes ausführt natürlich nicht. Um keine Schalteränderung zu verpassen (Prellen bedarf andere Maßnahmen) siehe Beispiel 2 ISR (Interrupt Service Routine).

Beispiel 1 Polling:

int SchalterPin = 4;
bool SchalterStatus = false;
void setup()
 {               
 pinMode(SchalterPin,  INPUT);
 }
void loop()
{
 if (digitalRead(SchalterPin) == HIGH)
   {
   SchalterStatus = true;
   }
   else
   {
   SchalterStatus = false;
   }
//
// Führe andere loop-Aufgaben aus
//
 if (SchalterStatus)
   {
   // Schalter war EIN
   }
   else
   {
   // Schalter war AUS
   }
}

Beispiel 2 Interrupt gesteuert

const   int SchalterPin = 2;         // ACHTUNG! Nicht alle Pin's sind Interruotfähig
volatile bool SchalterZustand = false; // Status des Schalters. Wird durch Interrupt gesetzt
void setup() {
         pinMode(SchalterPin, INPUT);    // Schalter ist INPUT  
         attachInterrupt(0, SchalterAenderungISR, CHANGE);  // Pin an Interrupt Service Routine(ISR) binden. Trigger durch CHANGE                                                 
 }
void loop() {
//
// Führe andere loop-Aufgaben aus
//
 if (SchalterZustand) // Wird durch ISR gesetzt
   {
   // Schalter war EIN
   }
   else
   {
   // Schalter war AUS
   }
}
void SchalterAenderungISR() // der Wert an "SchalterPin" ändert sich (CHANGE)
{                
  if (digitalRead(SchalterPin) == HIGH) // Zustand ermitteln und festhalten
   {
   SchalterZustand = true;
   }
   else
   {
   SchalterZustand = false;
   }
}

Das entprellen des Schalters solltest Du berücksichtigen.

Die ISR sollten so kurz wie möglich gehalten werden.

Hab die Beispiel ohne zu testen theoretisch zusammen gestellt und hoffe keinen Fehler gemacht zu haben

Woher ich das weiß:eigene Erfahrung
Gehilfling  22.09.2020, 14:44

Gute Antwort aber als Tipp: Nutz die Quelltext-Funktion für Codebeispiele, ist leserlicher als Zitate.

1
Dummy4711  22.09.2020, 15:47
@Gehilfling

ahhhhh.... *verzückt* wieder was gelernt. Gleich mal ausprobieren:

Beispiel 1 Polling:

   int SchalterPin = 4; 
   bool SchalterStatus = false; 

   void setup() 
    {               
    pinMode(SchalterPin, INPUT); 
    } 

   void loop() 
   { 
    if (digitalRead(SchalterPin) == HIGH) 
      { 
      SchalterStatus = true; 
      } 
      else 
      { 
      SchalterStatus = false; 
      } 
   // 
   // Führe andere loop-Aufgaben aus 
   // 
    if (SchalterStatus) 
      { 
      // Schalter war EIN 
      } 
      else 
      { 
      // Schalter war AUS 
      } 
   } 

//Beispiel 2 Interrupt gesteuert

const  int SchalterPin = 2;        // ACHTUNG! Nicht alle Pin's sind Interruptfähig 

volatile bool SchalterZustand = false; // Status des Schalters. Wird durch Interrupt gesetzt 

void setup() { 
   pinMode(SchalterPin, INPUT);   // Schalter ist INPUT  

   attachInterrupt(0, SchalterAenderungISR,CHANGE); //Pin an Interrupt Service Routine(ISR) binden. Trigger durch CHANGE                                          } 

void loop() { 
   // 
   // Führe andere loop-Aufgaben aus 
   // 

   if (SchalterZustand) // Wird durch ISR gesetzt 
     { 
     // Schalter war EIN 
     } 
     else 
     { 
     // Schalter war AUS 
     } 
} 

void SchalterAenderungISR() // der Wert an "SchalterPin" ändert sich (CHANGE) 
   {                
   if (digitalRead(SchalterPin) == HIGH) // Zustand ermitteln und festhalten 
      { 
      SchalterZustand = true; 
      } 
      else 
      { 
      SchalterZustand = false; 
      } 
}
1

Wahlweise über ein Interrupt oder, wenn die Genauigkeit nicht übertrieben wichtig ist, einmal in jedem Durchlauf der Hauptschleife.