Problem med en Meny i form av en lista.

Avdelningen för programmering, nätverk samt alternativa OS.
Post Reply
User avatar
Mike
Posts: 211
Joined: 2002-03-10 11:34:15
Location: Ludvika
Contact:

Problem med en Meny i form av en lista.

Post by Mike »

Nedan är koden. Problemet är att när man ska gå in på en UnderMeny så skrivs endast "Data skickas" ut varje gång. Jag tror att felet ligger i den här if satsen, if(temp==3). Skriv gärna förslag på lösningar eller fråga mer om koden så ska jag försöka förklara problemen nogrannare.



char Meny[4][17]={"1. Ställ Klocka", // Lista på meny
"2. Temperatur",
"3. Vindrikt/hast",
"4. Sänd Data"};

char UnderMeny[4][17]={ "Minuter sekunder", // Lista på Undermenyer
"Grader Celsius",
"Meter/Sekund",
"Data skickas"};
char MenyPosition;
char tmp;
char temp;
char MenyVal;

main(void)
{

extern char Knapp; // Hämtas externt från Tangenter.c
extern char NyKnapp; // Hämtas externt från Tangenter.c
char Tomrum[]=" "; // Tömmer Display raden
MenyPosition=0;
MenyVal=0;
temp=0;
InitTangenter(); // startar tangenterna
InitLCD(); // startar displayen
klocka(); // startar klockan
enable_interrupt(); // tillåter avgbrott

write_string (64, Meny[MenyPosition++]); // skriver ut första menyn ur listan "Meny". Sen ökar MenyPositionen med 1

while(1==1)
{

if(MenyVal==0) // alltid sann
{
if(NyKnapp==1)
{
NyKnapp=0;
if(Knapp=='#') // tangenten # (fyrkant) trycks ner
{
next:
write_string(64, Tomrum); // tömmer displayens tecken fönster
write_string(64, Meny[MenyPosition]); // skriver ut nästa meny ur listan
if(++MenyPosition==4) // öka menypositionen med 1, blir den 4 så nollställs den {
MenyPosition=0;
temp=3;
}
}

else if(Knapp=='*') // tangenten * (stjärna) trycks ner
{
tmp=0;
tmp=MenyPosition;
tmp--;
write_string(64, Tomrum); // tömmer displayens tecken fönster
write_string(64, UnderMeny[tmp]); // Skriver ut aktuell UnderMeny

if(temp==3)
{
write_string(64, Tomrum);
write_string(64, UnderMeny[tmp]);
}

if(Knapp=='#') // tangenten # trycks ner
goto next; // Hoppa till next
}
}
}

}
"There are liars, car salesmen, statisticians and benchmarkers. They should be trusted in that order." - Okänd tänkare
User avatar
nva
Hedersbit
Posts: 2517
Joined: 2002-03-07 23:34:21
Location: Skåneland
Contact:

Post by nva »

Code: Select all

if(++MenyPosition==4) 	// öka menypositionen med 1, blir den 4 så nollställs den {
MenyPosition=0;
temp=3;
}
Som du ser på första raden så har du kommenterat bort det första
'{'-tecknet vilket innebär att "temp=3" inte kommer med utan
alltid utförs. Borde ju har med det att göra.
The three most dangerous things in the world are a programmer with a soldering iron, a hardware type with a program patch and a user with an idea.

In theory, there is no difference between theory and practice. But, in practice, there is.
User avatar
Mike
Posts: 211
Joined: 2002-03-10 11:34:15
Location: Ludvika
Contact:

Post by Mike »

Koden blev lite omformad när jag klistrade in den i medelandet. I den riktiga koden så är inte '{'-tecknet bort kommenterat.
Så här ser koden ut.

if(++MenyPosition==4) // öka menypositionen med 1, blir den 4 så nollställs den
{
MenyPosition=0;
temp=3;
}
"There are liars, car salesmen, statisticians and benchmarkers. They should be trusted in that order." - Okänd tänkare
User avatar
nva
Hedersbit
Posts: 2517
Joined: 2002-03-07 23:34:21
Location: Skåneland
Contact:

Post by nva »

Eh, ja det var ju dumt av mig, du borde
ju fått kompileringsfel annars. :)
The three most dangerous things in the world are a programmer with a soldering iron, a hardware type with a program patch and a user with an idea.

In theory, there is no difference between theory and practice. But, in practice, there is.
User avatar
gottegrisen
Posts: 221
Joined: 2002-03-11 12:47:17
Location: Mölnlycke

Post by gottegrisen »

else if(Knapp=='*') // tangenten * (stjärna) trycks ner
{
tmp=0;
tmp=MenyPosition;
tmp--;
write_string(64, Tomrum); // tömmer displayens tecken fönster
write_string(64, UnderMeny[tmp]); // Skriver ut aktuell UnderMeny

if(temp==3)
{
write_string(64, Tomrum);
write_string(64, UnderMeny[tmp]);
}

/************************/

Menar du verkligen att när temp == 3 så skriv ut samma meny 2 gånger på raken annars en? Dessutom när du väl satt temp till 3 så kommer du aldrig att visa något annat än det första. Det är inte så att du skall sätta den till noll eller något i if(temp == 3) satsen?

/************************/

satsen nedan är ju onödig, det är ju knappast möjligt att användaren trycker '*' '#' inom loppet av några microsek:
if(Knapp=='#') // tangenten # trycks ner
goto next; // Hoppa till next
}

/************************/

tmp=0;
tmp=MenyPosition;
tmp--;
Är ekvialent med tmp = MenyPosition - 1
/************************/


Det är väldigt svårläst med 4 ifsatser på raken + en while. Du skriver att en if sats alltid är sann varför är den med då?
Det verkar som du pollar här och inte använder avbrott ännu, och ett sätt att komma undan är:
while(1){

if( NyKnapp != 1)
continue; // går vidare till nästa varv i while loopen
else
NyKnapp = 0;

// och nu följer din kod
if(knapp == '#'){}
if(knapp == '*'){}
if(knapp == '1'){}

}
/************************/

while(1 == 1) skrivs oftast while(1)
/************************/
Pyssla om lite så ordnar det sig säkert:)
User avatar
Mike
Posts: 211
Joined: 2002-03-10 11:34:15
Location: Ludvika
Contact:

Post by Mike »

Tack för svaret gottegrisen du hade rätt i mycket du sa och jag har optimerat koden därefter. Men när jag fösökte göra följande så gick det inte så bra, vet inte riktigt vad du menade.
gottegrisen wrote:if( NyKnapp != 1)
continue; // går vidare till nästa varv i while loopen
else
NyKnapp = 0;

// och nu följer din kod
if(knapp == '#'){}
if(knapp == '*'){}
if(knapp == '1'){}

}
"There are liars, car salesmen, statisticians and benchmarkers. They should be trusted in that order." - Okänd tänkare
User avatar
gottegrisen
Posts: 221
Joined: 2002-03-11 12:47:17
Location: Mölnlycke

Post by gottegrisen »

Nu har du inte förklarat hur det ska fungera, så min while lopp ovan var bara om följande kriterium ska följas:
1) kolla upp om en ny knapp tryckts, och om tryckt ,sätt den till otryckt
och gå till 2 annars gå till 3
2) kolla om knappen var 1,*,# och handla därefter.
3) reptera


Jag kanske har missuppfattat det hela lite, jag hade lite svårt att följa din kod. Förklara gärna vad det är du vill att den skall göra med de olika tryckningarna i stället så kan jag se.

så om vi styckar snutten som jag skrev innan:
/**************************/
while(1)
{
// motsvarar 1 steget
if( NyKnapp != 1) //om 1 så är det ett nytt tryck
continue; // går vidare till nästa varv i while loopen
// det fanns alltså ingen nytt tryck
else
NyKnapp = 0;
// kommer hit så var det ett nytt tryck och den
// forsätter därmed med koden nedan


// nu följer steg 2

if(knapp == '#')
{
// oki här har användaren tryckt ett # välj vad programmet skall göra
}

if(knapp == '*')
{
// som ovan fast *
}
if(knapp == '1')
{
// som ovan fast 1
}

// slut börja om från början
}
/********************************/

Är det ett skolarbete förresten?
User avatar
Mike
Posts: 211
Joined: 2002-03-10 11:34:15
Location: Ludvika
Contact:

Post by Mike »

Programmet jag skriver är till ett projekt jag håller på med i mikrodatorteknik på en högskola. Projektet går ut på att vi ska bygga en väderstation som ska känna av temperatur, vindhastighet, vindriktning och kunna skicka datan seriellt till hyperterminalen. Samtidigt som allt detta sker ska en klocka gå. Just nu håller jag på och försöker få knapparna * och # att fungera som dom ska. Med # ska jag stega igenom huvudmenyn och sen med * ska man gå in i den funktion som skall användas för att: ställa klocka, visa temp., vindhastighet-vindrikting och skicka data.

Men innan jag sätter in funktionerna så vill jag se vad som händer när man trycker på */# när man är inne i undermenyerna. Jag vill att ingenting ska hända i undermenyerna när man trycker på * men när man trycker på # ska man hoppa till nästa huvudmeny.

Nu har jag fixat koden lite så att den fungerar ganska bra.. det är en sak fel och det är att om man trycker på * och går in i undermenyn till 'sänd data' hamnar man rätt. Trycker man sen på * igen så hoppar den tillbaks till 'sänd data' vilket den inte ska göra.

Här kommer koden:
while(1)
{
if(NyKnapp==1)
{
NyKnapp=0;
if(Knapp=='#') // tangenten # trycks ner
{
temp=0;
write_string(64, Tomrum); // tömmer displayens undre rad
write_string(64, Meny[MenyPosition]); // skriver ut nästa meny ur listan

if(++MenyPosition==4) /* öka menypositionen med 1, blir den 4 så nollställs den */
{ MenyPosition=0; temp=3;}

}
else if(Knapp=='*') // tangenten * trycks ner
{
tmp = MenyPosition - 1;
write_string(64, Tomrum); // tömmer displayens tecken fönster
write_string(64, UnderMeny[tmp]); // Skriver ut aktuell UnderMeny

if(temp==3){write_string(64, Tomrum);write_string(64, UnderMeny[temp]);temp=0;}
}
}
"There are liars, car salesmen, statisticians and benchmarkers. They should be trusted in that order." - Okänd tänkare
User avatar
gottegrisen
Posts: 221
Joined: 2002-03-11 12:47:17
Location: Mölnlycke

Post by gottegrisen »

Oki är inte helt säker, men skrev ner hur jag trodde du ville ha det utan dina utskrifts metoder.

Du kan ju kompilera och testköra med lite #/* följt med return för att se ifall det är rätt.

/************************************************/

# include <stdio.h>

int main(){
char Meny[4][17]={"1. Ställ Klocka","2. Temperatur",
"3. Vindrikt/hast", "4. Sänd Data"};
char UnderMeny[4][17]={ "Minuter sekunder","Grader Celsius",
"Meter/Sekund","Data skickas"};
int MenyPosition = 0;
int NyKnapp;
char Knapp = 0;

while(1)
{
scanf("%c",&Knapp);
NyKnapp = 1;
if(NyKnapp==1)
{
NyKnapp=0;
if(Knapp=='#') // tangenten # trycks ner
{
printf("%s\n",Meny[MenyPosition]);
MenyPosition = (MenyPosition+1) % 4;
// plusar på MenyPosition och tar mod 4 på det
}

else if(Knapp=='*') // tangenten * trycks ner
{
printf("%s",UnderMeny[MenyPosition - 1]);
}
}
}
}
/************************************************/

För att köra ditt prog så får du göra lite ändringar, men de ser du nog :)
Post Reply