Pages: [1] 2   Go Down
Author Topic: Scrolling menu program hangs...  (Read 2165 times)
0 Members and 1 Guest are viewing this topic.
North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-sad:
Code:
#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
Logged

San Pedro, CA.
Offline Offline
Full Member
***
Karma: 3
Posts: 155
My head HURTS!!!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

DigitalJohnson

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Per Arduino ad Astra

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Mowcius
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 27
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
« Last Edit: May 20, 2010, 05:44:10 am by advancedservers » Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, intriguing...

You wanna add that code ] bracket back in? smiley

Mowcius
« Last Edit: May 20, 2010, 05:43:18 am by mowcius » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 27
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oops fixed
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12739
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


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

Code:
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();
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes indeed. Another problem in my code...  smiley-sad

Mowcius
Logged

Toronto, ON
Offline Offline
Full Member
***
Karma: 10
Posts: 233
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like plenty of recursion going on smiley-wink  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:
#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
Logged


North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Brett comes to the rescue again smiley

It works perfectly now. Well almost.

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

Mowcius
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Latest code with a little delay to help with debouncing smiley

Seems to work perfectly now.
Code:
#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);
}  
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 27
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It works without but I forgot to change this in the latest piece of code:
Code:
 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 smiley

Mowcius
Logged

Pages: [1] 2   Go Up
Jump to: