How to display data with PROS like Brain.Screen.printAt() of vexcode

how to display data with PROS like Brain.Screen.printAt() of vexcode

PROS is using Atom as its editor, which is much more conventient to use. but i can find PROS api do print simple things, it has LVGL, but not that friendly to use. and the Legacy LCD Emulator is not that cool .

lv_obj_t * label=lv_label_create(lv_scr_act(),nullptr);
lv_label_set_text(label ,"Hello ,Luo Qiang!");

You can try my graphics library.

I would also look at this thread that talked about the LVGL Library
Questions about LVGL & examples of V5 displays

1 Like

This is what I use for making my auton selector but it can print anything you want on to the screen. For diagnostic stuff I use printf and the pros terminal. Which can be accessed with prosv5 terminal or through atom.

pros::lcd::initialize(); //This only needs to be called once at the start of you program.
pros::lcd::set_text(7, "Hello World!"); //The 7 is the line number.

I think @vex_lq doesn’t want to use the LCD emulator. I would recommend going to the LVGL GitHub page and going through the root code to form a better understanding of how the code works. That and using the examples.

1 Like

Or instead of going through the source you coukd just read the docs:
Keep in mind that the version of LVGL in PROS is 5.1.1, not the latest 5.3, so there may be some discrepancies between the docs and reality (images especially).

Here is a link to a pros project that show LVGL button and text examples.

right, i dont like the LCD emulator,

1 Like

better than nothing…


#include “main.h”
#include <stdarg.h>
#include <string.h>

extern lv_obj_t *label[11];
extern int line;

extern bool display_print(int16_t line, const char *fmt, …);
extern void user_display_init();

#include “user_display.h”

lv_obj_t *label[11];
int line = 0;

void user_display_init() {
for (size_t i = 0; i < 11; i++) {
label[i] = lv_label_create(lv_scr_act(), NULL);
lv_obj_align(label[i], NULL, LV_ALIGN_IN_TOP_LEFT, 5, 20 * i);
lv_label_set_align(label[i], LV_LABEL_ALIGN_LEFT);
lv_label_set_text(label[i], “”);

bool _vprint(int16_t line, const char *fmt, va_list args) {
if (line < 0 || line > 11)
return false;

char *buf = (char *)malloc(512);

vsprintf(buf, fmt, args);
lv_label_set_text(label[line], buf);
return true;


bool display_print(int16_t line, const char *fmt, …) {
va_list args;
va_start(args, fmt);
bool res = _vprint(line, fmt, args);
return res;

1 Like

That’s very similar to the what one of the coders on the team I coach did. It looks like you have multiple “labels” where he only has one but stores multiple lines of text in a string array to be printed on different lines of the label.

I’ve tried to get him to publish it but he’s spends all his free time working on 3d printing now.

yes right hhhhhhhhhhh

Avoid C-style strings, they are difficult and messy to use.

1 Like

Good to note. I should be more careful with semantics, actual implementation is of the form:
char buffer [NUM_LINES][NUM_CHARS] = {""};

If you really want to cheat

#include <stdarg.h>

extern "C" {
	int32_t  vex_vsnprintf( char *out, uint32_t max_len, const char *format, va_list args );
	void     vexDisplayPrintf( int32_t xpos, int32_t ypos, uint32_t bOpaque, const char *format, ... );

printAt( int32_t x, int32_t y, const char *format, ... ) {
   char  _textStr[128];

   va_list args;
   va_start(args, format);
   vex_vsnprintf(_textStr, sizeof(_textStr), format, args );

   vexDisplayPrintf( x, y, true, _textStr );

   va_end( args );

void opcontrol() {
	int count;

	while (true) {
		printAt( 10, 40, "Hello V5 %d", count++ );


Won’t be quite the same as VEXcode/VCS, may be different font and vertical position.

(PROS team will probably get mad at me now)


:angry: :angry: :angry:

I mean I have no problem with folks using the more primitive/simpler API, but be aware that LVGL code may overwrite the screen at that area.


sure, if LVGL buffer changes then it will overwrite
but if LVGL is not used then there should be no issues.

I’m not sure there is a way to disable the LVGL task without recompiling pros =)
Unless there is a way to access the task handle by name and manually stop it.
Edit: Unless LVGL does not write until there is a change.

It doesn’t call the function to update the screen unless there is a change, that’s internal to LVGL, some sort of dirty flag I guess.
(at least that’s what I noticed when I ported LVGL over to VEXcode)

Oh don’t tell my coder this. He spend a week learning VA and arrays to put it in. :zipper_mouth_face:

here’s another reference implementation

1 Like