Forum: Mikrocontroller und Digitale Elektronik Programm reagiert nicht auf Tasterdruck


von Nils W. (darky9312)


Angehängte Dateien:

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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von Nils W. (darky9312)


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?

von Karl H. (kbuchegg)


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

von Nils W. (darky9312)


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

von Karl H. (kbuchegg)


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.

von Nils W. (darky9312)


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

von Frank B. (f-baer)


Lesenswert?

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

von Karl H. (kbuchegg)


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)

von Nils W. (darky9312)


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

von Nils W. (darky9312)


Angehängte Dateien:

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.

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von Nils W. (darky9312)


Lesenswert?

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

von Karl H. (kbuchegg)


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.

von Nils W. (darky9312)


Lesenswert?

Alles klar dann kram cih mein atmega16 lernboard mal wieder raus :P

von Karl H. (kbuchegg)


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

von Nils W. (darky9312)


Angehängte Dateien:

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

von Karl H. (kbuchegg)


Lesenswert?

Nur kurz drübergeschaut

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


was macht der Strichpunkt da am Ende?

von Nils W. (darky9312)


Lesenswert?

fehl am platze sein :D
Aber auch ohne wills net richtig funktionieren

von Karl H. (kbuchegg)


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

von Nils W. (darky9312)


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

von Karl H. (kbuchegg)


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.

von Nils W. (darky9312)


Lesenswert?

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

von Karl H. (kbuchegg)


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>

von Nils W. (darky9312)


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.

von Peter D. (peda)


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

von Karl H. (kbuchegg)


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

von Karl H. (kbuchegg)


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)

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.