Go Down

Topic: Scrolling menu program hangs... (Read 2866 times) previous topic - next topic

mowcius

I wrote this code (yes I know it's pretty crap but it was quick) for a 16x2 Serial LCD scrolling menu (tested on 20x4 and 16x2) but it's not quite working  :(:
Code: [Select]
#include <NewSoftSerial.h>

NewSoftSerial LCDserial(0, 2);

int prognumber = 1;
int line = 1;

int down = 8;
int select = 9;
int up = 10;

void menu();
void LCDclear();
void LCDfirst();
void LCDsecond();
void LCDmenudisplay();

void first();
void second();
void third();
void fourth();
void fifth();

void setup() {
 LCDserial.begin(9600);
 menu();
}

void loop() {
 //nothing to loop but is required in every sketch.
}

void LCDclear(){
 LCDserial.print(0xFE, BYTE);      
 LCDserial.print(0x01, BYTE);
}

void LCDfirst(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(128, BYTE);
}
void LCDsecond(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(192, BYTE);
}

void menu() {
 while(digitalRead(up) == HIGH or digitalRead(down) == HIGH or digitalRead(select) == HIGH){};
 delay(50);
 LCDclear();
 LCDfirst();
 if(prognumber > 1){
 prognumber--;
 }
 else{
   prognumber == 1;
 }
 LCDmenudisplay();
 LCDsecond();
 prognumber++;
 LCDmenudisplay();
 if(line == 1){
   LCDserial.print(0xFE, BYTE);
   LCDserial.print(143, BYTE);
   LCDserial.print("<");
 }
 else {
   LCDserial.print(0xFE, BYTE);
   LCDserial.print(207, BYTE);
   LCDserial.print("<");
 }
 while(digitalRead(up) == LOW && digitalRead(down) == LOW && digitalRead(select) == LOW){}
 if(digitalRead(down) == HIGH){
 line++;
 if(line > 2){
 line = 2;
 prognumber++;
 if(prognumber > 4){
 prognumber = 5;
 }
 }
 menu();
 }
 else if(digitalRead(up) == HIGH){
 line--;
 if(line < 1){
 line = 1;
 prognumber--;
 }
 menu();
 }
 else if(digitalRead(select) == HIGH){
 if(line == 1){
   prognumber--;
 }
 switch (prognumber) {                  
 case 1:                                
   first();
   break;                              
 case 2:
   second();
   break;
 case 3:
   third();
   break;
 case 4:
   fourth();
   break;
 case 5:
   fifth();
   break;
 default:
   first();
 }
 }
}

void LCDmenudisplay() {
 switch (prognumber) {                  
 case 1:                                
   LCDserial.print("First");  
   break;                              
 case 2:
   LCDserial.print("Second");
   break;
 case 3:
   LCDserial.print("Third");
   break;
 case 4:
   LCDserial.print("Fourth");
   break;
 case 5:
   LCDserial.print("Fifth");
   break;
 default:
   LCDserial.print("First");
 }
 
}

void first() {
 digitalWrite(13, HIGH);
 menu();
}

void second() {
 menu();
}

void third() {
 menu();
}

void fourth() {
 menu();
}

void fifth() {
 digitalWrite(13, HIGH);
 delay(1000);
 digitalWrite(13, LOW);
 menu();
}

All seems to work apart from after about 10-20 presses of up/down buttons it hangs and needs resetting.
Anyone got any ideas as to why?

Also if anyone else has any scrolling menu programs they have written then I would be interested in seeing them.

Mowcius

DigitalJohnson

I'm having a hard time following your code. As far as more menu examples, I recall seeing a few different menu libraries in one of the Arduino libraries pages.
DigitalJohnson

Groove

Code: [Select]
while(digitalRead(up) == HIGH or digitalRead(down) == HIGH or digitalRead(select) == HIGH){};

Just out of interest, how/where is "or" defined"?
Per Arduino ad Astra

mowcius

Quote
I'm having a hard time following your code. As far as more menu examples, I recall seeing a few different menu libraries in one of the Arduino libraries pages.

Yeah I'm not surprised and did you? Where?  :)

Quote
Just out of interest, how/where is "or" defined"?

Aha! That is a good point. That might be the issue. I had forgotten that it's || not 'or'...
I wonder why it didn't throw up an error for that one.  :-?

Mowcius

mowcius

Hmm. Changing that makes no difference...
Any other ideas?
Any links to these other menus?

Mowcius

advancedservers

#5
May 20, 2010, 12:39 pm Last Edit: May 20, 2010, 12:44 pm by advancedservers Reason: 1
hi everyone

I have added some serial debug lines and it appears to jump from 22a to 31 then to 38 and hang there..

Code: [Select]

void LCDclear(){
 LCDserial.print(0xFE, BYTE);      
 LCDserial.print(0x01, BYTE);
}

void LCDfirst(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(128, BYTE);
}
void LCDsecond(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(192, BYTE);
}

void menu() {
 Serial.println(" 1");
 while(digitalRead(up) == HIGH or digitalRead(down) == HIGH or digitalRead(select) == HIGH){};
 Serial.println(" 2");
 delay(50);
 Serial.println(" 3");
 LCDclear();
 Serial.println(" 4");
 LCDfirst();
 Serial.println(" 5");
 if(prognumber > 1){
   Serial.println(" 6");    
 prognumber--;
 Serial.println(" 7");
 }
 else{
   Serial.println(" 8");
   prognumber == 1;
 Serial.println(" 9");
 }
 LCDmenudisplay();
 Serial.println(" 10");
 LCDsecond();
 Serial.println(" 11");

 prognumber++;
Serial.println("12 ");
 LCDmenudisplay();
 Serial.println("13 ");
 if(line == 1){
   Serial.println("14 ");
   LCDserial.print(0xFE, BYTE);
   Serial.println("15 ");
   LCDserial.print(143, BYTE);
   Serial.println(" 16");
   LCDserial.print("<");
   Serial.println("17 ");
 }
 else {
   Serial.println("18 ");
   LCDserial.print(0xFE, BYTE);
   Serial.println("19 ");
   LCDserial.print(207, BYTE);
   Serial.println("20 ");
   LCDserial.print("<");
   Serial.println(" 21");
 }
  Serial.println("22A ");
 while(digitalRead(up) == LOW && digitalRead(down) == LOW && digitalRead(select) == LOW){}
 Serial.println("22 ");
 delay(50);
 if(digitalRead(down) == HIGH){
   Serial.println(" 23");
 line++;
 Serial.println("24 ");
 if(line > 2){
   Serial.println("25 ");
 line = 2;
 Serial.println(" 26");
 prognumber++;
 Serial.println("27 ");
 }
 if(prognumber > 4){
   Serial.println("28 ");
 prognumber = 5;
Serial.println(" 29");
 }
 Serial.println(" 30");
 menu();
 Serial.println(" 31");
 }
 delay(50);
 if(digitalRead(up) == HIGH){
   Serial.println("32 ");
 line--;
 Serial.println("33 ");
 if(line < 1){
   Serial.println("34 ");
 line = 1;
 Serial.println("35 ");
 prognumber--;
 Serial.println("36 ");
 }
 Serial.println(" 37");
 menu();
 Serial.println("38 ");
 }
 delay(50);
 if(digitalRead(select) == HIGH){
   Serial.println("39 ");
 if(line == 1){
   Serial.println(" 40");
   prognumber--;
   Serial.println("41 ");
 }
 Serial.println("42 ");
 switch (prognumber) {                  
 case 1:                                
Serial.println("43 ");
   first();
   break;                              
 case 2:
 Serial.println("44 ");
   second();
   break;
 case 3:
 Serial.println("45 ");
   third();
   break;
 case 4:
 Serial.println("46 ");
   fourth();
   break;
 case 5:
 Serial.println("47");
   fifth();
   break;
  default:
   Serial.println("48");
   first();
     break;
 }
 }
}

void LCDmenudisplay() {
 switch (prognumber) {                  
 case 1:                                
   LCDserial.print("First");  
   break;                              
 case 2:
   LCDserial.print("Second");
   break;
 case 3:
   LCDserial.print("Third");
   break;
 case 4:
   LCDserial.print("Fourth");
   break;
 case 5:
   LCDserial.print("Fifth");
   break;
 default:
   LCDserial.print("First");
 }
 
}

void first() {
 digitalWrite(13, HIGH);
 menu();
}

void second() {
 menu();
}

void third() {
 menu();
}

void fourth() {
 menu();
}

void fifth() {
 digitalWrite(13, HIGH);
 delay(1000);
 digitalWrite(13, LOW);
 menu();
}

any ideas????

thanks heaps

ben

mowcius

#6
May 20, 2010, 12:42 pm Last Edit: May 20, 2010, 12:43 pm by mowcius Reason: 1
Hmm, intriguing...

You wanna add that code ] bracket back in? :)

Mowcius


Coding Badly


Probably not the source of the problem but still worth fixing...

Code: [Select]
void menu() {
 while(digitalRead(up) == HIGH or digitalRead(down) == HIGH or digitalRead(select) == HIGH){};
 delay(50);
 LCDclear();
 LCDfirst();
 if(prognumber > 1){
 prognumber--;
 }
 else{
   prognumber [glow]=[/glow]= 1;  [glow]// Assignment?  Comparison?[/glow]
 }
 LCDmenudisplay();

mowcius

Yes indeed. Another problem in my code...  :(

Mowcius

Looks like plenty of recursion going on ;)  You keep calling menu() - even within menu().  Unchecked recursion on a microcontroller == out of memory fast!

I just removed all calls to menu() other than in loop().  I haven't tested it (but I have compiled it), so don't yell at me!

Code: [Select]

#include <NewSoftSerial.h>

NewSoftSerial LCDserial(0, 2);

int prognumber = 1;
int line = 1;

int down = 8;
int select = 9;
int up = 10;

void menu();
void LCDclear();
void LCDfirst();
void LCDsecond();
void LCDmenudisplay();

void first();
void second();
void third();
void fourth();
void fifth();

void setup() {
 LCDserial.begin(9600);
}

void loop() {
 menu();
}

void LCDclear(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(0x01, BYTE);
}

void LCDfirst(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(128, BYTE);
}
void LCDsecond(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(192, BYTE);
}

void menu() {
 while(digitalRead(up) == HIGH or digitalRead(down) == HIGH or digitalRead(select) == HIGH){};
 delay(50);
 LCDclear();
 LCDfirst();
 if(prognumber > 1){
   prognumber--;
 }
 else{
   prognumber = 1;
 }
 LCDmenudisplay();
 LCDsecond();
 prognumber++;
 LCDmenudisplay();
 if(line == 1){
   LCDserial.print(0xFE, BYTE);
   LCDserial.print(143, BYTE);
   LCDserial.print("<");
 }
 else {
   LCDserial.print(0xFE, BYTE);
   LCDserial.print(207, BYTE);
   LCDserial.print("<");
 }
 while(digitalRead(up) == LOW && digitalRead(down) == LOW && digitalRead(select) == LOW){}
 if(digitalRead(down) == HIGH){
   line++;
   if(line > 2){
     line = 2;
     prognumber++;
     if(prognumber > 4){
       prognumber = 5;
     }
   }
 }
 else if(digitalRead(up) == HIGH){
   line--;
   if(line < 1){
     line = 1;
     prognumber--;
   }
 }
 else if(digitalRead(select) == HIGH){
   if(line == 1){
     prognumber--;
   }
   switch (prognumber) {
   case 1:
     first();
     break;
   case 2:
     second();
     break;
   case 3:
     third();
     break;
   case 4:
     fourth();
     break;
   case 5:
     fifth();
     break;
   default:
     first();
   }
 }
}

void LCDmenudisplay() {
 switch (prognumber) {
 case 1:
   LCDserial.print("First");
   break;
 case 2:
   LCDserial.print("Second");
   break;
 case 3:
   LCDserial.print("Third");
   break;
 case 4:
   LCDserial.print("Fourth");
   break;
 case 5:
   LCDserial.print("Fifth");
   break;
 default:
   LCDserial.print("First");
 }

}

void first() {
 digitalWrite(13, HIGH);
}

void second() {
}

void third() {
}

void fourth() {
}

void fifth() {
 digitalWrite(13, HIGH);
 delay(1000);
 digitalWrite(13, LOW);
}  



b

mowcius

Brett comes to the rescue again :)

It works perfectly now. Well almost.

I am just playing with some delays for debounce but after that it seems good to go.

Mowcius

mowcius

Latest code with a little delay to help with debouncing :)

Seems to work perfectly now.
Code: [Select]
#include <NewSoftSerial.h>

NewSoftSerial LCDserial(0, 2);

int prognumber = 1;
int line = 1;

int down = 8;
int select = 9;
int up = 10;

void menu();
void LCDclear();
void LCDfirst();
void LCDsecond();
void LCDmenudisplay();

void first();
void second();
void third();
void fourth();
void fifth();

void setup() {
 LCDserial.begin(9600);
}

void loop() {
 menu();
}

void LCDclear(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(0x01, BYTE);
}

void LCDfirst(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(128, BYTE);
}
void LCDsecond(){
 LCDserial.print(0xFE, BYTE);
 LCDserial.print(192, BYTE);
}

void menu() {
 while(digitalRead(up) == HIGH or digitalRead(down) == HIGH or digitalRead(select) == HIGH){};
 LCDclear();
 LCDfirst();
 if(prognumber > 1){
   prognumber--;
 }
 else{
   prognumber = 1;
 }
 LCDmenudisplay();
 LCDsecond();
 prognumber++;
 LCDmenudisplay();
 if(line == 1){
   LCDserial.print(0xFE, BYTE);
   LCDserial.print(143, BYTE);
   LCDserial.print("<");
 }
 else {
   LCDserial.print(0xFE, BYTE);
   LCDserial.print(207, BYTE);
   LCDserial.print("<");
 }
 while(digitalRead(up) == LOW && digitalRead(down) == LOW && digitalRead(select) == LOW){}
 if(digitalRead(down) == HIGH){
   line++;
   if(line > 2){
     line = 2;
     prognumber++;
     if(prognumber > 4){
       prognumber = 5;
     }
   }
 }
 else if(digitalRead(up) == HIGH){
   line--;
   if(line < 1){
     line = 1;
     prognumber--;
   }
 }
 else if(digitalRead(select) == HIGH){
   if(line == 1){
     prognumber--;
   }
   switch (prognumber) {
   case 1:
     first();
     break;
   case 2:
     second();
     break;
   case 3:
     third();
     break;
   case 4:
     fourth();
     break;
   case 5:
     fifth();
     break;
   default:
     first();
   }
 }
 delay(50);
}

void LCDmenudisplay() {
 switch (prognumber) {
 case 1:
   LCDserial.print("First");
   break;
 case 2:
   LCDserial.print("Second");
   break;
 case 3:
   LCDserial.print("Third");
   break;
 case 4:
   LCDserial.print("Fourth");
   break;
 case 5:
   LCDserial.print("Fifth");
   break;
 default:
   LCDserial.print("First");
 }

}

void first() {
 digitalWrite(13, HIGH);
}

void second() {
 digitalWrite(13, HIGH);
 delay(1000);
 digitalWrite(13, LOW);
 delay(1000);
 digitalWrite(13, HIGH);
 delay(1000);
 digitalWrite(13, LOW);
}

void third() {
 digitalWrite(13, HIGH);
 delay(500);
 digitalWrite(13, LOW);
 delay(500);
 digitalWrite(13, HIGH);
 delay(500);
 digitalWrite(13, LOW);
}

void fourth() {
 digitalWrite(13, HIGH);
 delay(100);
 digitalWrite(13, LOW);
 delay(100);
 digitalWrite(13, HIGH);
 delay(100);
 digitalWrite(13, LOW);
}

void fifth() {
 digitalWrite(13, LOW);
}  

advancedservers

Hi Mowcius & bhagman,

I would like to thank you both for all your help especially Mowcius!!  and thanks to everyone else who contributed.

I love this community. ;D


thanks all

ben

mowcius

It works without but I forgot to change this in the latest piece of code:
Code: [Select]
 while(digitalRead(up) == HIGH || digitalRead(down) == HIGH || digitalRead(select) == HIGH){};
Should be '||' not 'or'

Quote
Hi Mowcius & bhagman,

I would like to thank you both for all your help especially Mowcius!!  and thanks to everyone else who contributed.

I love this community.

No problem! I love the community too :)

Mowcius

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy