Forum: Mikrocontroller und Digitale Elektronik Problem mit Tasterentprellung


von Newbie (Gast)


Lesenswert?

Hallöchen,

ich benutze Peter's Tasterentprellung...
http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
... und habe ein Problem mit der Funktion "get_key_short(1<<KEY1)".

Ich habe auf KEY1 die Repeat-Funktion der Entprellung und diese funzt 
auch einwandfrei - bei Loslassen des Tasters wird aber jedesmal auch ein 
"get_key_short"-Ereignis ausgelöst.

Ich möchte mir gern einen Dimmertaster bauen, wobei ich aber unbedingt 
auch genau diese "short"-Funktion brauche, um die LEDs mit einem kurzen 
Hub an-/ausschalten zu können.

Hat jemand von euch vielleicht einen Rat? (alle anderen Routinen des 
Codes funktionieren auch miteinander, nur diese eine nicht)

Viele Grüße

von Newbie (Gast)


Lesenswert?

EDIT:

Mit der zusätzlichen Variable bON bin ich nun zumindest soweit, dass das 
Ausschalten per kurzem Druck funktioniert:
1
if(get_key_short(1<<KEY1))
2
{
3
if(bON == 1)
4
{
5
if(!(get_key_rpt(1<<KEY1)))
6
nSavedPWM = OCR1A;
7
OCR1A = 0;
8
bON = 0;
9
}
10
else
11
{
12
OCR1A = nSavedPWM;
13
bON = 1;
14
}
15
}
16
17
if(get_key_rpt(1<<KEY1))
18
{
19
if(nCount > 1)
20
{
21
OCR1A += nSteps;
22
if(OCR1A >= 1023)
23
{
24
OCR1A = 0;
25
}
26
}
27
nSavedPWM = OCR1A;
28
bON = 0;
29
nCount++;
30
}
31
if(PINC & (1<<PINC0))
32
nCount=0;

Niemand einen Rat?

LG

von Peter D. (peda)


Lesenswert?


von Newbie (Gast)


Lesenswert?

Hallo Peter,

danke für die schnelle Antwort.;-)

Ich komm' aber leider nicht weiter. WIE genau muß ich denn...
"get_key_short() mit get_key_long_r() und get_key_rpt_l()" miteinander 
verbinden?
Die Grafik von 'Jonas' hab' ich verstanden, aber die Verknüfung der 
Funktionen leider nicht.:(

Viele Grüße

von Newbie (Gast)


Lesenswert?

Moin moin,;-)

ich hab' jetzt mal wie folgt versucht, aber ich bekomm es nicht hin, 
'bON' bei kurzem Tastendruck zu toggeln, sodass man neben der 
Dimmfunktion über '...rpt' auch ein-/ausschalten kann:

  while(1)
  {

    if(get_key_short(1<<KEY1))
    {
      if(bON == 1)
      {
        nSavedPWM = OCR1A;
        OCR1A = 0;
        bON = 0;
      }
      else
      {
        OCR1A = nSavedPWM;
        bON = 1;
      }
    }

    if(get_key_long_r(1<<KEY1) || get_key_rpt_l(1<<KEY1))
    {
      if(nCount > 1)
      {
        OCR1A += nSteps;
        if(OCR1A >= 1023)
          OCR1A = 0;
        nSavedPWM = OCR1A;
      }

      //bON = 0;
      nCount++;
    }
    if(PINC & (1<<PINC0))
      nCount=0;



  }
  return 0;

WAS mach ich denn nur falsch???

Viele Grüße

von Newbie (Gast)


Lesenswert?

Hey liebe Gemeinde^^,

bin langsam echt am Verzweifeln. Ich bastle jetzt seit seit über 30 
Stunden durchweg an dieser Taster-Entprellung und bekomm es einfach ned 
hin.
Die Tasterentprellung habe ich 1:1 von Peter übernommen, aber die 
Funktion 'Short+Repeat' funktioniert einfach NICHT wirklich. Manchmal 
geht's, aber meistens eher NICHT.

Mit 'Short+Repeat' bekomm ich nach jedem 'Repeat' auch ein 
'Short'-Signal und mit 'Short+LongR+RepeatL'(s. vorheriger Beitrag) 
kommt das 'Short'-Signal nur ab und an mal...?! WAS ist denn da nur los? 
Ist Peter's Code nicht voll funktionsfähig???

Dies ist mein restlicher Code:
1
#ifndef F_CPU
2
#define F_CPU 16000000
3
#endif
4
/*******************************************************************************************************/
5
// Einbindung von Standardbibliotheken...
6
#include <stdint.h>        // Datentypen (standardisiert)
7
#include <avr/io.h>        // Registernamen
8
#include <avr/interrupt.h>
9
#include <stdio.h>         // Rechenoperationen, etc.
10
#include <math.h>
11
//#include <string.h>        // Zeichenketten-Funktionen
12
// ... und externen Dateien
13
#include "buttons.h"
14
/*******************************************************************************************************/
15
#define RELAIS_ON PIND7
16
#define RELAIS_OFF PINB0
17
/*******************************************************************************************************/
18
volatile uint8_t sreg_local;
19
// zum Deaktivieren der ISRs(Interrupt Service Routine) auf globaler Ebene
20
void ISR_0() // ISRs deaktivieren
21
{
22
    sreg_local = SREG; // Erstellung einer lokalen Sicherungskopie von SREG
23
    cli();
24
}
25
// zum Aktivieren der ISRs auf globaler Ebene
26
// (Es werden ausschließlich die ISRs aktiviert, die auch vor dem Abschalten schon in Benutzung waren!)
27
void ISR_1() // ISRs aktivieren
28
{
29
    SREG = sreg_local; // Sicherungskopie von SREG laden
30
}
31
/*******************************************************************************************************/
32
// Steuerung der ISR(Interrupt Service Routine)
33
34
uint16_t iCount = 0;
35
uint16_t nVal = 960;
36
ISR(TIMER1_OVF_vect)
37
{
38
39
40
41
42
  /*iCount++;
43
  if(iCount>=nVal)
44
  {
45
    OCR1A = 5;
46
    if(iCount>=(nVal*2))
47
    {
48
      OCR1A = 50;
49
      iCount=0;
50
    }
51
  }*/
52
}
53
/*******************************************************************************************************/
54
int main (void)
55
{
56
  // Konfiguration der I/Os
57
  // Taster an Pin23:
58
  DDRC &= ~(1<<PC0); // Pin PC0 als Eingang
59
  PORTC |= (1<<PC0); // Aktivierung des internen Pull-Up an PC0
60
61
  DDRB = 0xFF;
62
  DDRD = 0xFF;
63
    /***************************************************************************************************/
64
  // Konfiguration des Timers
65
  // Mode:Fast PWM;TOP:OCR1A;Update:BOTTOM;TOV1:TOP;Prescaler:1(FRQ@16MHz = 16MHz)
66
  TCCR1A = (1<<COM1A1)|(1<<WGM11);
67
  TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);
68
    OCR1A = 0;          // PWM-Wert
69
  ICR1 = 1023;        // TOP-Wert des Zählers
70
  TIMSK1 |= 1<<TOIE1; // Aktivierung des Interrupts(Timer1 Overflow Interrupt Enable)
71
72
  TCCR0B = (1<<CS02)|(1<<CS00);      // divide by 1024
73
  TIMSK0 |= 1<<TOIE0;        // enable timer interrupt
74
  sei();
75
  /***************************************************************************************************/
76
  int16_t nSavedPWM = 0;
77
  int16_t nCount = 0;
78
  int16_t bON = 0;
79
80
  while(1)
81
  {
82
    
83
    if(get_key_short(1<<KEY1))
84
    {
85
      if(bON == 0)
86
      {
87
        OCR1A = nSavedPWM;
88
        bON = 1;
89
      }
90
      else
91
      {
92
        nSavedPWM = OCR1A;
93
        OCR1A = 0;
94
        bON = 0;
95
      }
96
      
97
    }
98
99
    if(get_key_long_r(1<<KEY1) || get_key_rpt_l(1<<KEY1))
100
    {
101
      if(nCount > 1)
102
      {
103
        OCR1A += 50;
104
        if(OCR1A >= 1023)
105
          OCR1A = 0;
106
        nSavedPWM = OCR1A;
107
      }
108
      
109
      bON = 0;
110
      nCount++;
111
    }
112
    if(PINC & (1<<PINC0))
113
      nCount=0;
114
115
116
117
  }
118
  return 0;
119
}

In Peter's Tasterentprellung habe ich nur einen Teiler für TCNT0, von 
'F_CPU' > 'F_CPU/16', eingefügt, um auf die originale 1MHz-Frequenz zu 
kommen.

PLEASE HELP ME.;-)

Liebe Grüße

von Newbie (Gast)


Lesenswert?

EDIT:

Hab's nun auch ohne Hilfe gelöst. Danke trotzdem.;-)
Meine Hilsvariable war nur an der falschen Stelle.

Dimmer mit EIN-/AUS-Schaltfunktion:

if(get_key_short(1<<KEY1))
    {
      if(bON == 0)
      {
        OCR1A = nSavedPWM;
        bON = 1;
      }
      else
      {
        nSavedPWM = OCR1A;
        OCR1A = 0;
        bON = 0;
      }

    }

    if(get_key_rpt(1<<KEY1))
    {
      if(nCount > 1)
      {
        OCR1A = OCR1A + 50;
        if(OCR1A >= 1023)
          OCR1A = 0;

        bON = 0;
        nSavedPWM = OCR1A;
      }


      nCount++;
    }
    if(PINC & (1<<PINC0))
      nCount=0;


LG

von Peter D. (peda)


Lesenswert?

Newbie schrieb:
> Mit 'Short+Repeat' bekomm ich nach jedem 'Repeat' auch ein
> 'Short'-Signal und mit 'Short+LongR+RepeatL'(s. vorheriger Beitrag)
> kommt das 'Short'-Signal nur ab und an mal...?! WAS ist denn da nur los?
> Ist Peter's Code nicht voll funktionsfähig???

Er funktioniert.
Aber Du mußt den Link schon lesen und Dich danach richten.
Es steht alles drin.
Und wenn da steht:
> - get_key_short() mit get_key_long_r() und get_key_rpt_l()
dann ist das auch so gemeint. Du darfst keine Funktion weglassen!
Du mußt sie ja nicht auswerten, nur aufrufen reicht.
Dein Würg-Around mit der Hilfsvariable ist dann völlig unnötig.

Überlege mal selber, wie die arme CPU erkennen soll, was Du willst. Sie 
kann doch nicht in Deinen Kopf sehen.


Peter

von Newbie (Gast)


Lesenswert?

Hi Peter,

ich hab' noch ein wenig Probleme mit Bitmanipulation und Datentypen, was 
wohl mein größtes Problem darstellt.
So läuft das Programm z.B. auch erst, seit ich meine (Hilfs-)Variablen 
von uint8_t auf int16_t umdeklariert habe.

Wie du oben sehen kannst, habe ich ja deine drei Funktionen aufgerufen - 
UND Probleme bekommen.
Es geht ja jetzt endlich (auch, wenn ich es anders gelöst habe). Falls 
deine anfängliche Variante wirklich funktionieren sollte und ich bei der 
Umsetzung nur Fehler gemacht habe, wäre ich sehr glücklich, wenn du mir 
es "richtig" aufzeigen könntest.^^

Die Hilfsvariable brauche ich UNBEDINGT, da ich sonst NICHT toggeln 
kann.

Liebe Grüße

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.