-
Hi! I'm scratching my head trying to figure this out... This is the scrolling text example for Arduino:
I want to scroll a text string in a more RTOS way. I'm using STM32 with HAL libraries, FreeRTOS and the C version of U8G2.
I also have gui.c and gui.h where the drawing functions are being written to keep the code organized. What I haven't figured out is how to implement that Arduino loop in a non blocking way. How to update offset and new x position without locking everything on do/while loops and considering page buffer switching occurs in another file?
Any help would be very appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I do not know much about your problem, but I suggest two improvements:
Only if the isUpdate flag is true (1), then redraw the display content. It might look like this: volatile int isUpdate = 1; // init with true so that display is updated during startup
void StartDisp(void *argument)
{
/* USER CODE BEGIN StartDisp */
/* Infinite loop */
for(;;)
{
while( isUpdate == 0 ) // do not update the display as long as isUpdate is false
;
/* isUpdate is not 0, so do the update */
u8g2_FirstPage(&u8g2);
do {
draw_bar();
draw_menu();
} while (u8g2_NextPage(&u8g2));
isUpdate = 0; // display update is done, clear the isUpdate flag and wait until it gets set again
}
/* USER CODE END StartDisp */
} Obviously you need the "volatile" attribute to avoid any compiler caching of the variable. Now you can set the isUpdate flag, whenever something has changed for the display, for example an offset for the text (scroll effect) or any update of the menu after any button press event. The main benefit is to reduce load on the uC. It also helps to react more quickly on any changes.
U8g2 picture loop requires constant values. Especially if you have multiple parallel tasks, modifing a variable while updating the display will lead to visible artefacts. void main_task() {
for() {
so+=2; // move text
isUpdate = 1;
task_delay( 100 milliseconds );
}
} Then your draw procedure should work on a shadow variable (lets call it "soShadow"): void draw_menu() {
u8g2_DrawRBox(&u8g2, 46, 27, 79, 25, 3);
u8g2_SetDrawColor(&u8g2, 0);
u8g2_SetFont(&u8g2, u8g2_font_nokiafc22_tu);
u8g2_DrawUTF8(&u8g2, 48, 38, "Test");
scroll_text(&u8g2, 48+soShadow, 45, "This is just a simple test", u8g2_font_5x7_tf);
u8g2_SetDrawColor(&u8g2, 1);
} Just before the picture loop, you should copy the original value to the shadow value: volatile int isUpdate = 1; // init with true so that display is updated during startup
void StartDisp(void *argument)
{
/* USER CODE BEGIN StartDisp */
/* Infinite loop */
for(;;)
{
while( isUpdate == 0 ) // do not update the display as long as isUpdate is false
;
/* isUpdate is not 0, so do the update */
soShadow = so; // copy the scroll offset
u8g2_FirstPage(&u8g2);
do {
draw_bar();
draw_menu();
} while (u8g2_NextPage(&u8g2));
isUpdate = 0; // display update is done, clear the isUpdate flag and wait until it gets set again
}
/* USER CODE END StartDisp */
} This approach will keep the scroll offset constant during the display update, avoiding unwanted artefacts on the display. |
Beta Was this translation helpful? Give feedback.
-
Long strings are better supported if u8g2 is put into 16 bit mode (see FAQ, https://github.com/olikraus/u8g2/blob/master/doc/faq.txt).
Use: https://github.com/olikraus/u8g2/wiki/u8g2reference#setclipwindow |
Beta Was this translation helpful? Give feedback.
Long strings are better supported if u8g2 is put into 16 bit mode (see FAQ, https://github.com/olikraus/u8g2/blob/master/doc/faq.txt).
Use: https://github.com/olikraus/u8g2/wiki/u8g2reference#setclipwindow