mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Programm reagiert nicht auf Tasterdruck


Autor: Nils Wiechert (darky9312)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS.
Dein Programm ist ein Kraut und Rüben Sammelsurium von Testcode. Du 
solltest mit einem neuen Testprogramm anfangen. Schön langsam wirds 
unübersichtlich.

Denn: Deine neu gewünschte Funktionalität (Tastendruck erkennen) ist gar 
nicht so einfach zu realisieren.

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht 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
if (!(PINB & (1<<PINB1)));
{
   if (PINB&(1<<PINB1));
   {
      Textaenderung();
   }
}
dann springt der doch sofort wieder weg wenn ich den Taster nicht 
innerhalb kürzester Zeit wieder loslasse oder?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
>
> if (!(PINB & (1<<PINB1)));
> {
>    if (PINB&(1<<PINB1));
>    {
>       Textaenderung();
>    }
> }
> 
> 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
  if (!(PINB & (1<<PINB1)));
  {
    while( !(PINB&(1<<PINB1))
     ;
    Textaenderung();
  }


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/Entprellun...

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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/Entprellun...

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.

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe erst jetzt den Link gesehen^^
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...
Ich versteh die Welt nichtmehr...

Autor: Frank Bär (f-baer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, statt den Taster zu pollen, wäre ein Interrupt die sinnvollere 
Methode um nicht Rechenzeit zu vergeuden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hatte ich auch schon überlegt aber so wie ich das dann gesehen habe 
können nur bestimmte Pins am uC nen interrupt auslösen und die sind 
leider schon belegt...

Autor: Nils Wiechert (darky9312)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nils Wiechert schrieb:
> Hatte ich auch schon überlegt aber so wie ich das dann gesehen habe
> können nur bestimmte Pins am uC nen interrupt auslösen und die sind
> leider schon belegt...

Pssst.
Man nimmt auch keine Interrupts für Tasten her. Das bringt mehr Ärger 
als es wert ist. Einzige Ausnahme: wenn man den µC mit einer Taste aus 
dem Tiefschlaf aufwecken muss.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar mach ich. Darf ich mich dann nochmal melden? :P
SOll ich die UNterprogramme dann vor oder nach Main amchen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar dann kram cih mein atmega16 lernboard mal wieder raus :P

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nils Wiechert schrieb:
> Alles klar dann kram cih mein atmega16 lernboard mal wieder raus :P

Wozu?
Du hast doch ein Board auf dem 1 Taster und mindestens 1 Led sitzt.

Ignorier doch einfach den Rest :-)

Autor: Nils Wiechert (darky9312)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hm so wie ich das sehen sollte das jetzt bei nem Tastendruck die 
Variable Leddefinition ändern. und danach die Led entweder ein oder 
ausschalten... aber irgendwie hab ich was falsch gemacht. Hängt das 
irgendwie damit zusammen dass das ein/ausschalten in nem eigenen 
Unterprogramm ist?
LG
Nils

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur kurz drübergeschaut

    if (!(PINB&(1<<PINB0)));


was macht der Strichpunkt da am Ende?

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fehl am platze sein :D
Aber auch ohne wills net richtig funktionieren

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void zustandaendern (void)
{
  if (Leddefinition == 0)
  {
    Leddefinition = 1;
  }
  else
  {
    Leddefinition = 1;
  }
  ledschalten();
  
}

Du setzt in beiden Fällen Leddefinition auf 1.

Schreibs so:
void zustandaendern (void)
{
  Leddefinition = 1 - Leddefinition;
  ledschalten();
}

oder so
void zustandaendern (void)
{
  Leddefinition ^= 0x01;
  ledschalten();
}

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 :-)

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht 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:
int main (void)
{
  while (1)
  {
    if (!(PINB&(1<<PINB0)));
    {
      while (!(PINB&(1<<PINB0)));
      {
      }
    zustandaendern();
    }
  }
  return 0;
}
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast

    if (!(PINB&(1<<PINB0)));

den Strichpunkt immer noch drinnen.
Sei ein bischen sorgfältiger

PS: Hier
      while (!(PINB&(1<<PINB0)));
ist ebenfalls ein überflüssiger ;
In deinem jetzigen Programm wirkt er sich aber nicht aus, insofern hast 
du Glück gehabt.

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mann ich Idiot...
aber jetzt springt der wenn ich das Bit an PINB setzte trotzdem wieder 
zum IF und nicht zur Zustandsänderung

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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>

Autor: Nils Wiechert (darky9312)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.