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

2 Likes

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 )

hi guys i tried to add data of a potentiometer between -100 and 100 to the chart of my screen. how can i add im a beginner. please help

"
// This file was generated by SquareLine Studio
// SquareLine Studio version: SquareLine Studio 1.4.0
// LVGL version: 8.3.6
// Project name: SquareLine_Project

#include “ui.h”

void ui_Screen2_screen_init(void)
{
ui_Screen2 = lv_obj_create(NULL);
lv_obj_clear_flag(ui_Screen2, LV_OBJ_FLAG_SCROLLABLE); /// Flags
lv_obj_set_style_bg_color(ui_Screen2, lv_color_hex(0x267AB0), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui_Screen2, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

ui_Label1 = lv_label_create(ui_Screen2);
lv_obj_set_width(ui_Label1, LV_SIZE_CONTENT);   /// 1
lv_obj_set_height(ui_Label1, LV_SIZE_CONTENT);    /// 1
lv_obj_set_x(ui_Label1, -220);
lv_obj_set_y(ui_Label1, -211);
lv_obj_set_align(ui_Label1, LV_ALIGN_CENTER);
lv_label_set_text(ui_Label1, "Broyeur: Donnees Vibrations...");
lv_obj_set_style_text_font(ui_Label1, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT);

ui_Button2 = lv_btn_create(ui_Screen2);
lv_obj_set_width(ui_Button2, 160);
lv_obj_set_height(ui_Button2, 50);
lv_obj_set_x(ui_Button2, -296);
lv_obj_set_y(ui_Button2, 204);
lv_obj_set_align(ui_Button2, LV_ALIGN_CENTER);
lv_obj_add_flag(ui_Button2, LV_OBJ_FLAG_SCROLL_ON_FOCUS);     /// Flags
lv_obj_clear_flag(ui_Button2, LV_OBJ_FLAG_SCROLLABLE);      /// Flags

ui_Chart1 = lv_chart_create(ui_Screen2);
lv_obj_set_width(ui_Chart1, 729);
lv_obj_set_height(ui_Chart1, 313);
lv_obj_set_x(ui_Chart1, -2);
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_range(ui_Chart1, LV_CHART_AXIS_PRIMARY_Y, -100, 100);
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);



ui_Label2 = lv_label_create(ui_Screen2);
lv_obj_set_width(ui_Label2, LV_SIZE_CONTENT);   /// 1
lv_obj_set_height(ui_Label2, LV_SIZE_CONTENT);    /// 1
lv_obj_set_x(ui_Label2, -300);
lv_obj_set_y(ui_Label2, 204);
lv_obj_set_align(ui_Label2, LV_ALIGN_CENTER);
lv_label_set_text(ui_Label2, "Retourner a l'accueil ");

ui_Label4 = lv_label_create(ui_Screen2);
lv_obj_set_width(ui_Label4, LV_SIZE_CONTENT);   /// 1
lv_obj_set_height(ui_Label4, LV_SIZE_CONTENT);    /// 1
lv_obj_set_x(ui_Label4, 534);
lv_obj_set_y(ui_Label4, 119);
lv_obj_set_align(ui_Label4, LV_ALIGN_CENTER);

lv_obj_add_event_cb(ui_Button2, ui_event_Button2, LV_EVENT_ALL, NULL);

}

You can use something like ui_Chart1series = lv_chart_get_series( chart, NULL ) mentioned above and simply modify the array content (that you get with something like lv_chart_get_y_array(ui_Chart1,ui_Chart1series) carefully not to exceed ranges), or assign a new array with something like lv_chart_set_ext_y_array(ui_Chart1,ui_Chart1series,CustomArray). After modifying the array content and chart properties, a refresh of it is advised (with something like lv_chart_refresh(ui_Chart1)).

1 Like

Alguno de ustedes me podría ayudar con un codigo de arduino basico para modificar los valores de mi gráfica mediante un pot

Hola Jordan, nos puedes dar un poco más de información sobre tu proyecto y cuál es exactamente tu problema? No puedes modificar el pot o el chart? Te agradecemos más detalles, screenshots, para poder ayudarte!

Gracias por responder Sofi, me gustaría solo saber cómo puedo declarar mi chart y así mismo que linea de código se utiliza para poder modificar sus valores

Isn’t my answer above a solution for you? That’s the most efficient way to do it IMO (instead of setting chart points with functions one-by-one. Do you prefer a different solution? Sorry, my Spanish knowledge converges to 0, just answer based on Sofi’s translation.

im trying to make a chart myself, i have been playing with it for weeks, ive tried alot of different methods, i seem to slow my display down to the point it crashes, i also seem to have no way to clear the last prior data plots, ive had it working a few times, but it grinds to a halt within 2-20 mins… do i need to clear the data each time, the chart will progress and show realtime changes, but i cant clear the old plots, and i feel like it is just taking in too much data. thanks!
p.s im a total beginner i have very little clue about this im just very eager to learn more on the lvgl stuff

I’ve had no problems with large datasets (even with around max 80000 datapoints refreshed in every second) in charts in the past if I used a big external array and a ring-buffer instead of some kind of shifting. LVGL has this shifting version of the chart by default, but it might need some tests to see how it goes with large data and what settings are needed to limit the stored data. I’d prefer the custom ring-buffer solution which never exceeds a certain datasize, so one has more control over the memory-usage over time.