Forum: Compiler & IDEs Arduino Taster als Schalter


von Fasaso H. (fasaso)


Lesenswert?

Guten Abend miteinander,

Ich möchte gerne einen Taster der mit meinem Arduino verbunden ist, als 
Schalter verwenden - 1. Drücken Einschalten... 2. Drücken Ausschalten 
usw. Nun habe ich im Internet mal gesucht und auch etwas gefunden, 
jedoch ist es für mein Programm auch Wichtig, dass es OHNE delay 
funktioniert. Da aber alle vorlagen, die ich gesehen habe, einen delay 
verwenden, wollte ich fragen, ob ihr schon so etwas Programmiert habt 
oder ob ihr einen Lösungsvorschlag hättet?

Beste Grüsse

fasaso

von Hans (Gast)


Lesenswert?

Melde dich im Arduino Forum an, da wirst du eher geholfen. Zudem wäre es 
wichtig zu wissen was du schalten willst

von Kevin M. (arduinolover)


Lesenswert?

Sollte so gehen. Ohne Gewähr auf Fehlerfreiheit es ist spät :D
Falls es mehrere Taster gibt kann man die Funktionen ggf. um einen 
Parameter erweitern und so dieselbe Funktion für alle Taster nutzen, die 
States müsste man dann in ein Array o.ä. speichern.
1
#define buttonPin 1
2
#define prellTime 250
3
4
bool switchState = 0;
5
int prell = 0;
6
7
void switchActiveHigh(){
8
  if(prell < millis()){
9
    if(digitalRead(buttonPin)){
10
      switchState != switchState;
11
      prell = millis()+prellTime;
12
    }
13
  }
14
}
15
16
void switchActiveLow(){
17
  if(prell < millis()){
18
    if(!digitalRead(buttonPin)){
19
      switchState != switchState;
20
      prell = millis()+prellTime;
21
    }
22
  }
23
}
24
25
void setup() {
26
  // put your setup code here, to run once:
27
   pinMode(buttonPin, INPUT_PULLUP);  //ggf INPUT
28
}
29
30
void loop() {
31
  // put your main code here, to run repeatedly:
32
  switchActiveLow();
33
}

von Adam P. (adamap)


Lesenswert?

Fasaso H. schrieb:
> Nun habe ich im Internet mal gesucht

Einfach das Beispiel in der Arduino IDE öffnen:
Datei -> Beispiele -> 02.Digital -> Debounce

Und dies anpassen, da wir nicht wissen wie du dein Taster angeschlossen 
hast.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Fasaso H. schrieb:
> Wichtig, dass es OHNE delay
> funktioniert.

Dann muß man das Entprellen und Flanke erkennen im Timerinterrupt 
machen.

Beitrag "Universelle Tastenabfrage"

von Adam P. (adamap)


Lesenswert?

Peter D. schrieb:
> Dann muß man das Entprellen und Flanke erkennen im Timerinterrupt
> machen.

Ähm...Nein!

von Fasaso H. (fasaso)


Lesenswert?

Kevin M. schrieb:
> Sollte so gehen. Ohne Gewähr auf Fehlerfreiheit es ist spät :D
> Falls es mehrere Taster gibt kann man die Funktionen ggf. um einen
> Parameter erweitern und so dieselbe Funktion für alle Taster nutzen, die
> States müsste man dann in ein Array o.ä. speichern.
>
1
> void switchActiveHigh(){
2
>   if(prell < millis()){
3
>     if(digitalRead(buttonPin)){
4
>       switchState != switchState;
5
>       prell = millis()+prellTime;
6
>     }
7
>   }
8
> }
9
> 
10
> void switchActiveLow(){
11
>   if(prell < millis()){
12
>     if(!digitalRead(buttonPin)){
13
>       switchState != switchState;
14
>       prell = millis()+prellTime;
15
>     }
16
>   }
17
> }
18
> 
19
> void setup() {
20
>   // put your setup code here, to run once:
21
>    pinMode(buttonPin, INPUT_PULLUP);  //ggf INPUT
22
> }
23
> 
24
> void loop() {
25
>   // put your main code here, to run repeatedly:
26
>   switchActiveLow();
27
> }
28
>

für was ist void switchActiveHigh() oder wo wird sie aufgerufen?

Danke für die Vorlage!

Grüsse

von Kevin M. (arduinolover)


Lesenswert?

Das kommt drauf an ob dein Taster eine Pull Up hat und gegen Low zieht 
(active low) oder einen high Pegel schaltet ( active high). Ich habe den 
Pin mit Input Pullup initialisiert und gehe davon aus, dass der Taster 
nach GND zieht deshalb die active low Funktion...

Was du hast weiß ich ja nicht.

von Karl M. (Gast)


Lesenswert?

Adam P. schrieb:
> Peter D. schrieb:
> Dann muß man das Entprellen und Flanke erkennen im Timerinterrupt
> machen.
>
> Ähm...Nein!

Ja genau so funktioniert es sicher.
Mann muss nur wollen.

von Adam P. (adamap)


Lesenswert?

Karl M. schrieb:
> Adam P. schrieb:
>> Peter D. schrieb:
>> Dann muß man das Entprellen und Flanke erkennen im Timerinterrupt
>> machen.
>>
>> Ähm...Nein!
>
> Ja genau so funktioniert es sicher.
> Mann muss nur wollen.

Was meinst du nun genau?

von Peter D. (peda)


Lesenswert?

Adam P. schrieb:
> Was meinst du nun genau?

Durch den Timerinterrupt erfolgt die Entprellung und Flankenerkennung 
unabhängig von der Laufzeit der Mainloop. Es geht also kein Tastendruck 
verloren, auch wenn die Mainloop mal 1s lang beschäftigt ist.

Das Beispiel von Kevin enthält übrigens den 49,7 Tage Bug. Nur 
Differenzen stimmen immer.

von Kevin M. (arduinolover)


Lesenswert?

Peter D. schrieb:
> Das Beispiel von Kevin enthält übrigens den 49,7 Tage Bug. Nur
> Differenzen stimmen immer.

Das ist kein Bug sondern einfach ein systembedingtes Fehlverhalten was 
ich toleriert habe. Nichts gegen Fasaso und ich mag mich auch irren aber 
es wirkt auf mich so als ob er nicht sehr tief in der Materie drin 
steckt. Ich glaube kaum das er eine Loop hat die ewig braucht noch das 
das Board ewig am Stück läuft. Mein Beispiel ist wie gesagt eine 
Möglichkeit die kurz und einfach ist. Natürlich ist ein Input Capture 
oder eine external Interrupt die elegantere Variante. Aber ganz ehrlich 
für die meisten Sachen ist es Overkill und man kann meinen Code durchaus 
so anpassen, dass das Problem mit millis nicht Auftritt. Nur wenn jemand 
schon Hilfe braucht um einen Taster derart anzufragen und nicht den 
Unterschied zwischen active high und low kennt sollte man vielleicht 
nicht gleich mit einem Timer kommen. Wie gesagt vielleicht tu ich ihm 
auch unrecht, ist nur mein Eindruck.

von Peter D. (peda)


Lesenswert?

Kevin M. schrieb:
> Natürlich ist ein Input Capture
> oder eine external Interrupt die elegantere Variante.

Ganz gewiß nicht!
Bzw. nur zum Aufwachen (EMPTY_INTERRUPT) aus dem Power-Down.

von Kevin M. (arduinolover)


Lesenswert?

Fängst du hier jetzt eine Grundsatzdiskussion an?

Frag 10 Leute und sie haben 10 Meinungen....

Ich mach es in der Regel bei einem einfachen Taster immer mit Abfrage in 
der Loop, wenn dein Programm dafür zu lange braucht ist eh was 
schiefgelaufen. Es gibt aber durchaus Fälle wo auch ein external 
Interrupt sinnvoll sein kann, wenn es z.B. auf präzises Timing ankommt……

von Peter D. (peda)


Lesenswert?

Kevin M. schrieb:
> Natürlich ist ein Input Capture
> oder eine external Interrupt die elegantere Variante.

Kevin M. schrieb:
> Frag 10 Leute und sie haben 10 Meinungen....

Es dürfte Einigkeit herrschen, daß genau das nicht elegant ist. Mehr 
habe ich nicht gesagt.

von Kevin M. (arduinolover)


Lesenswert?

Peter D. schrieb:
> Es dürfte Einigkeit herrschen, daß genau das nicht elegant ist. Mehr
> habe ich nicht gesagt.

Du hast recht und ich meine Ruhe ;)

von Peter D. (peda)


Lesenswert?

Kevin M. schrieb:
> Das ist kein Bug sondern einfach ein systembedingtes Fehlverhalten was
> ich toleriert habe.

Das ist nicht systembedingt, sondern es liegt allein in der Hand des 
Programmierers, den Bug zu vermeiden.
Ich hab ja auch hingeschrieben, wie.
Es gibt daher nichts zu tolerieren. Man muß es einfach nur richtig 
machen.

von Kevin M. (arduinolover)


Lesenswert?

Heul doch?
Machs besser und laber nicht, es ging doch nur um ein Beispiel und nicht 
irgendwelchen fertigen code zu produzieren.

von Peter D. (peda)


Lesenswert?

Ich rede mich jedenfalls nicht damit heraus, daß die Arduino-Umgebung 
daran schuld sei.
Nur weil die W95/W98 Programmierer diesen Bug gemacht haben, muß man ihn 
lange noch nicht nachmachen. Aus Fehlern sollte man lernen und nicht die 
beleidigte Leberwurst spielen.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.