ROBOTC.net Blog  

ROBOTC News

Archive for the ‘Battery’ tag

Advanced Applications with the VEX LCD

with one comment

The VEX LCD allows you to output text and numbers on a 2×16 character grid. This is extremely useful for outputting messages and sensor values at different key points in a program. For example, you could have it display when the robot switches from one behavior to the next, or output key sensor values.

The LCD also contains 3 buttons which serve as inputs. These are also very helpful as they allow you to do things like control when certain sections of your program are run, or even create a basic menu system on the robot. This is perfect for programming the robot to automatically calculate its own sensor thresholds in different environments, or writing sophisticated programs that perform different sets of behaviors based on a choice you make.

Below are sample programs that show how to accomplish two LCD-based behaviors that are frequently asked about: displaying battery voltage, and creating a user interface.

Displaying Battery Voltage

If you’ve worked with robotic systems, chances are you’ve discovered that motor performance is closely tied to battery voltage. As the battery drains, motors don’t move as quickly or as powerfully. The following sample program displays the voltage of the main battery on the first line of the LCD, and the voltage of the backup battery (responsible for helping to maintain VEXnet connection) on the second line.

#pragma config(UART_Usage, UART2, uartVEXLCD, baudRate19200, IOPins, None, None)
//*!!Code automatically generated by 'ROBOTC' configuration wizard                             !!*//

/*
Display Battery Voltage
ROBOTC on VEX 2.0 Cortex
This program uses the Display functions of ROBOTC on the VEX 2.0 Cortex platform.
It will display the value of the main battery on line 0 and backup battery on line 1.

ROBOT CONFIGURATION
MOTORS & SENSORS:
[I/O Port]                    [Name]                            [Type]                                [Description
UART Port 2                    none                                VEX LCD                                VEX LCD Screen
*/

task main()
{
bLCDBacklight = true;                                    // Turn on LCD Backlight
string mainBattery, backupBattery;

while(true)                                                        // An infinite loop to keep the program running until you terminate it
{
clearLCDLine(0);                                            // Clear line 1 (0) of the LCD
clearLCDLine(1);                                            // Clear line 2 (1) of the LCD

//Display the Primary Robot battery voltage
displayLCDString(0, 0, "Primary: ");
sprintf(mainBattery, "%1.2f%c", nImmediateBatteryLevel/1000.0,'V'); //Build the value to be displayed
displayNextLCDString(mainBattery);

//Display the Backup battery voltage
displayLCDString(1, 0, "Backup: ");
sprintf(backupBattery, "%1.2f%c", BackupBatteryLevel/1000.0, 'V');    //Build the value to be displayed
displayNextLCDString(backupBattery);

//Short delay for the LCD refresh rate
wait1Msec(100);
}
}

Check out these sections of the ROBOTC Wiki for more information on the different commands used in this sample program:


User Interface / Code Chooser

The following sample program allows the user to choose from 4 different options with the buttons on the LCD screen. The left and right buttons cycle through the options, and the center button is used to make the selection. Once the user presses the center button, the robot runs the code associated with that choice. This code can easily be adapted for a competition setting, where a robot may start in any of 4 different locations.

#pragma config(UART_Usage, UART2, uartVEXLCD, baudRate19200, IOPins, None, None)
#pragma config(Motor,     port2,                        rightMotor,         tmotorNormal, openLoop, reversed)
#pragma config(Motor,     port3,                        leftMotor,         tmotorNormal, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard                             !!*//

/*
Code Chooser
ROBOTC on VEX 2.0 Cortex

This program uses the Display functions of ROBOTC on the VEX 2.0 Cortex platform.
It allows the user to choose from 4 different pieces of code using the left and right buttons
on the VEX LCD. Once the center button is pressed, the code corresponding with the choice is run.
This code can be adapted for competition based settings - just place the code for the first
switch case in the pre_auton function, and the code for the second switch in the autonomous task.
Replace the basic movement behaviors in the second switch with your own autonomous routines.

ROBOT CONFIGURATION
MOTORS & SENSORS:
[I/O Port]                    [Name]                            [Type]                                [Description]
UART Port 2                    none                                VEX LCD                                VEX LCD Screen
Motor Port 2                rightMotor                    VEX 3-wire module            Right side motor
Motor Port 3                leftMotor                        VEX 3-wire module            Left side motor
*/

const short leftButton = 1;
const short centerButton = 2;
const short rightButton = 4;

//Wait for Press--------------------------------------------------
void waitForPress()
{
while(nLCDButtons == 0){}
wait1Msec(5);
}
//----------------------------------------------------------------

//Wait for Release------------------------------------------------
void waitForRelease()
{
while(nLCDButtons != 0){}
wait1Msec(5);
}
//----------------------------------------------------------------

task main()
{
//Declare count variable to keep track of our choice
int count = 0;

//------------- Beginning of User Interface Code ---------------
//Clear LCD
clearLCDLine(0);
clearLCDLine(1);
//Loop while center button is not pressed
while(nLCDButtons != centerButton)
{
//Switch case that allows the user to choose from 4 different options
switch(count){
case 0:
//Display first choice
displayLCDCenteredString(0, "Autonomous 1");
displayLCDCenteredString(1, "<         Enter        >");
waitForPress();
//Increment or decrement "count" based on button press
if(nLCDButtons == leftButton)
{
waitForRelease();
count = 3;
}
else if(nLCDButtons == rightButton)
{
waitForRelease();
count++;
}
break;
case 1:
//Display second choice
displayLCDCenteredString(0, "Autonomous 2");
displayLCDCenteredString(1, "<         Enter        >");
waitForPress();
//Increment or decrement "count" based on button press
if(nLCDButtons == leftButton)
{
waitForRelease();
count--;
}
else if(nLCDButtons == rightButton)
{
waitForRelease();
count++;
}
break;
case 2:
//Display third choice
displayLCDCenteredString(0, "Autonomous 3");
displayLCDCenteredString(1, "<         Enter        >");
waitForPress();
//Increment or decrement "count" based on button press
if(nLCDButtons == leftButton)
{
waitForRelease();
count--;
}
else if(nLCDButtons == rightButton)
{
waitForRelease();
count++;
}
break;
case 3:
//Display fourth choice
displayLCDCenteredString(0, "Autonomous 4");
displayLCDCenteredString(1, "<         Enter        >");
waitForPress();
//Increment or decrement "count" based on button press
if(nLCDButtons == leftButton)
{
waitForRelease();
count--;
}
else if(nLCDButtons == rightButton)
{
waitForRelease();
count = 0;
}
break;
default:
count = 0;
break;
}
}
//------------- End of User Interface Code ---------------------

//------------- Beginning of Robot Movement Code ---------------
//Clear LCD
clearLCDLine(0);
clearLCDLine(1);
//Switch Case that actually runs the user choice
switch(count){
case 0:
//If count = 0, run the code correspoinding with choice 1
displayLCDCenteredString(0, "Autonomous 1");
displayLCDCenteredString(1, "is running!");
wait1Msec(2000);                        // Robot waits for 2000 milliseconds

// Move forward at full power for 3 seconds
motor[rightMotor] = 127;            // Motor on port2 is run at full (127) power forward
motor[leftMotor]    = 127;            // Motor on port3 is run at full (127) power forward
wait1Msec(3000);                            // Robot runs previous code for 3000 milliseconds before moving on
break;
case 1:
//If count = 1, run the code correspoinding with choice 2
displayLCDCenteredString(0, "Autonomous 2");
displayLCDCenteredString(1, "is running!");
wait1Msec(2000);                        // Robot waits for 2000 milliseconds

// Move reverse at full power for 3 seconds
motor[rightMotor] = -127;            // Motor on port2 is run at full (-127) power reverse
motor[leftMotor]    = -127;            // Motor on port3 is run at full (-127) power reverse
wait1Msec(3000);                            // Robot runs previous code for 3000 milliseconds before moving on
break;
case 2:
//If count = 2, run the code correspoinding with choice 3
displayLCDCenteredString(0, "Autonomous 3");
displayLCDCenteredString(1, "is running!");
wait1Msec(2000);                        // Robot waits for 2000 milliseconds

//Turn right for 3seconds
motor[rightMotor] = -63;            // Motor on port2 is run at half power reverse
motor[leftMotor]    = 63;                // Motor on port3 is run at half power forward
wait1Msec(3000);                            // Robot runs previous code for 3000 milliseconds before moving on
break;
case 3:
//If count = 3, run the code correspoinding with choice 4
displayLCDCenteredString(0, "Autonomous 4");
displayLCDCenteredString(1, "is running!");
wait1Msec(2000);                        // Robot waits for 2000 milliseconds

//Turn left for 3 seconds
motor[rightMotor] = 63;                // Motor on port2 is run at half power forward
motor[leftMotor]    = -63;            // Motor on port3 is run at half power reverse
wait1Msec(3000);                            // Robot runs previous code for 3000 milliseconds before moving on
break;
default:
displayLCDCenteredString(0, "No valid choice");
displayLCDCenteredString(1, "was made!");
break;
}
//------------- End of Robot Movement Code -----------------------
}

Both of these sample programs will be included in the next update to ROBOTC for Cortex and PIC. If you don’t have a VEX LCD, grab one here.

Written by Jesse Flot

May 18th, 2012 at 11:05 am