PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ansatz für Menü mit 3 Tastern



DarkFire
10.06.2006, 21:21
Hallo!

Nachdem ich nun mein 4x27 Zeichen Display erfolgreich ansteueren kann, wollte ich mich an einen der nächsten Schritte wagen, und zwar ein Menü mit 3 Taster realisieren.

Nur fällt mir keine wirklich zufriedenstellende Lösung für die Umsetzung ein.
Ich habe schon hier im Forum gesucht, nur bin ich nicht wirklich fündig geworden.

Vorgestellt habe ich mir das ganze so:
Wenn ich Taster 1 eine bestimmte Zeit lang drücke, wird das Menü aufgerufen. Wenn ich diesen Taste wieder eine bestimmte Zeit lang drücke, wird das Menü verlassen, und erst dann die Werte übernommen.
Wenn ich den Taster kurz drücke, möchte ich zwischen den einzelnen Menüpunkten wechseln. Mit den anderen beiden Taster werden die Werte verändert.
Zusätzlich soll noch eine Art Timeout eingebaut werden, dass das Menü nach einer bestimmten Zeit wieder von selbst verlassen wird.

Da ich aber in der µController Programmierung noch nicht so viel Ahnung habe, scheiterte es leider an der Umsetzung.
Vielleicht liegt es auch nur daran, dass ich einfach zu kompliziert denke! :-s


Ich wäre für jegliche Hilfe von euch sehr dankbar!


Chris

uwegw
10.06.2006, 21:25
Du müsstest dich mal etwas näher mit den Timern des AVRs beschäftigen. Du proggst einen Timer so, dass er z.B. alle 10ms eienn Interrupt liefert. In dessen ISR fragst du dann die Tasten ab und bestimmst dann, was zu tun ist. Du kannst dir ja mal überlegen, wie Brain1.0 das ganze erledigen würde, wenn es alle paar Sekunden kurz mitkriegen würde, welche Taster momentan gedrückt sind...

VictimOfMyOwn
11.06.2006, 12:33
hi ho...

ich habe damals auf dem 89c4051 ein menü mit 2 tastern programmiert.

durch einen druck von taster2 (z.b.) wird das menü aufgerufen. nun hat taster2 die funktion durch das menü zu blättern. beim druck von taster1 wird in den aktuellen menüpunkt gesprungen. mit taster2 kann nun z.b. eine variable verändert werden. auf knopfdruck wird sie immer um 1 erhöht...nachdem sie den wert 5 enthält springt sie bei erneutem tatendruck wieder auf 1. taster1 hat nun eine "OK" funktion, übernimmt die einstellung und deaktiviert den menüpunkt wieder. mit taster2 kann man nun im menü weiterblättern. der letzte menüpunkt heißt "menü verlassen", welcher dann mit taster1 ausgelöst und das menü so wieder geschlossen wird.

hoffe man kann meinen ausführungen folgen...

2 taster reichen also vollkommen aus...du musst ihre funktion nur der situation anpassen.

mfg

DarkFire
11.06.2006, 12:38
2 taster reichen also vollkommen aus...du musst ihre funktion nur der situation anpassen.

Mein Problem ist ja genau das, dass ich nicht weis, wie ich die Funktion der Taster der Situation anpasse.
Könntest du vielleicht einen Ausschnitt deines Quellcodes posten, damit ich einen Anhaltspunkt habe?


Chris

VictimOfMyOwn
11.06.2006, 12:59
hi ho...

puh...also ich hab mal was aus dem programm ausgeschnitten...ich weiß aber nicht ob man da durchsteigt...tue ich nämlich selber nimmer weil das schon ne weile her is...müsste ich mich erst wieder reinfuchsen.



while(1)
{

taster_abfrage();

//Abfrage Status

if((taster1==1) && (status==0))
{
taster1=0;
status=1;
}

if((status==0) && (taster2==1)) //falls Status = nicht-menue Modus
{
index++;
if(index==3)
{
index=0;
}
}


if(status==1) //falls Status = menue Modus
{
switch (menue_index)
{
case 0:
send_b(0x03);

strcpy(text, "Schaltbl.: ");
send_d(text);

send(48+schaltblitz_ztausend);
send(48+schaltblitz_tausend);
send(48+schaltblitz_hundert);
send(48);
send(48);

send_b(0xC0);
if(einstellen==0)
{
strcpy(text, "Ok Weiter >");
}
else
{
strcpy(text, "Ziffer erhoehen");
}
send_d(text);

taster_abfrage_menue();

break;

case 1:
send_b(0x03);
strcpy(text, "Impulse / U: ");
send_d(text);
if (takt==1)
{
strcpy(text, " 1");
send_d(text);
}
else
{
strcpy(text, "0.5");
send_d(text);
}
send_b(0xC0);
strcpy(text, "Aendern Weiter >");
send_d(text);
taster_abfrage_menue();
break;

case 2:
send_b(0x03);
strcpy(text, "Uhrzeit ");
send_d(text);
send_b(0xC0);
strcpy(text, "Ok Weiter >");
send_d(text);
taster_abfrage_menue();
break;

case 3:
send_b(0x03);
strcpy(text, "Balken max ");
send_d(text);
umwandeln(balken_max);
send(48+ztausender);
send(48+tausender);
send(48+hunderter);
send(48+zehner);
send(48+einer);
send_b(0xC0);
strcpy(text, "Aendern Weiter >");
send_d(text);
taster_abfrage_menue();
break;

case 4:
send_b(0x03);
strcpy(text, "Verlassen ");
send_d(text);
send_b(0xC0);
strcpy(text, "Ok Weiter >");
send_d(text);
taster_abfrage_menue();
menue_index=0;

break;
}
}

} //ende While
} //ende Main

void taster_abfrage()
{
//Taster Entprellung

if((s1 == 0) && (gesperrt1 == 0))
{
taster1 = 1;
gesperrt1 = 1;
pause(10);
}

if(s1 == 1)
{
taster1 = 0;
gesperrt1 = 0;
pause(10);
}

if((s2 == 0) && (gesperrt2 == 0))
{
taster2 = 1;
gesperrt2 = 1;
pause(10);
}

if(s2 == 1)
{
taster2 = 0;
gesperrt2 = 0;
pause(10);
}

}

void taster_abfrage_menue()
{
taster1=0;
if(einstellen==1)
{
taster1=1; //ins einstellen springen
}

while((taster1==0) && (taster2==0))
{
taster_abfrage();
}

if(taster2==1)
{
taster2=0;
menue_index++;
}

if(taster1==1)
{
taster1=0;

switch(menue_index)
{
case 0:
if(einstellen==0)
{
einstellen=1;
break;
}
send_b(0x0F); // 0000 1111 Cursor an; Blinken
switch(ziffer_aktiv)
{
case 0:
send_b(0x8B);
while((taster1==0) && (taster2==0))
{
taster_abfrage();
}
if(taster1==1)
{
ziffer_aktiv++;
taster1=0;
}

if(taster2==1)
{
taster2=0;
schaltblitz_ztausend++;
if(schaltblitz_ztausend==3)
{
schaltblitz_ztausend=0;
}
}

break;

case 1:
send_b(0x8C);
while((taster1==0) && (taster2==0))
{
taster_abfrage();
}
if(taster1==1)
{
ziffer_aktiv++;
taster1=0;
}

if(taster2==1)
{
taster2=0;
schaltblitz_tausend++;
if(schaltblitz_tausend==10)
{
schaltblitz_tausend=0;
}
}

break;

case 2:
send_b(0x8D);
while((taster1==0) && (taster2==0))
{
taster_abfrage();
}
if(taster1==1)
{
ziffer_aktiv++;
taster1=0;
}

if(taster2==1)
{
taster2=0;
schaltblitz_hundert++;
if(schaltblitz_hundert==10)
{
schaltblitz_hundert=0;
}
}
break;

case 3:
ziffer_aktiv=0;
einstellen=0;
break;
}
schaltblitz_drehzahl=schaltblitz_ztausend*10000 + schaltblitz_tausend*1000 + schaltblitz_hundert*100;
break;



case 4:
status=0;
break;
}
}
}


sorry, wenns net perfekt eingerückt ist.

mfg

Felix G
11.06.2006, 14:00
Hmm...

ganz ehrlich, ich finde Drehimpulsgeber + 2 Taster immernoch am besten von der Bedienung her. (oder alternativ eben 4 Taster)
Klar, man kann auch ein Menü mit nur zwei oder sogar nur einem einzigen Taster bedienen, aber das ist nicht nur programmiertechnisch aufwändiger, sondern auch für den Benutzer nicht so intuitiv.

Es gibt Dinge an denen man zwar sparen kann, aber es nicht unbedingt tun sollte ;)


Was die eigentliche Frage angeht...
Wenn ein Taster je nach Situation verschiedene Funktionen haben soll, würde ich Funktionspointer verwenden.

Bei jedem Tastendruck wird der gleiche Funktionspointer aufgerufen, der aber je nach Situation auf unterschiedliche Funktionen zeigt. Falls noch unterschieden werden soll ob die Taste lang oder kurz gedrückt wurde kann man das entweder als Parameter dem Funktionspointer übergeben, oder man macht eben zwei Funktionspointer.

VictimOfMyOwn
11.06.2006, 14:22
hi ho...

drehimpulsgeber mit 1 bis 2 tastern ist natürlich supi. allein schon um im menü zu blätter oder werte im menü zu erhöhen/verringern ist ´n nippel zum drehen schon was feines ;)

manchmal ist das aber nicht möglich...aus irgendwelchen gründen...und dann finde ICH PERSÖNLICH eben 2 taster besser als z.b. 3. denke aber, daß muss jeder für sich selber entscheiden, wie er es haben will.

gibt eben leute die ein autoradio mt 1000 bunten knöpfen ganz toll finden...und wieder andere, die eher auf ein aufgeräumtes, dezentes bedienfeld stehen.

so...genug offtopic...

so ÄHNLICH wie felix es erklärt hat, habe ich es in dem geposteten quellcode ja auch gemacht...vielleicht nicht gerade sehr sauber alles aber es funzt.

bei tastendruck wird abgefragt in welchem menüzweig man sich befindet (glaub menue_index war die entsprechende variable) und dementsprechend werden unterschiedliche befehle ausgeführt.

mfg