Leicester, MA USA
Offline
Jr. Member
Karma: 0
Posts: 70
Arduino newbie
|
 |
« on: December 09, 2012, 03:11:14 pm » |
I've searched and searched and can't seem to find exactly what I'm looking for. I want to create a basic menu (if you can even call it that) for my LCD display with just a single button to change the menus, and up/down buttons for fan speeds (that'll be controlled only when that fan's menu is displayed). Here's how I want it to go:
Welcome screen (on power-up) | | Display 1 (coolant temp/flow rate) | | Display 2 (Intake fan speed/voltage) | | Display 3 (Exhaust fan 1 speed/voltage) | | Display 5 (Exhaust fan 2 speed/voltage) | | Back to display 1 and so on
There will also be a button-controlled servo to open and close a door but that will be independent of the menu system and not displayed.
Obviously I need 5 interrupts (flow meter, fan 1, fan 2, fan 3, servo button) and only have 2, which is why I'm going to use a ChipKIT MAX32 which has 5 interrupts and plenty of I/O for controlling fan speeds, etc. so that problem it solved.
I've got each system (except fan speed control) working independently with separate coding and each works fine (temp/flow works fine, fan speed display works fine). I just can't figure out how to merge them all together into a single working unit. I've seen several different menu libraries but they seem way more complex than what I need. I was thinking button state change or something but can't figure out how to get it all working properly.
What's the best way to go about that?
|
|
|
|
|
Logged
|
|
|
|
|
Central MN, USA
Online
Faraday Member
Karma: 35
Posts: 5927
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
|
 |
« Reply #1 on: December 09, 2012, 04:03:14 pm » |
You just need a user interface to adjust parameters. For simplicity, such as maybe 3 lines per parameter adjustment, you can get the phi-panel: http://www.inmojo.com/store/liudr-arduino-and-physics-gadgets/item/serial-lcd-back-pack---phi-panel/Then the menu will be like case 'U': if (speed<max_speed) speed+=speed_increment; //update serial lcd break; case 'D': if (speed>minspeed) speed-=speed_increment; //update serial lcd break;
|
|
|
|
|
Logged
|
|
|
|
|
Pakistan
Offline
Sr. Member
Karma: 5
Posts: 318
Arduino rocks
|
 |
« Reply #2 on: December 10, 2012, 09:56:32 am » |
Look this thread and especially the end of pages and you will find no menu easier than it.This is called MENWIZ by brunialti... Its brilliant, easy and cover almost all the things in a very easy way. Dont forget to read the pdf guide. http://arduino.cc/forum/index.php/topic,99693.0.html
|
|
|
|
« Last Edit: December 10, 2012, 09:58:12 am by Khalid »
|
Logged
|
|
|
|
|
Central MN, USA
Online
Faraday Member
Karma: 35
Posts: 5927
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
|
 |
« Reply #3 on: December 10, 2012, 10:21:20 am » |
Look this thread and especially the end of pages and you will find no menu easier than it.This is called MENWIZ by brunialti... Its brilliant, easy and cover almost all the things in a very easy way. Dont forget to read the pdf guide. http://arduino.cc/forum/index.php/topic,99693.0.htmlYes it is good but what you view as easy maybe hard to those beginners. If you have found my phi-panels, you will take back the "find no menu easier than it" statement.
|
|
|
|
|
Logged
|
|
|
|
|
Pakistan
Offline
Sr. Member
Karma: 5
Posts: 318
Arduino rocks
|
 |
« Reply #4 on: December 10, 2012, 10:59:39 am » |
liudr, I downloaded your phi library but it was difficult to understand, its not your fault, but i have less brain power.. I really like the videos you posted about your library but its difficult to find simple examples using Analoge button and 3wire lcds... Is their any, pls point out.
|
|
|
|
|
Logged
|
|
|
|
|
Central MN, USA
Online
Faraday Member
Karma: 35
Posts: 5927
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
|
 |
« Reply #5 on: December 10, 2012, 01:34:27 pm » |
liudr, I downloaded your phi library but it was difficult to understand, its not your fault, but i have less brain power.. I really like the videos you posted about your library but its difficult to find simple examples using Analoge button and 3wire lcds... Is their any, pls point out.
Khalid, there are two things I provide that does menus: 1) phi_prompt library and its support library. They run with most types of inputs and HD44780 LCD. The setup part is a bit hard but my new version will provide simple setup functions. 2) phi-panel serial lcd panels or backpacks. These are hardware I designed and are already set up to run some of the phi_prompt menu functions. You simply send out a plain text to these panels through serial port with a command. The panels render the menu and interacts with users then return to you what the user selects. I was referring to solution 2 for the OP.
|
|
|
|
|
Logged
|
|
|
|
|
Pakistan
Offline
Sr. Member
Karma: 5
Posts: 318
Arduino rocks
|
 |
« Reply #6 on: December 11, 2012, 08:40:22 am » |
both the options require custom hardware which i have to purchase with the high shipment. 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 114
Posts: 2205
|
 |
« Reply #7 on: December 11, 2012, 09:22:21 am » |
What's the best way to go about that? It is fairly simple: button=read_button(button_pin); //read button on button_pin switch (button) { case 'U': //up button is pressed app_index = (app_index)?(app_index-1):MAX_APP; //update app_index break; case 'D': //down button is pressed app_index = (app_index==MAX_APP)?0:(app_index+1_; //update app_index break; default: do_something(); //illegal key press. do something / nothing }
switch (app_index) { case 0: app0(); //run 1st application break; case 1: app1(); //run 2nd application break; ... }
You can start to fill the various boxes / functions. For example, if you use analog buttons, you just need to implement it in read_button(); and you can put your coolant / flowrate display in app0(); your fan speed/voltage in app1(); ... It cannot be simpler than that, once you cut it down to logical blocks and implement those blocks one at a time.
|
|
|
|
|
Logged
|
|
|
|
|
Central MN, USA
Online
Faraday Member
Karma: 35
Posts: 5927
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
|
 |
« Reply #8 on: December 11, 2012, 09:51:33 am » |
both the options require custom hardware which i have to purchase with the high shipment.  Option one is free. just get an hd44780 display and a few buttons. If you think $6 is expensive for international shipping, FYI shipping to Australia or Europe is almost $6 plus bubble wrap and time.
|
|
|
|
|
Logged
|
|
|
|
|
Leicester, MA USA
Offline
Jr. Member
Karma: 0
Posts: 70
Arduino newbie
|
 |
« Reply #9 on: February 02, 2013, 08:13:02 pm » |
What's the best way to go about that? It is fairly simple: button=read_button(button_pin); //read button on button_pin switch (button) { case 'U': //up button is pressed app_index = (app_index)?(app_index-1):MAX_APP; //update app_index break; case 'D': //down button is pressed app_index = (app_index==MAX_APP)?0:(app_index+1_; //update app_index break; default: do_something(); //illegal key press. do something / nothing }
switch (app_index) { case 0: app0(); //run 1st application break; case 1: app1(); //run 2nd application break; ... }
You can start to fill the various boxes / functions. For example, if you use analog buttons, you just need to implement it in read_button(); and you can put your coolant / flowrate display in app0(); your fan speed/voltage in app1(); ... It cannot be simpler than that, once you cut it down to logical blocks and implement those blocks one at a time. ok so where exactly do I put my functions? do I put it in app0(xxxx);?
|
|
|
|
|
Logged
|
|
|
|
|
Central MN, USA
Online
Faraday Member
Karma: 35
Posts: 5927
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
|
 |
« Reply #10 on: February 02, 2013, 08:25:13 pm » |
That code is a snippet, i.e. not complete. You complete it. Yes that was what dhenry meant.
|
|
|
|
|
Logged
|
|
|
|
|
Leicester, MA USA
Offline
Jr. Member
Karma: 0
Posts: 70
Arduino newbie
|
 |
« Reply #11 on: February 02, 2013, 08:32:42 pm » |
That code is a snippet, i.e. not complete. You complete it. Yes that was what dhenry meant.
I know it's just a snippet I'm just lost as to where to put my actual analogRead etc etc in the snippet
|
|
|
|
|
Logged
|
|
|
|
|
Leicester, MA USA
Offline
Jr. Member
Karma: 0
Posts: 70
Arduino newbie
|
 |
« Reply #12 on: February 02, 2013, 08:45:12 pm » |
Here's what I've got so far. It works as is with the commented-out lines (kinda - I can't get the % to display if it's showing 100). Am I on the right track? #include <LiquidCrystal.h> LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
const int buttonPin = 11; const int potPin = A0; const int tempPin = A1; const int fan = 10; const int buttonMin = 0; const int buttonMax = 1; int buttonState; int lastButtonState = LOW; long lastDebounceTime = 0; long debounceDelay = 50;
void setup(){ pinMode(buttonPin, INPUT); pinMode(potPin, INPUT); pinMode(tempPin, INPUT); pinMode(fan, OUTPUT); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print(" Project: "); lcd.setCursor(0, 1); lcd.print(" Circuit Box "); delay(5000); lcd.clear(); }
void loop(){ int reading = digitalRead(buttonPin); if (reading != lastButtonState) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { buttonState = reading; } //int range = map(reading, buttonMin, buttonMax, 0, 1); //Map the range to 2 options // switch (range) { // case '0': // Manual Mode lcd.setCursor(0, 0); lcd.print(" Manual Mode "); int fanSpeed = analogRead(potPin); fanSpeed = map(fanSpeed, 0, 1023, 120, 255); int fanpct = map(fanSpeed, 120, 254, 40, 100); lcd.setCursor(0, 1); lcd.print("Fan Speed:"); lcd.setCursor(11, 1); lcd.print(fanpct); if (fanpct < 100) lcd.print ('%'); // lcd.setCursor(14, 1); // lcd.print("%"); analogWrite(fan, fanSpeed); /* break; case '1': // Automatic Mode lcd.setCursor(0, 0); lcd.print(" Automatic Mode "); int break; } delay(1); }
lcd.setCursor(0, 0); lcd.print(" Manual Mode "); int fanSpeed = analogRead(potPin); fanSpeed = map(fanSpeed, 0, 1023, 120, 255); int fanpct = map(fanSpeed, 120, 255, 40, 100); lcd.setCursor(0, 1); lcd.print("Fan Speed:"); lcd.setCursor(14, 1); lcd.print("%"); analogWrite(fan, fanSpeed); */ }
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13897
Lua rocks!
|
 |
« Reply #13 on: February 02, 2013, 08:56:14 pm » |
I'm confused by dhenry's answer. Your original question was how to show 5 screens by pushing one button? This shows the general idea. It outputs to serial so you can test by just grounding pin 8 (to act as your switch). const byte mySwitch = 8;
// these "states" are what screen is currently being displayed. typedef enum { POWER_ON, COOLANT, INTAKE_SPEED, EXHAUST_FAN1, EXHAUST_FAN2, // add more here ... LAST_STATE // have this last } states;
byte state = POWER_ON;
byte oldSwitch = HIGH;
void powerOn () { Serial.println ("Welcome!"); } void showCoolant () { Serial.println ("Coolant level = x"); } void showIntakeSpeed () { Serial.println ("Intake speed = x"); } void showExhaustFan1 () { Serial.println ("Exhaust Fan 1 = x"); } void showExhaustFan2 () { Serial.println ("Exhaust Fan 2 = x"); } void setup () { pinMode (mySwitch, INPUT_PULLUP); Serial.begin (115200); powerOn (); } // end of setup void loop () { byte switchValue = digitalRead (mySwitch); // detect switch presses if (switchValue != oldSwitch) { delay (100); // debounce
// was it pressed? if (switchValue == LOW) { state++; // next state if (state >= LAST_STATE) state = COOLANT; switch (state) { case POWER_ON: powerOn (); break; case COOLANT: showCoolant (); break; case INTAKE_SPEED: showIntakeSpeed (); break; case EXHAUST_FAN1: showExhaustFan1 (); break; case EXHAUST_FAN2: showExhaustFan2 (); break; } // end of switch } // end of switch being pressed oldSwitch = switchValue; } // end of switch changing state } // end of loop
|
|
|
|
|
Logged
|
|
|
|
|
Leicester, MA USA
Offline
Jr. Member
Karma: 0
Posts: 70
Arduino newbie
|
 |
« Reply #14 on: February 02, 2013, 09:01:25 pm » |
I'm confused by dhenry's answer. Your original question was how to show 5 screens by pushing one button? This shows the general idea. It outputs to serial so you can test by just grounding pin 8 (to act as your switch). const byte mySwitch = 8;
// these "states" are what screen is currently being displayed. typedef enum { POWER_ON, COOLANT, INTAKE_SPEED, EXHAUST_FAN1, EXHAUST_FAN2, // add more here ... LAST_STATE // have this last } states;
byte state = POWER_ON;
byte oldSwitch = HIGH;
void powerOn () { Serial.println ("Welcome!"); } void showCoolant () { Serial.println ("Coolant level = x"); } void showIntakeSpeed () { Serial.println ("Intake speed = x"); } void showExhaustFan1 () { Serial.println ("Exhaust Fan 1 = x"); } void showExhaustFan2 () { Serial.println ("Exhaust Fan 2 = x"); } void setup () { pinMode (mySwitch, INPUT_PULLUP); Serial.begin (115200); powerOn (); } // end of setup void loop () { byte switchValue = digitalRead (mySwitch); // detect switch presses if (switchValue != oldSwitch) { delay (100); // debounce
// was it pressed? if (switchValue == LOW) { state++; // next state if (state >= LAST_STATE) state = COOLANT; switch (state) { case POWER_ON: powerOn (); break; case COOLANT: showCoolant (); break; case INTAKE_SPEED: showIntakeSpeed (); break; case EXHAUST_FAN1: showExhaustFan1 (); break; case EXHAUST_FAN2: showExhaustFan2 (); break; } // end of switch } // end of switch being pressed oldSwitch = switchValue; } // end of switch changing state } // end of loop
OK that makes much more sense now that I see it laid out. I'm going much simpler than originally planned with only 2 options instead of 5 - automatic mode (temp-sensor controlled PWM fan speed) and manual mode (potentiometer-controlled PWM fan speed). I'll also be upgrading to a 20x4 LCD (when it arrives). The top 2 lines will display coolant temp and flow rate all the time with the bottom 2 lines switching between manual and auto modes with fan speed shown (which is what I'm trying to get working right now on the 16x2 I'm currently using)
|
|
|
|
|
Logged
|
|
|
|
|
|