Go Down

Topic: Aquarium Reef Controller, stage 1, the LCD shield, (Read 41 times) previous topic - next topic

Harlequin

#5
Mar 30, 2010, 06:08 pm Last Edit: Mar 30, 2010, 06:11 pm by Harlequin Reason: 1
example of the menu system i'd like to do

Start up:-
                         [   REEF MINDER  ]
                         [  VERSION  1.00 ]

Idle screen:-
                        [TEMP:25*C  12:30]
                        [WHT:100  BLU:100]

Menu Screen:-
                        [1. SET LIGHTS   ]
                        [2. VIEW PERAMS  ]

                        [3.DO OTHER STUFF]
                        [4.DO OTHER STUFF]

then if the user "selected" set lights/option 1 it would lead to these screens:-

                      [1. SET INTENSITY]
                      [2. SET TIMEPEROD]

if the user then selected set intensity :

                     [ SET BLUE MAX   ]
                     [         XXX %  ]
                                      |
                                      | user then presses select/next
                                      |
                                     \ /
                    [ SET WHITE MAX  ]
                    [         XXX %  ]
                                      |
                                      | user then presses select/next
                                      |
                                     \ /
                   [   LIGHTS SET   ]
                   [                ]
                                      |
                                      |  
                                      |
                                     \ /
                short delay then back to menu
                   




Thats sort of what im aiming for, in my "mock" screen i was going to use a switch statement/ while loop, then depending on what key is pressed at what time in the program it sets the variable/case to the corisponding menu screen which gets loaded,

anything highlighted in red, would need to be constantly updated. the temp from a temp probe, the time from the RTC, the light intensitys on the LCD screen would be a variable which would change when the user pressed up or down when in the "set blue max" etc...

that make sense?
;D :o



edit: just sene your reply chris, thats brilliant someone who actually vaguely understands what i plan to do ! i know temp measurement should be relatively easy, wait till i get to dosing pumps and Auto top off devices XD. like i said though i dont have much codea s i dont really know where to begin, i assume my first step would be to get a "scrollable/interactive" menu system adn go from there?

(and for the record i have a 125ltr Fresh water at my mums, a 4ft Full reef 300 ltr system at my dads and my hose, and a 20 ltr marine pico, which this controllers for, if it gets goign i'll build one for the other reef tank)






Imahilus

The technique you're looking for is called a "state machine".
While the arduino supports some object orientated programming, you're still mostly doing procedural programming.

A state machine is the thing to use in these situations.
Essentially, your menu would have 3 or 4 states.
1. (default) display data
if button is pressed, go to state 2
2. display the basic menu options
if button is pressed, either change the selection or go to the state of the selected item
3. light intensity was chosen, button up raises the intensity displayed, button down lowers it. the select button changes the output, has a delay, and returns to state 1.

Now I won't do your work for you and put it into actual code, but I hope you get the idea now  :)

Harlequin

sounds about right to me Imahilus, i shall do some googling/reading up. thank you.

it sounds vaguely what i had in mind with my While statements or more should i say thats what i wanted to do. thanks.

just writing some coding and see where im at, you were right Chris, i was clearing the menu at the start of the loop which caused the flickering. Just writing up a new piece of code tonight and i'll post it once im done

Luke

Harlequin

Ok so heres some rough coding i knocket together this evening, Its not pretty, its probably not effiecent but its what first came to mind for me that worked.

its just the various "menu" screens or cases, i need to somehow interface the button pad coding into this exisiting coding.

oh and if your wondering why theres 2 of everything its because one has an asterix "*" at the end, this is the way i decided to show which option is "selected".

i looked at the Display blink tutorial in the arduino folders and would like to have a blinking cursor at the end instead of using a asterix but i figured if i used the delay method it used then i could see problems with how the program runs.

its not much but you get the idea.

next step is implimenting the actual keypad. i wrote psudo code in each method sawing what i want to happen when each butten is pressed.

Code: [Select]
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);//delares the LCD Pins for the liquidCrystal library methods.
int x = 0;//Used for testing purposes to show the LED strength
int menuOption = 3;//used for the Switch statement, each menu has its own value,
int tankTemp = 25;//used for testing purposes, in real build this value with come from a temp probe
int timeHour = 12;//used for testing purposes, in real build RTC wil give this value
int timeMinute = 30;//used for testing purposes, in real build RTC wil give this value
//-----------------------------------------------------
void setup() {//ran once AKA welcome screen
 lcd.begin(16, 2);//sets the LCD screen dimentions up
 lcd.print(" Reef Minder ");
 lcd.setCursor(0,1);
 lcd.print("by Luke V1.00");
 delay(5000);
 lcd.clear();
}
//-----------------------------------------------------
void loop() {
 switch(menuOption){//loads each menu depending on what value "menuOption" has at the start of the loop.
   
   case 1:  mainMenuOneOne();break;
   case 2:  mainMenuOneTwo();break;
   
   case 3:  mainMenuTwoOne();break;
   case 4:  mainMenuTwoTwo();break;
   
   case 5:  setIntensityOne();break;
   case 6:  setIntensityTwo();break;
   case 7:  setIntensityThree();break;
   
   case 8:  setLightsOne();break;
   case 9:  setLightsTwo();break;
   
   case 10: setTimePeriodOne();break;
   case 11: setTimePeriodTwo();break;
   
   default: idleMenu();break;
 }  
}
//-----------------------------------------------------
void idleMenu(){//case 0
 //this is the idle screen which will be the ran as default, when the user hasnt pressed anything, after X amount of time if the user hasnt pressed anything load this menuOption
 lcd.setCursor(0,0);
 lcd.print("Temp:"); lcd.print(tankTemp);  lcd.print("*C ");//temp half, top line
 lcd.print(timeHour); lcd.print(":"); lcd.print(timeMinute);// time half, top line
 lcd.setCursor(0,1);
 lcd.print("WHT:");lcd.print(x);lcd.print(" BLU:");lcd.print(x);
 if(x <100){//used in testing, real value will come from the led's/set by the user in the SET intensity menu option
   x++;
   delay(5000);
   lcd.clear();
 }
 //If any button pressed, load mainMenuOne()/ menuOption = 1;
}
//-----------------------------------------------------

void mainMenuOneOne(){ //case 1
 //main menu,
 lcd.setCursor(0,0);
 lcd.print("1.SET LIGHTS   *");
 lcd.setCursor(0,1);
 lcd.print("2.VIEW PERAMS");
 lcd.setCursor(0,0);
   
   
 /*if V pressed load menuOptionOneTwo();
   if ^ pressed do nothing
   if < pressed load idleMenu()/ menuOption = 0;
   if > pressed load setLightsOne();/ menuOption = 8;
   if * pressed load setLightsOne();/ menuOption = 9;
 */
}
void mainMenuOneTwo(){ //case 2
 //main menu,
 lcd.setCursor(0,0);
 lcd.print("1.SET LIGHTS");
 lcd.setCursor(0,1);
 lcd.print("2.VIEW PERAMS  *");
 lcd.setCursor(0,0);
 
   
 /*if V pressed load menuOptionTwoOne()/menuOption = 3;
   if ^ pressed load menuOptionOneOne()/menuOption = 2;
   if < pressed load idleMenu()/menuOption = 0;
   if > pressed load viewPerams(); not coded yet
   if * pressed load viewPerams(); not coded yet
 */
}
void mainMenuTwoOne(){// case 3
 lcd.setCursor(0,0);
 lcd.print("3.BLANK        *");
 //flashing pixel
 lcd.setCursor(0,1);
 lcd.print("4.BLANK");
 lcd.setCursor(0,0);


 /*if V pressed load menuOptionTwoTwo()/menuOption = 4;
   if ^ pressed load menuOptionOneTwo()/menuOption = 2;
   if < pressed load idleMenu()/menuOption = 0;
   if > pressed load 3rd menu;/not coded yet
   if * pressed load 3rd menu()/not coded yet
 */
}

void mainMenuTwoTwo(){// case 4
 lcd.setCursor(0,0);
 lcd.print("3.BLANK");
 lcd.setCursor(0,1);
 lcd.print("4.BLANK        *");
 //flashing pixel
 lcd.setCursor(0,0);


 /*if V pressed do nothing;
   if ^ pressed load menuOptionTwoOne()/menuOption = 3;
   if < pressed load idleMenu()/menuOption = 0;
   if > pressed load 4rd menu;/not coded yet
   if * pressed load 4th menu();/not coded yet
 */
}

//----------------------------------------------------

void setLightsOne(){// case 8
 lcd.setCursor(0,0);
 lcd.print("1.SET INTENSITY*");
 lcd.setCursor(0,1);
 lcd.print("2.SET TIMES");
 lcd.setCursor(0,0);


/*if V pressed load setLightsTwo()/menuOption = 9;
   if ^ pressed do nothing
   if < pressed load idleMenu()//menuOption = 0;
   if > pressed load setintensityOne()/menuOption = 5;
   if * pressed load setLightsTwo()/menuOption = 9;
 */
}


void setLightsTwo(){//case 9
 lcd.setCursor(0,0);
 lcd.print("1.SET INTENSITY");
 lcd.setCursor(0,1);
 lcd.print("2.SET TIMES    *");
 //flash pixel
 lcd.setCursor(0,0);


/*if V pressed do nothing;
   if ^ pressed load setLightsOne()/menuOption = 8;
   if < pressed load mainMenuOneOne()/menuOption = 1;
   if > pressed load setTimeOne()/menuOption = 10;
   if * pressed load setTimeOne()/menuOption = 10;
 */
}

//----------------------------------------------------
void setIntensityOne(){// case 5
 lcd.setCursor(0,0);
 lcd.print("1. SET BLUE MAX");
 lcd.setCursor(0,1);
 lcd.print("   100%");
 lcd.setCursor(0,0);
 
 
  /*if V pressed value-- While => 0;
   if ^ pressed value++ while <= 100;
   if < pressed do nothing;
   if > pressed load setIntenistyTwo()//menuOption = 6;
   if * pressed load setIntenistyTwo()/menuOption = 6;
 */
}

void setIntensityTwo(){//case 6
 lcd.setCursor(0,0);
 lcd.print("1. SET WHITE MAX");
 lcd.setCursor(0,1);
 lcd.print("   100%");
 lcd.setCursor(0,0);
 
 
 /*if V pressed value-- While => 0;
   if ^ pressed value++ while <= 100;
   if < pressed do nothing;
   if > pressed load setIntenistyThree()/menuOption = 7;
   if * pressed load setIntenistyThree()//menuOption = 7;
 */
}

void setIntensityThree(){//case 7
 lcd.setCursor(0,0);
 lcd.print("LIGHTS SET");
 lcd.setCursor(0,1);
 delay(5000);
 lcd.setCursor(0,0);
 menuOption = 1;


 /*if V pressed do nothing;
   if ^ pressed do nothing;
   if < pressed do nothing;
   if > pressed load mainMenuOne()/menuOption = 1;
   if * pressed load mainMenuOne()/menuOption = 1;
 */
}
//-------------------------------------------------  
void setTimePeriodOne(){//case 10
 lcd.setCursor(0,0);
 lcd.print("1.SET START    *");
 lcd.setCursor(0,1);
 lcd.print("2.SET END");
 lcd.setCursor(0,0);
 
 /*if V pressed load setTimePeriodTwo()/menuOption = 11;
   if ^ pressed do nothing;
   if < pressed load setLightsTwo()/menuOption = 9;
   if > pressed load setStartTime/not coded yet;
   if * pressed load setStartTime)/not coded yet
 */
}

void setTimePeriodTwo(){//case 11
 lcd.setCursor(0,0);
 lcd.print("1.SET START");
 lcd.setCursor(0,1);
 lcd.print("2.SET END      *");
 lcd.setCursor(0,0);

  /*if V pressed do nothing;
   if ^ pressed load setTimePeriodOne/menuOption = 10;
   if < pressed load setLightsTwo()/menuOption = 9;
   if > pressed load setEndTime/not coded yet
   if * pressed load setEndTime)/not coded yet
 */
}
//-------------------------------------------------


ludnix

Hi Harlequin, I'm undergoing the same project as you so I'd thought I'd drop by. I'm still playing around with with the LCD and temperature probes at this point, so I'm still in the beginning. I'm currently working on getting a reading from two dallas temperature probes (DS18B20 in Parasite Mode) from the same pin using the onewire library.

I'm awaiting a real time clock and serial i2c for my 20x4 LCD screen. The clock will let me set the times for turning my lights on and off and the i2c will prevent the LCD from taking up so many of my precious i/o ports. I also need to buy a keypad to control it, but I haven't found one that I was particularly enthusiastic about yet.

I'm implementing mine into a running 120g tank. I'm using solid state relays to power on the lights or pumps which is where my project will vary a bit from your LED controlling.

I'll be looking forward to seeing how you go about the project, it's reassuring to see other's attempting the same project.


Go Up