Forum: Mikrocontroller und Digitale Elektronik mehrere Taster gleichzeitig abfragen (ATTINY 85)


von Andre S. (pipesmoker)


Lesenswert?

Hallo Leute,
ich beschäftige mich seit einigen Tagen mit folgendem Problem:
ein uC (tiny85), eine LED, zwei Taster.
Wenn TASTER1 gedrückt -> LED soll langsam blinken
Wenn TASTER2 gedrückt -> LED soll schnell blinken

funktioniert soweit, aber:

Wenn TASTER1 und TASTER2 gedrückt -> LED soll abwechselnd kurz und lang 
aufleuchten.
Das habe ich noch nicht hinbekommen.
Weiterhin: Ich drücke TASTER1, LED leuchtet lang. Währendessen drücke 
ich TASTER2 und möchte dass die LED, nachdem sie eine lange Periode 
geleuchtet hat, nochmal kurz aufleuchtet.

meine Abfrageroutine sieht so aus:
1
void request()          //are buttons pressed?
2
{
3
4
  if(bit_is_set(TASTER_PIN,0) && bit_is_set(TASTER_PIN,1))
5
  {
6
7
    shortbuf[0]=1;
8
    longbuf[0]=1;
9
  }
10
11
  else if(bit_is_set(TASTER_PIN,0))    //check if button1 is on
12
  {
13
    shortbuf[0]=1;
14
  }
15
16
  else if(bit_is_set(TASTER_PIN,1))  //check if button2 is pressed
17
  {
18
    longbuf[0]=1;
19
  }
20
21
  else if(bit_is_clear(TASTER_PIN,0) && bit_is_clear(TASTER_PIN,1))  //if no botton is pressed
22
  {
23
    longbuf[0]=0;
24
    shortbuf[0]=0;  
25
  }
26
}
27
28
void output()
29
{
30
  if(longbuf[0]==1 && shortbuf[0]==1)
31
  {
32
                tx_long();
33
                tx_short();
34
    longbuf[0]=0;
35
    shortbuf[0]=0;
36
  }
37
  else if(shortbuf[0]==1 && longbuf[0]==0)
38
  {
39
    tx_short();
40
    shortbuf[0]=0;
41
  }
42
43
  else if(longbuf[0]==1 && shortbuf[0]==0)
44
  {
45
    tx_long();
46
    longbuf[0]=0;
47
  }
48
49
  else if(longbuf[0]==0 && shortbuf[0]==0)
50
  {
51
    LED_PORT |= (1<<LED);
52
  }
53
}

also im Prinzip funktionieren nur beide Taster, wenn sie einzeln 
gedrückt werden. Sobald irgendwas in Kombination aktiviert wird, blinkt 
die LED lang.
Ich bin Anfänger mit Mikrocontrollern und Programmierung, deswegen 
entschuldigt bitte meine Frage. Aber ich habe bisher nichts Passendes 
gefunden...

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Solls 'ne ELBUG werden?
http://www.elektronik-labor.de/AVR/Elbug.html

von Thomas E. (thomase)


Lesenswert?

Und wo ist die Entprellung?

mfg.

von Electronics'nStuff (Gast)


Lesenswert?

Warum so kompliziert o.0?

[c]

 void main (void)

{

 if (Taster1 && Taster2)
 {
   LED_kurz();
   LED_lang();
 }

 if (Taster1 && !Taster2)
 {
   LED_kurz();
 }

 if (!Taster1 && Taster2)
 {
   LED_lang();

  }
}

void LED_kurz(); // <- kenne dein System nicht, wirst die Funktion 
selber
void LED_lang(); //    schreiben können

von Karl H. (kbuchegg)


Lesenswert?

Mir kommt da noch eine Idee

zeig doch mal deine Funktionen tx_long() bzw. tx_short()
Wie sind die gemacht?
Dir ist hoffentlich bewusst, dass du eine kleine Pause zwischen den 
Funktionen benötigst, in denen die LED dann auch wieder ausgeschaltet 
ist. Ansonsten geht nämlich die 'lange Brenndauer' der LED nahtlos in 
die 'kurze Brenndauer' über, ohne das du siehst wo das eine aufhört und 
das andere anfängt.

von Andre S. (pipesmoker)


Lesenswert?

Hallo,
danke fuer die Antworten.
Also
1
if (Taster1 && Taster2)
funktioniert irgendwie nicht, da blinkt die LED immer...
Ueber meinen kompliziertern Umweg gehts.

@Route66 - ja, soll ein elBug werden, aber nicht fuers Radio sondern 
fuer die HST :-)

@Karl - naja, sollte ja eigentlich einen Unterschied sehen ob es kurz 
oder lang blinkt.
Zum Blinken hatte ich testweise mit _delay_ms gearbeitet, aber jetzt 
habe ich es mit einem Timer und einer Zaehlvariable gemacht.
Wenn beide Tasten gedrueckt werden, sollte es so aussehen: 'Lang - Pause 
- Kurz - Pause - Lang -...'
Hier der Code:
1
void tx_long(void)          
2
{  
3
  if(long_count>=0 && long_count<=7)    //compare counter for 9 steps
4
  {
5
    LED_PORT &= ~(1<<LED);    //switch LED on
6
  } 
7
8
  else if(long_count>=8 && long_count <= 10)  //compare counter for 3 steps
9
  {
10
    LED_PORT |= (1<<LED);    //switch LED off for (time_LED_on/3)
11
    if(long_count==10)
12
    {
13
      long_count=0;    //after off_time is over, reset counter
14
    }
15
  }
16
}
17
18
19
void tx_short()
20
{
21
  if(short_count==2)      //compare counter 
22
  {  
23
    LED_PORT ^= (1<<LED);    //toggle LED
24
    short_count=0;      //set short_counter to 0
25
  }
26
}

von Andre S. (pipesmoker)


Lesenswert?

ich habe das Problem selbst geloest:
ich habe mir noch eine Funktion fuer zwei Taster geschrieben. Damit hat 
es dann geklappt :-)
Danke an alle, die mir geholfen haben!

von Peter D. (peda)


Lesenswert?

Andre S. schrieb:
> ich habe mir noch eine Funktion fuer zwei Taster geschrieben.

Ein Forum ist nicht als Einbahnstraße gedacht.
Man sollte daher die anderen an der Lösung teilhaben lassen.
Könnte ja sein, daß man nochmal ne Frage hat.


Peter

von Jürgen S. (jurs)


Lesenswert?

Peter Dannegger schrieb:
> Ein Forum ist nicht als Einbahnstraße gedacht.
> Man sollte daher die anderen an der Lösung teilhaben lassen.
> Könnte ja sein, daß man nochmal ne Frage hat.

Keine Ahnung, wie der OP es gelöst hat, aber ich kann etwas dazu 
schreiben, wie es funktioniert:

Bei dem geschilderten Blink-Problem gilt es doch dieselbe Klippe zu 
umschiffen wie bei dem gerade erst vor drei Tage nachgefragten 
Arduino-Warnblinker, bei dem ebenfalls der Doppel-Tasterdruck eine 
dritte Blinkfunktion aktivieren sollte. Da ging es um Linkblinken, 
Rechtsblinken, Warnblinken mit zwei Tastern und hier geht es um 
Langblinken, Kurzblinken, Lang-Kurzblinken mit zwei Tastern. Ist fast 
dasselbe.

Die Klippe besteht darin, dass der Tastaterstatus und der Blinkstatus 
nur noch sehr bedingt miteinander zusammenhängen, wenn
- ein Prellen der Taster auftreten kann und
- der Zustand "beide Taster gedrückt" etwas bewirken soll
- aber der Zustand "beide Taster loslassen" nichts am Blinkstatus ändern 
soll

Der Trick besteht darin sicherzustellen, dass beim Loslassen eines 
Tasters keine Umschaltung im Blinkstatus stattfinden darf.

D.h. wenn nach dem Drücken beider Taster die dritte Blinkaktion 
aktiviert wurde, muß diese Blinkaktion beibehalten werden, egal ob als 
nächstes festgestellt wird "beide Taster unbetätigt", "linker Taster 
betätigt, rechter unbetätigt" oder "rechter Taster betätigt, linker 
unbetätigt". Denn beim Loslassen der beiden Tasten ist es sehr 
wahrscheinlich, dass diese mit mehr oder weniger zeitlicher Verzögerung 
nacheinander losgelassen werden. Die nächste Änderung im Blinkstatus 
darf dann erst erfolgen, wenn vorher einmal festgestellt wurde "beide 
Taster unbetätigt". Erst danach darf ein gedrückter Taster wieder zu 
einer Änderung im Blinkstatus führen.

Das ist jedenfalls die Art, wie ich drei verschiedene Blinkstates mit 
zwei Tastern realisiere.

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.