Serial or parallel LCD

What is more efficient, faster, using fewer instructions (processor cycles)?
I have the problem that when the program send data to the LCD this cause a delay in the processor, some microseconds, but I want to know I using a serial LCD connection can be faster.
Thanks

helipilotraptor:
What is more efficient, faster, using fewer instructions (processor cycles)?
I have the problem that when the program send data to the LCD this cause a delay in the processor, some microseconds, but I want to know I using a serial LCD connection can be faster.
Thanks

Microsecond delays are unavoidable any way you update a display. What is your project's main goal, which requires a real-time system down to microseconds?

If you have a serial LCD running at 115200, then your speed of communication is 11520 bytes/sec. Most serial LCDs can only go up to 38400 though. I2C LCD is faster but you need to run all the overhead together, not just data.

For speed of parallel LCD, here:

Page 25

If you have a spare hardware serial port and you use the Arduino 1.0 beta software (which uses interrupt-driven buffered transmit), then driving a serial LCD via the hardware serial port will use fewer CPU cycles than using the LiquidCrystal library. However, if you are prepared to modify the LiquidCrystal library to not block when it needs to allow time for a command byte to be executed, then a parallel LCD need not use much CPU time either.

Thanks for your answer dc42, although I’m not sure that I understand clearly; what is the Arduino 1.0 beta software, and why will use less cpu cycles. Well, if I need to modify the LCD library I will, only need to know what is needed, I think you are referring that the commands to the LCD can be lower priority that others in the program, is that correct?

Arduino is trying to move to a 1.0 version.
Here is a link to the latest pre-release of that:
http://code.google.com/p/arduino/wiki/Arduino1

1.0 has changed the way the hardware serial ports work. It has pluses and minuses.
It now buffers the serial output data. Which means that it has a memory
buffer to hold the transmitted characters before they are given
to the UART. So instead of having to wait until the UART finishes transmitting
a currently transmitting character, it will only wait for room in the buffer.

The plus side for applications like yours is that if there is room in the buffer
the character is written to the buffer and the library immediately returns without
having to wait for any previous characters to finish transmitting.
The minus side is that this consumes additional memory.
Up to 64 bytes of RAM per UART.

Now if you are really slamming out characters, eventually you can fill the buffer and
then it will wait on room in the buffer to hold the character.
So what the means, is that if you are really slamming out characters, as soon as you fill the buffer,
it will start to work exactly the same as it does with 0022
Because of this it is only useful if you have very small bursts of data to transmit.

--- bill

This serial LCD works at 115200bps and has many complex functions to explore: :wink:

http://www.inmojo.com/store/liudr-arduino-and-physics-gadgets/item/serial-lcd-back-pack---phi-panel/

Because of this it is only useful if you have very small bursts of data to transmit.

Which is really not a problem if you use the LCD to display the type of short messages that it was originally designed for. Things like "Ready", "Toner Out", "Paper Jam", "Garage Fire", "Toast Ready", etc. These things were really not designed as CRT or Teletype replacements where they have to display long messages on multiple lines.

Don

helipilotraptor:
Thanks for your answer dc42, although I’m not sure that I understand clearly; what is the Arduino 1.0 beta software, and why will use less cpu cycles. Well, if I need to modify the LCD library I will, only need to know what is needed, I think you are referring that the commands to the LCD can be lower priority that others in the program, is that correct?

Others have already answered your question about the 1.0 beta software. Regarding the LCD library, it has delay calls in it to avoid sending data to the lcd faster than it can execute the commands. What I had in mind was to have the LCD software work asynchronously, that is, when a large delay is needed, remember what needs to be done and return to the caller. Either the main loop of your sketch or a tick interrupt would need to make a call into the LCD library from time to time to continue where it had left off.

I've heard that if you use the LiquidCrystal440 library with a 7-pin connection (i.e. connect the R/W pin of the LCD back to the Arduino as well as the usual 6 pins), that library blocks for much less time than the standard library. This is because it can tell when the LCD is ready to accept another command, rather than having to delay for long enough to satisfy the worst case.

It may be that you only need to worry about the LCD commands that take the longest, such as the command to clear the display. So implementing an asynchronous lcd.clear() function might be enough for you, depending on what exactly you are trying to achieve. What exactly is the problem you are having or anticipate having with the existing LiquidCrystal library?

Thanks dc42; the software I am working is a RC servo tester, using the Servo.h and LiquidCrystal.h, some of the problems are that when the program work with a potentiometer for setting the position and you move the pot slowly you can see that the servo is moving stepping and no in a linear sweep, if I do not sent display commands this work fine, so I deduct that the display commands are causing a delay in the servo update signal witch as to be each 20ms, also I want to change the update to 10 or 5 ms for test digital servos, and that can make the problem worse.
A solution that I implemented is rewrite the display at a period of 400ms using millis() function; before was updated at each AD conversion cycle. This solution work fine, but I have some ICs PCF8574 that can be used to make a serial interface to the LCD, so that’s the reason I want to know if serial command use less CPU cycles.
Any input will be greatly appreciated, because this is my first application with Arduino and any processor.

It surely will not. With the chip you mentioned, you are just using less pins but you still need to obey the timing of the LCD, only worse since you communicate with one pin instead of 5 pins. You should use a serial LCD backpack that has a real processor on it, not an I2C extender.

My suggest1ons:

  1. When you send data to the LCD, only rewrite the data that changes. For example, if you have some static text and some changing numbers, just rewrite the numbers.

  2. Use the LiquidCrystal440 library and a 7-wire interface to the LCD (I haven't used this myself, but I have heard that this works much more quickly).

  3. If the LCD calls still block for too long, then modify the LiquidCrystal library to be non-blocking.

The quickest communication is to have two parties agree on what to do and only send in changes.

Processor one, hooked up to an LCD, displays a static interface and a spot for dynamic number
Processor two, the arduino, sends only one byte each time you want an update. 0-127 is increment on the dynamic number, 128-255 is decrement on the dynamic number. This way you just send one byte to the serial hardware every update so your time spent is in the microseconds, for updating register. Apparently you will need to program the processor that has the LCD to accept this byte-long message and update LCD accordingly. Any time you use a library on your arduino, dozens lots of microseconds are lost in the code and wait on LCD per data transfer, 37us per 4-bit transfer per the spec sheet, if I understood correctly, plus time for the LCD address increment to work out.

Some LCDs can be driven at high speed using a serial interface. I'm currently using a graphical 128x64 LCD with ST7920 controller chip. Sending a command using SPI at 1MHz takes 24us, which is less than the 72us that the chip takes to execute most commands, according to the data sheet. So serial isn't necessarily slower than parallel, it depends on how fast the LCD can execute commands as well.

@ DC42, not really exact. At the basis, serial IS always slower than parallel, because if you send 8 bits at the same time it is 8 times faster.

However, some interfaces are faster than others, and a parallel (eg. software driven) interface becomes slower than a (faster) serial interface when its (byte) transmission rate is at least 8 times slower. Using 1MHz SPI is better than 115200 (though both serial), and using 16 bit parallel is two times better than 8 bit parallel, if your library supports it. I didn't time my ITDB02 library, but painting the LCD in one color takes seconds, blocking the Arduino, and this has nothing with the parallel/serial question.

BTW, @liudr, a small mistake : "a serial LCD [interface] running at 115200, [bauds doesn't give a] speed of communication is 11520 bytes/sec", but rather about 1100 bytes/sec, because it's a "bit" rate, not byte, and you need to count at least one start and stop bits, and often space between bytes.

I2C is also not really recommended for fast/reliable communication, as ANY device on the bus can hold it down for as long as it wants.

Alternatively, using 2 CPUs like proposed by liudr is an interesting alternative. Using interrupts is more complex, but could also be fun. At least then you can ensure that your servo will be updated exactly x times /second. But that's maybe better left for 32 bits derivatives like Maple or PINGUINO that can handle more interrupts.

tochinet:
BTW, @liudr, a small mistake : "a serial LCD [interface] running at 115200, [bauds doesn't give a] speed of communication is 11520 bytes/sec", but rather about 1100 bytes/sec, because it's a "bit" rate, not byte, and you need to count at least one start and stop bits, and often space between bytes.

I2C is also not really recommended for fast/reliable communication, as ANY device on the bus can hold it down for as long as it wants.

Alternatively, using 2 CPUs like proposed by liudr is an interesting alternative. Using interrupts is more complex, but could also be fun. At least then you can ensure that your servo will be updated exactly x times /second. But that's maybe better left for 32 bits derivatives like Maple or PINGUINO that can handle more interrupts.

One start bit and one stop bit with 8 bit data no parity check so 115200bps=11520Byte/s I don't see where I made any mistake. You should re-read what you wrote and what I wrote. Need new glasses counting the zeros?

What you described is simply a serial port with flow control lines as interrupts. My phi-panels are already doing serial communications but without the interrupts. Arduino has no serial port flow control but can certainly implement that to free the MCU from waiting. It's just making programming more complex for beginners so waiting is fine.

tochinet:
@ DC42, not really exact. At the basis, serial IS always slower than parallel, because if you send 8 bits at the same time it is 8 times faster.

You appear to have missed my point. If sending a command through a parallel interface takes time P and sending it through a serial interface takes time S, then it may well be the case that S > P. However, if the device requires time T between executing consecutive commands, where T > S, it makes little difference whether you use serial or parallel (unless you can usefully use the waiting time), because the speed at which you can update the device is the same in both cases.

dc42:

tochinet:
@ DC42, not really exact. At the basis, serial IS always slower than parallel, because if you send 8 bits at the same time it is 8 times faster.

You appear to have missed my point. If sending a command through a parallel interface takes time P and sending it through a serial interface takes time S, then it may well be the case that S > P. However, if the device requires time T between executing consecutive commands, where T > S, it makes little difference whether you use serial or parallel (unless you can usefully use the waiting time), because the speed at which you can update the device is the same in both cases.

(I assume you meant T is really the time to execute/complete the command
vs an intercommend delay which is nearly zero for these displays)

But it goes one step further. Assume that there is an attempt to update the display every time U interval
and that T2 is the time to execute the full LCD output API function like
lcd.print(“xxx”);
which consists of multiple lcd commands.
so T2 is really N (T+S) or N(T+P)

It is when T2 > U that there are serious issues.
And that is what it sounded like helipilotraptor was bumping into
as it sounded like the original code was attempting to update the display faster
than was possible regardless of whether serial or parallel was used.

helipilotraptor,
There are many ways to solve things like this but the best way proceed is
to look at things from a global perspective. In other look at the system design as whole
vs trying to optimize any single component.
Because just like dc42 said, you can run into issues because the system component you concentrated
on optimizing was not the limiting factor.
For example, even if say S and P are zero, T2 still exists.
In that case T2 becomes N*T
And so you can still have a situation where U < T2 and it won’t work.

Perhaps you have a situation where you can’t ever have the main loop be blocked for NT amount of time.
(U is much larger than N
( S+T) or N*(S+P), say even half second or more,
but you can’t tolerate being blocked for T2 in the main loop)
Now that becomes a real challenge because you now need to figure out how to keep the output
routine from blocking during the full T2 time interval.
In that case, you need to be able have your other code run while the display is off doing its command.

This can be done with an intelligent serial device like say a smart serial backpack. In that
case the main Arduino tosses commands at the backpack and the backpack buffers them and
processes the commands (including waiting for the lcd commands to complete) so the main Arduino
processor is free to keep running.
In that case you don’t wait N*(T+S) you will only block N*S on arduino 022 and will not block at all on Arduino 1.0
(But on arduino 1.0 your loop code will be interrupted as needed to grab the bytes from the buffer)

Another way to do this is the use the RW line and BUSY status on the display so that instead of always blindly waiting
a period of time for each command to complete you send the command and never wait.
But then you also check the display BUSY status to make sure it is ready before you send a command.
This will reduce the wait to the absolute minimum as well as allow other code to run while the command
is being processed by the lcd.
The use of BUSY status will never be as good as using something like an intelligent device that can
que commands because if you a send series of commands (like from something like a lcd.print(“xxx”); )
you may end up having to wait for a few
of them to complete vs letting the other CPU do all that for you.

Now the real issue with trying to use the RW line and the BUSY status, is that the current LiquidCrystal
library simple does not support BUSY status polling. Yep. It can use the RW line but all it does is
ground it and not use it, so using the RW line is a total waste of a pin.

Another thing to consider is that the Current LiquidCrystal library uses very primitive blind
delay techniques that are in some cases overly conservative that insert blind delays
that quite a bit longer than needed so there is quite a bit of room to increase its performance.

Something to really keep in mind, as dc42 said, is that it can be very worthwhile to optimize how you write
to the display.
home() and clear() both currently block for 2 milliseconds!
So for example, it is MUCH faster to goto 0,0 than to home()
clear() also does a “home” so there is no need to home() after a clear().
But if you only need to update a single changing field, than only do that
which can save even more time.
And those are examples of optimizing the system as a whole vs trying
to speed up individual components.

— bill

There's (at least) one more factor to be aware of if you are considering the 'smart serial backpack' option. These backpacks are only as 'smart' as the person who programmed the dedicated processor on the backpack. Many if not most of these are not open source so you know nothing about how well that programmer followed the LCD controller protocol and you have no control over how many of the native commands of that LCD controller have been implemented. Also, there is no uniformity in the commands that you must send to the various controllers that are available.

I'm not saying that none of them are any good, but you have to be aware that they are not all equal.

Don

bperrybap:
(I assume you meant T is really the time to execute/complete the command
vs an intercommend delay which is nearly zero for these displays)

But it goes one step further. Assume that there is an attempt to update the display every time U interval
and that T2 is the time to execute the full LCD output API function like
lcd.print("xxx");
which consists of multiple lcd commands.
so T2 is really N (T+S) or N(T+P)

It isn't necessarily N * (T + S) or N * (T + P), it can be N * T for either interface provided that T is a fixed time you need to allow between commands (i.e. you are not waiting on a busy flag), and the the mcu interface operates in parallel with executing the command. For example, the GLCD I am driving serially is specified as needing 72us to execute each command, and it takes 24us to send a command serially. So I am delaying (72 - 24) = 48us between commands, and the GLCD is quite happy with this. If I were driving it in parallel interface mode instead (which I haven't tried due to shortage of pins), I would expect to have to delay longer than 48us.

floresta:
There’s (at least) one more factor to be aware of if you are considering the ‘smart serial backpack’ option. These backpacks are only as ‘smart’ as the person who programmed the dedicated processor on the backpack. Many if not most of these are not open source so you know nothing about how well that programmer followed the LCD controller protocol and you have no control over how many of the native commands of that LCD controller have been implemented. Also, there is no uniformity in the commands that you must send to the various controllers that are available.

I’m not saying that none of them are any good, but you have to be aware that they are not all equal.

Don

You are right Don. My serial backpack/panel is not yet open source but part of it is using my open source libraries such phi_buttons, phi_prompts, multi-tap code etc and the firmware is 24K of FLASH so thousands of lines of code + several of my libraries + arduino core libraries. So my LCD implementation is arduino’s library. I seriously doubt any other serial backpack can measure up to 10% the complexity of mine. They are all created not equal. Mine speaks standard ANSI escape sequence and ascii commands so it is the only one I know of that speaks a standardized language, which terminals speak (except you can’t change colors or brightness etc.). All others use non-standardized protocols since that’s much easier to implement. I am planning on opening the source and providing more development support but that will happen after this panel gets it recognition as worthy hardware in the community first.

Also watch out for the “Serial I2C” backpacks as they have no processors on board. The arduino does all the heavy lifting.