菜单选择创建LCDsheild和arduino接口

时间:2014-02-25 11:28:25

标签: c arduino avr lcd

我正在尝试创建菜单选择过程。如果按下SELECT按钮应该显示Display参数,如果按下选择按钮两次应该进入Set_parameter窗口(我们设置参数的位置)。一旦使用向上和向下箭头显示参数选择显示窗口。但我面临的问题是它进入显示参数但是直接从菜单窗口出来。

Circuit diagram for LCD is given here

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Pin configuration of the buttons
#define btnRIGHT  0     // Okay
#define btnUP     1     // inc
#define btnDOWN   2     // dec
#define btnLEFT   3     // Select
#define btnSELECT 4     // Menu
#define btnNONE   5
#define beeper A1      // Alarm buzzer
#define shortBeep 100
#define longBeep  500
int button_counter=0;
void setup()
{
    Serial.begin(9600);
}
void loop()
{
    Select_Menu();
}
void Select_Menu()
{
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("MENU");
 int button=read_LCD_buttons();
 if(button==btnSELECT)
 {
    button_counter=button_counter+1
 }
 if(button_counter==1)
 {
     Display_function();
 }else if((button_counter==2))
 {
    Set_function();
 }else
 {
    button_counter=0;
 }
}

void Display_function()
{
    int button = read_LCD_buttons();  
    if(button==btnUP)
    {
        button_counter=button_counter+1; 
        Serial.print("button_counter");
        Serial.println(button_counter);
    }else if(button==btnDOWN)
    {
        button_counter=button_counter-1; 
        Serial.println(button_counter);
    }
    if (button_counter>5)
    {
        button_counter=1;
    }else
        while(button_counter<5)
        {
            int button = read_LCD_buttons();  
            if(button != prev_button && button !=  btnNONE)
            {
                prev_button = button; 
            //timedBeep(shortBeep,2); 
            }

            if ((((button ==btnUP )||(button_counter==1))||((button ==btnDOWN )))&&(prev_button==btnUP)
            {
                digitalClockDisplay();//timedBeep(200,1); 

            }else if((((button ==btnUP )||(button_counter==2))||((button ==btnDOWN )))&&(prev_button==btnUP))
            {
                Display_angle();//timedBeep(200,1); 
            }else if((((button ==btnUP )||(button_counter==3))||((button ==btnDOWN )))&&(prev_button==btnUP))
            {
                Display_coordinate();//timedBeep(200,1); 
            }else if((((button ==btnUP )||(button_counter==4))||((button ==btnDOWN )))&&(prev_button==btnUP))
            {
                 button_loop();//timedBeep(500,4); 
            }else if((((button ==btnUP )||(button_counter==5))||((button ==btnDOWN )))&&(prev_button==btnUP))
            {
                  Display_Wind();//timedBeep(200,1); 
            }

        }
}


void Display_Wind()
{
 lcd.setCursor(0,0);
 lcd.print("WS kmph:");
 lcd.print(Wind_Kmph);
 lcd.setCursor(0,1);  
 lcd.print("WS m/s:");
 lcd.print(Wind_Speed);
}
void button_loop()
{
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.print("Welcome");
}
void Display_coordinate()
{
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.print("Latitude:");
 lcd.print(latitude);
 lcd.setCursor(0,1);  
 lcd.print("Longitude:");
 lcd.print(longitude);
}
void  Display_angle()
{
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.print("DESIRED: ");
 lcd.print(tracker_des_angle,DEC);
 lcd.setCursor(0,1);
 lcd.print("ACTUAL: ");
 lcd.print(tracker_actual_pos,DEC);

}
void digitalClockDisplay()
{
 lcd.begin(16,2);
 lcd.setCursor(0,0);
 lcd.print("Date:");
 lcd.print(local_day);
 lcd.print("/");
 lcd.print(local_month);
 lcd.print("/");
 lcd.print(local_year);
 lcd.setCursor(0,1);
 lcd.print("Time:");
 lcd.print(local_h);
 lcd.print(":");
 lcd.print(local_m);
 lcd.print(":");
 lcd.print(local_s);
 lcd.print("   ");
}
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 131, 307, 481, 722
  // we add approx 50 to those values and check to see if we are close
  // No button pressed should be 1023
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...

}

1 个答案:

答案 0 :(得分:2)

您遇到了流量控制问题。

您的主循环运行SelectMenu(),您输入Display_function(),其中不包含循环,因此它到达结尾并返回SelectMenu(),然后返回loop()再次调用SelectMenu()重新绘制菜单并再次使用菜单覆盖显示。

有很多方法可以解决这个问题,但是因为这是一个arduino环境,其中资源不是无穷无尽的我建议你在需要继续时让每个“页面”自己的循环突破它。不要在循环中切换页面,否则你将构建完全相同的callstack。

伪代码:

loop():
  #print and handle input
  if (navigate)
    Display_function()

Display_function():
  while(true)
    # print and do whatever
    if (nav_angle)
       Display_angle()
    else if (nav_coord)
       Display_coordinate()
    #... etc.
    if (nav_back)
      return

Display_angle():
  while(true)
    #do stuff
    if (nav_back)
      return

这应该会给你一个想法,只要你没有太深的结构和内存不足,它就会起作用。