Tasks not working

Description

Hi, i am trying to map a potentiometer value from port A0 to a LVGL gauge however i am experiencing the error:
‘invalid conversion from ‘void ()(lv_task_t) {aka void ()(_lv_task_t)}’ to ‘lv_task_cb_t {aka void ()(_lv_task_t)}’ [-fpermissive]’

What MCU/Processor/Board and compiler are you using?

Arduino IDE/ Arduino DUE

What LVGL version are you using?

latest (7.8.1)

What do you want to achieve?

A smooth gauge that shows the current value of the Potentiometer

What have you tried so far?

I have tried copying code from LVGL academy but i still get the same error

Code to reproduce


#include <lvgl.h>
#include <lv_examples.h>
#include <UTFT.h>
#include <UTouch.h>

static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 54];

const byte potPinOn       = A0;
long  triggerInterval = 0;

lv_obj_t* gauge;
static uint32_t user_data = 10;

UTFT myGLCD(SSD1963_480272, 38, 39, 40, 41); //(byte model, int RS, int WR, int CS, int RST, int SER)

UTouch  myTouch( 43, 42, 44, 45, 46);  //byte tclk, byte tcs, byte din, byte dout, byte irq

#if USE_LV_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{

  Serial.printf("%s@%d->%s\r\n", file, line, dsc);
  Serial.flush();
}
#endif

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

  myGLCD.drawBitmap(area->x1, area->y1, w , h, (bitmapdatatype)color_p, 1);

  lv_disp_flush_ready(disp);
}

/*Read the touchpad*/
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
  uint16_t touchX, touchY;


  myTouch.read();
  int x = myTouch.getX();
  int y = myTouch.getY();
  bool touched = false;
  if ((x != -1) and (y != -1)) touched = true;

  if (!touched)
  {
    data->state = LV_INDEV_STATE_REL;
  }
  else
  {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = x;
    data->point.y = y;
  }

  return false; /*Return `false` because we are not buffering and no more data to read*/
}

void setup()
{

  Serial.begin(115200); /* prepare for possible serial debug */

  lv_init();
#if USE_LV_LOG != 0
  lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif

  myGLCD.InitLCD();
  // -------------------------------------------------------------
  pinMode(8, OUTPUT);  //backlight
  digitalWrite(8, HIGH);//on
  // -------------------------------------------------------------
  myGLCD.clrScr();

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);

  lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

  /*Initialize the display*/
  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.buffer = &disp_buf;
  lv_disp_drv_register(&disp_drv);

  /*Initialize the (dummy) input device driver*/
  lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);

  ///////////////////////////////////////////////////////////////////////////////////////////////////

}


void loop()
{
  // myGLCD.fillScr(0xff, 0x00, 0x00);
  //myGLCD.fillScr(0x00, 0xff, 0x00);
  triggerInterval = analogRead(potPinOn);
  triggerInterval = map(triggerInterval, 0, 1023, 0, 1000);
  lv_task_handler(); /* let the GUI do its work */
  delay(5);
}

void task_cb(lv_task_t task)
{
  Serial.print("called");
}

void task(void)
{
  lv_task_t* task = lv_task_create(task_cb, 100, LV_TASK_PRIO_MID, NULL);
  lv_obj_t* gauge = lv_gauge_create(lv_scr_act(), NULL);
  lv_obj_t* label = lv_label_create(gauge, NULL);
  lv_obj_set_pos(gauge, 20, 20);
  lv_obj_set_size(gauge, 250, 250);
  lv_gauge_set_range(gauge, 0, 1000);
  lv_gauge_set_value(gauge, NULL, triggerInterval);
  lv_label_set_text(label, "POT");
  lv_obj_align(label, gauge, LV_ALIGN_CENTER, 0, 50);
}

Screenshot and/or video

As you are using C++ you need to explicitly cast the task function to lv_task_cb_t.

How do i do this?

void task_cb(lv_task_t task)

should be

void task_cb(lv_task_t * task)

Somehow I missed the last 10 lines of your code snippet, so I assumed you hadn’t copied the function, and thus, gave my suggestion based on the compiler error alone. @kisvegabor’s suggestion should work.

@embeddedt @kisvegabor The compiled code now only shows a blank white screen, do you know why this may be?

Is task() invoked once somewhere? I don’t see it in your code.

Side note: avoid naming variables with the same name as a function; most compilers will give you a warning or error for that.

void task(void)
{
  /* change this to `t` or `tsk`. */
  lv_task_t* task = lv_task_create(task_cb, 100, LV_TASK_PRIO_MID, NULL);

@embeddedt So should i call task(); in the setup?

P.s I just wanted to say thankyou for your help :slight_smile:

@embeddedt
I try using the code below however it just shows a gauge that is frozen (when i press it theres no dark blue circle that forms around it

#include <lvgl.h>
#include <lv_examples.h>
#include <UTFT.h>
#include <UTouch.h>

static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 54];

const byte potPinOn       = A0;
long  triggerInterval = 0;

lv_obj_t* gauge;

UTFT myGLCD(SSD1963_480272, 38, 39, 40, 41); //(byte model, int RS, int WR, int CS, int RST, int SER)

UTouch  myTouch( 43, 42, 44, 45, 46);  //byte tclk, byte tcs, byte din, byte dout, byte irq

#if USE_LV_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{

  Serial.printf("%s@%d->%s\r\n", file, line, dsc);
  Serial.flush();
}
#endif

/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

  myGLCD.drawBitmap(area->x1, area->y1, w , h, (bitmapdatatype)color_p, 1);

  lv_disp_flush_ready(disp);
}

/*Read the touchpad*/
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
  uint16_t touchX, touchY;


  myTouch.read();
  int x = myTouch.getX();
  int y = myTouch.getY();
  bool touched = false;
  if ((x != -1) and (y != -1)) touched = true;

  if (!touched)
  {
    data->state = LV_INDEV_STATE_REL;
  }
  else
  {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = x;
    data->point.y = y;
  }

  return false; /*Return `false` because we are not buffering and no more data to read*/
}

void setup()
{

  Serial.begin(115200); /* prepare for possible serial debug */

  lv_init();
#if USE_LV_LOG != 0
  lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif

  myGLCD.InitLCD();
  // -------------------------------------------------------------
  pinMode(8, OUTPUT);  //backlight
  digitalWrite(8, HIGH);//on
  // -------------------------------------------------------------
  myGLCD.clrScr();

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);

  lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

  /*Initialize the display*/
  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.buffer = &disp_buf;
  lv_disp_drv_register(&disp_drv);

  /*Initialize the (dummy) input device driver*/
  lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);
  
  task();

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  //  lv_obj_t* gauge = lv_gauge_create(lv_scr_act(), NULL);
  //  lv_obj_t* label = lv_label_create(gauge, NULL);
  //  lv_obj_set_pos(gauge, 20, 20);
  //  lv_obj_set_size(gauge, 250, 250);
  //  lv_gauge_set_range(gauge, 0, 1000);
  //  lv_gauge_set_value(gauge, NULL, triggerInterval);
  //  lv_label_set_text(label, "POT");
  //  lv_obj_align(label, gauge, LV_ALIGN_CENTER, 0, 50);

}


void loop()
{
  // myGLCD.fillScr(0xff, 0x00, 0x00);
  //myGLCD.fillScr(0x00, 0xff, 0x00);
  triggerInterval = analogRead(potPinOn);
  triggerInterval = map(triggerInterval, 0, 1023, 0, 1000);
  lv_task_handler(); /* let the GUI do its work */
  delay(5);
}

void task_cb(lv_task_t* tsk)
{
  lv_gauge_set_value(gauge, NULL, triggerInterval);
  Serial.print("called");
}

void task(void)
{
  lv_task_t* tsk = lv_task_create(task_cb, 500, LV_TASK_PRIO_HIGHEST, NULL);
  lv_obj_t* gauge = lv_gauge_create(lv_scr_act(), NULL);
  lv_obj_t* label = lv_label_create(gauge, NULL);
  lv_obj_set_pos(gauge, 20, 20);
  lv_obj_set_size(gauge, 250, 250);
  lv_gauge_set_range(gauge, 0, 1000);
}

Two possibilities:

  • lv_task_handler hangs the second time (this can be tested by adding a print statement in loop).
  • The touch driver is broken (this can also be tested with print statements).

@embeddedt I added a print statement to the loop and it outputs the serial data 4 times before stopping. Why could this be the case?

I dont believe it to be the touch driver as i can sucessfully run demos on the LCD screen.

Is there anything else im missing? I noticed this function being used in a demo that i dont currently utilise:
lv_obj_set_event_cb(slider, slider_event_cb)

Part of your problem is that you’re redeclaring gauge inside the task function. You don’t need to do that as there is already a global variable named gauge referenced in task_cb.