Entprellung nach Peter Dannegger funktioniert nicht wie sie soll?!

Gast #3073214
Lesenswert?

Hallo,
ich sitze nun schon seit fast zwei Tagen an dieser Entprellung. Ich 
wollte erst einmal nur einen Taster verwenden, der soll aber auch lang 
und kurz unterscheiden können, so wie es in dieser Routine ja auch 
angekündigt ist.
Leider will das so nicht funktionieren. Ich habe den Eindruck als wenn 
der Taster immer gedrückt ist und er jedesmal da reinspringt. Direkt 
nach Power On steht auf dem Display Modus 2 und nicht Modus 1.

ich habe nur an PB0 einen Taster, PB1 und PB2 liegen über 10kohm an 
Plus, nach Ground ist kein Taster montiert.

Im Grunde habe ich alles so kopiert aus dem Wiki und nur folgende 
Änderungen gemacht:

taster.h
1
#define KEY_DDR         DDRB
2
#define KEY_PORT        PORTB
3
#define KEY_PIN         PINB
4
#define KEY0            0
5
#define KEY1            1
6
#define KEY2            2
7
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2)
8

9

10
#define REPEAT_MASK     (1<<KEY1 )       // repeat: key1, key2
11
#define REPEAT_START    50                        // after 500ms
12
#define REPEAT_NEXT     20                        // every 200ms
13

14
// #define LED_DDR         DDRA
15
// #define LED_PORT        PORTA
16
// #define LED0            0
17
// #define LED1            1
18
// #define LED2            2

taster.c
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include "taster.h"
5
#include "delay.h"
6

7
rest wie im Beispiel

in der main.c
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#include "lcd.h"
5
#include "taster.h"
6
#include "delay.h"
7

8
int main(void)
9
{
10
  
11
  // Configure debouncing routines
12
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
13
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
14
  
15
  TCCR0 = (1<<CS02)|(1<<CS00);         // divide by 1024
16
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
17
  TIMSK |= 1<<TOIE0;                   // enable timer interrupt
18
  
19
  sei();
20
  
21
  lcd_init();
22
  lcd_clear();
23
  lcd_setcursor( 0, 0 );
24
  lcd_string("Modus 1");
25

26
  while(1)
27
  {
28
    if( get_key_press( 1<<KEY0 ) || get_key_rpt( 1<<KEY0 ))
29
        {
30
            lcd_clear();
31
            lcd_setcursor( 0, 0 );
32
            lcd_string("Modus 2");
33
          }
34
        }
35
  
36
  return 0;
37
}

Ich benutze einen Atmega8. Ich denke es wird nichts großes sein aber 
irgendwie sehe ich den Fehler nicht.

Danke für die Hilfe.

Gruß Frank
#3073486
Lesenswert?

>     if( get_key_press( 1<<KEY0 ) || get_key_rpt( 1<<KEY0 ))

mach da mal eine zusätzliche Textumschaltung dazu und schreib 
abwechselnd was anderes aufs Display.
Und dann probierst du erst mal, ob die Taste grundsätzlich funktioniert 
oder ob das nur ein Effekt ist, weil sich die Tastenabfrage beim 
Hochfahren des Programms erst mal in einen gültigen Zustand versetzen 
muss und dabei (versehentlich) eine Tastenbetätigung meldet, die in 
Wirklichkeit nie stattgefunden hat, sich aber aus den Default-Belegungen 
der Variablen beim Einschalten des µC ergibt.
#3073492
Lesenswert?

> ich habe nur an PB0 einen Taster, PB1 und PB2 liegen über 10kohm an
> Plus, nach Ground ist kein Taster montiert.

Da hast du dir aber viel Arbeit gemacht.

Alles was du hättest tun müssen, ist in den #define einzutragen, dass du 
nur 1 Taste hast:
1
#define KEY_DDR         DDRB
2
#define KEY_PORT        PORTB
3
#define KEY_PIN         PINB
4
#define KEY0            0
5
#define ALL_KEYS        (1<<KEY0)
6

7
#define REPEAT_MASK     (1<<KEY0)
8
#define REPEAT_START    50                        // after 500ms
9
#define REPEAT_NEXT     20                        // every 200ms

fertig. Schon spielt die Anschlussbelegung von PB1 und PB2 keine Rolle 
mehr.
#3073501
Lesenswert?

> Ich habe den Eindruck als wenn der Taster immer gedrückt ist
> und er jedesmal da reinspringt.

So, so. Du hast also den Eindruck.
Was hast du unternommen, um aus deinem "Eindruck" Gewissheit werden zu 
lassen?

Wenn man etwas nicht sicher weiß, dann muss man sich halt überlegen, wie 
und mit welchem Test man diesen Punkt abklären kann.
#3073507
Lesenswert?

> Ich habe bei offenen Schalter am µC vcc und bei gedrückten Taster gnd.

Sollte es so sein oder hast du das tatsächlich nachgemessen?
Nachgemessen ist immer die bessere Alternative. Und ja: manche Taster 
kann man auch verkehrt rum anschliessen, weil sie sowohl als Öffner als 
auch als Schliesser benutzbar sind. Hast du so einen Taster und hast du 
ihn als Öffner angehängt, dann ergibt das für dein Programm "Dauerfeuer" 
- was alles erklären würde.

Also: Hast du nachgemessen, welchen Pegel du direkt am µC-Pin wirklich 
hast oder vermutest du das nur?
Gast #3073573
Lesenswert?

Hallo,

also ich habe die Pegel nachgemessen, da ich dort erst meinen Fehler 
vermutet habe. Ich nachher das ganze mal umstricken auf 2 Schalter.

Karl Heinz Buchegger schrieb:
> So, so. Du hast also den Eindruck.
>
> Was hast du unternommen, um aus deinem "Eindruck" Gewissheit werden zu
>
> lassen?

Ich habe in der ursprünlichen Schleife immer Modus 1 schreiben lassen, 
was aber nicht passiert es. es wird immer Modus 2 ausgegeben.

Karl Heinz Buchegger schrieb:
> Da hast du dir aber viel Arbeit gemacht.

so verkürzt hatte ich es auch schon. Entgegen der obigen Behauptung, 
dass ich meinen Kopf nicht anstrenge, kann ich nur sagen, dass ich viel 
nachgedacht habe und auch viel probiert. Mit nur einem ging es aber auch 
nicht :)

Wie gesagt sitze ich da schon einige zeit dran und habe auch das gröbste 
Verstanden nur finde ich meinen fehler nicht, daher meine Hoffnung auf 
eine rettende Idee.

Ich berichte später was bei rausgekommen ist.

Gruß
#3073588
Lesenswert?

OK. Dann lass uns mal am Problem arbeiten.

Als erstes schalten wir mal den Autorepeat weg. Zur Fehlersuche braucht 
den zur Zeit kein Mensch.

Neues Testprogramm
1
...
2
#include <utils/delay.h>
3
...
4

5
int main(void)
6
{
7
  int i = 0;
8
  char Buffer[30];
9

10
  // Configure debouncing routines
11
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
12
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
13
  
14
  TCCR0 = (1<<CS02)|(1<<CS00);         // divide by 1024
15
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
16
  TIMSK |= 1<<TOIE0;                   // enable timer interrupt
17
  
18
  sei();
19
  
20
  lcd_init();
21
  lcd_clear();
22
  lcd_setcursor( 0, 0 );
23
  lcd_string( "Press Key PB0" );
24

25
  _delay_ms( 500 );
26

27
  while(1)
28
  {
29
    if( get_key_press( 1<<KEY0 ) )
30
    {
31
      sprintf( Buffer, "Pressed %d", i++ );
32
      lcd_setcursor( 0, 0 );
33
      lcd_string( Buffer );
34
      _delay_ms( 100 );
35
    }
36
  }
37
  
38
  return 0;
39
}


Was siehst du am LCD?
Tut sich was, wenn du auf die Taste drückst?
#3073598
Lesenswert?

Frank schrieb:

>> Was hast du unternommen, um aus deinem "Eindruck" Gewissheit werden zu
>>
>> lassen?
>
> Ich habe in der ursprünlichen Schleife immer Modus 1 schreiben lassen,
> was aber nicht passiert es. es wird immer Modus 2 ausgegeben.

Das meinte ich nicht.
Du schrubst, du hättest den Eindruck, dass die Tastenroutinen ständig 
einen Tastendruck melden.
Wie hast du abgeklärt, ob dem wirklich so ist und da ständig eine 
Tastenbetätigung gemeldet wird? Mit deinem jetzigen Testprogramm kannst 
du das nicht besonders gut klären (ausser, wenn du das Flackern siehst), 
denn du schreibst immer das gleiche auf die Anzeige und wenn es erst mal 
dort steht, dann steht es dort, egal ob die Routine ein zweites mal 
aufgerufen wird oder nicht.

Von daher: dein Test ist scheisse. Wenn du wissen willst, ob eine 
Routine mehrmals aufgerufen wird, dann musst du dafür sorgen, dass bei 
jedem Aufruf was anderes aufs LCD kommt. Eine simple Variable die man 
hochzählt und ausgibt reicht dafür schon. Steht die Zahl auf dem LCD 
still, dann wird die Funktion NICHT mehrmals aufgerufen sondern nur 
einmal. Verändert sich die Zahl an der Anzeige, dann WIRD die Funktion 
mehrmals aufgerufen.
So ein Test ist aussagekräftig und verwandelt 'Ich habe den Eindruck, 
dass ...' zu 'Ich weiß, dass ...'
#3073615
Lesenswert?

Und nur zur Sicherheit ein allererstes Testprogramm, welches erst mal 
nichts mit dem Debouncen zu tun hat, sondern die Hardware klärt:
1
int main(void)
2
{
3
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
4
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
5

6
  while(1)
7
  {
8
    lcd_setcursor( 0, 0 );
9

10
    if( KEY_PIN & (1<<KEY0) )
11
      lcd_string( "Pin auf >> 1 <<" );
12
    else
13
      lcd_string( "Pin auf >> 0 <<" );
14
  }
15
  
16
  return 0;
17
}

Ist die Anzeige wie erwartet?
Normal steht
1
Pin auf >> 1 <<
auf dem LCD.
Drückst du auf den Taster, dann muss da
1
Pin auf >> 0 <<
dort stehen. Taste loslassen und die Anzeige muss wieder zurückwechseln. 
Achte auch auf die entscheidende 0/1 Position im Text. Wenn da auch nur 
der Hauch eines Flackerns zu sehen ist, dann ist da was faul.

Ist nur ein einfacher Test. Aber: Wenn das schon nicht klappt, dann 
brauchen wir gar nicht erst mit den Debounce Routinen anfangen. Von 
daher: ein einfacher Test, der schnell gemacht ist und der uns die 
Sicherheit gibt, dass der Eingangsport sich grundsätzlich genau so 
verhält wie erwartet. Dauert keine 2 Minuten und gibt erst mal eine 
gewisse Grundsicherheit.
Gast #3074086
Lesenswert?

Karl Heinz Buchegger schrieb:

>   _delay_ms( 500 );
>
>   while(1)
>   {
>     if( get_key_press( 1<<KEY0 ) )
>     {
>       sprintf( Buffer, "Pressed %d", i++ );
>       lcd_setcursor( 0, 0 );
>       lcd_string( Buffer );
>       _delay_ms( 100 );
>     }
>   }
>
>   return 0;
> }
>
>
> Was siehst du am LCD?
> Tut sich was, wenn du auf die Taste drückst?


ja es tut sich etwas, direkt nach Power On fängt er an hochzuzählen ohne 
das ich eine Taste drücke. Pegel am Eingang ist auf High. (gemessen)
#3074171
Lesenswert?

Hmm.
Der Code ist korrekt kopiert.

Aus meiner Sicht bleibt eigentlich nur noch die Möglichkeit, dass sich 
der Pin eine Störstrahlung einfängt, die er brav als Tastendrücke 
weitergibt. Nur sollte das eigentlich nicht sein, da ja der Taster nach 
Masse verschaltet ist und der Pullup eingeschaltet ist.

Der Entprellcode an sich ist ja in Ordnung. Den verwenden viele (ich 
inklusive) in vielen Projekten völlig problemlos. Es muss irgendwas in 
deiner Hardware sein.
Gast #3074179
Lesenswert?

ich habe das ganze auf einem Steckboard aufgebaut. Die Leitungen sind ja 
noch überschaubar. Merkwürdig ist doch aber, dass das einfache Programm 
funktioniert. Ich habe auch schon andere Ports ausprobiert, überall das 
gleiche Ergebnis. Wenn ich den Display Port umlege geht es auch nicht, 
das Display geht aber an anderen Ports. Damit kann ich ausschließen das 
der Atmega hin ist?!
#3074189
Lesenswert?

Karl Heinz Buchegger schrieb:
> Es muss irgendwas in
> deiner Hardware sein.

Sehe ich auch so.

Folgendes macht mich aber stutzig:

Frank schrieb:
> Pegel am Eingang ist auf High. (gemessen)

Es kann eigentlich nicht sein, dass die Routine einen High-Pegel als 
Tastendruck auswertet. Frank, womit und wie hast Du den Pegel gemessen? 
Und vor allen Dingen: Wo hast Du gemessen? Direkt am µC-Pin?

Ist der Taster auch wirklich an PB0 angeschlossen?
#3074194
Lesenswert?

Frank schrieb:
> ich habe das ganze auf einem Steckboard aufgebaut. Die Leitungen sind ja
> noch überschaubar.


Lass mal das ganze LCD Zeugs weg.
Nur Taster und 1 LED.

Im Programm bei jedem Tastendruck die LED umschalten und das Programm
bereinigen.

So schliessen wir erst mal aus, dass irgendwelcher Fremdcode an der
Sache beteiligt ist.

Steckboard und Taster sind so eine Sache. Meine Taster passen nicht
zuverlässig in mein Steckboard - die Pins sind zu dick.
:-)
Taster weglassen und dafür den Taster mit einem Stück Draht simulieren,
den man händisch bei Bedarf an Masse verbindet (2 Drähte: einer am Port,
einer an GND, bei Kontakt Tastendruck)

Da fällt mir ein:
Was passiert, wenn du den Taster entfernst und alles andere gleich
lässt? Zählt dann die Zahl immer noch hoch?
Gast #3074200
Lesenswert?

Gemessen habe ich den Pegel mit einem Multimeter, direkt am µC.

Der Taster ist über zwei kabel verbunden. Aber selbst wenn ich die Kabel 
weglasse und den Pin 1 nur über 10 kOhm auf high setze tritt das Problem 
auf.
#3074201
Lesenswert?

J.-u. G. schrieb:
> Karl Heinz Buchegger schrieb:
>> Es muss irgendwas in
>> deiner Hardware sein.
>
> Sehe ich auch so.
>
> Folgendes macht mich aber stutzig:
>
> Frank schrieb:
>> Pegel am Eingang ist auf High. (gemessen)
>
> Es kann eigentlich nicht sein, dass die Routine einen High-Pegel als
> Tastendruck auswertet.

yep.
selbst wenn er Dauer-Low hätte, würde er nur 1 Tastendruck kriegen und 
nicht laufende.
#3074206
Lesenswert?

Frank schrieb:
> Gemessen habe ich den Pegel mit einem Multimeter, direkt am µC.
>
> Der Taster ist über zwei kabel verbunden. Aber selbst wenn ich die Kabel
> weglasse und den Pin 1 nur über 10 kOhm auf high setze tritt das Problem
> auf.

Völlig unlogisch.
Mit >dem< Code ist das so nicht möglich.


Überprüf mal, ob du für den korrekten µC compilierst.
Gast #3074256
Lesenswert?

Neue Beobachtung: Ich hatte das zwar vorher schon ausprobiert aber da 
trat es irgendwie nicht auf.
Wenn Ich meinen Programmer abziehe dann habe ich bei 1 on 10 mal keinen 
durchlauf heist er steht bei "press key". Nehme ich dann meine 
drahtbrücke und simuliere einen tastendruck dann steht eine eins da usw. 
irgendwann fängt aber an selber weiter hoch zu zählen ohne das ich etwas 
mache....
Gast #3074285
Lesenswert?

Wenn ich den µC starte, so dass er in dem Zustand ist wo steht Press Key 
PB0 dann bleibt er da auch für jetzt 10 min. sobald ich aber anfange 
taster zu spielen mit meiner Drahtbrücke läuft er irgendwann von selbst 
los?!

Ich versteh es nicht....
Gast #3074303
Lesenswert?

100 nF zwischen 7 und 8 und zwischen 22 und 20. Es funktioniert 
ansonsten alles auch der ADC etc. nur das tasten nicht.

Ich habe jetzt zwei neue µC ausgepackt und eingebaut. Bei allen das 
gleiche Problem. Beim letzten habe ich die Schaltung auf dem Board an 
eine andere Ecke verpflanzt aber das ist es auch nicht....
Gast #3152228
Lesenswert?

Hallo,

also ich habe die Platine nun ätzen lassen. Ich habe zum Spielen mal den 
Schalter mit eingebaut aber nach wie vor habe ich das gleiche Problem.

Ich nutze nun einen ATMEG16, der Schalterhängt am PortB Pin 0. Kann es 
sein das der PORT Probleme macht?! Ist der Port B sonst irgendwie 
reserviert?!

Gruß
#3160817
Lesenswert?

Es geht nicht mehr um Ideen.

Die PeDa Entprellung funktioniert nachweislich 100-fach erstklassig und 
völlig problemlos.
Irgendetwas ist bei dir anders als normal. Da hier aber keiner hellsehen 
kann, gibt es so gut wie keine Möglichkeit, das von hier aus zu klären.


Edit:
Mach mal Photos von deinem Aufbau und stell sie ein. Vielleicht fällt 
einem ja dabei etwas auf. Denn das Grundproblem bleibt - die 
naheliegenden und gebräuchlichen Hardware-Probleme sind (so wie ich den 
Thread nochmal überflogen habe) alle abgehakt. Es muss irgendwas in 
deiner Hardware sein, was nicht so oft vorkommt und das keiner denkt.
Gast #3160871
Lesenswert?

Offensichtlch hast Du noch nicht so recht verstanden, wie diese 
Entprellung funktioniert.

Deswegen solltest Du erstmal Schaltungen OHNE Software-Entprellung 
aufbauen. Du kannst ja auch mit einem kleinen Kondensator (100nF) 
parallel zum Taster entprellen.

Wenn diese Sachen dann funktionieren, baue dann die Software-Entprellung 
wieder ein. Am Besten aber nicht einfach 1:1 kopieren, sondern die 
Funktion von Peter Programm verstehen und dann selsbt implementieren (so 
oder anders).

Am wichtigsten ist, dass Du nur Programmcode verwendest, den Du selbst 
versteht.
#3160894
Lesenswert?

Hmm schrieb:
> Naja. Ich würd' sagen wir warten erstmal ab, wie die Fotos aussehen. Der
> Code von Peter ist so ein Ausnahmefall bei dem doch schon mal eine ganze
> Kanne Kaffee und 'ne Pizza d'raufgehen können.

Jau.
Der ist nicht leicht komplett zu verstehen.
Aber - er funktioniert einfach zu gut als das man ihn ignorieren könnte.

Ich denke ernsthaft, dass es sich um irgend ein Hardware Problem 
handelt. Nur hab ich keinerlei Ideen mehr, was es noch sein könnte.
#3160895
Lesenswert?

Hmm schrub:
>Der Code von Peter ist so ein Ausnahmefall bei dem doch schon mal eine >ganze 
Kanne Kaffee und 'ne Pizza d'raufgehen können.

Gut, die Kanne ist aus Porzellan, die geht ohne Entprellung kaputt, wenn
sie herunterfällt -aber eine Pizza? Die ist doch weich genug.

Flücht
MfG Paul
Gast #3160899
Lesenswert?

>Ich denke ernsthaft, dass es sich um irgend ein Hardware Problem
>handelt. Nur hab ich keinerlei Ideen mehr, was es noch sein könnte.

Meine Glaskugel murmelt was von halblebigen Kurzschlüssen. Na, mal 
sehen.


> -aber eine Pizza? Die ist doch weich genug.
Die Entprellung, die hat Zähne... He he.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren