Issues with LVGL and the web editor - "../../lv_conf.h: no such file or directory"

Hi - it seems for some reason I can only create topics in the hardware section, so hopefully a mod will move it to the most appropriate section for me.

I have a display project running nicely on LVGL in the local editor (2.x) and I need to port it to the online editor. LVGL is a crucial library for me. When I try and verify the sketch, I get "../../lv_conf.h: no such file or directory". I've tried uploading the LVGL library as part of my project zip, but it was discarded. I've tried including the library from the online libraries manager, and I get similar results.

In the LVGL hierarchy, the lv_conf.h file sits at the same level as the LVGL directory. Normally to use LVGL you have to go in and edit the config files, and I can't find a way to do this either.

I really need things to work through the online editor - I'm relying on OTA updates for a project.

My board is a RP2040 Connect, and it's Arduino C++ I'm working with.

Is there a way to configure this library file I'm missing, or a idiom I've not seen?

Thanks

I have moved it to the Web Editor category....This is where you wanted it?

Thank you - that definitely seems most appropriate.

1 Like

It is clear that the compiler can't find the file. Have you tried removing the path in the #include directive?

#include <lv_conf.h> or #include "lv_conf.h"

Can you share your sketch?

The problem I think I have is that I can't edit the library file, where the include to lv_conf.h lives. LVGL usually expects to find this file at the same level as the library directory, not in the directory itself. LVGL is there as part of the standard library includes, but it looks like no-ones actually tried it before (from what I can see searching for help before I tried the forum. LVGL itself is a big beast with quite a deep hierarchy as well. I could paste the entire contents of the lv_conf.h into one of my files and include it in my sketch, but it won't affect the issue with the include.

I'm happy to share ... the actual full sketch is substantial now, but here's the includes, etc. at the beginning.

// lvgl - Version: 8.3.6
#include <lvgl.h>

#include <TFT_eSPI.h>
#include <ui.h>
#include "globals.h"
#include "pitches.h"
#include "myEvents.h"
#include <TouchScreen.h>
#include "pins.h"
#include <WiFiNINA.h>
#include "stringTuple.h"
#include "wifiFunctions.h"
#include "globals.h"
#include "pressureConverter.h"

/*Don't forget to set Sketchbook location in File/Preferencesto the path of your UI project (the parent foder of this INO file)*/

#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(const char *buf) {
  Serial.printf(buf);
  Serial.flush();
}
#endif

byte macAddress[6];
WiFiServer server(80);

static Placeholder<OneWireNg_CurrentPlatform> ow;
DS18B20Manager sensorManager(ow);

/*Change to your screen resolution*/
static const uint16_t screenWidth = 480;
static const uint16_t screenHeight = 320;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * screenHeight / 10];

TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 260);

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

  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  tft.endWrite();

  lv_disp_flush_ready(disp);
}

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

  //bool touched = false;//tft.getTouch( &touchX, &touchY, 600 );
  TSPoint p = ts.getPoint();
  bool touched = !(p.z < MINPRESSURE || p.z > MAXPRESSURE);

  touchX = map(p.y, TS_MAXX, TS_MINX, 0, screenWidth - 1);
  touchY = map(p.x, TS_MINY, TS_MAXY, 0, screenHeight - 1);
  if (!touched) {
    data->state = LV_INDEV_STATE_REL;
  } else {
    data->state = LV_INDEV_STATE_PR;

    /*Set the coordinates*/
    data->point.x = touchX;
    data->point.y = touchY;
  }
}

void setup() {
  debugPrint dp("setup");
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(115200); /* prepare for possible serial debug */
  while (!Serial)
    ;
  if (!sd.begin(chipSelectCard, SD_SCK_MHZ(20))) {

    dp.p("Card failed, or not present");
    cardStatus = false;
    // don't do anything more:
  } else {
    dp.p("SD card initialized.");
    cardStatus = true;
  }

  new (&ow) OneWireNg_CurrentPlatform(OW_PIN, false);
  sensorManager.begin(sd);
  sensorManager.populateFromSD();

  
  sensorManagerPtr = &sensorManager;
#ifdef COMMON_RES
  /*
     * Set common resolution for all sensors.
     * Th, Tl (high/low alarm triggers) are set to 0.
     */
  drv.writeScratchpadAll(0, 0, COMMON_RES);

  /*
     * The configuration above is stored in volatile sensors scratchpad
     * memory and will be lost after power unplug. Therefore store the
     * configuration permanently in sensors EEPROM.
     */
  drv.copyScratchpadAll(PARASITE_POWER_ARG);
#endif

  String LVGL_Arduino = "LVGL Version ";
  LVGL_Arduino += String("V") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

  dp.p(LVGL_Arduino);
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    dp.p("Communication with WiFi module failed!");
    wifiDown = true;
  } else {
    wifiDown = false;
    WiFi.macAddress(macAddress);
    dp.p("Mac Address: ", false);
    printMacAddress(macAddress);

    String fv = WiFi.firmwareVersion();
    if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
      dp.p("Please upgrade the firmware");
    }
  }

  dp.p("Setting up time: RTC ", false);
  Wire.begin();
  if (!rtc.begin()) {
    dp.p("Couldn't find RTC");
  } else {
    dp.p("RTC initialised");
  }


  sensor.begin(Bme280TwoWireAddress::Primary);
  sensor.setSettings(Bme280Settings::indoor());
  auto temperature = String(sensor.getTemperature());
  dp.p("temp: ", temperature);

  if (setupWifi()) {
    delay(100);
    adjustForBST();
    dp.p("NTP: ", false);
    displayNTPTime();
    dp.p("RTC: ", false);
    displayDateTime();

    if (checkDrift()) {
      dp.p("We have clock drift - adjusting ...");
      updateTimeFromNTPtoRTC();
    }
  } else {
    dp.p("can't connect to wifi yet, so not checking drift with NPT");
  }


  lv_init();

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

  tft.begin();        /* TFT init */
  tft.setRotation(3); /* Landscape orientation, flipped */

  lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * screenHeight / 10);

  /*Initialize the display*/
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  /*Change the following line to your display resolution*/
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  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);
}

Hi - I've tried reaching for help to see if I was doing anything wrong, but not getting any real response. I'm trying to use the LVGL library (8.3.6), and I'm getting a "../../lv_conf.h": no such file or directory. I think this is because LVGL puts that file at the same level as the library top directory rather than in this directory. As such, there's no way would it be included in a path. The lvgl file that does this include "lvgl.h" isn't available to me to edit to choose a path to lv_conf.h that I can actually put in my hierarchy.

Is there a way to either edit the lvgl library files to put a more manageable path in, or have some form of PATH variable, or some other solution I can use?

It's pretty important to us to be able to do OTA updates, hence choosing this ecosystem.

I'm editing on Chrome, on MacOs Monterey, and am using RP2040 Connect Microcontrollers. It all builds and works well locally.

Is there a workaround where I can distribute OTA with .uf2 file I create locally?

Thanks

There are two solutions:

  1. Do as LVGL asks and put the file in that location relative to the default library location.

  2. Copy all the library files to their own subdirectories and put it relative to that directory. This is what PlatformIO does.

I've used LVGL with both the desktop IDE and VSCode+PlatformIO. They both work.

I don't see how this would affect OTA updates. You're not building remotely somehow, are you?

I think, herein lies the rub. I have LVGL working perfectly on the desktop, but I need it to build in the online editor so I can use the Arduino Cloud OTA updates.

If there's a way of doing OTA other than this way (for the RP2040 Connect), or an example of a simple build where a simple example complies online, my problem is solved.

In the online editor, it's not possible to put the lv_conf.h file where the library expects it, and it's not possible to edit the header file to find it in a different place, so it can be edited.

Catch-22.

I see. I've never used the online editor so I wasn't aware. Didn't know it provided OTA updates though. That could be useful to me in the future!

I have merged your cross-posts @chosenatrandom.

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting can result in a suspension from the forum.

In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

Hi @chosenatrandom. I'll provide instructions you can follow to use the "lvgl" library in Arduino Create:

  1. Click the following link to open the release page for the latest version of lvgl:
    https://github.com/lvgl/lvgl/releases/latest

  2. Click the "Source code (zip)" link under the "Assets" section of the release page.

  3. Wait for the download to finish.

  4. Unzip the downloaded ZIP file.

  5. Delete the downloaded ZIP file.

  6. Add your lv_conf.h file to the src subfolder of the unzipped folder of the library.
    For anyone reading this later who doesn't already have a lv_conf.h file, you can prepare one by following the instructions here, but disregard the part about putting the file in the libraries folder.

  7. Delete all subfolders from the library folder except the following folders:

    • examples/arduino
    • src

    This step is done because the other folders are completely unnecessary for the purposes of using lvgl as an Arduino library and those unnecessary folders contain many megabytes of files which would use up much of your Arduino Create personal storage allowance if you didn't delete them before importing the library to your account.

  8. Zip the library folder.

  9. Open "Arduino Web Editor" in your browser:
    https://create.arduino.cc/editor

  10. Select "Libraries" from the menu on the left side of the "Arduino Web Editor" window.

  11. Click the upward pointing arrow button ("Import") to the right side of the "LIBRARY MANAGER" button.

  12. If you get a popup about importing your sketchbook, click the "IMPORT" button.

  13. Select the "ZIP" file you created during the previous step.

  14. Click the "Open" button.
    A "Please wait while your file is importing..." dialog will appear that shows the progress of the import.

  15. Wait for "Arduino Web Editor" to display the notification that the library was successfully imported.

  16. Click the "OK" button.

You should now be able to compile your lvgl sketches without getting that error about lv_conf.h.


Please let me know if you have any questions or problems while following those instructions.

1 Like

Thanks - that's really useful for us. I'll give it a try.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.