Menu driven 16x2 LCD display....

Hi everyone!

This is my first Arduino project, so go easy on me. :wink:

I'm trying to get a menu driven display working to operate 4 hoists, each connected to a H-Bridge w/ enable motor controller. I've used the example "Hunt The Wumpus" as a base for the project.

1st - The issue that I'm having right now is that "void handle_menu()" is not detecting "clicked_buttons", however void input_move() which sets the state to handle_menu does see them correctly. You can see the result with serial monitor.

2nd - How do you Serial.print the current state and if it changes? I tried Serial.println(state); but it wouldn't compile like that.

3rd - I know in void move_hoist I will need to use something different than clicked_buttons. Clicked_buttons only triggers when releasing the button. The UP and DOWN pins will need to stay HIGH during the whole key press and go LOW when released.

Kind regards and Thanks!

// -------------------------------------------------------------------------------
// An Arduino sketch that controlls 4 hoists connected to the Arduino Digital PINs:
// Each hoist has a H bridge motor controller attached to it with an ENABLE PIN 
// as well as UP and DOWN PINs.  All hoists share the UP and DOWN PINs and are
// selected by enabling a specific hoist.
//
// PIN  8 - Hoist 1 Enable
// PIN  9 - Hoist 2 Enable 
// PIN 10 - Hoist 3 Enable
// PIN 11 - Hoist 4 Enable 
// PIN 12 - UP
// PIN 13 - DOWN
// --------------------------------------------------------------------------------
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

uint8_t current_hoist;
const int hoist_up = 13;
const int hoist_down = 12;
const int hoist[] = {8, 9, 10, 11};

void (*state)() = NULL;
void (*last_state)() = NULL;
unsigned long last_state_change_time;
unsigned long time;
const uint8_t menu_col[4][2] = { {0,  3},
                                 {4,  7},
                                 {8,  11},
                                 {12, 15} };

uint8_t selected_menu_idx;
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
enum BackLightColor { RED=0x1, YELLOW=0x3, GREEN=0x2, TEAL=0x6, BLUE=0x4, VIOLET=0x5, WHITE=0x7 };
uint8_t clicked_buttons;


void setup() {
  Serial.begin(9600);
  Serial.println("Debug");
  delay(2000);
  
  pinMode(hoist_up, OUTPUT);
  pinMode(hoist_down, OUTPUT);
  pinMode(hoist[0], OUTPUT);
  pinMode(hoist[1], OUTPUT);
  pinMode(hoist[2], OUTPUT);
  pinMode(hoist[3], OUTPUT);
  
  lcd.begin(16, 2);
  int current_hoist = 0;
  state = begin_welcome;
}

void loop() {
  time = millis();
  
  if (last_state != state) {
    last_state = state;
    last_state_change_time = time;
    Serial.print("State change time: ");
    Serial.println(last_state_change_time);
  }
  read_button_clicks();
  state();
  delay(10);
}


void read_button_clicks() {
  static uint8_t last_buttons = 0;
  uint8_t buttons = lcd.readButtons();
  clicked_buttons = (last_buttons ^ buttons) & (~buttons);
  last_buttons = buttons;

}

void clear_current_menu() {
  Serial.print("In clear_current_menu: ");
  Serial.print(menu_col[selected_menu_idx][0], 1);  
  lcd.setCursor(menu_col[selected_menu_idx][0], 1);
  lcd.print(' ');
  Serial.print(" , ");
  Serial.println(menu_col[selected_menu_idx][1], 1);
  lcd.setCursor(menu_col[selected_menu_idx][1], 1);
  lcd.print(' ');
}

void highlight_current_menu() {
//  Serial.println("In highlight_current_menu");
  lcd.setCursor(menu_col[selected_menu_idx][0], 1);
  lcd.write(0x7E);
  lcd.setCursor(menu_col[selected_menu_idx][1], 1);
  lcd.write(0x7F);
}

//! Check for left and right button clicks and update the menu index as needed.
void handle_menu() {
//    Serial.println("In handle_menu");
    
    if (clicked_buttons & BUTTON_UP) {
      Serial.println("H-UP ");
    }
    if (clicked_buttons & BUTTON_DOWN) {
      Serial.println("H-DOWN ");
    }
    if (clicked_buttons & BUTTON_LEFT) {
      Serial.println("H-LEFT ");
    }
    if (clicked_buttons & BUTTON_RIGHT) {
      Serial.println("H-RIGHT ");
    }
    if (clicked_buttons & BUTTON_SELECT) {
      Serial.println("H-SELECT ");
    }
    
  
  
  
  if (clicked_buttons & BUTTON_LEFT) {
    Serial.print("Clicked Left - New index: ");
    selected_menu_idx = (selected_menu_idx > 0) ? selected_menu_idx - 1 : 3;
    Serial.println(selected_menu_idx);
  } else if (clicked_buttons & BUTTON_RIGHT) {
    Serial.print("Clicked Right - New index: ");
    selected_menu_idx = (selected_menu_idx < 3) ? selected_menu_idx + 1 : 0;
    Serial.println(selected_menu_idx);
  } 
}


void begin_welcome() {
  lcd.clear();
  lcd.setBacklight(TEAL);
  lcd.print(F("Hoist Controller"));
  state = blink_select;
}

void blink_select() {
  static boolean blink = true;
  static unsigned long last_blink_time;
  
  if (time - last_blink_time >= 1000) {
    lcd.setCursor(0, 1);
    if (blink) {
      lcd.write(0x7E);
      lcd.print(F(" PRESS SELECT "));
      lcd.write(0x7F);
    } else {
      lcd.print(F("                "));
    }
    blink = !blink;
    last_blink_time = time;
  }
  
  if (clicked_buttons & BUTTON_SELECT) {
    state = start_menu;
  }
}


// -------------------------------------------------------------------------------
// Moving states / functions
// -------------------------------------------------------------------------------

void start_menu() {
  digitalWrite(hoist[0], LOW);
  digitalWrite(hoist[1], LOW);
  digitalWrite(hoist[2], LOW);
  digitalWrite(hoist[3], LOW);
  

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Select Hoist #"));
  
  lcd.setCursor(0, 1);
  lcd.print(F(" 01  02  03  04"));

  selected_menu_idx = 0;
  lcd.setCursor(menu_col[selected_menu_idx][0], 1);
  lcd.print('[');
  lcd.setCursor(menu_col[selected_menu_idx][1], 1);
  lcd.print(']');

//  Serial.println("Goint to begin_input_move from start_menu");
  state = begin_input_move;
}

void begin_input_move() {
//  Serial.println("In begin_input_move");
  lcd.setCursor(0, 0);
  lcd.print(F("Select Hoist # "));
  lcd.print(' ');
  
  state = input_move;
}

void input_move() {
  if (clicked_buttons) {
    
    if (clicked_buttons & BUTTON_UP) {
      Serial.println("UP ");
    }
    if (clicked_buttons & BUTTON_DOWN) {
      Serial.println("DOWN ");
    }
    if (clicked_buttons & BUTTON_LEFT) {
      Serial.println("LEFT ");
    }
    if (clicked_buttons & BUTTON_RIGHT) {
      Serial.println("RIGHT ");
    }
    if (clicked_buttons & BUTTON_SELECT) {
      Serial.println("SELECT ");
    }
       
    clear_current_menu();
    if (clicked_buttons & BUTTON_SELECT) {
        current_hoist = selected_menu_idx;
        Serial.println("Goint to move_hoist from input_move");
        state = move_hoist;
      }
    } else {
//      Serial.println("Goint to handle_menu from input_move");
      handle_menu();
    }
    
    highlight_current_menu();
  }


void move_hoist () {
  // Enable Selected Hoist
  digitalWrite(hoist[current_hoist], HIGH);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Press UP or DOWN"));
  lcd.setCursor(0, 1);
  lcd.print(F("To Move Hoist"));

// Going to have to use something different than clicked_buttons
// clicked_buttons only captures on button release.

  if (clicked_buttons) {
    
    if (clicked_buttons & BUTTON_UP) {
      digitalWrite(hoist_up, HIGH);
    } else if ( clicked_buttons & BUTTON_DOWN) {
      digitalWrite(hoist_down, HIGH);
    } else if ( clicked_buttons & BUTTON_SELECT) {
      state = start_menu;
    }
  }
  
  digitalWrite(hoist_up, LOW);
  digitalWrite(hoist_down, LOW);
}