Jag håller på med ett projektarbete där jag använder mig av en arduino, lite knappar och en LCD skärm. Målet är att göra en meny. Menyn är klar, men jag vill ha ytterligare en funktion.
Funktionen jag söker är att jag ska ha en photoresistor som läser av ljuset och t.ex. om värdet från den är för hög så ska LCD'n printa "För ljust" eller liknande om knapp blir tryckt, och låsa menyn (så den inte går vidare till nästa steg). Men om värdet går under de önskade så ska man släppas igenom till nästa del av menyn.
Detta är koden jag använder:
Kod: Markera allt
/
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal.h> //this library is included in the Arduino IDE
const int buttonPinLeft = 8; // pin for the Up button
const int buttonPinRight = 9; // pin for the Down button
const int buttonPinEsc = 11; // pin for the Enter button
const int buttonPinEnter = 10; // pin for the Esc button
int lastButtonPushed = 0;
int lastButtonEnterState = LOW; // the previous reading from the Enter input pin
int lastButtonEscState = LOW; // the previous reading from the Esc input pin
int lastButtonLeftState = LOW; // the previous reading from the Left input pin
int lastButtonRightState = LOW; // the previous reading from the Right input pin
int ledPin = 13;
int ledPon = 12;
long lastEnterDebounceTime = 0; // the last time the output pin was toggled
long lastEscDebounceTime = 0; // the last time the output pin was toggled
long lastLeftDebounceTime = 0; // the last time the output pin was toggled
long lastRightDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 500; // the debounce time
// LiquidCrystal display with:
// rs on pin 7
// rw on ground
// enable on pin 6
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
MenuItem menu1Item1 = MenuItem("Item1");
MenuItem menuItem1SubItem1 = MenuItem("Item1SubItem1");
MenuItem menuItem1SubItem2 = MenuItem("Item1SubItem2");
MenuItem menu1Item2 = MenuItem("Item2");
MenuItem menuItem2SubItem1 = MenuItem("Item2SubItem1");
MenuItem menuItem2SubItem2 = MenuItem("Item2SubItem2");
MenuItem menu1Item3 = MenuItem("Item3");
MenuItem menuItem3SubItem1 = MenuItem("Item3SubItem1");
MenuItem menuItem3SubItem2 = MenuItem("Item3SubItem2");
MenuItem menu1Item4 = MenuItem("Item4");
MenuItem menuItem4SubItem1 = MenuItem("Item4SubItem1");
MenuItem menuItem4SubItem2 = MenuItem("Item4SubItem2");
MenuItem menu1Item5 = MenuItem("Item5");
MenuItem menuItem5SubItem1 = MenuItem("Item5SubItem1");
MenuItem menuItem5SubItem2 = MenuItem("Item5SubItem2");
MenuItem menu1Item6 = MenuItem("Item6");
MenuItem menuItem6SubItem1 = MenuItem("Item6SubItem1");
MenuItem menuItem6SubItem2 = MenuItem("Item6SubItem2");
void setup()
{
pinMode(buttonPinLeft, INPUT);
pinMode(buttonPinRight, INPUT);
pinMode(buttonPinEnter, INPUT);
pinMode(buttonPinEsc, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(ledPon, OUTPUT);
lcd.begin(20, 4);
//configure menu
menu.getRoot().add(menu1Item1);
menu1Item1.addRight(menu1Item2).addRight(menu1Item3).addRight(menu1Item4).addRight(menu1Item5).addRight(menu1Item6);
menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2);
menu1Item3.add(menuItem3SubItem1).addRight(menuItem3SubItem2);
menu1Item4.add(menuItem4SubItem1).addRight(menuItem4SubItem2);
menu1Item5.add(menuItem5SubItem1).addRight(menuItem5SubItem2);
menu1Item6.add(menuItem6SubItem1).addRight(menuItem6SubItem2);
menu.toRoot();
lcd.setCursor(0,0);
lcd.print("Menu");
} // setup()...
void loop()
{
readButtons(); //I splitted button reading and navigation in two procedures because
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings)
} //loop()...
void menuChanged(MenuChangeEvent changed){
MenuItem newMenuItem=changed.to; //get the destination menu
lcd.setCursor(0,0); //set the start position for lcd printing to the second row
if(newMenuItem.getName()==menu.getRoot()){
lcd.print(" Press enter Main Menu ");
}else if(newMenuItem.getName()=="Item1"){
lcd.print("Acton 1 ");
}else if(newMenuItem.getName()=="Item1SubItem1"){
lcd.print("Performing action ");
{digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
lcd.setCursor(0,0);
lcd.print("press Enter ");
}
}else if(newMenuItem.getName()=="Item2"){
lcd.print("Action 2 ");
}else if(newMenuItem.getName()=="Item2SubItem1"){
lcd.print("Performing action ");
{digitalWrite(ledPon, HIGH);
delay(1000);
digitalWrite(ledPon, LOW);
delay(1000);
digitalWrite(ledPon, HIGH);
delay(1000);
digitalWrite(ledPon, LOW);
delay(1000);
digitalWrite(ledPon, HIGH);
delay(1000);
digitalWrite(ledPon, LOW);
delay(1000);}
}else if(newMenuItem.getName()=="Item2SubItem2"){
lcd.print("Item2SubItem2 ");
}else if(newMenuItem.getName()=="Item3"){
lcd.print("Item3 ");
}else if(newMenuItem.getName()=="Item3SubItem1"){
lcd.print("Performing action ");
{digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
lcd.setCursor(0,0);
lcd.print("press Enter ");
}
}else if(newMenuItem.getName()=="Item3SubItem2"){
lcd.print("Item3SubItem2 ");
}else if(newMenuItem.getName()=="Item4"){
lcd.print("Item4 ");
}else if(newMenuItem.getName()=="Item4SubItem1"){
lcd.print("Performing action ");
{digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
lcd.setCursor(0,0);
lcd.print("Groggen klar Tryck Enter ");
}
}else if(newMenuItem.getName()=="Item4SubItem2"){
lcd.print("Item4SubItem2 ");
}else if(newMenuItem.getName()=="Item5"){
lcd.setCursor(0,0);
lcd.print("Item5 ");
}else if(newMenuItem.getName()=="Item5SubItem1"){
lcd.print("Performing action ");
{digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
lcd.setCursor(0,0);
lcd.print("Press Enter ");
}
}else if(newMenuItem.getName()=="Item5SubItem2"){
lcd.print("Item5SubItem2 "); }
else if(newMenuItem.getName()=="Item6"){
lcd.print("Item6 ");
}else if(newMenuItem.getName()=="Item6SubItem1"){
lcd.print("Performing action ");
{digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
lcd.setCursor(0,0);
lcd.print("Press Enter ");
}
}else if(newMenuItem.getName()=="Item6SubItem2"){
lcd.print("Item6SubItem2 ");
}
}
void menuUsed(MenuUseEvent used){
lcd.setCursor(0,0);
lcd.print("You chose ");
lcd.setCursor(0,1);
lcd.print(used.item.getName());
delay(3000); //delay to allow message reading
lcd.setCursor(0,0);
lcd.print("www.coagula.org");
menu.toRoot(); //back to Main
}
void readButtons(){ //read buttons status
int reading;
int buttonEnterState=LOW; // the current reading from the Enter input pin
int buttonEscState=LOW; // the current reading from the input pin
int buttonLeftState=LOW; // the current reading from the input pin
int buttonRightState=LOW; // the current reading from the input pin
//Enter button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEnter);
// check to see if you just pressed the enter button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEnterState) {
// reset the debouncing timer
lastEnterDebounceTime = millis();
}
if ((millis() - lastEnterDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEnterState=reading;
lastEnterDebounceTime=millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEnterState = reading;
//Esc button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEsc);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEscState) {
// reset the debouncing timer
lastEscDebounceTime = millis();
}
if ((millis() - lastEscDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEscState = reading;
lastEscDebounceTime=millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEscState = reading;
//Down button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinRight);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonRightState) {
// reset the debouncing timer
lastRightDebounceTime = millis();
}
if ((millis() - lastRightDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonRightState = reading;
lastRightDebounceTime =millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonRightState = reading;
//Up button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinLeft);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonLeftState) {
// reset the debouncing timer
lastLeftDebounceTime = millis();
}
if ((millis() - lastLeftDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonLeftState = reading;
lastLeftDebounceTime=millis();;
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonLeftState = reading;
//records which button has been pressed
if (buttonEnterState==HIGH){
lastButtonPushed=buttonPinEnter;
}else if(buttonEscState==HIGH){
lastButtonPushed=buttonPinEsc;
}else if(buttonRightState==HIGH){
lastButtonPushed=buttonPinRight;
}else if(buttonLeftState==HIGH){
lastButtonPushed=buttonPinLeft;
}else{
lastButtonPushed=0;
}
}
void navigateMenus() {
MenuItem currentMenu=menu.getCurrent();
switch (lastButtonPushed){
case buttonPinEnter:
if(!(currentMenu.moveDown())){ //if the current menu has a child and has been pressed enter then menu navigate to item below
menu.use();
}else{ //otherwise, if menu has no child and has been pressed enter the current menu is used
menu.moveDown();
}
break;
case buttonPinEsc:
menu.toRoot(); //back to main
break;
case buttonPinRight:
menu.moveRight();
break;
case buttonPinLeft:
menu.moveLeft();
break;
}
lastButtonPushed=0; //reset the lastButtonPushed variable
}
