- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 20

Thema: ATTiny13A Schalter abfragen/entprellung mit Variablen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    11.06.2014
    Beiträge
    9

    Frage ATTiny13A Schalter abfragen/entprellung mit Variablen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo liebe Community!

    Seit einigen Tagen bin ich "stiller" Leser hier und habe mir schon einige Tipps und Anregungen geholt

    Leider sitze ich noch immer an einem kleinen Problem:

    Ich habe einen ATTiyn13A auf einem Versuchsboard aufgebaut. Als Programm nutze ich das AtmelStudio 6.1

    -Die Anschlüsse PB0 und PB1 sind jeweils mit einer LED verbunden.

    -Die Anschlüsse PB3 und PB4 jeweils mit einem Taster der mit der anderen Seite auf GND liegt.

    Das Endergebnis soll einmal so Aussehen das eine gewisse Reihenfolge und Häufigkeit einiger Taster gedrückt werden muss um z.B. eine Segmentanzeige zu Aktivieren. (Klar das der Tiny13 da schnell ausgelastet ist mit Ports aber ich habe auch noch einen 2313A da. Der Tiny13 ist erstmal für den Test gedacht)

    Z.B. wenn Taster 1 5mal betätigt wurde und danach Taster 2 3mal soll auf der Segmentanzeige eine 8 aufleuchten.


    Angefangen habe ich mit einem Taster der wenn er gehalten wurde eine LED leuchten lies. Dies funktionierte auch.

    Wenn ich jedoch statt der LED eine Variable hochzählen will und zb wenn die Variable 5 erreicht die LED anschalten soll geht sie gar nicht an. Egal wie schnell oder häufig man die Taste drückt.

    Dann habe ich versucht mit jedem Tastendruck die LED zu invertieren. dh. 1.Druck an, 2.Druck aus usw... Jetzt geht die LED allerdings mal an und mal wieder aus, mal bleibt sie einfach an... Sehr unkontrolliert...

    Da habe ich an eine Entprellung gedacht die wie unten eingebaut ist. Jedoch flackert die LED jetzt nur währen die Taste gedrückt ist und die Schaltzustände sind weiterhin sehr unkontrolliert....

    Vielleicht kann mir jemand einen Denkanstoß geben?

    Hier das aktuelle Programm:
    Code:
    /*
     * LED_Anzeige.c
     *
     * Created: 18.05.2014 19:27:56
     *  Author: Dennis
     */ 
    #define F_CPU 9000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    
    unsigned char Taster1;
    unsigned char Taster2;
    
    void entprellung( volatile uint8_t *port, uint8_t maske ) {
    	uint8_t   port_puffer;
    	uint8_t   entprellungs_puffer;
    	
    	for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {
    		entprellungs_puffer<<=1;
    		port_puffer = *port;
    		_delay_us(150);
    		if( (*port & maske) == (port_puffer & maske) )
    		entprellungs_puffer |= 0x01;
    	}
    }
    
    
    int main (void)
    {
    	DDRB=0x03; //Ein /Ausgänge ;
    	PORTB = 0x18; //Pullup aktivieren (PB3+PB4)
    	Taster1 = 0;
    	Taster2 = 0;
    	while(1)
    	{
    		entprellung( &PINB, (1<<PINB3) ); // ggf. Prellen abwarten 
    		if(!(PINB & (1 << PB3)))
    		{
    			Taster1++;
    			PORTB^=0x02;  //PB1 invertieren
    			
    		}
    		entprellung( &PINB, (1<<PINB4) ); // ggf. Prellen abwarten 
    		if(!(PINB & (1 << PB4)))
    		PORTB^=0x01; //PB0 invertieren
    		//PORTB&=~(1<<PB0);	//PB0 ausschalten
    	}
    }
    Vielen Dank für eure Mühe im Voraus!

    Gruß
    Dennis
    Geändert von Denn Is (11.06.2014 um 00:22 Uhr) Grund: Code überarbeitet

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.686
    Hallo Dennis, willkommen im Forum!
    ... Vielleicht kann mir jemand einen Denkanstoß geben? ...
    Zuerst kurz und schnell zum Problem (bei mir kommen Prellprobleme ohne Entprellen fast nicht vor - seltsam). Eine pfiffige Lösung zum Entprellen ist es, die Taste mehrfach abzufragen (vielleicht quick´n-dirty ...) :

    if ( (taste-an) || (taste-an) || (taste-an) ) { irgendwas(); }
    das steht irgendwo in den Tiefen des Forums als :
    while((PollSwitch() == 0) || (PollSwitch() == 0) || (PollSwitch() == 0))

    So ne Lösung läuft auf meinem Pacer total problemlos - der Pacer hatte anfangs auch nen tiny13.

    Noch ein bisschen wie ich mir die Tastenbedienung zurecht gestrickt habe :
    Code:
    // ...
      #define IsBitSet(ADDR,BIT)     (((ADDR)  &  (1<<BIT))?1:0)    // Fragt Bit = 1?
      #define IsBitClr(ADDR,BIT)     (!((ADDR)  &  (1<<BIT))?1:0)   // Fragt Bit = 1?
    // ...
      #define PrtTAST       PIND    //
      #define Tst_1            6    //
      #define Tst_2            7    //
    // ...
      #define Taste1_an     IsBitClr (PrtTAST, Tst_1)       // Taster 1 gedrückt ??
      #define Taste1_aus    IsBitSet (PrtTAST, Tst_1)       // Taster 1 gelöst ??
      #define Taste2_an     IsBitClr (PrtTAST, Tst_2)       // Taster 2 gedrückt ??
      #define Taste2_aus    IsBitSet (PrtTAST, Tst_2)       // Taster 2 gelöst ??
    //... oder mit Buchstaben (verwende ich mittlerweile bei Tasten lieber) :
      #define TasteA_an     IsBitClr (PRTtstLCD, Tst_A)     // Taster A gedrückt ??
      #define TasteA_aus    IsBitSet (PRTtstLCD, Tst_A)     // Taster A gelöst ??
      #define TasteB_an     IsBitClr (PRTtstLCD, Tst_B)     // Taster B gedrückt ??
      #define TasteB_aus    IsBitSet (PRTtstLCD, Tst_B)     // Taster B gelöst ??
    // ... und das geht NOCH deutlich kürzer in dieser Form :
      #define TAan          IsBitClr (PRTtstLCD, Tst_A)     // Taster A gedrückt ??
      #define TAaus         IsBitSet (PRTtstLCD, Tst_A)     // Taster A gelöst ??
      #define TBan          IsBitClr (PRTtstLCD, Tst_B)     // Taster B gedrückt ??
      #define TBaus         IsBitSet (PRTtstLCD, Tst_B)     // Taster B gelöst ??
    // - - - - - - - - - - - - - - -
    // Da dies keine Funktion ist, erfolgt der Aufruf so (NUR beispielsweise) :
    // - - - - - - - - - - - - - - -
    // ...
        if ( TAan ) off = 99;   // Taste A gedrückt ?? Ausgangsflag setzen
        while ( TAan ) {}       // Weiter nur mit gelöster Taste
        if ( off == 99 )            //
        {                           //
          off       = 0;            //
          break;                    //
        }                           //
    Hoffentlich hilfts Dir bei Deiner Tastendrückerei.

    Nachtrag: Dein 150µs-wait für die Entprellung ist schon ok, beim Tastendrücken hat der Controller sozusagen alle Zeit der Welt. Ich orientiere mich bei Mehrfach-Tastendruck am Zeitschema meiner TV-IR-Fernbedienungen. Die senden bei gedrückter Taste etwa alle 100ms - 150ms (MILLI-) ein Signal, wenn man mehrere, unterschiedliche Tasten drückt werten die auch ein Toggelbit aus (wurde die Taste zwischendurch gelöst?) und lassen einem z.T über zwei Sekunden Zeit für ein Mehrfachtasten-Telegramm.
    Geändert von oberallgeier (11.06.2014 um 10:18 Uhr) Grund: Nachtrag: Pausen- und andere Zeiten (Tastenhaptik)
    Ciao sagt der JoeamBerg

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    11.06.2014
    Beiträge
    9
    Mhh hilft mir noch nicht wirklich weiter. Die einfachen "Entprellung" durch die || in der Abfrage löst das Problem leider nicht das weiterhin die LEDs unkontrolliert anschalten oder anbleiben bei Tastendruck etc... Vielleicht liegt das Problem auch gar nicht am entprellen sondern an meiner Port invertierung?

    Mit deinem Code habe ich folgendes zusammengestrickt, da funktioniert jedoch gar nichts mehr

    Code:
    #define F_CPU 9000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    
      #define IsBitSet(PINB,PINB3)     (((PINB)  &  (1<<PINB3))?1:0)    // Fragt Bit = 1?
      #define IsBitClr(PINB,PINB3)     (!((PINB)  &  (1<<PINB3))?1:0)   // Fragt Bit = 1?
      // ...
      #define PrtTAST       PINB    //
      //#define PrtLED		PORTB	//
      #define Tst_1            PB3    //
      #define Tst_2            PB4    //
      //#define Led1				
      //#define Led2
      
      #define Taste1_an     IsBitClr (PrtTAST, Tst_1)       // Taster 1 gedrückt ??
      #define Taste1_aus    IsBitSet (PrtTAST, Tst_1)       // Taster 1 gelöst ??
      #define Taste2_an     IsBitClr (PrtTAST, Tst_2)       // Taster 2 gedrückt ??
      #define Taste2_aus    IsBitSet (PrtTAST, Tst_2)       // Taster 2 gelöst ??
      
      int main (void)
      {
    	  DDRB=0x03; //Ein /Ausgänge ;
    	  PORTB = 0x18; //Pullup aktivieren (PB3+PB4)
    	 // Taster1 = 0;
    	 // Taster2 = 0;
    	  while(1)
    	  {
    	     if ( Taste1_an ) off = 99;   // Taste A gedrückt ?? Ausgangsflag setzen
    	    
    		 while ( Taste1_an ) {}       // Weiter nur mit gelöster Taste
    	     if ( off == 99 )            //
    	     {                           //
    		     PORTB^=0x02;  //PB1 invertieren
    			 off       = 0;            //
    				                    //
    	     }                           //
    	 }
    }
    - - - Aktualisiert - - -

    So folgendes Programm ist der "Aktuelle" Stand:

    Code:
    //	Definitionen	//
    
    #define F_CPU 9000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    
    //	Variablen	//
    
    unsigned char True;
    unsigned char False;
    unsigned char Taster1;
    unsigned char Taster2;
    
    
    	
    //	Hauptprogramm	//
    
    int main (void)
    {
    	DDRB=0x06;		 // I/O Ports PB1+PB2;
    	PORTB = 0x18;	 //Pull up aktivieren (PB3+PB4)
    	True	= 1;	//Startwert zuweisung
    	False	= 0;	//Startwert zuweisung
    	Taster1	= 0;	//Startwert zuweisung
    	Taster2	= 0;	//Startwert zuweisung
    	
    	while(1)
    	{
    		//	Taster abfragen	//
    		
    		if(!(PINB & (1 << PB3))||!(PINB & (1 << PB3))||!(PINB & (1 << PB3))) //Tasterabfrage PB3
    		{
    			Taster1++;	//Taster inkrementieren
    
    		}
    		if(!(PINB & (1 << PB4))||!(PINB & (1 << PB4))||!(PINB & (1 << PB4))) //Tasterabfrage PB4
    		{	
    			Taster2=True;			 //Taster 2 gedrückt
    		}
    		
    		//	LED Anzeige	//
    		
    		if (Taster1>=5)				//Wenn Taster1 größer gleich 5 erreicht
    		{
    			PORTB|=(1<<PINB2);		//PB2 an
    			PORTB&=~(1<<PINB1);		//PB1 aus
    			Taster1=False;			//Taster 1 zurücksetzen
    		}
    		if (Taster2==True)			//Wenn Taster 2 gedrückt
    		{	
    			PORTB&=~(1<<PINB2);		//PB2 aus
    			PORTB|=(1<<PINB1);		//PB1 an
    			Taster2=False;			//Taster 2 zurücksetzen
    		}
    	}
    }
    Das Programm SOLLTE nach fünfmaliger Betätigung des Taster1 die LED 2 anschalten und LED 1 aus. Sowie (derzeit) nach einmaliger Betätigung des Taster 2 die LED 1 anschalten und LED 2 aus.

    Das Programm schaltet jedoch die LED 2 bereits beim ERSTEN betätigen des Taster1 ein und wartet nicht bis der Wert größer fünf wird. Hat da jemand einen Rat?

    Grüße

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    11.06.2014
    Beiträge
    9
    Mhh hat dazu keiner eine Idee? Oder nutzen alle das gute Wetter?

    Ich habe jetzt durch den Debug wohl einen Fehleransatz gefunden...

    Solange der Taster "gedrückt" ist zählt die Variable hoch, was bedeuten könnte ich kann den Taster nicht schnell genug los lassen eh das Programm 5 mal an der Stelle vorbei kommt.

    Kann man irgendwie nur die steigende oder fallende Flanke des Tasters abfragen so das zwischen zwei inkrementierungen neu gedrückt werden muss?
    Geändert von Denn Is (12.06.2014 um 18:28 Uhr)

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    Du musst den letzten Wert immer speichern und nur wenn LastValue != CurrentValue && Currentvalue == Gedrückt, dann +1.

    mfg

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    11.06.2014
    Beiträge
    9
    Danke! Das hat schon mal ein ganzes Stück weiter gebracht

    Hatte heute leider erst Zeit zum testen. Wenn ich zwischen zwei Tastendrücken nun 1-2 sekunden Warte klappt es wunderbar! Leider noch nicht ganz wenn ich die Taste mehrfach schnell hintereinander drücke. Dann leuchtet die LED teilweise schon beim dritten oder vierten druck.

    Hat da jemand noch einen Verbesserungsvorschlag?

    Hier der aktuelle Code:

    Code:
    //	Definitionen	//
    
    #define F_CPU 9000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    
    
    
    
    //	Variablen	//
    
    unsigned char True;
    unsigned char False;
    unsigned char Taster1;
    unsigned char Taster2;
    unsigned char Zustand1aktuell;
    unsigned char Zustand1alt;
    unsigned char Zustand2aktuell;
    unsigned char Zustand2alt;
    	
    //	Hauptprogramm	//
    
    int main (void)
    {
    	DDRB			= 0x06;		 // I/O Ports PB1+PB2;
    	PORTB			= 0x18;	 //Pull up aktivieren (PB3+PB4)
    	True			= 1;	//Startwert zuweisung
    	False			= 0;	//Startwert zuweisung
    	Taster1			= 0;	//Startwert zuweisung
    	Taster2			= 0;	//Startwert zuweisung
    	Zustand1aktuell	= 0;
    	Zustand1alt		= 0;
    	Zustand2aktuell	= 0;	
    	Zustand2alt		= 0;
    	
    	while(1)
    	{
    		//	Taster abfragen	//
    		
    		if(!(PINB & (1 << PINB3))||!(PINB & (1 << PINB3))||!(PINB & (1 << PINB3))) //Tasterabfrage PB3
    		{
    			Zustand1aktuell=1;
    			Zustand1alt=1;
    		}
    		else
    		{
    			Zustand1aktuell=0;
    		}
    		
    		if(!(PINB & (1 << PINB4))||!(PINB & (1 << PINB4))||!(PINB & (1 << PINB4))) //Tasterabfrage PB4
    		{	
    			Zustand2aktuell=1;
    			Zustand2alt=1;
    		}
    		else
    		{
    			Zustand2aktuell=0;
    		}
    		
    		if (Zustand1aktuell!=Zustand1alt)
    		{
    			Taster1++;	//Taster inkrementieren
    			Zustand1alt=0;
    		}
    		
    		if (Zustand2aktuell!=Zustand2alt)
    		{
    			Taster2=True;			 //Taster 2 gedrückt
    			Zustand2alt=0;
    		}
    		
    		//	LED Anzeige	//
    		
    		if (Taster1>=5)				//Wenn Taster1 größer gleich 5 erreicht
    		{
    			PORTB|=(1<<PINB2);		//PB2 an
    			PORTB&=~(1<<PINB1);		//PB1 aus
    			Taster1=False;			//Taster 1 zurücksetzen
    		}
    		if (Taster2==True)			//Wenn Taster 2 gedrückt
    		{	
    			PORTB&=~(1<<PINB2);		//PB2 aus
    			PORTB|=(1<<PINB1);		//PB1 an
    			Taster2=False;			//Taster 2 zurücksetzen
    		}
    	}
    }

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Hat da jemand noch einen Verbesserungsvorschlag?
    Erstmal etwas vereinfachen und lesbarer machen:

    Code:
    // Programm 'Taster abfragen'
    #define F_CPU 9000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    
    // Definitionen
    typedef uint8_t byte;					// bzw. unsigned char
    
    // Abfrage-Funktion eines Tasters
    // mit Software-Entprellung
    byte isPressed(byte pin, byte pinNr) {
    	return (pin & (1 << pinNr)) || (pin & (1 << pinNr)) || (pin & (1 << pinNr));
    }
    
    //	Hauptprogramm
    int main (void) {
    	DDRB			= 0x06;			// I/O Ports PB1+PB2;
    	PORTB			= 0x18;			// Pull up aktivieren (PB3+PB4)
    
    	// Variablen
    	enum btn_states {not_pressed, pressed, checked};
    	byte btn1		= not_pressed;
    	byte btn2		= not_pressed;
    	byte btn1_counter	= 0;
    
    	while(1) {
    		//	Taster1 abfragen	
    		if (isPressed(PINB, PINB3)) 		// Taster1 (PB3) gedrückt?		
    			if (btn1 == not_pressed) {	// erste Abfrage im Schaltmoment?
    				btn1_counter++;
    				btn1 = pressed;
    			}
    		else btn1 = not_pressed;
    		
    		//	Taster2 abfragen
    		if (isPressed(PINB, PINB4)) 		// Taster2 (PB4) gedrückt?	
    			if (btn2 == not_pressed)	// erste Abfrage im Schaltmoment?	
    				btn2 = pressed;		
    		else btn2 = not_pressed;
    		
    		//	LED Anzeige steuern
    		if (btn1_counter == 5  &&  btn1 == pressed) {// Taster 1 5x gedrückt?
    			PORTB |=  (1 << PINB2);		// PB2 an
    			PORTB &= ~(1 << PINB1);		// PB1 aus
    			btn1 = checked;
    		}
    		else if (btn2 == pressed) {		// Wenn Taster 2 gedrückt	
    			PORTB |=  (1<<PINB1);		// PB1 an
    			PORTB &= ~(1<<PINB2);		// PB2 aus
    			btn1_counter = 0;		// Zähler für Taster 1 zurücksetzen
    			btn2 = checked;
    		}
    	}
    }
    Geändert von Sisor (16.06.2014 um 16:35 Uhr)

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    11.06.2014
    Beiträge
    9
    Sorry das ich jetzt erst antworte aber war über das lange WE im Urlaub

    Soo habe jetzt deinen Code mal so 1zu1 in mein Atmelstudio übertragen und auf den Tiny13 gespielt.

    Leider leuchtet LED 1 nun dauerhaft(LED2 aus) bis Taster 2 gedrückt wird dann wechselt die LED (LED1 aus LED2 an) bis der Taster wieder losgelassen wurde (LED1 wieder an)
    Taster 1 zeigt gar keine reaktion...

    Leider habe ich deine "Vereinfachung" auch noch nicht ganz durchschaut...

    wäre:
    Code:
    if (btn1 == not_pressed) {	// erste Abfrage im Schaltmoment?
    nicht eigentlich die Funktionsschleife wenn der Taster NICHT gedrückt ist?

    Was verursacht der btn zustand "checked" zb bei:
    Code:
    btn1 = checked;
    ?

    Ich bekomme auch beim Compilieren zwei Warnings:
    Code:
    Warning	1	suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]	C:\Users\Dennis\Documents\Geocaching Programme\Taster\Taster\Taster\Taster_org.c	28	6	Taster
    Warning	2	suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]	C:\Users\Dennis\Documents\Geocaching Programme\Taster\Taster\Taster\Taster_org.c	36	6	Taster

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Ok, ich geb zu viel leichter ist das auch nicht zu verstehen...
    Ich bekomme auch beim Compilieren zwei Warnings...
    Grund:
    else btn2 = not_pressed;

    mit Klammern:

    else {
    btn2 = not_pressed;
    }

    Was verursacht der btn zustand "checked" ?
    Wenn die Taste gedrückt wird, aber der counter schon ein hochgezählt hat, brauche ich einen weiteren Zustand, damit der Counter erst nach Loslassen und erneutem Drücken wieder hochzäht. 'checked' wie 'bereits geprüft'

    Ich hatte eine Klammer vergessen, die die Logik verändert hatte.
    Hier korrigert:
    Code:
    #define F_CPU 9000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    typedef uint8_t byte;	
    
    byte isPressed(byte pin, byte pinNr) {
    	return (pin & (1 << pinNr)) || (pin & (1 << pinNr)) || (pin & (1 << pinNr));
    }
    
    //	Hauptprogramm
    int main (void) {
    	DDRB			= 0x06;			// I/O Ports PB1+PB2;
    	PORTB			= 0x18;			// Pull up aktivieren (PB3+PB4)
    
    	// Variablen
    	enum btn_states {not_pressed, pressed, checked};
    	byte btn1		= not_pressed;
    	byte btn2		= not_pressed;
    	byte btn1_counter	= 0;
    
    	while(1) {
    		//	Taster1 abfragen	
    		if (isPressed(PINB, PINB3)) {		// Taster1 (PB3) gedrückt?		
    			if (btn1 == not_pressed) {	// erste Abfrage im Schaltmoment?
    				btn1_counter++;
    				btn1 = pressed;
    			}
                    }
    		else { 
                    	btn1 = not_pressed;
    		} 
    		
    		//	Taster2 abfragen
    		if (isPressed(PINB, PINB4)) 		// Taster2 (PB4) gedrückt?	
    			if (btn2 == not_pressed) {	// erste Abfrage im Schaltmoment?	
    				btn2 = pressed;	
    		}	
    		else { 
                    	btn1 = not_pressed;
    		} 
    		
    		//	LED Anzeige steuern
    		if (btn1_counter == 5  &&  btn1 == pressed) {// Taster 1 5x gedrückt?
    			PORTB |=  (1 << PINB2);		// PB2 an
    			PORTB &= ~(1 << PINB1);		// PB1 aus
    			btn1 = checked;
    		}
    		else if (btn2 == pressed) {		// Wenn Taster 2 gedrückt	
    			PORTB |=  (1<<PINB1);		// PB1 an
    			PORTB &= ~(1<<PINB2);		// PB2 aus
    			btn1_counter = 0;		// Zähler für Taster 1 zurücksetzen
    			btn2 = checked;
    		}
    	}
    }
    Das sollte keine fertige Lösung sein, sondern nur ein Ansatz, wie man das Tasterproblem auch anders angehen kann.
    Pick dir das raus, was du gut findest / gebrauchen kannst.

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Ich hab mir mal 2 Std Zeit genommen und ein Programm geschrieben, dass deine Anforderungen erfüllen sollte.

    Ist getestet und arbeitet einwandfrei. Es werden 4 verschiedene Codes (Tasterfolgen) abgefragt. Kann aber fast beliebig erweitert werden. Es wurden 4 Taster auf den Pins 4 bis 7 benutzt.

    Leider ist es für Arduino. Aber sollte mit wenig Aufwand für den Tiny angepasst werden können.

    Code:
    // button pins 
    // 4 is pin of button1
    // 5 is pin of button2
    // 0 means end of buttons
    byte buttons[] = {4, 5, 6, 7, 0}; 
    // first 0 is for counting in function
    // 1,1,2,1 is code (press Button1, 2, 2, 1 for activating)
    // last 0 is end of code 
    byte code1[]  = {0,   1, 2, 2, 1,            0};
    byte code2[]  = {0,   2, 1, 2, 2,            0};
    byte code3[]  = {0,   3, 3, 3,               0};
    byte code4[]  = {0,   1, 2, 3, 4, 3, 2, 1,   0};
    byte* codes[] = {code1, code2, code3, code4, 0};
    
    
    byte initButtons(byte buttons[]) {
      // setup button pins for reading
      byte counter = 0;
      while(buttons[counter]) pinMode(buttons[counter++], INPUT);
    }
    
    byte checkButtons(byte* pressed_btn, byte* codes[], byte buttons[]) {
      static byte last_pressed = 0;
      if (last_pressed) {
        if(!digitalRead(buttons[last_pressed-1])) return 0;  // Button still pressed?     -> return
        else { last_pressed = 0; }                             // else: not pressed anymore -> go on
      }
      *pressed_btn = 0;
      byte btn_counter  = 0; // iterate over all buttons 
      byte code_counter = 0; // iterate over all codes
      while(buttons[btn_counter]) {
        byte is_pressed = !digitalRead(buttons[btn_counter]); // check buttons one after another
        if(is_pressed) {
          last_pressed = btn_counter+1;  // store pressed button number
          *pressed_btn = last_pressed;   // write pressed button number to external variable pressed_btn
          while(codes[code_counter]) {   // check all codes one after another
            if(codes[code_counter][(codes[code_counter][0])+1] == btn_counter + 1) { // is the pressed button nr equal to next button nr in code?
              codes[code_counter][0]++;
              if(!codes[code_counter][(codes[code_counter][0])+1]) { // code veryfied?
                byte i = 0; while(codes[i]) { *codes[i++] = 0; }     // reset all counters
                return code_counter+1;                               // returns number of detected code
              }
            }
            else { codes[code_counter][0] = 0; }
            code_counter++;
          }
          code_counter = 0;
        }
      btn_counter++;
      }
      return 0;  // 0 means no code veryfied
    }
    
    void setup() {
      initButtons(buttons);
      Serial.begin(57600);
    }
    
    void loop() {
      byte btn;
      byte detected_code = checkButtons(&btn, codes, buttons);
      //if (btn) { Serial.print("Button pressed: "); Serial.println(btn); }
      if (detected_code) { Serial.print("Code detected: ");Serial.println(detected_code); }
    }
    Ausgabe nach dem Drücken der Taster 1,2,2,1 (in dieser Reihenfolge):

    Code detected: 1
    ---
    Ausgabe nach dem Drücken der Taster 1, 2, 3, 4, 3, 2, 1 (in dieser Reihenfolge):

    Code detected: 4
    Geändert von Sisor (25.06.2014 um 07:38 Uhr)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Attiny13a RS232
    Von flecralf im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 09.10.2013, 19:27
  2. Variablen ändern sich durch Berechnung anderer Variablen
    Von Amri im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 03.05.2013, 18:30
  3. Kann Schalter nicht abfragen
    Von Icon2k im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 30.07.2010, 18:51
  4. Entprellung
    Von wolfshund im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 2
    Letzter Beitrag: 08.05.2007, 21:21
  5. Entprellung
    Von djdune im Forum Elektronik
    Antworten: 9
    Letzter Beitrag: 10.06.2004, 22:49

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests