We seem to have a lot of questions this year on how to use the LCD to select different autonomous routines for your robot. I’m going to present several examples, each of which is going to increase in complexity, the first three of which are here, there may be more later.
Most code that uses the LCD to allow autonomous selection has common features.
- Choices are presented to the user, these can be simple or a complex series of menus.
- The code must monitor button presses and releases on the LCD display.
- The code must be aware of the competition state so that the autonomous task may run.
Item 2 is one of the most basic functions that the code must perform. A user will press an LCD button, this is detected and causes the code to take some action, the code then must generally wait for the button to be released so the action does not happen multiples times in quick succession. To help simplify the LCD selection code I decided to create a wrapper for this most basic function that combines LCD button press detection and also waiting for button release. It also needs to be aware of the competition state so that it does not block (that means wait in a loop forever). This function is saved in its own file and “included” in the code for the three demo’s, here is the function.
// Wrap code with definition so it's not included more than once
#ifndef _GETLCDBUTTONS
#define _GETLCDBUTTONS
// Some utility strings
#define LEFT_ARROW 247
#define RIGHT_ARROW 246
static char l_arr_str[4] = { LEFT_ARROW, LEFT_ARROW, LEFT_ARROW, 0};
static char r_arr_str[4] = { RIGHT_ARROW, RIGHT_ARROW, RIGHT_ARROW, 0};
/*-----------------------------------------------------------------------------*/
/* This function is used to get the LCD hutton status but also acts as a */
/* "wait for button release" feature. */
/* Use it in place of nLcdButtons. */
/* The function blocks until a button is pressed. */
/*-----------------------------------------------------------------------------*/
// Little macro to keep code cleaner, masks both disable/ebable and auton/driver
#define vexCompetitionState (nVexRCReceiveState & (vrDisabled | vrAutonomousMode))
TControllerButtons
getLcdButtons()
{
TVexReceiverState competitionState = vexCompetitionState;
TControllerButtons buttons;
// This function will block until either
// 1. A button is pressd on the LCD
// If a button is pressed when the function starts then that button
// must be released before a new button is detected.
// 2. Robot competition state changes
// Wait for all buttons to be released
while( nLCDButtons != kButtonNone ) {
// check competition state, bail if it changes
if( vexCompetitionState != competitionState )
return( kButtonNone );
wait1Msec(10);
}
// block until an LCD button is pressed
do {
// we use a copy of the lcd buttons to avoid their state changing
// between the test and returning the status
buttons = nLCDButtons;
// check competition state, bail if it changes
if( vexCompetitionState != competitionState )
return( kButtonNone );
wait1Msec(10);
} while( buttons == kButtonNone );
return( buttons );
}
#endif // _GETLCDBUTTONS
The functionality of this code, in pseudo code form, is as follows.
Wait for all buttons to be released unless
the robot is enabled which causes exit
Wait for a button press unless
the robot is enabled which causes exit
return the pressed button
Demo 1
This allows selection of one of three autonomous routines, the three LCD buttons are used to make that selection. The code separates the display of the choices and selected routine from the selection of that routine.
/*-----------------------------------------------------------------------------*/
/* LCD autonomous demo 1 */
/* Copyright (c) 2013 James Pearman */
/* This is unlicensed software - you may modify and use as you wish */
/*-----------------------------------------------------------------------------*/
//Competition Control and Duration Settings
#pragma competitionControl(Competition)
#include "Vex_Competition_Includes.c" //Main competition background code...do not modify!
// Include the lcd button get utility function
#include "getlcdbuttons.c"
// global hold the auton selection
static int MyAutonomous = 0;
/*-----------------------------------------------------------------------------*/
/* Display autonomous selection */
/*-----------------------------------------------------------------------------*/
void
LcdSetAutonomous( int value )
{
// Simple selection display
if( value == 0 ) {
displayLCDString(0, 0, "auton 0");
displayLCDString(1, 0, "[00] 01 02 ");
}
if( value == 1 ) {
displayLCDString(0, 0, "auton 1");
displayLCDString(1, 0, " 00 [01] 02 ");
}
if( value == 2 ) {
displayLCDString(0, 0, "auton 2");
displayLCDString(1, 0, " 00 01 [02]");
}
// Save autonomous mode for later
MyAutonomous = value;
}
/*-----------------------------------------------------------------------------*/
/* Select one of three autonomous choices */
/*-----------------------------------------------------------------------------*/
void
LcdAutonomousSelection()
{
TControllerButtons button;
// Clear LCD and turn on backlight
clearLCDLine(0);
clearLCDLine(1);
bLCDBacklight = true;
// diaplay default choice
LcdSetAutonomous(0);
while( bIfiRobotDisabled )
{
// this function blocks until button is pressed
button = getLcdButtons();
// Display and select the autonomous routine
if( button == kButtonLeft )
LcdSetAutonomous(0);
if( button == kButtonCenter )
LcdSetAutonomous(1);
if( button == kButtonRight )
LcdSetAutonomous(2);
// Don't hog the cpu !
wait1Msec(10);
}
}
void pre_auton()
{
bStopTasksBetweenModes = true;
LcdAutonomousSelection();
}
task autonomous()
{
switch( MyAutonomous ) {
case 0:
// run auton code
break;
case 1:
// run some other auton code
break;
default:
break;
}
}
task usercontrol()
{
while (true) {
wait1Msec(10);
}
}
A global called MyAutonomous stores the selected choice, you would run a different autonomous routine depending if it was 0, 1 or 2. The selection function is called in pre_auton() and will run until the robot is enabled, it does not run again unless the cortex is power cycled.
Demo 2 will be in the next post
The three programs are attached as a zip file so you don’t have to cut and paste from the forum.
Lee!