Programm reagiert nicht auf Tasterdruck

OP #1803798
Lesenswert?

Hallo
Ich wollte mir ein Board bauen auf dem ungefähr ind er Mitte ein LCD ist 
und drumherum 32 Leds, einzeln über 2 16er Multiplexer ansteuerbar. 
Gesteuert werden sollte das ganze mit einem AtMega8 der mit 12 Mhz 
läuft. Über Taster sollte jetzt nun entweder der derzeitige Effekt der 
Leds festgestellt werden oder der Text der über das Display läuft 
geändert werden. Ich habe noch einen Weiteren Taster für eine eventuelle 
andere Erweiterung eingebaut. Mit den Effekten der Leds und dem 
Ansteuern vom Lcd hat alles funktioniert. Ich muss dazu sagen dass das 
mein erstes richtiges Programm in C ist allerdings mein Bruder etwas C 
kann und mir deswegen geholfen hat. Mein Problem ist nun, dass wenn ich 
den entsprechenden Taster drücke nichts passiert, im Gegenteil sogar, da 
ich den ersten Taster dafür verwenden wollte um den Text zu ändern hab 
ich mit dem auch angefangen. Nun ändert sich der Text allerdings auch 
wenn ich den Taster garnicht drücke. Aber auch wenn ich ihn drücke 
passiert nicht anderes. ICh hab schon ein paar andere Sachen probiert, 
vorher hatte ich die Textänderung auch nicht in einem Unterprogramm 
sondern in Main stehen. Kann mir Jemand bitte helfen???? Ich weiß 
nichtmehr weiter und bin am verzweifeln.
Liebe Grüße
Nils
Angehängte Dateien:
#1803809
Lesenswert?

Deine Taster schalten nach Masse?
Hast du einen externen Pullup Widerstand?

Wahrscheinlich nicht. Das heißt du musst zumindest den internen Pullup 
Widerstand einschalten. Ansonsten hast du einen Eingang der buchstäblich 
bei nicht gedrücktem Taster in der Luft hängt und nur Gott alleine weiß, 
welchen Zustand der dann annimmt, aber der sagt nichts.

Das ist das eine.
Das andere ist:

    if (!(PINB & (1<<PINB1)));
    {
      Textaenderung();
    }

Dir muss klar sein, dass das keine Abfrage ist: Wenn eine Taste gedrückt 
wird.

Das ist eine Abfrage, ob eine Taste gedrückt ist!
Der UNterschied ist in etwa so, wie der Unterschied von deiner 
TV-Fernbedienung, bei der ein Tastendruck um 1 Kanal weiterschaltet und 
einer Rollosteuerung bei der das Rollo rauf/runter fährt solange die 
Taste gedrückt ist und stehen bleibt, wenn du die Taster wieder 
loslässt.

Du willst ersteres, hast aber letzteres programmiert.
OP #1803824
Lesenswert?

Habe 10k Pulllup Widerstände udn auch nachgemessen, wenn taster nicht 
gedrückt wird, 5V und wenn er gedrückt wird bin ich bei 0V also masse. 
Habe vorher in Assembler programmiert bin aber jetzt umgestiegen weil 
mir jemand gesagt hätte C wäre bei diesem Projekt einfacher, da ich auch 
noch niicht sehr viel in Asm gemacht hatte. Wie könnte ich das denn mit 
"TV-Fernbedienungseffekt" programmieren? dann müsste der doch am besten 
warten wenn ein taster gedrück wird und ert umschalten wenn der wieder 
losgelassen wird oder? aber wie mache ich das denn denn wenn ich mache
1
if (!(PINB & (1<<PINB1)));
2
{
3
   if (PINB&(1<<PINB1));
4
   {
5
      Textaenderung();
6
   }
7
}
dann springt der doch sofort wieder weg wenn ich den Taster nicht 
innerhalb kürzester Zeit wieder loslasse oder?
#1803834
Lesenswert?

Nils Wiechert schrieb:
> Habe 10k Pulllup Widerstände udn auch nachgemessen, wenn taster nicht
> gedrückt wird, 5V und wenn er gedrückt wird bin ich bei 0V also masse.

OK.
Dann brauchst du natürlich keinen internen Pullup


> losgelassen wird oder? aber wie mache ich das denn denn wenn ich mache
>
1
> if (!(PINB & (1<<PINB1)));
2
> {
3
>    if (PINB&(1<<PINB1));
4
>    {
5
>       Textaenderung();
6
>    }
7
> }
8
>
> dann springt der doch sofort wieder weg wenn ich den Taster nicht
> innerhalb kürzester Zeit wieder loslasse oder?

Richtig.
So schnell kannst du nicht drücken und loslassen.

Ich ignoriere jetzt erst mal etwas, was das ganze zu Fall bringen wird:


Die while Schleife ist schon erfunden!
Wenn in der Hauptschleife festgestellt wird, dass eine Taste gedrückt 
ist, dann gehts in das if hinein. Und dort wartest du in einer Schleife 
solange, bis die Taste wieder losgelassen wird
1
  if (!(PINB & (1<<PINB1)));
2
  {
3
    while( !(PINB&(1<<PINB1))
4
     ;
5
    Textaenderung();
6
  }


Probiers ruhig aus.
Wie gesagt, ich hab hier etwas ignoriert, welches dieses Vorgehen 
(abgesehen vom Warten) zu Fall bringt: Tasten prellen.


Eine saubere Entprellung, die auch gleich noch die anderen Schwachpunkte 
der Einfachstlösung behebt, findet sich hier.

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
OP #1803842
Lesenswert?

DIckes fettes danke werde ich gleich ausprobieren
Zum Prellen: Im tutorial steht, dass man einfach eine Pause von 100ms 
oder so einfügen soll... Hab ich bisher aber nicht gemacht, weil mir 100 
ms etwas lange vorkommen und ich beim ausprobieren eigentlich nicht 
wollte dass 100ms lang etwas nicht normal funktioniert und ich jedesmal 
nen schock bekomme bis mir einfällt dass das die Pause wegen dem 
entprellen ist. Oder gibt es eine besere Methode?
Liebe Grüße:
Nils
#1803851
Lesenswert?

Nils Wiechert schrieb:
> DIckes fettes danke werde ich gleich ausprobieren
> Zum Prellen: Im tutorial steht, dass man einfach eine Pause von 100ms
> oder so einfügen soll... Hab ich bisher aber nicht gemacht, weil mir 100
> ms etwas lange vorkommen

100ms sind etwas lang. 20ms sollten auch reichen. Muss man aber 
ausprobieren. Hängt von den Tastern ab.

> und ich beim ausprobieren eigentlich nicht
> wollte dass 100ms lang etwas nicht normal funktioniert

100ms ist eine Zehntelskunde. Auch wenn diese Zeit aus µC Sicht ziemlich 
kurz ist, aus Benutzersicht wird es wohl kaum jemand bemerken, der es 
nicht weiß.

> und ich jedesmal
> nen schock bekomme bis mir einfällt dass das die Pause wegen dem
> entprellen ist. Oder gibt es eine besere Methode?

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

Ist aber schon etwas anspuchsvoll. Allerdings ist das Code von dem du 
als Einsteiger nicht wissen musst wie er funktioniert. Wichtig ist nur, 
dass er funktioniert. Und das tut er erstklassig.
#1803858
Lesenswert?

Nils Wiechert schrieb:

> Aber jetzt ist immer noch nicht das Problem behoben, dass mein
> Controlelr wie verrückt zwischen den Texten wechselt... aber das kann
> doch eigentlich garnicht sein...

Dein Programm sieht jetzt wie aus?

(Wie gesagt: Fang ein frisches Programm an. Dein jetziges ist schon 
Kraut und Rüben. Da blickt keiner mehr durch, ob es nicht irgendwelche 
Nebeneffekte gibt)
#1803873
Lesenswert?

Nils Wiechert schrieb:
> Habe mich vertan, es passiert etwas, aber immernoch falsch, wenn ich den
> Taster drücke machen die Leds nichtsehr und dann erst scrollt der Text
> durch.
> Und auch einmaliges Drücken des Tasters bringt nichts.

Ich kann mich nur wiederholen:
Mach ein neues Testprogramm. Deines ist schon extrem unübersichtlich.
Und tu dir selbst einen Gefallen und verwende sprechende Variablennamen.
#1803879
Lesenswert?

Nils Wiechert schrieb:
> Alles klar mach ich. Darf ich mich dann nochmal melden? :P
> SOll ich die UNterprogramme dann vor oder nach Main amchen?

Davor. Ist einfachen.

Dein erstes Programm mit einer Taste könnte sein:

Eine (!) LED mit einem Tastendruck einschalten.
Dieselbe LED mit dem nächsten Tastendruck wieder ausschalten.

Nicht mehr. Das reicht schon, damit du eine Tastenauswertung in Aktion 
siehst.

Dein Fokus in diesem Testprogramm liegt ja auf der Auswertung eines 
Tastendrucks und nicht darauf, was dann alles passieren soll.
#1803969
Lesenswert?

1
void zustandaendern (void)
2
{
3
  if (Leddefinition == 0)
4
  {
5
    Leddefinition = 1;
6
  }
7
  else
8
  {
9
    Leddefinition = 1;
10
  }
11
  ledschalten();
12
  
13
}

Du setzt in beiden Fällen Leddefinition auf 1.

Schreibs so:
1
void zustandaendern (void)
2
{
3
  Leddefinition = 1 - Leddefinition;
4
  ledschalten();
5
}

oder so
1
void zustandaendern (void)
2
{
3
  Leddefinition ^= 0x01;
4
  ledschalten();
5
}

dann passiert dir sowas nicht mehr. Du hast für eine einfache 
Funktionalität ( 1 Bit toggeln ) zu viel Code produziert, so das du die 
Übersicht verloren hast. Ansonsten wär dir der Copy&Paste Fehler selbst 
aufgefallen :-)
OP #1804142
Lesenswert?

hab grad ma mein Programm bei Avrstudio simuliert... unglaublich dass 
ich mit sowas simplem wie einer Tasterabfrage nen ganzen Tag 
verbringe... naja egal... ich habe jetzt den code:
1
int main (void)
2
{
3
  while (1)
4
  {
5
    if (!(PINB&(1<<PINB0)));
6
    {
7
      while (!(PINB&(1<<PINB0)));
8
      {
9
      }
10
    zustandaendern();
11
    }
12
  }
13
  return 0;
14
}
also nur die main... der kommt aber nie weiter als bis zum while... also 
wenn ich PINB0 im Simulator auf 1 setzt dann wechselt der immer zwischen 
if und while, aber eigentlich soll der ja bei einer 1 aus der while 
schleife rausspringen und zustandaendern ausführen.
Oder sehen ich das mal wieder falsch???????
Ich bin echt am verzweifeln...
Lg
Nils
#1804189
Lesenswert?

Nils Wiechert schrieb:
> Mann ich Idiot...
> aber jetzt springt der wenn ich das Bit an PINB setzte trotzdem wieder
> zum IF und nicht zur Zustandsänderung

Kein Wunder: Du fragst ja auch ab, ob der Pin zu 0 wird.
Dein Ruhezustand ist: Pin ist 1
Wenn du eine Taste drückst, wird der Pin zu 0.

Du musst im Simulator schon das nachstellen, was auch in Wirklichkeit 
passiert, wenn du eine Taste drückst.

Schon vergessen?
<Zitat>
Habe 10k Pulllup Widerstände udn auch nachgemessen, wenn taster nicht
gedrückt wird, 5V und wenn er gedrückt wird bin ich bei 0V also masse.
</Zitat>
OP #1804258
Lesenswert?

Das ist mir klar... Ich kann ja im SImulator bei PINB die Kästtchen 
füllen... aber wenn ich das kästchen leer mache bleibt er beim while und 
wenn ich es dann wieder fülle (also die 1) dann springt er wieder zum if 
und nicht zur Zustandsaenderung... DAS ist mein Problem im Moment.
#1804437
Lesenswert?

Nils Wiechert schrieb:
> unglaublich dass
> ich mit sowas simplem wie einer Tasterabfrage nen ganzen Tag
> verbringe...

Diesen Fehler machen leider auch viele Profis, sie halten Tastenabfrage 
für simpel, einer ordentlichen Programmierung nicht würdig.

Daher sieht man leider auch so viele kommerzielle Geräte mit Problemen, 
z.B. Prellen, Drücke gehen verloren, Reaktion ohne Drücken 
(elektrostatische Störungen), Programm hängt bei langem Drücken und 
vieles ander mehr.

Es gibt aber bereits ausgereifte fertige Lösungen. Daher sollte man 
nicht versuchen, das Fahrrad nochmal zu erfinden. Weder die 
Funktionssicherheit noch die Effizienz wird man nicht in unter 2 Wochen 
erreichen.

Beitrag "Universelle Tastenabfrage"


Peter
#1804450
Lesenswert?

Nils Wiechert schrieb:
> Das ist mir klar... Ich kann ja im SImulator bei PINB die Kästtchen
> füllen... aber wenn ich das kästchen leer mache bleibt er beim while und
> wenn ich es dann wieder fülle (also die 1) dann springt er wieder zum if
> und nicht zur Zustandsaenderung... DAS ist mein Problem im Moment.

Dann hast du noch irgendwo einen Fehler in der Schreibweise.

(Den Optimizer hast du ausgeschaltet?)
#1804452
Lesenswert?

Peter Dannegger schrieb:
> Nils Wiechert schrieb:
>> unglaublich dass
>> ich mit sowas simplem wie einer Tasterabfrage nen ganzen Tag
>> verbringe...
>
> Diesen Fehler machen leider auch viele Profis, sie halten Tastenabfrage
> für simpel, einer ordentlichen Programmierung nicht würdig.

Ich bin grundsätzlich 100% bei dir.
Sein Problem ist aber, dass er als Neuling noch zu schlampig arbeitet 
und dann natürlich eine Menge Zeit darauf draufgeht, die selbst 
eingebauten Schlampigkeitsfehler zu finden.

> Es gibt aber bereits ausgereifte fertige Lösungen. Daher sollte man
> nicht versuchen, das Fahrrad nochmal zu erfinden. Weder die
> Funktionssicherheit noch die Effizienz wird man nicht in unter 2 Wochen
> erreichen.

Da'cor  (oder wie das heisst)

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