LiquidCrystal library no delay()

Is there a similar library available without delay() loops, or do I have to modify it myself?

Thank you!

Hi, and welcome.

I'm not aware of delay() within the LiquidCrystal library. But then again, there's a few of those and i haven't seen all of them. Could you point to your version of the library, and the delay() in it ?

The version is: Arduino, Adafruit v 1.0.5

There are delay loops all over this code…yikes :o

LiquidCrystal.cpp (8.86 KB)

Those delays are needed to comply with the LCD driver data sheet. LCD's are slow devices anyway so it should not be a big problem.

Obviously, a delay is needed, but using the delay function is a bad way to achieve it. That's why I'm trying to see if someone has a different Library.

I am fully aware of how to make the code modifications I was just curious to see if there was already a different library available.

devdo: Obviously, a delay is needed, but using the delay function is a bad way to achieve it. That's why I'm trying to see if someone has a different Library.

What's needed and used(!) in the LiquidCrystali libraryactually is delayMicroseconds). Currently I don't see how you can circumvent that in "blocking" functions which have to finish before returning to caller like: function to initialize contrroller and LCD hareware - function to print characters and execute commands on LCD

Besides of that different conttroller hardware and different LCD hardware ctually need a little bit different timings. Most hardware is a bit timing tolerant, but not much. The timings in Arduino LiquidCrystal library has been choosen well to work with a broad selection of different hardware. If you like to do special optimizsations for special hardware, you are free to do: All Arduino libraries are open source and you are free tro experiment with different timings to (possibly) achieve better performance in some cases with some LCD hareware.

I’ve got my profile set up so the ‘signatures’ are turned off but I believe that MAS3 has a reference to looking at the ‘blink without delay’ example in his. Have you done that?

Don

devdo: Obviously, a delay is needed, but using the delay function is a bad way to achieve it. That's why I'm trying to see if someone has a different Library.

The problem lies in the term "library". To my knowledge, there are no libraries written to support multi-threaded code. You could call that expectation a RTOS, but that is just a little excessive. What you are requesting, is a library with the calls broken down into steps called individually with status returns which will require further processing in the user code. And the "blink without delay()" code requires allocation of at least one static timer variable within the library code, possibly to a greater extent than the present libraries.

You are asking for vastly more sophistication in an API.

devdo: Obviously, a delay is needed, but using the delay function is a bad way to achieve it. That's why I'm trying to see if someone has a different Library.

I am fully aware of how to make the code modifications I was just curious to see if there was already a different library available.

Hey devdo, did you get anywhere with this re-write? Feel like sharing? :D

Actually, Bill Perry has now incorporated this functionality into his new "HD44780" library which you can install directly from the IDE.

devdo: Is there a similar library available without delay() loops, or do I have to modify it myself?

This is no way you can eliminate all of them. For sure not in a simplistic environment like Arduino. It isn't clear to me what you are really wanting/trying to do. The inter instruction time delay not much of a delay anyway so there isn't much time to reclaim even if you could, especially if you consider the time necessary to do a context switch, which, BTW, is not available in the Arduino environment.

If you think you know of a way to eliminate the delays, I'd be very interested in hearing how, as I don't believe it is possible.

Most of the delays you are seeing in the code you posted are for initialization. After that, most (all hd44780 LCD libraries I've ever seen) do a blind fixed time delay after sending the instruction to the LCD to ensure that the LCD will be ready for the next instruction. There are ways to handle it better. But using BUSY is not the answer as using BUSY takes more time than the delays, other than for clear() and home(). In other words just polling BUSY once takes more time than the default instruction delay of around 37 to 38us.

The hd44780 library is smarter with its delays. It does not delay after sending an instruction to the LCD, and will immediately return from the write() function once the LCD has the instruction. It does not wait.timeelay When the next write() comes down, it will only delay if it needs to if the previous instruction has not yet completed.The delay time will vary depending on how much time is needed to allow the previous command to finish. So if you send a single character to the LCD, it returns immediately, if you send back to back characters it will may delay a small amount depending on how fast the characters are sent down to the hd44780 write() function.

This does improve performance quite a bit as the Arduino processor can run in parallel with the LCD executing instructions. However, it does not eliminate delays. It merely eliminates any unnecessary delay time since if characters are sent down faster than the LCD can process them the library will delay to allow the necessary amount of time to allow the previous instruction/command to complete

Keep in mind that the Print class is synchronous, in that if you call print() it calls write() to send out all the characters, one at a time before it returns. So when you call lcd.print() it will block until all the characters have been sent to the display. You can avoid using Print, but you can't change this. This how it works, and how the i/o class libraries under Print work.

--- bill

The point is as I understand it, that you do this using the "Blink without delay" technique that I believe devdo was suggesting and I predicted in #7. (#8 in the new forum numbering system :grin:)

That is to say, you set a static/ global variable to the time you write to the display, and following writes do wait until the specified time has expired.

My comments were aimed at devdo's comments:

devdo: Obviously, a delay is needed, but using the delay function is a bad way to achieve it. That's why I'm trying to see if someone has a different Library.

I am fully aware of how to make the code modifications I was just curious to see if there was already a different library available.

as, to me, it seems to be naive. The delay() function is not always a bad way to achieve delays particularly in a synchronous API interface like what is being talked about. I also don't believe that there is anyway to modify the library code he was talking about or any other LCD code that provides that type of API to totally avoid blocking. A delay is a delay is a delay regardless of the way it is implemented. And in some cores, if you spin too long (like a few ms) you can cause a watchdog, so using delay() can actually be necessary.

In terms of providing a library with a LiquidCrystal or LCD 1.0 API about the best you can do is try to minimize the blocking delay time, which is what the hd44780 library does.

Delays block interrupts. This must be avoided for any serious project that uses interrupts. If for example you are dimming an AC LED light, LCD code will interfere and give really bad flicker. A simple task like updating the display every second causes flicker.

This is avoidable by using non-blocking delays, not the built in blocking delay. The timing will not be quite as accurate, but the advantage is being able to use interrupts again

Waiting for Bill Perry to chime in as since 2019, his “HD44780” library now in the IDE addresses this topic.

I haven’t looked at it, but this claims to be non blocking.

I developed an audio application some time ago and, depending on how I used the LCD display, I had noticeable jitter caused by the display blocking a buffer from filling. I found some work around so didn’t look further into it.

delay() and delayMicroseconds() don’t block interrupts, unless preceded by noInterrupts() or cli() .

It's hard to understand sometimes. They cause disruption to say the least. Not suited for doing much while refreshing LCDs. What I know is a light dimmer project doesn't work with a ~500ms LCD refresh, because of delays. There's just not enough spare CPU time with delays

Can you post the code for this project.? It sounds as if the loop() is being used for critical timing activities which would be better delegated to a hardware timer.

I thought the loop was the only possibility. Yes, near the start of the loop I have time critical code (if ((onMicros - myTime) >= OnTime)). The project is complete, but I know there's better ways to achieve it. It used a zero crossing triac dimmer with a 1602 LCD and an RTC. LDT_AC_rewrite.zip - Google Drive