Go Down

Topic: Menu Driven Program (Read 16 times) previous topic - next topic

advancedservers

May 10, 2010, 07:25 am Last Edit: May 10, 2010, 07:25 am by advancedservers Reason: 1
Hi

Im in the process of building and automatic toilet cistern valve tester.

It basically consists of a linear actuator, LCD, and a couple of switches.

I am stuck trying to implement the sceen. The menu will have 6 options which have to be set before the actuator starts testing.

Menu Below

1. Fill Delay Time
2. Ram Delay Time
3. Ram Pulse Time
4. Start
5. Pause
6. Stop

obviously the pause and stop commands will have to run during the void loop() part of the code and opt 1, 2 & 3 could run in the void setup() part of the code. The pause function will have to not interupt the current ram cycle.

Below is my current code with static variables for opt 1,2 3.

Code: [Select]
int FRPin =  8;  
int MotorPin = 7;

int FillDelay = 10000;
int RamDelay = 500;
int RamPulse = 2000;
int TCount;
int Cycles = 10;

void setup()   {  
 Serial.begin(9600);
 Serial.println("Testing Rig V1.0");
 Serial.println("");
 
 pinMode(FRPin, OUTPUT);  
 pinMode(MotorPin, OUTPUT);
 
 //Pull Ram in fully
 Serial.println("Retracting Ram");
 digitalWrite(MotorPin, HIGH);
 digitalWrite(FRPin, LOW);
 delay(6000);
 digitalWrite(MotorPin, LOW);
}


void loop()                    
{
 for(int i=0; i<Cycles; i++){
   
   
   //Turn on Motor then push out for RamPulse Time
   Serial.println("Extending Ram");
   digitalWrite(MotorPin, HIGH);  
   digitalWrite(FRPin, HIGH);
   delay(RamPulse);
   
   //Hold the motor for RamDelay Time (-- PUSH OUT--)
   Serial.println("Holding Ram");
   digitalWrite(MotorPin, LOW);
   delay(RamDelay);
   
   //Turn on Motor then pull in for RamPulse Time
    Serial.println("Retracting Ram");
   digitalWrite(MotorPin, HIGH);  
   digitalWrite(FRPin, LOW);        
   delay(RamPulse);
   
   //Hold the motor for RamDelay Time (--PULL IN--)
   Serial.println("Holding Ram");
   Serial.println("");
   digitalWrite(MotorPin, LOW);
   delay(FillDelay);
   
   //test code
   TCount++;
   Serial.println(TCount);
 }
}


The LCD im using is a sparkfun Serial Enabled 16x2 LCD - Black on Green 5V.

Any help on how to impletmen this would be great.

thanks ben

Coding Badly


Two things will help: "finite state machine" and "blink without delay".

advancedservers

Thanks for the tips   :D

the problem Im having is not really anything to do with the lcd its more of the button press detection.

Sorry I should have explained this better!!

I have 3 buttons <Back, >Foward & OK buttons


I need to know the correct way of detecting button press's  for 3 buttons(currenty Im using the arduino example way) and when to poll them and not cause any interferance  to the loop part of the code.

thanks

Ben

MatthewS

I am new and this might not be what you are looking for but this is what I use to read my analog buttons

butt1=analogRead(button1);    //read in button 1
      if (butt1 < buttthres){   //if button one is low then button was pushed
     //do stuff here
    }
butt2..
butt3..

mowcius

#4
May 10, 2010, 09:43 am Last Edit: May 10, 2010, 09:44 am by mowcius Reason: 1
Right, I would say you want to implement a menu code routine.

Ignore the loop code. Stick code at the end of your setup routing to call Menu(); then in the menu, call other sections of code for the different things you want to do.

My code for a 20x4 serial LCD might help you. I was only using one button for moving on an option and holding it for selecting.

Code: [Select]
void Menu(){                      
 LCDclear();  
 LCDserial.print("Program Menu");
 LCDsecond();    
 switch (programnumber) {                  
 case 1:                                
   LCDserial.print("Race Timer");
   LCDthird();
   LCDserial.print("Track: ");
   LCDserial.print(distance);
   LCDserial.print("m");    
   break;                              
 case 2:
   LCDserial.print("Reaction Tester");
   break;
 case 3:
   LCDserial.print("Calibration Mode");
   break;
 default:
   LCDserial.print("Race Timer");
   LCDthird();
   LCDserial.print("Track: ");
   LCDserial.print(distance);
   LCDserial.print("m");
 }

 LCDserial.print(0xFE, BYTE);
 LCDserial.print(226, BYTE);
 LCDserial.print("Next >");
 while(digitalRead(starterbutton) == HIGH){}
 delay(5);
 while(digitalRead(starterbutton) == LOW){}
 menudelaycount = 0;
   while(menudelaycount <500){
   delay(1);
   menudelaycount++;
   if(digitalRead(starterbutton) == LOW){
     programnumber++;
   if(programnumber > 3){
     programnumber = 1;
   }
   Menu();
   }
 }
 switch (programnumber) {
     case 1:
       Race();
       break;
     case 2:
       Reaction();
       break;
     case 3:
       Calibration();
       break;
     default:
       Race();
     }
}


The LCDsecond(); is a seperate routine for selecting the LCD line.

The code waits until you press a button. When you press the button it times how long you press it for. If it is longer than a certain time then it 'selects' that option, if not then it moves on one option.

I can help more if you need it.

Mowcius

Go Up