How To Program LCD Display (ROBOTC)

We just purchased an LCD Display this year, and want to know how to use it.

We would like to display our robot batteries voltage, we also would like to scroll through multiple autonomous routines and be able to select them.

Can we see sample code, or something? What other cool things do you use your LCD screen for?

(Off topic: What should we use our extra lexan for on our robot?)

The RobotC Blog has an example of one way to write LCD code to do both of those things. I don’t like the way they did their menu system because it leaves redundant code all over the program and won’t let you choose a program to run during intialization, but it will almost work. Their battery code is almost exactly the way I would write it, though. If you’re using a Power Expander, it might be worth looking into the High Resolution Analog Input that will allow you to get that battery’s charge level, too.

http://www.robotc.net/blog/2012/05/18/advanced-applications-with-the-vex-lcd/

I’ve got a version of RobotC running on a different computer now, and I’ll port the code I wrote last night over minus the battery levels if I can ever figure out their LCD Menu commands. I don’t want to do the math for that right now, but the other thing is really easy. Give me 10 minutes, and I’ll see what I can do.

EDIT: Okay, I don’t use RobotC. Ever. But I think that this code should work. If there are errors, it’s in how I tracked button presses from the LCD Screen and/or initialized it. Sorry. I’ve written exactly zero lines of code in RobotC before, and this was the best I could do from their (quite honestly unhelpful) documentation and help page. If someone else could take a look, that would be great.

[Code]#pragma platform(VEX)

//Competition Control and Duration Settings
#pragma competitionControl(Competition)
#pragma autonomousDuration(20)
#pragma userControlDuration(120)
#pragma config(UART_Usage, UART1, uartVEXLCD, baudRate19200, IOPins, None, None)
//Variable that will carry between modes
int Program;

#include “Vex_Competition_Includes.c” //Main competition background code…do not modify!

/////////////////////////////////////////////////////////////////////////////////////////
//
// Pre-Autonomous Functions
//
// You may want to perform some actions before the competition starts. Do them in the
// following function.
//
/////////////////////////////////////////////////////////////////////////////////////////

void pre_auton()
{
// Set bStopTasksBetweenModes to false if you want to keep user created tasks running between
// Autonomous and Tele-Op modes. You will need to manage all user created tasks if set to false.
bStopTasksBetweenModes = true;
//Leave this value alone
int lcdScreenMin = 1;
//This keeps track of which program you want to run
int lcdScreen = 1;
//Change this value to be the maximum number of programs you want on the robot
int lcdScreenMax = 4;
//Turns on the Backlight
bLCDBacklight = true;

//Copied from someone's sample code because the documentation for RobotC won't tell me anything useful
//These should logically work, but I'm not 100% sure
const short leftButton = 1;
const short centerButton = 2;
const short rightButton = 4;

while (vrDisabled == 1) { //Ensures this code will run ONLY when the robot is disabled
	if (nLCDButtons == leftButton) { //Scrolls to the left
		if (lcdScreenMin == lcdScreen) {
			lcdScreen = lcdScreenMax;
			wait1Msec(250);
		} else {
			lcdScreen --;
			wait1Msec(250);
		}
	}
	if (nLCDButtons == rightButton) { //Scrolls to the right
		if (lcdScreenMax == lcdScreen) {
			lcdScreen = lcdScreenMin;
			wait1Msec(250);
		} else {
			lcdScreen++;
			wait1Msec(250);
		}
	}
	if (lcdScreen == 1 && Program != 1) {
		displayLCDCenteredString (0, "Program"); //Name the first program here
		displayLCDCenteredString (1, "1"); //Name the first program here
		if (nLCDButtons == centerButton) {
			Program = lcdScreen; //Sets the Program to the one on-screen
			displayLCDCenteredString (0, "Autonomous Has");
			displayLCDCenteredString (1, "Been Selected!");
			wait1Msec(1500);
		}
	} else if (lcdScreen == 1 && Program == 1) {
		displayLCDCenteredString (0, "Program"); //We use brackets to mark which program we have chosen
		displayLCDCenteredString (1, "[1]"); //So that while we're scrolling, we can have one marked
	} else if (lcdScreen == 2 && Program != 2) {
		displayLCDCenteredString (0, "Program"); //Name the second program here
		displayLCDCenteredString (1, "2"); //Name the second program here
		if (nLCDButtons == centerButton) {
			Program = lcdScreen; //Sets the Program to the one on-screen
			displayLCDCenteredString (0, "Autonomous Has");
			displayLCDCenteredString (1, "Been Selected!");
			wait1Msec(1500);
		}
	} else if (lcdScreen == 2 && Program == 2) {
		displayLCDCenteredString (0, "Program"); //We use brackets to mark which program we have chosen
		displayLCDCenteredString (1, "[2]"); //So that while we're scrolling, we can have one marked
	} else if (lcdScreen == 3 && Program != 3) {
		displayLCDCenteredString (0, "Program"); //Name the third program here
		displayLCDCenteredString (1, "3"); //Name the third program here
		if (nLCDButtons == centerButton) {
			Program = lcdScreen; //Sets the Program to the one on-screen
			displayLCDCenteredString (0, "Autonomous Has");
			displayLCDCenteredString (1, "Been Selected!");
			wait1Msec(1500);
		}
	} else if (lcdScreen == 3 && Program == 3) {
		displayLCDCenteredString (0, "Program"); //We use brackets to mark which program we have chosen
		displayLCDCenteredString (1, "[3]"); //So that while we're scrolling, we can have one marked
	} else if (lcdScreen == 4 && Program != 4) {
		displayLCDCenteredString (0, "Program"); //Name the fourth program here
		displayLCDCenteredString (1, "4"); //Name the fourth program here
		if (nLCDButtons == centerButton) {
			Program = lcdScreen; //Sets the Program to the one on-screen
			displayLCDCenteredString (0, "Autonomous Has");
			displayLCDCenteredString (1, "Been Selected!");
			wait1Msec(1500);
		}
	} else if (lcdScreen == 4 && Program == 4) {
		displayLCDCenteredString (0, "Program"); //We use brackets to mark which program we have chosen
		displayLCDCenteredString (1, "[4]"); //So that while we're scrolling, we can have one marked
	}
}

}

/////////////////////////////////////////////////////////////////////////////////////////
//
// Autonomous Task
//
// This task is used to control your robot during the autonomous phase of a VEX Competition.
// You must modify the code to add your own robot specific commands here.
//
/////////////////////////////////////////////////////////////////////////////////////////

task autonomous()
{
if(Program == 1){
//Put your second program in here
}
else if(Program == 2){
//Put your second program in here
}
else if(Program == 3){
//Put your third program in here
}
else if(Program == 4){
//Pur your fourth program in here
}
// …
// Insert user code here.
// …

AutonomousCodePlaceholderForTesting();  // Remove this function call once you have "real" code.

}

/////////////////////////////////////////////////////////////////////////////////////////
//
// User Control Task
//
// This task is used to control your robot during the user control phase of a VEX Competition.
// You must modify the code to add your own robot specific commands here.
//
/////////////////////////////////////////////////////////////////////////////////////////

task usercontrol()
{
// User control code here, inside the loop

while (true)
{
  // This is the main execution loop for the user control program. Each time through the loop
  // your program should update motor + servo values based on feedback from the joysticks.

  // .....................................................................................
  // Insert user code here. This is where you use the joystick values to update your motors, etc.
  // .....................................................................................

  UserControlCodePlaceholderForTesting(); // Remove this function call once you have "real" code.
}

}

Here is a “skeleton” I did for one of my teams to use. It works fine, it will ask you to choose an autonomous and then will display voltages after autonomous mode is over or during driver control mode.

I will bet you a dollar JPearman has something much cleaner and more impressive, but this will work.

#include "Vex_Competition_Includes.c"   //Main competition background code...do not modify!

//LCD Display code.
const short leftButton = 1;
const short centerButton = 2;
const short rightButton = 4;
//Declare count variable to keep track of our choice
	int count = 0;
//Wait for Press--------------------------------------------------
void waitForPress()
{
	while(nLCDButtons == 0){}
	wait1Msec(5);
}
//----------------------------------------------------------------

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

//

/////////////////////////////////////////////////////////////////////////////////////////
//
//                          Pre-Autonomous Functions
//
// You may want to perform some actions before the competition starts. Do them in the
// following function.
//
/////////////////////////////////////////////////////////////////////////////////////////

void pre_auton()
{


	//------------- 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, "Red Left");
			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, "Red Right");
			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, "Blue Left");
			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, "Blue Right");
			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;

		}
	}

}

/////////////////////////////////////////////////////////////////////////////////////////
//
//                                 Autonomous Task
//
// This task is used to control your robot during the autonomous phase of a VEX Competition.
// You must modify the code to add your own robot specific commands here.
//
/////////////////////////////////////////////////////////////////////////////////////////

task autonomous()
{
 	//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, "Red Left");
		displayLCDCenteredString(1, "is running!");
		wait1Msec(250);						// Robot waits for 250 milliseconds

//Insert "Red Left" autonommous code here.



		break;
	case 1:
		//If count = 1, run the code correspoinding with choice 2
		displayLCDCenteredString(0, "Red Right");
		displayLCDCenteredString(1, "is running!");
		wait1Msec(250);						// Robot waits for 250 milliseconds

// Insert "Red Right" autonomous code here.
		
	
		break;
	case 2:
		//If count = 2, run the code correspoinding with choice 3
		displayLCDCenteredString(0, "Blue Left");
		displayLCDCenteredString(1, "is running!");
		wait1Msec(250);						// Robot waits for 250 milliseconds
		
// Insert "Blue Left" autonomous code here.


		break;
		
	case 3:
		//If count = 3, run the code correspoinding with choice 4
		displayLCDCenteredString(0, "Blue Right");
		displayLCDCenteredString(1, "is running!");
		wait1Msec(250);						// Robot waits for 250 milliseconds

		// Insert "Blue Right" autonomous code here.
		
		break;
	default:
		displayLCDCenteredString(0, "No valid choice");
		displayLCDCenteredString(1, "was made!");
		break;
	}}

/////////////////////////////////////////////////////////////////////////////////////////
//
//                                 User Control Task
//
// This task is used to control your robot during the user control phase of a VEX Competition.
// You must modify the code to add your own robot specific commands here.
//
/////////////////////////////////////////////////////////////////////////////////////////

task usercontrol()
{
	// User control code here, inside the loop


	   while(1 == 1)
  {
    //Remote Control Commands go here.
   
  

 
    
   
    {
	bLCDBacklight = true;									// Turn on LCD Backlight
	string mainBattery, backupBattery;

{
		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);
	}
}

  }
}

What does that do if you press the left button on the first screen, or the right button on the fourth screen? The reason I rewrote the code instead of just using the one on the RobotC Blog was that I didn’t expect it to loop from screen 1 to 4 when the left button was pressed. I’m not familiar with “case,” and don’t know what it does. If that works, then the only thing the code I wrote does differently is to mark which program was selected, and allow the user to keep scrolling through menus afterwords.

Yours may well work better, I believe we were posting at the same time, your post was not there when I hit the reply button. I am not a programmer, I just keep hacking until I find something that works and then run with it. :smiley:

I would expect an example from someone who truly knows how to program to work smoother and look much cleaner than the crude examples I provide which are usually pieced together from sample programs.

I’ve quickly bashed together the LCD Menu system I will likely be using this year. I’ve tested it on a real robot (not the emulator), and it’s working. I’ve included three selections: alliance color, alliance position, and routine to run. The first two are plain-ol’ shmlain-ol left button means left and right button means right. The routine to run cycles through 5 routines to select (easy to change to be more or less). It also has a timeout feature, and will skip all remaining selections to be made if a timeout happens. All values have a default pseudo-null value, so you can use the psuedo-null value to detect a timeout during autonomous. I’ve attached the code and copied below:

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

typedef enum 
{
	noButton = 0,
	leftButton = 1,
	centerButton = 2,
	rightButton = 4
} sLCDButtons;

typedef enum
{
	left = -1,
	right = 1,
	nullPosition = 0,
} pAlignments;

typedef enum
{
	blue = -1,
	red = 1,
	nullColor = 0
} pAllianceColors;

#define numberOfRoutines 5



void LCDWaitForRelease ()
{
	while(nLCDButtons != noButton) wait1Msec(100);
}
//The enterLCDButton function will look for and wait for a button to be pressed, and returns that button's name
sLCDButtons enterLCDButton ( bool useLeft, bool useCenter, bool useRight, int timeoutSec = 10)
{
	ClearTimer(T1);
	bool quit = false;
	sLCDButtons returnButton = noButton;

	while(!quit)
	{
		if(useLeft && nLCDButtons == leftButton)
		{
			quit = true;
			LCDWaitForRelease();
			returnButton = leftButton;
		}
		else if(useCenter && nLCDButtons == centerButton)
		{
			quit = true;
			LCDWaitForRelease();
			returnButton = centerButton;
		}
		else if(useRight && nLCDButtons == rightButton)
		{
			quit = true;
			LCDWaitForRelease();
			returnButton = rightButton;
		}
		else if(time1[T1] > (timeoutSec * 1000))
		{
			quit = true;
			returnButton = noButton;
		}
	}
	return returnButton;
}

void displayLCDAlignedString(int nLine, pAlignments align, const string textToDisplay)
{
	int rightPosition = 16-strlen(textToDisplay);
	writeDebugStreamLine("%i", rightPosition);
	switch(align)
	{
	case left: displayLCDString(nLine,0,textToDisplay); break;
	case right: displayLCDString(nLine,rightPosition, textToDisplay); break;
	}
}


task main()
{
	bLCDBacklight = true;
	sLCDButtons retrievedButton = noButton;

	/* INFORMATION TO BE DETERMINED */
	pAllianceColors allianceColor = nullColor;
	pAlignments alliancePosition = nullPosition;
	int routineToRun = -1;

	displayLCDCenteredString(0,"Loading..."); // random loading screen becase we can
	clearLCDLine(1);
	wait1Msec(100);

	displayLCDCenteredString(0,"Alliance Color?");
	displayLCDAlignedString(1,left,"Blue");
	displayLCDAlignedString(1,right,"Red");
	retrievedButton = enterLCDButton(true,false,true);
	switch(retrievedButton)
	{
	case leftButton:
		allianceColor = blue;
		displayLCDCenteredString(0,"Selected:");
		displayLCDCenteredString(1,"BLUE");
		break;
	case rightButton:
		allianceColor = red;
		displayLCDCenteredString(0,"Selected:");
		displayLCDCenteredString(1,"RED");
		break;
	default:
		allianceColor = nullColor;
		displayLCDCenteredString(0,"Error Selecting");
		displayLCDCenteredString(1,"Terminating"); //Your code would "terminate" the selection process, or you could say "defaulting" if you have a default autonomous
		break;
	}
	wait10Msec(50);
	clearLCDLine(0);
	clearLCDLine(1);
	retrievedButton = noButton;

	if(allianceColor != nullColor)
	{
		displayLCDCenteredString(0,"Alliance Pos?");
		char leftArrow = 200;
		char rightArrow = 199;
		string leftText; sprintf(leftText, "%c Left", leftArrow);
		string rightText; sprintf(rightText, "Right %c", rightArrow);
		displayLCDAlignedString(1,left,leftText);
		displayLCDAlignedString(1,right,rightText);
		retrievedButton = enterLCDButton(true,false,true);
		switch(retrievedButton)
		{
		case leftButton:
			alliancePosition = left;
			displayLCDCenteredString(0,"Selected:");
			displayLCDCenteredString(1,"LEFT");
			break;
		case rightButton:
			alliancePosition = right;
			displayLCDCenteredString(0,"Selected:");
			displayLCDCenteredString(1,"RIGHT");
			break;
		default:
			alliancePosition = nullPosition;
			displayLCDCenteredString(0,"Error Selecting");
			displayLCDCenteredString(1,"Terminating");
			break;
		}
		wait10Msec(50);
		clearLCDLine(0);
		clearLCDLine(1);
		retrievedButton = noButton;

		if(alliancePosition != nullPosition)
		{
			bool quit = false;
			int selectedRoutine = (numberOfRoutines/2);

			displayLCDCenteredString(0,"Select Routine");
			while(!quit)
			{
				switch(selectedRoutine) {
				case 1:
					displayLCDCenteredString(1,"<    R1    >");
					break;
				case 2:
					displayLCDCenteredString(1,"<    R2    >");
					break;
				case 3:
					displayLCDCenteredString(1,"<    R3    >");
					break;
				case 4:
					displayLCDCenteredString(1,"<    R4    >");
					break;
				case 5:
					displayLCDCenteredString(1,"<    R5    >");
					break;
				default:
					displayLCDCenteredString(1,"ERROR");
					break;
				}
				retrievedButton = enterLCDButton(true,true,true);
				switch(retrievedButton) {
				case leftButton:
					if(selectedRoutine <= 1) selectedRoutine = numberOfRoutines;
					else selectedRoutine--;
					break;
				case rightButton:
					if(selectedRoutine >= numberOfRoutines) selectedRoutine = 1;
					else selectedRoutine++;
					break;
				case centerButton:
					routineToRun = selectedRoutine;
					quit = true;
					break;
				}
			}
			displayLCDCenteredString(0,"Selected:");
			switch(routineToRun)
			{
			case 1:
				displayLCDCenteredString(1,"R1");
				break;
			case 2:
				displayLCDCenteredString(1,"R2");
				break;
			case 3:
				displayLCDCenteredString(1,"R3");
				break;
			case 4:
				displayLCDCenteredString(1,"R4");
				break;
			case 5:
				displayLCDCenteredString(1,"R5");
				break;
			default:
				displayLCDCenteredString(1,"ERROR");
				break;
			}
			wait1Msec(500);
			
			displayLCDCenteredString(0,"Selections:");
			string selections; sprintf(selections, "%i , %i , R%i", allianceColor, alliancePosition, selectedRoutine);
			displayLCDCenteredString(1,selections);
			wait1Msec(1000);
		}
	}
}

It’s quite unusual for me to give code without really any real explanation (or comments), but I’m currently in the middle of finishing up a tutorial for holonomic x-drives. That being said, if you have any questions about the code, please ask.

EDIT: The .c file (and the above version) contains the header and the example menu system I used. The .h version does not contain the example menu system.
LCDHeader.c (5.75 KB)
LCDHeader.h (1.78 KB)

It would almost be worth writing something just to see a dollar change hands :slight_smile:

Anyway, I have posted menu type code before, here was a overly complex example which was more about demonstrating an extreme use of pointers when ROBOTC first released that capability.

https://vexforum.com/showpost.php?p=315448&postcount=120

The “open source robot” code also had some LCD menu code, although not specifically for autonomous selection but rather status display.

https://vexforum.com/showpost.php?p=335899&postcount=16

I tried both examples that were posted by Ephemeral_Being and sbdrobotics and have a few (hopefully constructive) comments.

They both mostly work

This is incorrect code for checking that the robot is disabled.


while (vrDisabled == 1) { //Ensures this code will run ONLY when the robot is disabled

vrDisabled is a constant meaning something else, the code should be

while(bIfiRobotDisabled == 1) { //Ensures this code will run ONLY when the robot is disabled

the concept is, however, correct. You don’t want to get stuck in the pre_auton() function if the user forgets to make a selection.

Neither program needs to define the button values, there are constants for that (from RobotCIntrinsics.c)

#if defined(hasLCDButtons) || defined(_WINDOWS)
    typedef enum
        {
        kButtonNone     = 0x00,
        kButtonLeft     = 0x01,
        kButtonCenter   = 0x02,
        kButtonRight    = 0x04,
        kButtonExit     = 0x08,
        kButtonExit2    = 0x10,
        } TControllerButtons;
    intrinsic const TControllerButtons propertyIndex(nLCDButtons, propertySystem, kSystemLCDButtons);
#endif

the idea of creating two functions for checking for button press and release is good, I will point out that they hog the cpu a little, I suspect curly brackets wee slightly misplaced. This

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

Should probably have been as below, the delay was outside of the while loop, not really a problem in ROBOTC as it anticipates this type of code but would be in other firmware like ConVEX. Always try and yield so the scheduler can allow other tasks at the same or lower priority level to run (higher priority tasks will always run).

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

I’m not going to write another complete example today, however, if I were doing this I would separate the actual display code from the button detection and action code. My version of sbdrobotics code would have been more like this (incomplete, just the menu part, no auton or operator functions here).

// These are the different choices we have
typedef enum {
    kLcdDispStart = 0,

    kLcdAuto_1    = 0,
    kLcdAuto_2,
    kLcdAuto_3,
    kLcdAuto_4,

    kLcdDispNumber
    } kLcdDispType;

// globals for tracking choices
short           autoMode = (-1);

// Display LCD choice
void lcdMenuDisplay(kLcdDispType current)
{
    //Switch case that allows the user to choose from 4 different options
    switch(current){
        case kLcdAuto_1:
            //Display first choice
            displayLCDCenteredString(0, "Red Left");
            displayLCDCenteredString(1, "<     Enter    >");
            break;              
        case kLcdAuto_2:
            //Display second choice
            displayLCDCenteredString(0, "Red Right");
            displayLCDCenteredString(1, "<     Enter    >");
            break;
        case kLcdAuto_3:
            //Display third choice
            displayLCDCenteredString(0, "Blue Left");
            displayLCDCenteredString(1, "<     Enter    >");
            break;
        case kLcdAuto_4:
            //Display fourth choice
            displayLCDCenteredString(0, "Blue Right");
            displayLCDCenteredString(1, "<     Enter    >");
            break;
            
        default:
            break;
        }
}

// Pre auton code - allow auton choice until enabled or selection is made
void pre_auton()
{
    int     i;
    int     autoTime = 1000;
    TControllerButtons    Buttons;
    
    // current choice
    kLcdDispType    mode = kLcdAuto_1;
    
    //Clear LCD
    clearLCDLine(0);
    clearLCDLine(1);
    bLCDBacklight = true;
    
    // Initial display
    lcdMenuDisplay(mode);
    
    //Loop while disabled
    while( bIfiRobotDisabled )
        {
        // Select display Item
        Buttons = nLCDButtons;

        // if right or left pressed change display
        if( (Buttons == kButtonLeft) || (Buttons == kButtonRight) )
            {
            // check for button press
            if( Buttons == kButtonRight )
                {
                mode++;
                if(mode >= kLcdDispNumber)
                    mode = kLcdDispStart;
                }
            if( Buttons == kButtonLeft )
                {
                mode--;
                if(mode < kLcdDispStart)
                    mode = (kLcdDispNumber-1);
                }
         
            // update display
            lcdMenuDisplay(mode);
             
            // wait for release or auto repeat time
            for( i=0;i<autoTime;i+=10)
                {
                if( nLCDButtons == kButtonNone )
                    {
                    autoTime = 1000;   
                    break;
                    }
                wait1Msec(10);
                }
            // shorten auto repeat for next time
            if( nLCDButtons != kButtonNone )
                autoTime = 250;  
            }
            
        // Center button selects choice
        if( Buttons == kButtonCenter )
            {
            displayLCDCenteredString(1, "<   Selected   >");
            // set the autononomous mode (replaces choice variable from sdrobotics code)
            autoMode = (short)mode;
            wait1Msec(1000);
            return;
            }
        
        // don't hog cpu
        wait1Msec(25);
        }
}

Hey, I got the commands right? Neat.

For future reference, is there a better spot to get documentation on RobotC? I couldn’t find much this morning.

Where were you looking? The ROBOTC wiki is not bad.
http://www.robotc.net/wiki/Main_Page

Nice, I missed that this morning. I was piecing the program together from the F1 menu and a sample I posted at the top of the thread.

I’ll read through it later.

Also, I believe in the RobotC sample files they have an autonomous chooser for the VEX LCD.

In our team’s 2013 code, we had an LCD menu with autonomous switching capabilities. To use the menu, you need a potentiometer and an LCD.

The LCD left/right buttons are for switching which menu item is shown. (Analog sensor viewer, motor test, autonomous selector/starter, etc.)
The potentiometer is for selecting a sub-menu item, when applicable. (Switch what analog sensor to view, which motor to test, which autonomous routine to select, etc.)
The LCD center button is for executing an action. (Start selected autonomous routine, run motor test, calibrate line follower, etc.)

There is probably a good way to do the same w/o a potentiometer…

Thank you for all the information! I am going to have our programmers look through this!

How do you set-up the LCD in ROBOTC?

There’s a line at the top of the code I posted that (I think) works.


#pragma config(UART_Usage, UART1, uartVEXLCD, baudRate19200, IOPins, None, None)

I don’t have an exact idea what that does, or what any of it means. If you use that code and plug the LCD Screen into UART1 it will respond to commands.

This probably has something to do with the documentation Pearman posted. I really should take a look at that.

Standard behavior is for ROBOTC to configure UART2 to be the LCD, you don’t need to do anything.

This line of code is generated by the “Motor&Sensors Setup” menu. It is configuring UART1 for use by the LCD instead of the default which is UART2. It is setting the baud rate (the communications speed, how many bits per second are sent to the LCD) to be 19200 as well as other parameters that have little meaning on the cortex. ROBOTC is available on several platforms (NXT, arduino etc) and this #pragma has some parameters which are platform dependent.

im looking for something similar to this, however instead of switching through autonomous modes, i want it to switch from battery voltage on the main battery to its main screen as written in this code:

clearLCDLine(0);
bLCDBacklight = true;
wait1Msec(100);
displayLCDCenteredString(0, “Darkez 8.X”);
wait1Msec(1000);
displayLCDCenteredString(1, “ACTIVE”);

and then to the alternate sensor detections, such as a light sensor value display, a ultrasonic value display, etc.

how would i implement the code for switching to these modes? im running a fully controlled robot, non-autonomous. the full code is as follows:

#pragma config(Sensor, dgtl1, , sensorLEDtoVCC)
#pragma config(Sensor, dgtl2, , sensorLEDtoVCC)
#pragma config(Motor, port1, , tmotorVex393_HBridge, openLoop, reversed)
#pragma config(Motor, port2, , tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port3, , tmotorVex393_MC29, openLoop)
#pragma config(Motor, port4, , tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port5, , tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port8, , tmotorServoStandard, openLoop)
#pragma config(Motor, port9, , tmotorVexFlashlight, openLoop, reversed)
#pragma config(Motor, port10, , tmotorVex393_HBridge, openLoop)
//!!Code automatically generated by ‘ROBOTC’ configuration wizard !!//

task flash2;
task headlight;
task Start_light;
task light;

task headlight()
{
while(true)
{
if(vexRT[Btn6U] == 1)
{
motor[port4] = 67;
}
else if(vexRT[Btn6D] == 1)
{
motor[port4] = -67;
}
else
{
motor[port4] = 0;
}
{
if(vexRT[Btn7U] == 1)
{
motor[port5] = 127;
}
else if(vexRT[Btn7D] == 1)
{
motor[port5] = -127;
}
else
{
motor[port5] = 0;
}
}
}
}

task light()
{
while(true)
{
motor[port9] = 127;
}

}

task Start_light()
{
while(true)
{
SensorValue[dgtl1] = true;
wait1Msec(500);
SensorValue[dgtl1] = false;
wait1Msec(500);
}
}

task flash2()
{
while(true)
{
if(vexRT[Btn5U] == 1)
{
startTask(Start_light);
}
else if(vexRT[Btn5D] == 1)
{
stopTask(Start_light);
SensorValue[dgtl1] = false;
}
if(vexRT[Btn8U] == 1)
{
startTask(light);
}
else if(vexRT[Btn8D] == 1)
{
stopTask(light);
motor[port9] = 0;
}
}

}

task main()
{
clearLCDLine(0);
bLCDBacklight = true;
wait1Msec(100);
displayLCDCenteredString(0, “Darkez 8.X”);
wait1Msec(1000);
displayLCDCenteredString(1, “ACTIVE”);
startTask(flash2);
startTask(headlight);
startTask(flash2);
while(1==1)
{
motor[port1] = (vexRT[Ch1] + vexRT[Ch2])/2;
motor[port10] = (vexRT[Ch1] - vexRT[Ch2])/2;

motor[port2] = (vexRT[Ch3]);
motor[port3] = (vexRT[Ch3]);

if(vexRT[Ch1] ||  vexRT[Ch2] == 0)
{
	SensorValue[dgtl2] = false;
}
else
	SensorValue[dgtl2] = true;
}

}

however, i want to add the features as described above

Theres some good stuff here
https://renegaderobotics.org/tag/lcd/