RobotC Header File: Useful LCD Functions

(I assume this is the right forum to post this in…)

This package includes two functions and one task, among other things:
**LCD_Display: **This task displays the competition status, time spent within that status, and voltages of the main battery, power expander (if installed) and backup battery. The battery display is easily customized; see documentation.
**LCD_Prompt: **This function displays a prompt of up to 28 characters and three answer choices on the LCD and reports which one was selected. A default choice and timeout can be specified. Fully customizable; see documentation.
**LCD_Menu: **Displays complex, multi-level menus on the LCD, and allows the user to scroll through with the buttons. Useful for requesting large amounts of information from the user, such as autonomous configuration. A Sack Attack menu is included. Fully customizable; see documentation and included prebuilt menus.

Unwanted features can easily be completely removed at compile time. See the documentation for details.

This package also includes a patched Vex_Competition_Includes.c file, which does not hog the LCD and is more lightweight.

This header file uses a timer system similar to the timers.h system. Read the documentation for that header file for details.

The statistics below are with Release optimization enabled and the Sack Attack menu included. Note that removing or reducing the menu significantly reduces resource usage. See the compile statistics for details.

File "lcd_demo.c" compiled on Jul 21 2012 21:20:41

Compile Statistics:  (lcd_demo.c)
    0.032 Total Compile Time (seconds)
    4,541 Total code bytes, (after 638 bytes removed during optimization)
      392 Constant Pool Size (in bytes)
    1,156 Used memory locations (of 12000), 2 Tasks, 15 Procedures
      638 User Source file lines,     3,688 tokens
    6,169 System Include file lines, 26,792 tokens
        0 Errors, 0 Warnings, 0 Info Messages
                                 CPU     ......Lines/sec.....
                             Seconds         Total     Source
     Scanner/parsing: Setup    0.003     2,097,202    196,564
    Scanner/parsing: System    0.000    34,435,783  3,227,564
Scanner/parsing: User Files    0.006     1,113,670    104,380
            Code Generation    0.016       426,822     40,004
              Code Optimize    0.004     1,772,812    166,160
                      Total    0.032       210,055     19,687
      121 Total symbols added to symbol table
    1.083 Avg hash bucket depth (1.0 is best possible)

File "lcd_demo.c" compiled on Jul 21 2012 21:24:22
*Warning*:LCD_Menu() and related functions and variables have been excluded from this compilation.

Compile Statistics:  (lcd_demo.c)
    0.022 Total Compile Time (seconds)
    2,756 Total code bytes, (after 425 bytes removed during optimization)
      198 Constant Pool Size (in bytes)
      380 Used memory locations (of 12000), 2 Tasks, 8 Procedures
      470 User Source file lines,     2,673 tokens
    6,169 System Include file lines, 26,792 tokens
        0 Errors, 1 Warnings, 0 Info Messages
                                 CPU     ......Lines/sec.....
                             Seconds         Total     Source
     Scanner/parsing: Setup    0.003     2,308,899    163,455
    Scanner/parsing: System    0.000    39,361,242  2,786,531
Scanner/parsing: User Files    0.004     1,586,199    112,293
            Code Generation    0.011       627,628     44,432
              Code Optimize    0.002     2,875,082    203,537
                      Total    0.022       299,252     21,185
       96 Total symbols added to symbol table
    1.082 Avg hash bucket depth (1.0 is best possible)

File "lcd_demo_competition.c" compiled on Jul 21 2012 21:20:20

Compile Statistics:  (lcd_demo_competition.c)
    0.074 Total Compile Time (seconds)
    4,857 Total code bytes, (after 735 bytes removed during optimization)
      392 Constant Pool Size (in bytes)
    1,160 Used memory locations (of 12000), 4 Tasks, 21 Procedures
      965 User Source file lines,     4,419 tokens
    6,169 System Include file lines, 26,792 tokens
        0 Errors, 0 Warnings, 0 Info Messages
                                 CPU     ......Lines/sec.....
                             Seconds         Total     Source
     Scanner/parsing: Setup    0.003     2,516,192    340,359
    Scanner/parsing: System    0.034       209,342     28,317
Scanner/parsing: User Files    0.009       769,203    104,048
            Code Generation    0.020       361,839     48,945
              Code Optimize    0.004     1,754,596    237,340
                      Total    0.074        96,758     13,088
    1,403 Total symbols added to symbol table
    1.076 Avg hash bucket depth (1.0 is best possible)

I’d like to acknowledge this thread. It was very useful in the creation of this header and I recommend it to programmers of all skill levels.

You may also be interested in my other header file: Timers.h.
lcd_v0.9.zip (13.7 KB)

Apologies. It seems that the Technical Discussion forum would be a better place for this thread, and this one too. Would a moderator please move them?

Great post! Thanks for sharing your work. Moved to Technical Discussion section as requested.

I’m going to post a few comments on the LCD code, much of what I said in this thread also applies here but I have a few additional things.

The code as posted does not display the battery voltages correctly, everything is shown as 0. The issue is that various integer variables need to be cast to float for division and display to work properly.

for example, this line from lcd_menu_sackattack.h


sprintf(LCD.Menu[12].Text, "%1.3fv", nAvgBatteryLevel / 1000);

needs the nAvgBatteryLevel cast to float.


sprintf(LCD.Menu[12].Text, "%1.3fv", (float)nAvgBatteryLevel / 1000);

The same for these lines

sprintf(LCD.Menu[13].Text, "%1.3fv", SensorValue[LCD.Display.BattB] / 1000);
sprintf(LCD.Menu[14].Text, "%1.3fv", BackupBatteryLevel / 1000);

and various other places.

Firmware version display from here


sprintf(LCD.Menu[15].Text, "v%4.0f", firmwareVersion);

needs redoing as firmwareVersion is not a float at all (it’s a preprocessor definition of an integer), firmwareVersion is the ROBOTC virtual machine version not VEXnet version. You could use nVexMasterVersion which would be the closest thing, it’s the master firmware version.

My other comments about code formating and comments still stand but that’s your choice.

I appreciate your comments; I’ve already to responded to those regarding Timers.h and will look at these ASAP.

Code has been changed.

This part of the menu confused me bit. I understand that the VEX Cortex must be loaded with three items to run correctly:

VEXnet Firmware
Master Code
User Code

Not for every download of the user code, of course.

I would like to have version numbers for the first two items displayed in the Sys Info menu. Which variables should I use? :confused:

The cortex contains two micro-controllers, I posted some details here.

Master firmware is loaded onto the “supervisor” micro-controller, this is the one connected to the USB port and contains, amongst other things, the VEXnet functionality. This firmware is currently at version (July 2012) 3.21, you can access this version in ROBOTC using the nVexMasterVersion variable. You may display it using a line of code something like this

sprintf(str,"version %d.%02d\n", ( nVexMasterVersion >> 8 ) & 0xff, nVexMasterVersion & 0xFF );

The “user” processor runs the ROBOTC virtual machine which is really just a program written by CMU. This is currently at version 912 (or actually 912a which was released just before worlds to address the I2C issues although the version number was not increased) and can be found in the ROBOTC variable “version”. This is a simple integer so does not need the manipulation above to display.

When you download your code the ROBOTC virtual machine is storing it elsewhere on the user processor (using its own file system) and then running it, you can have several ROBOTC user programs on the cortex and choose between them, it’s a little awkward to do this but instruction were posted last year somewhere on the forums.

Thanks for your explanation: clear but detailed, as usual. I will certainly integrate your suggested modifications.

I will post an update in this thread on the 29th with the following changes:

#pragma LCD for demos, if missing
Cleaned-up semicolons
More comments (???)
Battery voltages casted to float before division
Version information corrected in the Sys Info menu
Credits modified to reflect participation of jpearman and anyone else that shows up…

Additional changes conceptualized from reading some more posts in this thread.

Add void LCD_WaitForRelease()
Automatically exit LCD_Menu if competition is started. Any remaining requirements will use defaults.
Considering moving scrolling code to two functions: LCD_Scroll_LoadText and LCD_Scroll_Continue. Currently implemented at two locations; bothersome to update. New funtions will use static variables to store data across calls; LCD_Scroll_Continue will need to be called in a loop.

I also realized the non-competition demo did not actually demo the menu. :o