Go Down

Topic: Scrolling menu program hangs... (Read 2643 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