LCD Menu with Joystick: phi_promnt and phi_interfaces

Hi,

I want make a LCD Menu with Joystick. I this found a Menu library: Phi_prompt | LiuDr Electronic Solutions LLC Official Blog
I managed to make the menu with analog buttons, but I want to work with the joystick. The joystick has 2 analog outputs ("x" and "y" axis )and 1 digital output (press).
With this library seems easier to use the joystick but not implement it in the menu: phi_interfaces | LiuDr Electronic Solutions LLC Official Blog

menu library with analog buttons:

#define buttons_per_column 5 // Each analog pin has five buttons with resistors.
#define buttons_per_row 1 // There are two analog pins in use.

#define name_length 8 // This is the max length of names.

char analog_mapping[]={'R','U','D','L','B'}; // This is an analog keypad.
byte analog_pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={0, 143, 328, 503, 741}; //These numbers need to increase monotonically. The 342 works better on my setup but you will need to change it back.
phi_analog_keypads analog_keypad(analog_mapping, analog_pins, values, analog_buttons_per_row, analog_buttons_per_column);

// This serial keypad is for debugging.
phi_serial_keypads debug_keypad(&Serial,9600);

// The following sets up function keys for phi_prompt library
char up_keys[]={"U"}; ///< All keys that act as the up key are listed here.
char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
char left_keys[]={"L"}; ///< All keys that act as the left key are listed here.
char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
char enter_keys[]={"B"}; ///< All keys that act as the enter key are listed here.
char escape_keys[]={"A"}; ///< All keys that act as the escape key are listed here.
char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here fhr phi_prompt.

// The following adds all available keypads as inputs for phi_prompt library
multiple_button_input * keypads[]={&analog_keypad, &debug_keypad,0};

PROGMEM prog_char msg_00[]="Developed by:\nDr.Liu 05/23/11\nhttp://liudr.wordpress.com\nThis is just a mock-up of an actual data acquisition system with a 2-level menu.\nIt serves as a template for your actual project. It also shows off various features of the phi_prompt library.\nGo in \"Set Menu Style\" to find out some menu features you could be using in your project.\nPress Confirm to continue";
// Setting up two menus top and sub_1

Phi_interfaces library:

/*
       __    ______   ____    ____  _______.___________. __    ______  __  ___
      |  |  /  __  \  \   \  /   / /       |           ||  |  /      ||  |/  /
      |  | |  |  |  |  \   \/   / |   (----`---|  |----`|  | |  ,----'|  '  /
.--.  |  | |  |  |  |   \_    _/   \   \       |  |     |  | |  |     |    <
|  `--'  | |  `--'  |     |  | .----)   |      |  |     |  | |  `----.|  .  \
 \______/   \______/      |__| |_______/       |__|     |__|  \______||__|\__\
*/
/** \brief class for 2-axis joy sticks
 * \details This class provides support to sense a 2-axis joy stick, with either analog output on each axis, or digital output of 8 directional keys.
 * These function codes, coupled with the lower level function code of each inheriting child class, completes the translation from sensing physical pins to outputting named buttons with mapping array.
 * The function hierarchy is getKey()<---scanKeypad()<---sense_all().
 * The sense_all reads digital pins for input.
 * The scanKeypad turns these inputs into status changes for keys and provide scan code of the pressed key. It handles status change including debouncing and repeat.
 * The getKey translates the key press from scan code (0 to max_key-1) into named keys with the mapping array.
*/
class phi_joysticks:public phi_keypads {
  public:
  phi_joysticks(char *na, byte *sp, int * dp, int th); ///< Constructor for joystick
  byte keyboard_type;               ///< This stores the type of the keypad so a caller can use special functions for specific keypads.
  int get_x(){return axis_vals[0];} ///< Returns x axis value of the joystick
  int get_y(){return axis_vals[1];} ///< Returns y axis value of the joystick
  unsigned long button_status_t;    ///< This is the time stamp of the sensed button first in the status stored in button_status.

  protected:
  int axis_vals[2];         ///< This stores the x and y axis values read from analog pin
  int threshold;            ///< This stores the threshold of matching the joystick with a directional key.
  int * values;             ///< This pointer points to an integer array with values of analog inputs. The number of values is equal to the number of axis times 3. The array starts with the value of the first axis, when it is pushed up, then the center value of this axis, then the value of this axis when it is pushed down.
  byte sense_all(); ///< This senses all input pins.
};

please someone could help me?

thank you!

please someone could help me?

Help you with what? You know how to read from the joystick? You know how to determine that the joystick button has become pressed?

I dont know how to determine that the joystick button has become pressed

I dont know how to determine that the joystick button has become pressed

The joystick library doesn't seem to support the extra switches. How have you connected the switches to the Arduino?

I think too. Its seems support the X and Y axis. I conect X and Y axis in analog input. I do not know how to call the joystick library from the menu joystick. In this example call analog keypad library but i want call joystick library to use the joystick as UP DOWN RIGHT LEFT/ENTER.

#define buttons_per_column 5 // Each analog pin has five buttons with resistors.
#define buttons_per_row 1 // There are two analog pins in use.

#define name_length 8 // This is the max length of names.

char analog_mapping[]={'R','U','D','L','B'}; // This is an analog keypad.
byte analog_pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={0, 143, 328, 503, 741}; //These numbers need to increase monotonically. The 342 works better on my setup but you will need to change it back.
phi_analog_keypads analog_keypad(analog_mapping, analog_pins, values, analog_buttons_per_row, analog_buttons_per_column);

// This serial keypad is for debugging.
phi_serial_keypads debug_keypad(&Serial,9600);

// The following sets up function keys for phi_prompt library
char up_keys[]={"U"}; ///< All keys that act as the up key are listed here.
char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
char left_keys[]={"L"}; ///< All keys that act as the left key are listed here.
char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
char enter_keys[]={"B"}; ///< All keys that act as the enter key are listed here.
char escape_keys[]={"A"}; ///< All keys that act as the escape key are listed here.
char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here fhr phi_prompt.

// The following adds all available keypads as inputs for phi_prompt library
multiple_button_input * keypads[]={&analog_keypad, &debug_keypad,0};

PROGMEM prog_char msg_00[]="Developed by:\nDr.Liu 05/23/11\nhttp://liudr.wordpress.com\nThis is just a mock-up of an actual data acquisition system with a 2-level menu.\nIt serves as a template for your actual project. It also shows off various features of the phi_prompt library.\nGo in \"Set Menu Style\" to find out some menu features you could be using in your project.\nPress Confirm to continue";
// Setting up two menus top and sub_1

This is the phi_interfaces.h library (Rotary_encoder, joystick, matrix keypad etc...) phi_interfaces | LiuDr Electronic Solutions LLC Official Blog

Help me please.

phi_interfaces

/*
       __    ______   ____    ____  _______.___________. __    ______  __  ___
      |  |  /  __  \  \   \  /   / /       |           ||  |  /      ||  |/  /
      |  | |  |  |  |  \   \/   / |   (----`---|  |----`|  | |  ,----'|  '  /
.--.  |  | |  |  |  |   \_    _/   \   \       |  |     |  | |  |     |    <
|  `--'  | |  `--'  |     |  | .----)   |      |  |     |  | |  `----.|  .  \
 \______/   \______/      |__| |_______/       |__|     |__|  \______||__|\__\
*/
/** \brief class for 2-axis joy sticks
 * \details This class provides support to sense a 2-axis joy stick, with either analog output on each axis, or digital output of 8 directional keys.
 * These function codes, coupled with the lower level function code of each inheriting child class, completes the translation from sensing physical pins to outputting named buttons with mapping array.
 * The function hierarchy is getKey()<---scanKeypad()<---sense_all().
 * The sense_all reads digital pins for input.
 * The scanKeypad turns these inputs into status changes for keys and provide scan code of the pressed key. It handles status change including debouncing and repeat.
 * The getKey translates the key press from scan code (0 to max_key-1) into named keys with the mapping array.
*/
class phi_joysticks:public phi_keypads {
  public:
  phi_joysticks(char *na, byte *sp, int * dp, int th); ///< Constructor for joystick
  byte keyboard_type;               ///< This stores the type of the keypad so a caller can use special functions for specific keypads.
  int get_x(){return axis_vals[0];} ///< Returns x axis value of the joystick
  int get_y(){return axis_vals[1];} ///< Returns y axis value of the joystick
  unsigned long button_status_t;    ///< This is the time stamp of the sensed button first in the status stored in button_status.

  protected:
  int axis_vals[2];         ///< This stores the x and y axis values read from analog pin
  int threshold;            ///< This stores the threshold of matching the joystick with a directional key.
  int * values;             ///< This pointer points to an integer array with values of analog inputs. The number of values is equal to the number of axis times 3. The array starts with the value of the first axis, when it is pushed up, then the center value of this axis, then the value of this axis when it is pushed down.
  byte sense_all(); ///< This senses all input pins.
};

/*
     ___      .__   __.      ___       __        ______     _______
    /   \     |  \ |  |     /   \     |  |      /  __  \   /  _____|
   /  ^  \    |   \|  |    /  ^  \    |  |     |  |  |  | |  |  __
  /  /_\  \   |  . `  |   /  /_\  \   |  |     |  |  |  | |  | |_ |
 /  _____  \  |  |\   |  /  _____  \  |  `----.|  `--'  | |  |__| |
/__/     \__\ |__| \__| /__/     \__\ |_______| \______/   \______|
*/
/** \brief a class for buttons connected to analog pin with resistors
 * \details This class turns analogButton into a keypad. You may connect several buttons to one analog pin with resistors.
 * You may also use multiple analog pins, with each pin connected to several buttons and resistors, to form a keypad.
 * You have to use the same resistor values for all analog pins and thus the same amount of buttons per analog pin.
 * If you need less buttons, just don't connect that many and leave the rest of the circuit with all resistors untouched.
 * Only one function needs to be implemented, the sense_all(). Everything higher level is the same across all keypad subclasses, defined in phi_keypads.
 * Find the sample circuit on my blog under http://liudr.wordpress.com/phi_interfaces/
*/
class phi_analog_keypads: public phi_keypads{
  public:
  phi_analog_keypads(char *na, byte *sp, int * dp, byte r, byte c); ///< Constructor for analog keypad

  protected:
  int * values;             ///< This pointer points to an integer array with values of analog inputs. The number of dividers is equal to the number of buttons on each row. The values should increase monotonically, such as 0,146,342,513,744. A range of 10 between the stored and read values is taken as match to guarantee the match is good. These values apply to all columns so if you want to make a keypad with say three analog pins and 5 buttons on each pin, use the same button/resistor setup on all three pins.
  byte sense_all();         ///< This senses all analog input pins for change of key status.
};

please, anyone could help me?

hugofn,

Got your message. Been busy lately. You should be able to use phi_interfaces to sense joysticks and buttons. Give me some time to respond.

Thank you very much.

I´m trying with phi_interfaces but I cant control the menu with joystick :frowning:

this is a fraction of my sketch:

#define lcd_rows 2
#define lcd_columns 16

#define analog_buttons_per_column 5 // Each analog pin has five buttons with resistors.
#define analog_buttons_per_row 1 // There are two analog pins in use.
// LCD pin setting
//Phi-panel LCD pin setting
#define LCD_RS 8
#define LCD_EN 9
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7

#include <LiquidCrystal.h>
#include <phi_interfaces.h>
#include <phi_prompt.h>

LiquidCrystal lcd(LCD_RS,LCD_EN,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // Create the lcd object

#define buttons_per_column 5 // Each analog pin has five buttons with resistors.
#define buttons_per_row 1 // There are two analog pins in use.

#define name_length 8 // This is the max length of names.

char analog_mapping[]={'UL','U','UR','R','DR','D','DL','L'}; // This is an analog keypad.
byte analog_pins[]={4, 5}; // The pin numbers are analog pin numbers.
int values[]={1024, 512, 0, 1024, 512, 0}; //These numbers need to increase monotonically. The 342 works better on my setup but you will need to change it back.
phi_joysticks joy_stick(analog_mapping, analog_pins, values, 8);

// This serial keypad is for debugging.
phi_serial_keypads debug_keypad(&Serial,9600);

// The following sets up function keys for phi_prompt library
char up_keys[]={"U"}; ///< All keys that act as the up key are listed here.
char down_keys[]={"D"}; ///< All keys that act as the down key are listed here.
char left_keys[]={"L"}; ///< All keys that act as the left key are listed here.
char right_keys[]={"R"}; ///< All keys that act as the right key are listed here.
char enter_keys[]={'B'}; ///< All keys that act as the enter key are listed here.
char escape_keys[]={"A"}; ///< All keys that act as the escape key are listed here.
char * function_keys[]={up_keys,down_keys,left_keys,right_keys,enter_keys,escape_keys}; ///< All function key names are gathered here fhr phi_prompt.

// The following adds all available keypads as inputs for phi_prompt library
multiple_button_input * keypads[]={&joy_stick, &debug_keypad,0};

PROGMEM prog_char msg_00[]="Developed by:\nDr.Liu 05/23/11\nhttp://liudr.wordpress.com\nThis is just a mock-up of an actual data acquisition system with a 2-level menu.\nIt serves as a template for your actual project. It also shows off various features of the phi_prompt library.\nGo in \"Set Menu Style\" to find out some menu features you could be using in your project.\nPress Confirm to continue";
// Setting up two menus top and sub_1


int menu_top_pointer_1=0;  //Posición en el top_menu
int menu_sub_pointer_1=0;   //Posición en el sub_menu_timelapse
int user_input=1;  //tiempo de exposición
int user_choice=0;  //lista fps
int fps;


#define MOTORLATCH 12 //12 verde
#define MOTORCLK 2 //4 naranja blanco
#define MOTORENABLE 13 //7 naranja
#define MOTORDATA 1  //8 verde blanco

// 8-bit bus after the 74HC595 shift register 
// (not Arduino pins)
// These are used to set the direction of the bridge driver.
#define MOTOR1_A 2
#define MOTOR1_B 3

// Arduino pins for the PWM signals.
#define MOTOR1_PWM 3 //11


// Codes for the motor function.
#define FORWARD 1
#define BACKWARD 2
#define BRAKE 3
#define RELEASE 4



// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

void setup()
{
  Serial.begin(9600);
  lcd.begin(lcd_columns, lcd_rows);
  init_phi_prompt(&lcd,keypads,function_keys, lcd_columns, lcd_rows, '~'); // Supply the liquid crystal object, input keypads, and function key names. Also supply the column and row of the lcd, and indicator as '>'. You can also use '\x7e', which is a right arrow.
  //show_credit();
  
  lcd.clear();
  lcd.setCursor(4,0);
  lcd.print("Welcome");
  lcd.setCursor(3,1);
  lcd.print("TimeSlider");
  wait_on_escape(2000);
  
  //Variables para el menú
  
  
}

void loop()
{
  
  
  top_menu();
  
}

I change this part of the code acording with phi_interfaces.cpp but doesnt work!

Arduino analog inputs: Analog 4 (X axis) Analog 5 (Y axis) Analog 1 (switch)

char analog_mapping[]={'UL','U','UR','R','DR','D','DL','L'}; // This is an analog keypad.
byte analog_pins[]={4, 5, 1}; // The pin numbers are analog pin numbers.
int values[]={1024, 512, 0, 1024, 512, 0}; //These numbers need to increase monotonically. The 342 works better on my setup but you will need to change it back.
phi_joysticks joy_stick(analog_mapping, analog_pins, values, 8);

phi_interfaces.cpp (joystick skecth fraction)

//Joystick class member functions
/*
       __    ______   ____    ____  _______.___________. __    ______  __  ___
      |  |  /  __  \  \   \  /   / /       |           ||  |  /      ||  |/  /
      |  | |  |  |  |  \   \/   / |   (----`---|  |----`|  | |  ,----'|  '  /
.--.  |  | |  |  |  |   \_    _/   \   \       |  |     |  | |  |     |    <
|  `--'  | |  `--'  |     |  | .----)   |      |  |     |  | |  `----.|  .  \
 \______/   \______/      |__| |_______/       |__|     |__|  \______||__|\__\
*/
/**
 * \details A joystick has two potentiometers and provides the x and y axis locations with the wiper pins.
 * If the shaft is clickable, declare the button in a phi_button_groups object.
 * \param na This is the name of (or pointer to) a char array that stores the names corresponding to each directional key press. The array starts with the top left direction and iterates through top, top right, etc. The middle position is filled with NO_KEYs, not NO_KEY.
 * \param sp This is the name of (or pointer to) a byte array that stores all analog pins used by the joystick.
 * \param dp This is the name of (or pointer to) an integer array that stores the analog values of each button press (stick push). The array must be sorted from small to big then from one axis to the next.
 * \param th This stores the threshold of matching the joystick with a directional key.
 */
phi_joysticks::phi_joysticks(char *na, byte *sp, int * dp, int th)
{
  device_type=Joy_stick;
  key_names=na; // Translated names of the keys, such as '0'.
  mySensorPins=sp; // Row pins
  values=dp; // Points to divider value array.
  rows=2;
  columns=3;
  threshold=th;
  button_sensed=NO_KEYs; // This indicates which button is sensed or 255 if no button is sensed.
  button_status=buttons_up; // This indicates the status of the button if button_sensed is not 255.
  button_status_t=millis(); // This is the time stamp of the sensed button first in the status stored in button_status.
  
  for (int j=0;j<rows;j++) // Setting sensing rows to input and disabling internal pull-up resistors.
  {
    pinMode(mySensorPins[j],INPUT);
    digitalWrite(mySensorPins[j],LOW);
  }
}

/**
 * \details This is the most physical layer of the phi_joysticks. Senses all input pins for a valid status.
 * This function is not intended to be call by arduino code but called within the library instead.
 * If all you want is a key press, call getKey.
 * \return It returns the button scan code (0-max_button-1) that is pressed down or NO_KEYs if no button is pressed down. The return is 0-based so the value is 0-15 if the array has 16 buttons.
 */
byte phi_joysticks::sense_all()
{
  byte diff[2];
  diff[0]=NO_KEYs;
  diff[1]=NO_KEYs;
  for (byte i=0;i<rows;i++)
  {
    axis_vals[i]=analogRead(mySensorPins[i]);
    delay(5);
  }
  for (byte j=0;j<rows;j++)
  {
    for (byte i=0;i<columns;i++)
    {
      if(abs(values[j*columns+i]-axis_vals[j])<threshold) diff[j]=i; // Find the difference between analog read and stored values.
    }
  }
  if ((diff[0]==NO_KEYs)||(diff[1]==NO_KEYs)||((diff[0]==columns/2)&&(diff[1]==columns/2))) return NO_KEYs; // returns the button pressed if neither axis is in the middle.
  else return (diff[0]*columns+diff[1]);
}

could any one help me?

could any one help me?

With what, EXACTLY?

So far, all that you have said is that you are trying to use some libraries. You have NOT told us how the joystick is connected to the Arduino. You have NOT shown us all of your code. You have NOT demonstrated that you can detect a switch press on the joystick.

You have not explained in detail what is not working. It's hard to believe that the code that you've posted snippets of does NOTHING at all.