Forum: Compiler & IDEs Taster Stromstoßschalter


von Christian (Gast)


Lesenswert?

Hallo Forum

Möchte mit einem ATmega32 einen Stromstoßschalter realisieren, d. h., 
wenn ich den Taster drücke sollen alle LEDs von PORTC leuchten. Bei 
nochmaltigen drücken des Tasters sollen alle LEDs wieder ausgehen.

Verwende einen externen PullDown für die Taster.

Habe schon einige Programme probert, jedoch ohne Erfolg.
Vermutlich handelt es sich um einen Denkfehler.

Hier mein derzeitiger Stand:
1
#include <avr/io.h>
2
#define F_CPU 8000000UL
3
#include <util/delay.h>
4
#include <stdlib.h>
5
#include <avr/interrupt.h>
6
7
8
9
int main(void)
10
{
11
    DDRC = 0xFF;
12
    PORTC =0xFF;
13
 
14
    DDRD =0x00;
15
    //PORTD =0xFF;  // PullUp aktivieren!!
16
17
    while(1){
18
     
19
        if(PIND & (1<<PD0) && PORTC == 0xFF)  
20
        {           
21
        PORTC = 0;
22
        }          
23
        if(PIND & (1<<PD0) && PORTC == 0x00)  
24
        {           
25
        PORTC = 1;
26
        }  
27
    }   
28
}

Danke für eure Hilfe

von Alex (Gast)


Lesenswert?

PORTC = 1;
==>
PORTC = 0xFF;

von Rolf Magnus (Gast)


Lesenswert?

Außerdem fehlt die Entprellung.

von Flo (Gast)


Lesenswert?

Das ist wie diese elektronischen Würfel, wenn du nicht wartest, bis die 
Taste wieder losgelassen wurde (ggf. mit Entprellung, je nach Taster), 
bleibst du durch Zufall entweder im An oder Auszustand, da die beim 
Taste gedrückt-Zustand mehrere hundert Mal wechseln.

von Michael M. (Gast)


Lesenswert?

das geht btw inkl entprellung mit 2 invertern...

von Peter D. (peda)


Lesenswert?

Da hab ich kürzlich was in der Codesammlung gesehen:

Beitrag "Entprellen für Anfänger"


Peter

von Rolf Magnus (Gast)


Lesenswert?

Gibt's dich jetzt mehrfach? ;-)

von Christian (Gast)


Lesenswert?

Hat den keiner eine Idee wie man einen Stromstoßschalter realisieren 
kann?

von Michael M. (Gast)


Lesenswert?

super beitrag!

von noname (Gast)


Lesenswert?

Das kann man mit einer state machine lösen.

state0 //Start
       Wenn Taster gedrückt, dann state1

state1 LEDs einschalten
       Wenn Taster losgelassen wird, dann state2

state2 Wenn Taster gedrückt wird, dann state3

state3 LEDs ausschalten
       Wenn Taster losgelassen wird, dann state4

state4 Wenn Taster gedrückt wird, dann state1

Versuchs mal!

von Christian (Gast)


Lesenswert?

Danke für deinen Hinweis, aber ich weiß nicht wie ich deine Anweisung in 
C umsetzten soll. Vielleicht könntest du ein bisschen konkreter werden. 
Überlege schon den ganzen Tag, jedoch ohne Erfolg.

von Michael M. (Gast)


Lesenswert?

hast du eig die post davor wenigstens mal gelesen???
es werden dir mehrere möglichkeiten zur lösung genannt.

von noname (Gast)


Lesenswert?

Fang erst mal einfach an. Schreib ein Programm das die
LEDs einschaltet, wenn der Taster gedrückt ist und die
LEDs ausschaltet, wenn der Taster losgelassen ist.

Als zweiter Schritt kommt die state machine.
Eine Variable enthält den aktuellen state.
Z.B. mystate.

Jetzt wird fortlaufend abgefragt, welchen Wert mystate
hat. Dies ist in einer switch-Anweisung am übersichtlichsten.


while (1)
{
 switch (mystate)
 {
   case 0: if (/* Taste gedrückt */)
             mystate=1;
           break;
   case 1: /* LEDs einschalten */
           if (/* Taste losgelassen */)
             mystate=2;
           break;
   case 2:

   case 3:

   case 4:
 }
}

Ich habe nur die Kommentare eingefügt. Du musst dort
deine Tasterabfrage programmieren und die LEDs schalten.
Wie es nach case 1 weitergeht habe ich ja schon beschrieben.

von Christian (Gast)


Lesenswert?

Danke für deine Unterstützung. Habe das Programm nach deinen Anweisungen 
programmiert, doch es will nicht funktionieren.

Bitte um Korrektur meines Codes
1
while (1)
2
{
3
 switch (mystate)
4
 {
5
   case 0: if (PINB & (1<<PB0))
6
             mystate=1;
7
           break;
8
   case 1: PORTC =0x00;
9
           if (~PINB)
10
             mystate=2;
11
           break;
12
   case 2: if (PINB & (1<<PB0))
13
             mystate=3;
14
           break;
15
   case 3: PORTC =0xFF;
16
           if (~PINB)
17
             mystate=4;
18
           break;
19
   case 4: if (PINB & (1<<PB0))
20
             mystate=1;
21
           break;
22
 }
23
}

von Peter D. (peda)


Lesenswert?

noname schrieb:
> Das kann man mit einer state machine lösen.

Das ist aber nicht der optimale Ansatz, da dabei nicht das Prellen 
gelöst wird.
Besser ist eine Entprellroutine als erster Schritt und da fällt dann das 
Ereignis des Drückens nebenbei mit ab.
Und dann braucht man nur noch ne Toggle-Funktion (EXOR).

Aber das steht ja oben schon alles fix und fertig für 2 Tasten + 2 LEDs.


Peter

von noname (Gast)


Lesenswert?

Du kannst zum Debuggen über die LEDs mystate anzeigen lassen.
Dann siehst du wo das Programm steht.
Es liegt vermutlich an ~PINB. Du must hier maskieren.
D.h. den Portpin (das Bit von PINB) auswerten.

von Birger Z. (nohelp)


Lesenswert?

Also 'ne State machine für diese popelige Aufgabenstellung ist doch 
reichlichst übertrieben. Richtig ist, man braucht eine Entprellung. Rest 
siehe Peter D.

von noname (Gast)


Lesenswert?

Muss man eigentlich eine Entprellroutine verwenden,
wenn der Taster gar nicht prellt?
(Einfach ein RC-Glied vor den AVR-Eingang schalten)
Ich denke das Prellen ist hier nicht das Problem
sondern das Abfragen eines Eingangs und die
Anfangsschwierigkeiten mit C.
Ich habe den Beitrag von P.D. noch nicht durchgelesen,
werde dies aber tun, wenn ich mal eine sehr gute
Entprellung benötigen sollte.

von Jens (Gast)


Lesenswert?

1
uint8_t TaOn;    // Flag
2
3
4
5
6
   void Entprell(uint16_t a)
7
  {
8
     while (a != 0)
9
     {
10
       a = a+1;  // oder irgend einen anderen Unsinn
11
       a = a-2;
12
     }
13
  }
14
15
16
int main(void)
17
{
18
    DDRC = 0xFF;
19
    PORTC =0xFF;
20
 
21
    //DDRD =0x00;
22
    PORTD |= (1<<PD0);  // nimm doch den internen PullUp
23
24
25
26
    while(1)
27
    {
28
     
29
        if(PIND & (1<<PD0))  
30
        { 
31
           // Taster Off
32
           
33
           if(TaOn)      // if(TaOn == 1)
34
           {
35
              // Taster war vorher an
36
37
              Entprell(500);        // Wert testen !!!
38
39
              TaOn = 0;
40
        
41
              PORTC = 0;
42
           }
43
        }
44
        else 
45
        {
46
            // Taster On
47
48
            if(!TaOn)       // if(TaOn == 0)
49
            {
50
                // Taster war vorher aus
51
52
                 Entprell(500);        // Wert testen !!!
53
54
                 TaOn = 1;
55
56
                 PORTC = 0xFF;
57
            }
58
        }
59
    }   
60
}

von Christian (Gast)


Lesenswert?

@ Jens

Danke für dein Programm, jedoch behandelt es nur die Prellzeit und nicht 
die eigentliche Funktion. Mein Anliegen ist einen Stromstoßschalter zu 
ralisieren.--> Wenn eine Taste gedrückt wird sollen alle LEDs leuchten, 
bei einem weiteren betätigen des Tasters sollen die LEDs wieder 
ausgehen. Vielleicht haben andere User einen Tipp.


Danke an alle für die Hilfe.

von noname (Gast)


Lesenswert?

@Christian

Hat das Programm: Taste gedrückt -> alle LEDs an
und Taste losgelassen -> alle LEDs aus
funktioniert?

von Christian (Gast)


Lesenswert?

@ nonqme

Nein leider nicht. Ich vermute auch, dass es an dem ~PINB liegt.
Weißt du was ich ausbessern könnte?

Danke

von noname (Gast)


Lesenswert?

if (!(PINB & (1<<PB0)))

von Christian (Gast)


Lesenswert?

@ noname

Danke für dein Programm, wäre nicht so schnell auf diese Variante 
gekommen.
Den letzten Eintrag von dir habe ich auch schon vorher probiert nur mit 
der ~. Wieder mal ein Denkfehler! Gibt es auch andere 
Programmiervarianten für den Stromstoßschalter?

Danke nochmal für deine Hilfe

von Michael M. (Gast)


Lesenswert?

> Gibt es auch andere
> Programmiervarianten für den Stromstoßschalter?

Peter Dannegger schrieb:
> Besser ist eine Entprellroutine als erster Schritt und da fällt dann das
> Ereignis des Drückens nebenbei mit ab.
> Und dann braucht man nur noch ne Toggle-Funktion (EXOR).
>
> Aber das steht ja oben schon alles fix und fertig für 2 Tasten + 2 LEDs.
>
>
> Peter

lies doch einfach mal, was man dir schreibt.
und wart nicht nur auf fertigen code, den du weder verstehst, noch zu 
100% per copy/paste übernehmen kannst.

von Jens (Gast)


Lesenswert?

1
uint8_t  TaOn,    // Flag für die Taste selbst
2
         LedsOn;   // Flag für die Leds
3
4
5
6
7
   void Entprell(uint16_t a)
8
  {
9
     while (a != 0)
10
     {
11
       a = a+1;  // oder irgend einen anderen Unsinn
12
       a = a-2;
13
     }
14
  }
15
16
17
int main(void)
18
{
19
    DDRC = 0xFF;
20
    PORTC =0xFF;
21
 
22
    //DDRD =0x00;
23
    PORTD |= (1<<PD0);  // nimm doch den internen PullUp
24
25
26
27
    while(1)
28
    {
29
        if(PIND & (1<<PD0))  
30
        { 
31
           // Taster Off
32
           
33
           if(TaOn)      // if(TaOn == 1)
34
           {
35
              // Taster war vorher an
36
37
              Entprell(500);        // Wert testen !!!
38
39
              TaOn = 0;
40
             
41
              // Aktion, wenn Taster losgelassen wird, brauchen wir nicht            
42
           }
43
        }
44
        else 
45
        {
46
            // Taster On
47
48
            if(!TaOn)       // if(TaOn == 0)
49
            {
50
                // Taster war vorher aus
51
52
                 Entprell(500);        // Wert testen !!!
53
54
                 TaOn = 1;
55
56
                // Nun folgt die Aktionen, wenn der Taster gedrückt wird
57
58
                 if(LedsOn)
59
                 {
60
                   LedsOn=0;
61
                   PORTC = 0;  // Die Off-Aktion
62
                 }
63
                 else
64
                 {
65
                   LedsOn = 1;
66
                   PORTC = 0xFF;  // Die On-Aktion
67
                 }
68
            }
69
        }
70
    }   
71
}

von Karl H. (kbuchegg)


Lesenswert?

@Jens

Ich denke, über eines sind wir uns einig.
Tasten entprellen ist eine wichtige und oft benötigte Funktionalität. 
Von daher ist es kontraproduktiv, das Einlesen und Entprellen von 
Tastern in die Aufgabenstellung so dermassen einzuweben, wie du das 
machst.

Legen wir die PeDa-Entprellung zu Grunde, so lautet die Hauptschleife
1
int main()
2
{
3
 ....
4
5
  while( 1 ) {
6
    if( get_keypress( 1<<KEY0 ) )
7
      PORTC = 0xFF;
8
  }
9
}

und jetzt vergleich das mit deiner Lösung.

von Jens (Gast)


Lesenswert?

ja natürlich,

ich wollte es doch nur ganz verständlich machen.

Wenn ich mehrere Taster auslese, dann auch mit XOR und alten Pinzustand 
mit neuem vergleichen, wo Änderung und ob Taste gedrückt oder 
losgelassen wurde usw. und als extra Routine oder auch Datei 
(Tasten.c)usw..
Auch die Aktionen, die dann ausgeführt werden sollen, werden in 
Extradateien bzw. Routinen ausgeführt ---- z.B. TaAktionOn(i), 
TaAktionOff(i)

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.