How to call a function declared in main sketch from ui.c file?

What do you want to achieve?

I want to use the timer I created in ui.c file to execute a function declared in main ino sketch.

What have you tried so far?

I tried to put my function inside the .c file but gives me tons of errors with wire.h library…
I tried to declare the timer in main sketch but the lv_timer_create inside void ui_init(void) does not see it so again, errors… My function reads data from i2c sensor then returns the value in float. Then, I update the lv component every lets say 5 secs with the new value.

Others

  • SquareLine Studio version: 1.1.1
  • Operating system: Windows 10
  • Target hardware:ESP32 with ili9488 touch display

Anyone? I even tried creating timer with esp_timer_get_time() but my initial problem remains… When the sensor is reading (about 900ms) the screen becomes unresponsive. So I realy want to try the lv_timer to see if I get better results and not affecting UI while reading. Please, anyone?? :frowning:

uint64_t PH_DELAY_TIME = 10000000; // 10 sec
uint64_t phDelayStart = 0; // the time the delay started
bool phDelayRunning = false; // true if still waiting for delay to finish

void checkPH() { 
  // check if delay has timed out
  if (phDelayRunning && ((esp_timer_get_time() - phDelayStart) >= PH_DELAY_TIME)) {
    phDelayStart += PH_DELAY_TIME; 
    char phvalue[5];
    sprintf (phvalue, "%f", check_ph());
    String string1 = "pH\n";
    String finalstring = string1 + phvalue;
    lv_label_set_text(ui_Home_Ph_Label, finalstring.c_str());
    lv_arc_set_value(ui_Home_PH_Meter, 5);
  }
}

Not your problem but should your code not be (inside checkPH):

phDelayStart = esp_timer_get_time();

For using LVGL timer does this work for you?

lv_timer_t * timer = lv_timer_create(pollsensor, 10000,  NULL );

void pollsensor(lv_timer_t * timer)
{
    char phvalue[5];

    sprintf (phvalue, "%f", check_ph());
    String string1 = "pH\n";
    String finalstring = string1 + phvalue;
    lv_label_set_text(ui_Home_Ph_Label, finalstring.c_str());
    lv_arc_set_value(ui_Home_PH_Meter, 5);
}

Andy

Thanks alot @AndyFraser Thats what I did, and I placed the code inside the ino file instead of the ui.c file. It seems to work now but I still have the “unresponsive touch” while the i2c is reading the sensor (about 900ms each sensor and I have 4 of them lol thats almost 4 seconds without being able to use the touch). I guess I will have to live with it…

Why is your I2C so slow - even running at the slower speed of 100KHz the transactions should normally only take milliseconds - do you have a datasheet or link to the PH sensor you are using?

Andy

Its a pH sensor from Atlas Scientific. Here is a screenshot of the datasheet where it explains to wait 900ms before reading after sending the read command.

So I am assuming that check_ph sends the start command then waits 9 seconds and reads the result?
You should not do this - what you should do is, send the start command then return 9 seconds later and read the result. Doing something like this:

lv_timer_t * timer = lv_timer_create(pollsensor, 10000,  NULL );
start_ph();

void pollsensor(lv_timer_t * timer)
{
    char phvalue[5];

    sprintf (phvalue, "%f", check_ph());
    String string1 = "pH\n";
    String finalstring = string1 + phvalue;
    lv_label_set_text(ui_Home_Ph_Label, finalstring.c_str());
    lv_arc_set_value(ui_Home_PH_Meter, 5);

   start_ph();
}

So this will start a PH reading in the hardware then 10s later the timer function will be called where you read back the result. You then re-trigger the next reading and 10s later you read it again and so on.

Andy

Actually its 0.9Sec… but I request every 10 seconds.

Good idea!!! Will try that :slight_smile:

@AndyFraser should I set the first reading in a variable in the void setup()?

You could start the reading in setup() i.e. call start_ph() or whatever you call your function.

Andy

@AndyFraser Everything is working like a charm now! Thank a lot for you time and help!!! :pray:

I have another problem now… Of course hahaha
I created buttons to calibrate the probes. How can I use custom functions declared in ino file with buttons? For now, when I set the action to call function with the function name, it creates a ui_events.c file with this code:

// SquareLine LVGL GENERATED FILE
// EDITOR VERSION: SquareLine Studio 1.1.1
// LVGL VERSION: 8.3.3
// PROJECT: SquareLine_Project3

#include "ui.h"

void calibrate_ph(lv_event_t * e)
{
	// Your code here
}

But using Wire.h in a C file like that is a pain in the neck so if I could link this function to a working function in ino file, that would save me LOTS of trouble…

Found the solution!! I just declared the name of my function in the ui.h file like so:

void ph_sensors_calibrate(); 

and then called it in the ui.c file like so:

void ui_event_Home_Calibrate_Btn(lv_event_t * e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    lv_obj_t * target = lv_event_get_target(e);
    if(event_code == LV_EVENT_CLICKED) {
        ph_sensors_calibrate();
    }
}

@AndyFraser Thanks again for all your help!