Help creating menu for golf robot

Hello,

I am very new to arduino and programming in general. I am a senior at a university and for a senior project we are building a golfing robot. I'll give you a little backround about our project. first it is being positioned via RC and the entire drive system is seperate from the arduino. we are not hitting the ball with a club but rather launching it with a nitrogen powered golfball cannon. and it putts by spinning a motor with a putter on it to putt the ball.

The hardware we have is a arduino mega 2560 and the sainsmart LCD keypad 2X16

What needs to happen:
the arduino needs to be able control the pressure of our launcher and then launch the ball. we have a pressure transducer and a electronic valve. so the user needs to input the distance and then the arduino needs to start pressurizing monitor the pressure and stop it when it reaches the right pressure.

The putter is a motor that spins a mass (our Putter) and cotrolled with PWM.

The Menu Needs to be set up like this:
LEVEL 1:
Four Modes: Drive, Punch, Chip, Putt hit "select" to go to the next level

LEVEL 2:
Distance input under each mode: drive is in yards and in increments of 5 this is the same forpunch and chip. the putter needs to be in feet and in increments of 1.

After you select the distance you hit "select" and go to next level.

LEVEL 3:
Needs to display "FIRE?" for each of the modes then you hit "select" and it goes into it process for firing.

if anyone can help me that would be great.

Check out luidr's LCD menu library (plenty about it here on the forum), I think it will do this.


Rob

You could also use M2tklib
http://code.google.com/p/m2tklib/

Oliver

Ok, I went trough your description more carefully.
I would suggest to write down all dialog boxes and their sequence (control flow chart).

I think the boxes and transitions will be similar to this:

Mode select dialog.
If Mode in Drive, Punch, Chip then goto yard input
If mode is Putter then goto feet input

Yard input
If back button pressed, goto Mode select dialog
If select button pressed, goto fire dialog

Feet input
If back button pressed, goto Mode select dialog
If select button pressed, goto fire dialog

Fire Dialog
If back button pressed, goto Mode select dialog
if select button execute your action and goto Mode select dialog

Then you need to design the dialog boxes:
Mode select dialog:
Use M2_COMBO and M2_BUTTON combined in a M2_VLIST (or M2_XYLIST)

Yard Input
Use a M2_U32NUM readonly field to display the distance.
Use two M2_BUTTONs to increment and decrement by 5
Use two M2_ROOT buttons to go back or to the fire menu.
The description of the BUTTON element has a similar example:
http://code.google.com/p/m2tklib/wiki/elref#BUTTON

Hope this gives some ideas how to apply M2TKLIB here.

Oliver

Thanks those were both helpful. my only problem is that the keypad on the LCD uses just one analog button for all five buttons (left, right, up, down, selsct) and im not sure how to get either library that was pointed out to work with that?

im not sure how to get either library that was pointed out to work with that?

I'm not familiar with the code of either library, but presumably (if the libraries have been written well) at some point they call a function to get the button that has been pressed, you need to replace that function with your own that reads your input device and returns data in the format expected by the library you are using.

For example somewhere in their code they might be something like this

x = getPressedButton();

switch (x) {

   case 1:
     // left button
   case 2:
     // right button
   case 3:
     // up button
   case 4:
     // down button
   case 5:
     // enter button
}

You write your own version of getPressedButton(), replace the code in theirs, overload the method (if C++) or whatever.

Having done that the rest of the library should work if you have the same LCD connected in the same way.

It may be easy it may be a real pain in the bum, it depends largely on how the library code has been written.

I would ask the library authors, maybe they can point you to the right place.


Rob

Hi

Speaking for m2tklib, there is an independent subsystem called "event source" which has a well defined interface.
The "event source" subsystem is responible to translate the arduino hardware event to a m2tk event.

The event source is the second parameter to the m2tk constructor:
http://code.google.com/p/m2tklib/wiki/fnref#M2tk

Basically this subsystem is a callback procedure which in principle looks like this:

uint8_t m2_es_arduino(m2_p ep, uint8_t msg)  
{
    switch(msg)
    {
      case M2_ES_MSG_GET_KEY:
        return m2_arduino_get_key();
      case M2_ES_MSG_INIT:
        m2_arduino_setup();
        return 0;    
    }    
return 0;  
}

If the callback procedure gets the message M2_ES_MSG_GET_KEY, the callback proc must return one of the following values: M2_KEY_NONE, M2_KEY_SELECT, M2_KEY_EXIT, M2_KEY_NEXT, M2_KEY_PREV, M2_KEY_DATA_UP, M2_KEY_DATA_DOWN

It is not required to support all of these values. It will depend on the event handler how many and which buttons are used (see the description here: Google Code Archive - Long-term storage for Google Code Project Hosting.)

Additionally all these M2_KEY values undergo the internal debounce algorithm. If you want to skip the m2tklib debounce algorithm, simply return (as example) M2_KEY_EVENT(M2_KEY_SELECT) instead of a pure M2_KEY_SELECT.
The standard arduino event source is here:
http://code.google.com/p/m2tklib/source/browse/dev/arduino/m2esarduino.c
A version which avoids the debounce algorithm is here:
http://code.google.com/p/m2tklib/source/browse/dev/arduino/irremote/m2esarduinoir.c
This also demonstrates how to integrate the IRremove library with m2tklib.

So, as conclusion, please write a simple event source callback procedure which reads the analog values and returns the corresponding KEY values. Maybe it is best to use m2esarduinoir.c as starting point. Pass your new callback procedure as second argument to the m2tk constructor.

Oliver

So you are using "analogButton" then. My phi_prompt library now directly supports the following input devices:analogButton, digital button group, matrix keypad, rotary encoder, serial keypad, etc. You can download an example to see how to use analogButton to do the menu. There is a virtual layer in my library that renders what input device you use transparent to the menu so you can even later change what type of buttons to you, maybe not relevant.

Look at the analog keypad sample examples.

OK. i have tried to use both of those libraries and every time I even try to use them even the examples i get a ton of errors.

pyrokidd89:
OK. i have tried to use both of those libraries and every time I even try to use them even the examples i get a ton of errors.

Reporting the error would be the first step...

liudr:
Reporting the error would be the first step...

ok here is my code and errors when trying to use Mt2k example ""hello world"

#include <LiquidCrystal.h>
#include "M2tk.h"
#include "utility/m2ghlc.h"

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

M2_LABEL(hello_world_label, NULL, "Hello World!");
M2tk m2(&hello_world_label, NULL, NULL, m2_gh_lc);

void setup() {
  m2_SetLiquidCrystal(&lcd, 16, 2);
}

void loop() {
  m2.draw();
  delay(500);
}
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c:27:20: error: wiring.h: No such file or directory
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c: In function 'm2_arduino_setup_key':
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c:41: error: 'INPUT' undeclared (first use in this function)
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c:41: error: (Each undeclared identifier is reported only once
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c:41: error: for each function it appears in.)
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c:42: error: 'HIGH' undeclared (first use in this function)
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c: In function 'm2_arduino_check_key':
C:\Documents and Settings\ajkidd\Desktop\arduino-1.0\libraries\M2tklib\utility\m2esarduino.c:60: error: 'LOW' undeclared (first use in this function)

i also dont know how to insert my code into one of the scroll boxes. Sorry.

Maybe that library is not arduino 1.0 compatible? Try arduino 0022 or my library, which is arduino 1.0 compatible.

liudr:
Maybe that library is not arduino 1.0 compatible? Try arduino 0022 or my library, which is arduino 1.0 compatible.

whats the difference?

pyrokidd89:

liudr:
Maybe that library is not arduino 1.0 compatible? Try arduino 0022 or my library, which is arduino 1.0 compatible.

whats the difference?

You can read about it but the fact is most libraries work nicely before arduino 1.0 and they almost all broke when arduino upgraded from 0023 or 0.23 to 1.0
I took the time to rewrite parts of my library to stay compatible with both versions but not everyone has the time to do so.

Ok. so which file or files do i need from your download page?

Most recent libraries in a zip file.

http://code.google.com/p/phi-prompt-user-interface-library/downloads/detail?name=libraries.zip&can=2&q=

Just expand all folders under sketchbooks/libraries/

The TinyGPS was for my GPS logger project code. The other two, phi_prompt is the user interface library, the phi_interfaces is the input device library. Both have extensive sample code.

I tries to use your Phi_promt_example and I'm not sure how to define my button since they are all on one analog pin? I also tried to use your analog button example but i think my display uses serial it uses severel pins?

Hi

Indeed v1.03 of m2tklib was not Arduino 1.0 compatible. I have uploaded v1.06 for LiquidCrystal lib.
Download is here: Google Code Archive - Long-term storage for Google Code Project Hosting.

i think my display uses serial

Are you able to use the standard LiquidCrystal lib with your display?

Oliver

pyrokidd89:
I tries to use your Phi_promt_example and I'm not sure how to define my button since they are all on one analog pin? I also tried to use your analog button example but i think my display uses serial it uses severel pins?

http://code.google.com/p/phi-prompt-user-interface-library/downloads/detail?name=Template_using_analog_keys.pde&can=2&q=

This template should be able to get you started with analogbuttons.

@liudr

I have attempted to reconfigure the Phi_promt_example in the Ardunio IDE 1.0 using the Template_using_analog_keys.pde example for use with the DFRobot LCD Keypad Shield for Arduino.
Product code : RB-Dfr-07
http://www.robotshop.com/dfrobot-lcd-keypad-shield-arduino-1.html

But I'm getting some button response anomalies. The up key decrements by 2, whereas I'd presume 'up' would increment the variable. The down key doesn't do anything. The right key increments by 2. The left key acts the same as the select key. Both terminate the "input_integer(&myIntegerInput);" function call.

Any advice you could send through pointing me to how I can correct the button behaviour would be appreciated.

The code I am running is as follows:

#include <LiquidCrystal.h>
#include <Wire.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <phi_interfaces.h>
#include <phi_prompt.h>

//DFRobot LCD shield 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

//DFRobot LCD shield row & column assignments
#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.

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

char analog_mapping[]={'U','D','L','R','B'}; // This is an analog keypad.
byte analog_pins[]={0}; // The pin numbers are analog pin numbers.
int values[]={0, 144, 342, 505, 742}; //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};

// The following sets up LCD and other objects
LiquidCrystal lcd(LCD_RS,LCD_EN,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // Create the lcd object

void setup()
{
    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.
    Serial.begin(9600); // Serial is used as a debug keypad. This can be deleted after debug.
}

void loop()
{
int user_input=10;                        // This is the storage for the integer
phi_prompt_struct myIntegerInput;         // This struct stores information for library functions
myIntegerInput.ptr.i_buffer=&user_input;  // Pass the address of user_input to the library.
// After library function call, user input will be stored in this variable. Note the use of “&”.
myIntegerInput.low.i=0;                   // Lower limit. The number wraps to 20 when decreased from 0.
myIntegerInput.high.i=20;                 // Upper limit. The number wraps to 0 when increased from 20.
myIntegerInput.step.i=2;                  // Step size. You will get 0, 2, 4, 6, 8, etc if you set it to 2.
myIntegerInput.col=7;                     // Display the number at column 7 myIntegerInput.row=1; // Display the number at row 1
myIntegerInput.width=2;                   // The number occupies 2 character space.
myIntegerInput.option=0;                  // Option 0, space pad right, 1, zero pad left, 2, space pad left.
lcd.clear();                              // Clear the lcd.
lcd.print("Number(0-20):");               // Prompt user for input
input_integer(&myIntegerInput);           // This calls the library function.
/*
The initial number will be displayed first and the functions waits for the user to press up/down to change 
the number and enter to confirm, after which it stores the new number in user_input. Notice the "&" in front 
of the myIntegerInput struct.
*/

Serial.print("user_input was: ");
Serial.println(user_input);


}