Go Down

Topic: I2c lcd + delay (Read 312 times) previous topic - next topic

stefunkk

Hi,

I'm trying to make multitasking on ESP8266, I'm using ESP8266Scheduler and LiquidCrystal_I2C. I can see with console that code is executed and multitasking is working. But the values on display refresh with big delay. 

I've managed to find out the reason ... it's delay in other task, after removing it it start to refresh screen ok.

I'm a newbie in microcontrollers, am I doing something wrong? Maybe I just can't run 2 tasks and expect that it will handle dealy and run rest of the code "async".

Erik_Baas

#1
Oct 30, 2020, 12:57 am Last Edit: Oct 30, 2020, 01:00 am by Erik_Baas
am I doing something wrong?
Yes, you're using delay().  ;-) You should only use millis() for timing purposes! Take a good look at File -> Examples -> Digital - > BlinkWithoutDelay (in the IDE) to see how that works.

Delay() is a "blocking call", which means that the Arduino can do nothing else while processing it. Real multitasking is not possible, but by using millis() and/or creating a "State Machine" you can have the Arduino handle more than one task (sort of) at the same time.

alesam

#2
Oct 30, 2020, 01:19 am Last Edit: Oct 30, 2020, 01:20 am by alesam
On ESP delay() yields current time slice to scheduler. If you are using only loop() the delay() behavior is similar  to "regular" arduino since no other threads are running at your app. But if you create an additional thread it will be scheduled when another thread waiting on delay(); 
So it's actually good to use delay() instead of millis in that context.
Don't say "Thank you", just click on 'karma [add]' instead.

alesam

Hi,

I'm trying to make multitasking on ESP8266, I'm using ESP8266Scheduler and LiquidCrystal_I2C. I can see with console that code is executed and multitasking is working. But the values on display refresh with big delay.

I've managed to find out the reason ... it's delay in other task, after removing it it start to refresh screen ok.

I'm a newbie in microcontrollers, am I doing something wrong? Maybe I just can't run 2 tasks and expect that it will handle dealy and run rest of the code "async".
Could you post your code. Preferably a minimal but compliable version exhibiting mentioned problem 
Don't say "Thank you", just click on 'karma [add]' instead.

Paul__B

So it's actually good to use delay() instead of millis in that context.
I think you mean "as good" as using millis() since properly written co-operative multitasking is what the "BlinkWithoutDelay" principle is about.  :smiley-lol: \

stefunkk

Wow, thank you for all the answers! :) 

The code is here: https://github.com/stefunkk/openstill

As I mentioned before I'm using ESP8266Scheduler and delay is from it's base Task class. In the task class delay is implemented like that:

    void delay(unsigned long ms) {
        if (ms) {
            delay_time = millis();
            delay_ms = ms;
        }


        yield();
    }


    void yield() {
        cont_yield(&context);
    }


Maybe I wasn't clear enough, but i believe that task code is executed, becaue if I put Serial.println() next to lcd.println (in SensorTask class), I can see that the console call is executed.

alesam

I think you mean "as good" as using millis() since properly written co-operative multitasking is what the "BlinkWithoutDelay" principle is about.  :smiley-lol: \
Not really. ESP has FreeRTOS with preemptive multitasking under the hood. And if you have  multiple threads running simultaneously it's better to use delay() instead of spinning on millis() 
Don't say "Thank you", just click on 'karma [add]' instead.

Paul__B

The point is that properly written co-operative multitasking code avoids the overhead of the RTOS.  You no more "spin" on millis() than does the RTOS.

alesam

#8
Nov 02, 2020, 08:39 pm Last Edit: Nov 02, 2020, 08:39 pm by alesam
The point is that properly written co-operative multitasking code avoids the overhead of the RTOS.  You no more "spin" on millis() than does the RTOS.
Once again - if you have only one thread using millis() is a good solution. If you have a multiple threads using delay() (ie yield)  instead of millis() will give more CPU time to other threads.
Don't say "Thank you", just click on 'karma [add]' instead.

Paul__B

OK, that is true enough.  My point was that using an RTOS in order to divide it into multiple threads will be less efficient - unless of course, you have a processor which provides multiple cores.

stefunkk

So ... for future readers ... the problem was ... me :D 

I've set unused SSR pin to D2, to which also I2C lcd was connected. I've spent like 30h to find an issue. 

Thanks everyone for help :) 

Go Up