How to use Chart widget, ie for temperature data

Hi , I trying to “feed” data to Chart, code generated with SLS 1.3.4 working great, but code fail when i try to change chart data source.

Definition in ui.ino result error:

Compilation error: ‘ui_Chart1_series_1’ does not name a type

Tried define three ways:

extern ui_Chart1_series_1;

static lv_chart_series_t*ui_Chart1_series_1

lv_chart_series_t*ui_Chart1_series_1;

Hardware: Sunton 5 inch display w esp32s3.

ui.ino >>>

float power;
 extern ui_Chart1_series_1;
 // static lv_chart_series_t*ui_Chart1_series_1
 //lv_chart_series_t*ui_Chart1_series_1;
 //lv_chart_series_t * ui_Chart1_series_1; // !!! Chart data series

//#include "lv_demo_widgets.h"
#include <lvgl.h>
#include "ui.h"
/*******************************************************************************
 ******************************************************************************/
#include <Arduino_GFX_Library.h>
#define TFT_BL 2
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin

/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */

/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
//Arduino_DataBus *bus = create_default_Arduino_DataBus();

/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
//Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 0 /* rotation */, false /* IPS */);

Arduino_ESP32RGBPanel *bus = new Arduino_ESP32RGBPanel(
    GFX_NOT_DEFINED /* CS */, GFX_NOT_DEFINED /* SCK */, GFX_NOT_DEFINED /* SDA */,
    40 /* DE */, 41 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
    45 /* R0 */, 48 /* R1 */, 47 /* R2 */, 21 /* R3 */, 14 /* R4 */,
    5 /* G0 */, 6 /* G1 */, 7 /* G2 */, 15 /* G3 */, 16 /* G4 */, 4 /* G5 */,
    8 /* B0 */, 3 /* B1 */, 46 /* B2 */, 9 /* B3 */, 1 /* B4 */
);
// option 1:
// ST7262 IPS LCD 800x480
 Arduino_RPi_DPI_RGBPanel *gfx = new Arduino_RPi_DPI_RGBPanel(
   bus,
   800 /* width */, 0 /* hsync_polarity */, 8 /* hsync_front_porch */, 4 /* hsync_pulse_width */, 8 /* hsync_back_porch */,
   480 /* height */, 0 /* vsync_polarity */, 8 /* vsync_front_porch */, 4 /* vsync_pulse_width */, 8 /* vsync_back_porch */,
   1 /* pclk_active_neg */, 14000000 /* prefer_speed */, true /* auto_flush */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
 * End of Arduino_GFX setting
 ******************************************************************************/

/*******************************************************************************
 * Please config the touch panel in touch.h
 ******************************************************************************/
#include "touch.h"

/* Change to your screen resolution */
static uint32_t screenWidth;
static uint32_t screenHeight;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *disp_draw_buf;
static lv_disp_drv_t disp_drv;

/* 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);

#if (LV_COLOR_16_SWAP != 0)
  gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
  gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif

  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  if (touch_has_signal())
  {
    if (touch_touched())
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touch_last_x;
      data->point.y = touch_last_y;
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup()
{
  Serial.begin(115200);
  // while (!Serial);
  Serial.println("LVGL Widgets Demo");

  // Init touch device
  

  // Init Display
  gfx->begin();
#ifdef TFT_BL
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
#endif
  gfx->fillScreen(RED);
  delay(500);
  gfx->fillScreen(GREEN);
  delay(500);
  gfx->fillScreen(BLUE);
  delay(500);
  gfx->fillScreen(BLACK);
  delay(500);
  lv_init();
  delay(10);
  touch_init();
  screenWidth = gfx->width();
  screenHeight = gfx->height();
#ifdef ESP32
  disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight/4 , MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
#else
  disp_draw_buf = (lv_color_t *)malloc(sizeof(lv_color_t) * screenWidth * screenHeight/4);
#endif
  if (!disp_draw_buf)
  {
    Serial.println("LVGL disp_draw_buf allocate failed!");
  }
  else
  {
    lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight/4);

    /* Initialize the display */
    lv_disp_drv_init(&disp_drv);
    /* Change the following line to your display resolution */
    disp_drv.hor_res = 800;
    disp_drv.ver_res = 480;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    /* Initialize the (dummy) input device driver */
    static 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);

    ui_init();
    Serial.println("Setup done");
  }
}

void loop()
{
  lv_timer_handler(); /* let the GUI do its work */
  delay(5);
}

void setpoint()
{
  power = atof(lv_textarea_get_text(ui_TextArea1)); // get gui current field data
  lv_chart_set_next_value(ui_Chart1, ui_Chart1_series_1, power);

}


ui_Screen1.c >>>

// This file was generated by SquareLine Studio
// SquareLine Studio version: SquareLine Studio 1.3.4
// LVGL version: 8.3.3
// Project name: Sunton_5.0_esp32s3

#include "ui.h"
void ui_Screen1_screen_init(void)
{
    ui_Screen1 = lv_obj_create(NULL);
    lv_obj_clear_flag(ui_Screen1, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
    lv_obj_set_style_bg_color(ui_Screen1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_Screen1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

    ui_TextArea1 = lv_textarea_create(ui_Screen1);
    lv_obj_set_width(ui_TextArea1, 172);
    lv_obj_set_height(ui_TextArea1, 66);
    lv_obj_set_x(ui_TextArea1, 291);
    lv_obj_set_y(ui_TextArea1, 98);
    lv_obj_set_align(ui_TextArea1, LV_ALIGN_CENTER);
    lv_textarea_set_placeholder_text(ui_TextArea1, "XXX");
    lv_obj_set_style_text_font(ui_TextArea1, &lv_font_montserrat_44, LV_PART_MAIN | LV_STATE_DEFAULT);

    lv_obj_set_style_text_color(ui_TextArea1, lv_color_hex(0xFF0000), LV_PART_SELECTED | LV_STATE_DEFAULT);
    lv_obj_set_style_text_opa(ui_TextArea1, 255, LV_PART_SELECTED | LV_STATE_DEFAULT);


    ui_Keyboard1 = lv_keyboard_create(ui_Screen1);
    lv_keyboard_set_mode(ui_Keyboard1, LV_KEYBOARD_MODE_NUMBER);
    lv_obj_set_width(ui_Keyboard1, 204);
    lv_obj_set_height(ui_Keyboard1, 295);
    lv_obj_set_x(ui_Keyboard1, 293);
    lv_obj_set_y(ui_Keyboard1, -96);
    lv_obj_set_align(ui_Keyboard1, LV_ALIGN_CENTER);
    lv_obj_set_style_bg_color(ui_Keyboard1, lv_color_hex(0x0D1D0E), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_Keyboard1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

    lv_obj_set_style_bg_color(ui_Keyboard1, lv_color_hex(0xFCC442), LV_PART_ITEMS | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_Keyboard1, 255, LV_PART_ITEMS | LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(ui_Keyboard1, lv_color_hex(0x000000), LV_PART_ITEMS | LV_STATE_DEFAULT);
    lv_obj_set_style_text_opa(ui_Keyboard1, 255, LV_PART_ITEMS | LV_STATE_DEFAULT);

    ui_Button1 = lv_btn_create(ui_Screen1);
    lv_obj_set_width(ui_Button1, 151);
    lv_obj_set_height(ui_Button1, 65);
    lv_obj_set_x(ui_Button1, 295);
    lv_obj_set_y(ui_Button1, 189);
    lv_obj_set_align(ui_Button1, LV_ALIGN_CENTER);
    lv_obj_add_flag(ui_Button1, LV_OBJ_FLAG_SCROLL_ON_FOCUS);     /// Flags
    lv_obj_clear_flag(ui_Button1, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
    lv_obj_set_style_bg_color(ui_Button1, lv_color_hex(0x9C1F1F), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_Button1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(ui_Button1, lv_color_hex(0x43F414), LV_PART_MAIN | LV_STATE_PRESSED);
    lv_obj_set_style_bg_opa(ui_Button1, 255, LV_PART_MAIN | LV_STATE_PRESSED);

    ui_Chart1 = lv_chart_create(ui_Screen1);
    lv_obj_set_width(ui_Chart1, 503);
    lv_obj_set_height(ui_Chart1, 401);
    lv_obj_set_x(ui_Chart1, -105);
    lv_obj_set_y(ui_Chart1, -11);
    lv_obj_set_align(ui_Chart1, LV_ALIGN_CENTER);
    lv_chart_set_type(ui_Chart1, LV_CHART_TYPE_LINE);
    lv_chart_set_axis_tick(ui_Chart1, LV_CHART_AXIS_PRIMARY_X, 10, 1, 10, 10, true, 50);
    lv_chart_set_axis_tick(ui_Chart1, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 5, 2, true, 50);
    lv_chart_set_axis_tick(ui_Chart1, LV_CHART_AXIS_SECONDARY_Y, 10, 5, 5, 2, true, 25);
    lv_chart_set_update_mode(ui_Chart1, LV_CHART_UPDATE_MODE_SHIFT);
    //lv_chart_series_t* ui_Chart1_series_1 = lv_chart_add_series(ui_Chart1, lv_color_hex(0xDA1919), LV_CHART_AXIS_PRIMARY_Y);
    lv_chart_series_t*ui_Chart1_series_1 = lv_chart_add_series(ui_Chart1, lv_color_hex(0x49FF00), LV_CHART_AXIS_PRIMARY_Y);
    lv_chart_set_all_value(ui_Chart1, ui_Chart1_series_1, 0);
    //static lv_coord_t ui_Chart1_series_1_array[] = { 0, 10, 20, 40, 80, 80, 40, 20, 10, 0 };
    //lv_chart_set_ext_y_array(ui_Chart1, ui_Chart1_series_1, ui_Chart1_series_1_array);



    lv_obj_set_style_line_color(ui_Chart1, lv_color_hex(0x4040FF), LV_PART_TICKS | LV_STATE_DEFAULT);
    lv_obj_set_style_line_opa(ui_Chart1, 255, LV_PART_TICKS | LV_STATE_DEFAULT);

    lv_obj_add_event_cb(ui_Keyboard1, ui_event_Keyboard1, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui_Button1, ui_event_Button1, LV_EVENT_ALL, NULL);

}

Generated code make array local , then you cant aces it , but maybe can replace it


or change this as BUG

You should give a type for your array before its name, that’s what the error message is complaining about. So for example you should type extern lv_chart_series_t * ui_Chart1_series_1;

@Hermit maybe you missunderstand problem. Squareline generate chart widget in code and export only ui_Chart1 , but not export and make static local series. Then is impossible access it from user code and too from any other code.

Same problem here, version 1.3.4
It is still not clear to me how I can work around this?

Simply in Squareline create only empty chart, no data series when isnt static.
Series with actual data you need manage in your code.
For example generated

// This file was generated by SquareLine Studio
// SquareLine Studio version: SquareLine Studio 1.3.4
// LVGL version: 8.3.6
// Project name: Testiky

#include "../ui.h"

void ui_Screen3_screen_init(void)
{
    ui_Screen3 = lv_obj_create(NULL);
    lv_obj_clear_flag(ui_Screen3, LV_OBJ_FLAG_SCROLLABLE);      /// Flags

    ui_Chart1 = lv_chart_create(ui_Screen3);
    lv_obj_set_width(ui_Chart1, 200);
    lv_obj_set_height(ui_Chart1, 100);
    lv_obj_set_align(ui_Chart1, LV_ALIGN_CENTER);
    lv_chart_set_type(ui_Chart1, LV_CHART_TYPE_LINE);
    lv_chart_set_axis_tick(ui_Chart1, LV_CHART_AXIS_PRIMARY_X, 10, 5, 5, 2, true, 50);
    lv_chart_set_axis_tick(ui_Chart1, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 5, 2, true, 50);
    lv_chart_set_axis_tick(ui_Chart1, LV_CHART_AXIS_SECONDARY_Y, 10, 5, 5, 2, true, 25);
}

and in your code

void lv_example_chart_1(void)
{
    /*Add two data series*/
    lv_chart_series_t * ser1 = lv_chart_add_series(ui_Chart1, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_PRIMARY_Y);
    lv_chart_series_t * ser2 = lv_chart_add_series(ui_Chart1, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_SECONDARY_Y);

    uint32_t i;
    for(i = 0; i < 10; i++) {
        /*Set the next points on 'ser1'*/
        lv_chart_set_next_value(ui_Chart1, ser1, lv_rand(10, 50));

        /*Directly set points on 'ser2'*/
        ser2->y_points[i] = lv_rand(50, 90);
    }

    lv_chart_refresh(ui_Chart1); /*Required after direct set*/
}

ser1 and ser2 you can create global for next access and updates… this is only example

1 Like

In case it helps someone:
this is how I got my Waveshare 4.3 esp32 touch lcd is working, without the need for the TFT_espi library using Arduino IDE.
Charts are working fine.

// Declare a global series pointer
lv_chart_series_t *global_series; 
void lv_setup_TempChart_1(void) {
    // Create a global series
    global_series = lv_chart_add_series(ui_TempChart,  lv_palette_main(LV_PALETTE_YELLOW), LV_CHART_AXIS_PRIMARY_Y); 
    lv_chart_set_update_mode( ui_TempChart, LV_CHART_UPDATE_MODE_SHIFT );
}

void lv_update_TempChart_1(void) {
  // Fill chart data with sine wave data
  float sineOffset = millis() / 1000.0;
  int16_t maxValue = 50;
  //size_t count = lv_chart_get_point_count(ui_TempChart);
  size_t count = 12;
  for (size_t i = 0; i < count; i++) {
      lv_chart_set_value_by_id(ui_TempChart, global_series, i, maxValue * (1 + sin((sineOffset + i) * 0.7)));
  }
  lv_chart_refresh(ui_TempChart); /*Required after direct set*/
}

In setup() {

lv_setup_TempChart_1();

And refresh the series from code with:

lv_update_TempChart_1();
1 Like

An addition to the topic: Even if the series/dataset is not accessible outside the screen-init function, the chart itself is. Unfortunately to do anything with the prepared series/data you need to have the series in the lv_chart_set_ext_y_array(chart,series,array) and similar functions.
Fortunately lv_chart_get_series_next comes to the rescue: if NULL is given as 2nd argument it returns the first series, so an lv_chart_get_series( chart, NULL ) returns a hook to the series to the one made in SquareLine Studio, which you can use afterwards to delete/modify it and its data.
(The other topic contains the same answer albeit shorter: Declare variable ui_chart_x_series_x globally - #2 by kisvegabor )