Go Down

Topic: display with few free digital pins (Read 2 times) previous topic - next topic

floresta

#15
Mar 17, 2012, 03:16 pm Last Edit: Mar 17, 2012, 11:16 pm by floresta Reason: 1
I agree that an I2C I/O extender is a good way to go.

The advantage of the serial, I2C, SPI, backpack type devices such as the one mentioned on reply #11 is the ease of use.  Someone else has done all the LCD specific programming for you and all you really have to do is send the desired ASCII codes to the backpack and they are displayed on the LCD.  You need some special commands if you want to to clear the screen or position the cursor, but the display of messages is dead simple.

The disadvantage of the serial, I2C, SPI, backpack type devices such as the one mentioned on reply #11 is also the fact that someone else has done all the LCD specific programming.  You have no control whatsoever over that code and in most cases you can't even examine it.  The programmer may or may not have implemented all of the capabilities of the LCD controller and he may or may not have implemented them properly.

With an IC I/O expander you have the responsibility of implementing the LCD specific programming.  This also uses some of the resources of the host controller (the Arduino) but the tradeoff is that you have complete control of the whole process.  You can implement as much of the capability of the LCD controller as you need and you can be sure that it has been done correctly (or you can totally screw it up, but that's another story).

I still can't understand why there is so much emphasis on the use of shift registers for this job.


Don

bperrybap



I still can't understand why there is so much emphasis on the use of shift registers for this job.

Don


I can think of 3 reasons:

1) works the same as the included/standard LiquidCrystal at the API level
To me this is a VERY BIG DEAL.

The shift register implementations (2wire, 3wire, and I2C)
have LiquidCrystal API compatible libraries available.

Why a LiquidCrystal API is a good thing to have:
It is a well understood API with documentation available on the Arduino site.
It also means that from a sketch perspective it doesn't matter
whether what the communications interface is.
Many of the Async Serial Interface boards do not bother to provide
a LiquidCrystal API compatible library.
Which to me is silly since it is trivial to implement one.
They expect you to write your code to their proprietary
message interface rather than use a standardized lcd library API.

While sometimes a proprietary interface can offer some added features,
using the LiquidCrystal API is better for the user as it
does not lock them into the proprietary message interface
and allows the user to easily pick and chose a display and interface and not have
to change any of the code to drive it.
i.e. when using a LiquidCrystal API, you can switch from a LCD shield
to a 2wire/3wire shift register or i2c backpack and your sketch does not change.
(only a 1 line change to the constructor)

Plus for added features like menus, scroll bars, large fonts
there are other 3rd party libraries that sit on top of the standard LiquidCrystal API.
If you have to use a custom message interface, you are locked out of being
able to use those other libraries or will have to modify them to use the custom
message interface.
(It would be easier to write a LiquidCrystal compatible library for the custom message interface)


2) Cost & Simplicity
It is a simple DIY project for many hobbyists.
A simple "2 wire" backpack can be built for about $1USD
using a proto/strip board, a 74HC595, a diode, and 1 resistor, and a couple caps for decoupling
Toss in another resistor, a cap and transistor and you can even
get backlight control.
No other low wire count interface is this easy to make for a DIY project.


3) Speed
While not needed in most cases,
a 2wire or 3wire shift register interface can (depending on the library)
allow LCD updates to be faster than i2C or Asnyc serial.
With highly optimized low level bit twiddling code,
it can even be faster than the 4bit parallel code in the standard LiquidCrystal
library supplied with the IDE.

--- bill

Grumpy_Mike

Quote
works the same as the included/standard LiquidCrystal at the API level

Well so does the I2C option.
In fact in my version I have added some useful extra commands like put in blank spaces from the current position until a given cursor position. That makes menus easier. And a command that prints x number of spaces, to save on memory from defining large strings that just consist of blank spaces.

Quote
No other low wire count interface is this easy to make for a DIY project.

No it is the same level of complexity and cost to have an I2C chip as to have a shift register.

Quote
a 2wire or 3wire shift register interface can (depending on the library)
allow LCD updates to be faster than i2C or Asnyc serial.

No.
The limiting factor is how fast the LCD can respond to the commands. The slightly slower speed of the I2C interface does not actually slow down the rate of update of the LCD. In fact the standard library doesn't read the ready flag from the LCD and so has to insert large delays for some LCD commands where as in practice the display does not need this long to be ready. The LCD clear display can be up to twice as fast by reading the ready flag. The reason why this is not done is to save a pin, a factor that is not important when you dedicate an I2C chip to it. With shift registers you would need input and output registers.

floresta

#18
Mar 17, 2012, 11:31 pm Last Edit: Mar 17, 2012, 11:33 pm by floresta Reason: 1
Bill:  I think we agree completely but something has been misinterpreted.

The device mentioned in reply #11 started all of this.  At first glance it looks like a generic I/O expander but, when you read the datasheet, you will find that it is a backpack device that seems to use a dedicated microcontroller like many of the others.  It has all of the characteristics that I mentioned in my second and third paragraphs.

Your post agrees with just about everything that I mentioned in my fourth paragraph, specifically that when you use some sort of I/O expander instead of a controller programmed by someone else "you have complete control of the whole process", including the use of a standard API.

I wasn't questioning the validity of the use of serial adapters, just look at my first sentence.  What I don't understand is the emphasis on the use of the generic 74HC195 shift register for this purpose.

I think Mike was interpreting things as I did since I agree with all of his statements.


Don


bperrybap


Quote
works the same as the included/standard LiquidCrystal at the API level

Well so does the I2C option.

We are in total agreement. In my original comment:
Quote

The shift register implementations (2wire, 3wire, and I2C)
have LiquidCrystal API compatible libraries available.

I mistyped "shift register" when I meant "serial".
meaning all the 2wire, 3wire and i2c implementations
have Liquidcrystal API libraries available.
Sorry about any confusion/mis-understanding there.



Quote

Quote
No other low wire count interface is this easy to make for a DIY project.

No it is the same level of complexity and cost to have an I2C chip as to have a shift register.

Going to have to disagree here.
While a circuit design using an i2c i/o expander chip is similar in complexity,
a shift register implementation only uses 4 components
for a total component cost (without PCB) of 24 cents
Cost       Part
0.01   4.7k resistor
0.01   1N4148 diode
0.01   0.1uf   cap (bypass cap for 595)
0.01   0.1uf   cap (bypass cap for lcd)
0.20   74HC595
-----------------------
0.24

Add backlight control:

0.01   4.7k resistor
0.01   0.1uf cap
0.08   2N7000 mosfet
0.01   150 ohm resistor (lcd current limiting)
--------------------------------------------------------------------
0.35 (total with backlight control and current limiting)
NOTE: the backlight circuit could be modified to cut 6 cents off the cost if it used a cheaper transistor.

I have this working today and those are the actual QTY 1 pricing prices I paid from Tayda:
http://www.taydaelectronics.com/

I would be very interested to see an i2C implementation for a component
cost of less than 24 cents or less than 35 cents with backlight control.

From a software perspective, the software to run a shift register is substantially
smaller and less complex than the code needed to run an i2C i/o expander.
(especially when you look at all the needed code including the wire library for the i2c implementation)



Don:
You and I are in total agreement. I think something I typed didn't come across
very well. (I think the part of having/using a LiquidCrystal API threw everyone)

This is my guess as to why I think the 74HC595 is popular.
It is cheap (seems to be cheaper than some of the other shift registers - hard to beat 20 cents per chip).
It is easy to find
It is easy to understand and can be debugged with a simple logic probe or even a simple LED (poorman's logic probe).
While there isn't that much to really fail with i2c especially when the hardware is wired up correctly
and there is a working library,
if something does go wrong with I2c, most folks will be out of luck trying to debug it.
Don't get me wrong, I like many of the i2c implementations
and intelligent async serial backpacks, but they typically will cost more than a DIY 595 board.
If you are buying a lcd backpack they are all about $10-20 USD and
the performance of any one of them is good enough for most applications.



Quote

Quote
a 2wire or 3wire shift register interface can (depending on the library)
allow LCD updates to be faster than i2C or Asnyc serial.

No.
The limiting factor is how fast the LCD can respond to the commands. The slightly slower speed of the I2C interface does not actually slow down the rate of update of the LCD. In fact the standard library doesn't read the ready flag from the LCD and so has to insert large delays for some LCD commands where as in practice the display does not need this long to be ready. The LCD clear display can be up to twice as fast by reading the ready flag. The reason why this is not done is to save a pin, a factor that is not important when you dedicate an I2C chip to it. With shift registers you would need input and output registers.


Again, I am going to disagree here.
I have real world experience and math that I believe proves otherwise.

It isn't just about the time the LCD takes to process a command.
The time it takes to transfer the data/cmd to the lcd also matters because the lcd
can't start processing the command for the update until it actually receives the data/cmd.
The transfer time is pure latency overhead that can never be recovered
so it directly impacts how fast the LCD can be updated.
I think your are underestimating the impact of this transfer time especially
since in many cases the transfer time can be longer than the time it takes for the LCD to process
the command/data.


About the polling READY. Sure, polling READY is ideal. But it takes extra hardware to do it
(which is why it usually isn't done)
and for all but a few commands (clear, home) the needed "blind wait" is short (37uS) and
with a good library implementation it can often be hidden under
other code or the i/o transfer time. For example, with 2wire, i2c, and serial interfaces, the 37uS blind wait after
issuing a command or writing data can be eliminated or drastically reduced since it can
occur in parallel with (underneath) the transfer of the next command or data write.
There is no need to do a blind wait of 37uS if it takes longer than that to transfer the next
command/character, yet I see libraries that do this, which clearly shows the authors
don't understand the transfer/latency overheads and protocols involved.


Lets look at something more real.
Say the time of a real API call that the sketch would use:

lcd.write() to send out a character to the display.

Now lets go back and look at some real world transfer times:

A serial interface is often running at 9600 but lets assume 115200 at that rate, each character transmits
at about 87uS and this is in addition to any of the other s/w overhead from lcd.write(), the lcd library, or hardwareSerial code.
For this interface the 37uS blind delay after sending a command or data
is not needed since the serial interface can't send bytes faster than 87uS.
(The actual time for lcd.write() for Async Serial will *always* be longer than 87uS)

i2c using the default 400kbit/sec clock rate and 8 bit addressing is similar.
This is because with an i2c you not only have the overhead of the i2c physical layer protocol overhead
but also the overhead of using an i/o expander which requires a minimum of 2 output register
updates. (1 with E high, and then 1 with E low).
Ignoring start/end i2c overheads you have minimum of 3 bytes (i2c device addr, reg addr, data) to update
the output i/o expander latches.
And it takes two latch cycles to strobe E.
assuming you violate the LCD spec by setting E high at the same time you set the control and data lines.
If you don't violate the LCD spec it takes three latch cycles (E low with control and data lines set, E high, E back low)
So that is a minimum of 6 bytes. (assuming you want to save time by violating the spec)
At 400kbit/sec that is 120us of data bit transfer time.
There is more overhead.
(The actual time for lcd.write() for 400k i2C will *always* be longer than 120uS)

I believe that you can speed up i2c quite a bit but I believe that by default that the Arduino wire library
sets it to 400k/sec.


lcd.write() using an optimized 2wire implementation (not using the Arduino core teams shiftout() function)
can update the LCD in 76uS on AVR and 50us on pic32 Arduino (I have this working today).
And that is everything including strobing E and the needed blind wait.
That is the measured time of the full lcd.write() API call and returning back to the sketch.


For actual LCD commands the ascync serial interface can get slower depending on the async serial lcd backpack
message interface.
Async devices typically accept data as characters so to write a character to the display you simply
send the character.
For commands, some devices use control codes and some and need a escape code to issue a command.
For those devices that use an escape code, the latency doubles (potentially 4x for cursor positioning)
over the character write time since it takes extra bytes to perform the commands.



In the grand scheme of things it doesn't much matter.
All the devices and interface are usually fast enough for the application.

--- bill

Grumpy_Mike

Quote
Again, I am going to disagree here.
I have real world experience and math that I believe proves otherwise.

And so have I and I believe you are wrong.

I don't buy into what you wrote, you are misunderstanding things.

Anyway it is all a bit academic, you go with your solution and I will continue to build stuff with mine.

bperrybap

#21
Mar 18, 2012, 06:56 am Last Edit: Mar 18, 2012, 07:17 am by bperrybap Reason: 1

Quote
Again, I am going to disagree here.
I have real world experience and math that I believe proves otherwise.

And so have I and I believe you are wrong.

I don't buy into what you wrote, you are misunderstanding things.

Anyway it is all a bit academic, you go with your solution and I will continue to build stuff with mine.


Maybe this was misinterpreted:
Quote
No other low wire count interface is this easy to make for a DIY project.

What I meant was:
No other low wire count interface is this easy to use for building a DIY lcd backpack.

Perhaps that threw things in the ditch.
If so, Ignore the rest of this post.
If not......


--- bill





Remember my original comment was that building a DIY 2 wire SR register lcd backpack implementation
is cheaper, simpler, and depending the library, can be faster updating the display
than 115200 baud async serial or i2c in 400k/sec mode when using a LiquidCrystal compatible API.





So here are some facts:
- A 74hc595 Serial chip can be purchased for 20 cents QTY 1 (how much is an i2c i/o expander chip QTY 1?)
- A working 2wire SR lcd backpack can be built for under $1 with QTY 1 prices from tayda including 70 cents for a strip board.
(as low as 42 cents each if you build 4 backpacks from the single 70 cent strip board)

- The time it takes the LCD to process a data write or a simple command is not more than 37us.
- All apl calls but home() and clear() in the LiquidCrystal API use simple/fast commands (< 37 us)
- The LCD cannot start processing data/cmd until it receives the data/cmd on the hd44780 interface.
- The LCD cannot be updated faster than it can receive data/cmd(s) on the hd44780 interface.
- The total time to update the display can not be shorter than either the transfer time or LCD processing time.
- If the transfer time is longer than the LCD processing time, then LCD updates cannot occur faster than the transfer time.
- Transfer time can be "hidden" under the LCD processing time when it is shorter than the processing time.
(This only applies to back to back data/cmd(s))

-It takes 87uS just to transmit a byte at 115200 baud, so the LCD cannot be updated faster than
87uS with asynchronous serial as the interface no matter what is handling the serial to hd44780 conversion
even if all the other overhead is zero, which it isn't.

- When using 4 bit mode, the hd44780 interface cannot be strobed for the next first nibble for a new data/cmd
 until the previous data/command has been fully processed.

- A 2 wire SR interface can send a nibble to the hd44780 interface in 24uS.
- The above 24uS can potentially "hide" under the 37uS processing time of a previous data/cmd.

- a 3wire SR interface can transfer data faster to the hd44780 interface than a 2 wire SR interface.
- a 3wire interface could transfer a full byte to the hd44780 interface in about 15us.
 (when running the hd44780 interface in 8 bit mode vs 4 bit mode)
- The above 15uS can potentially "hide" under the 37uS processing time of a previous data/cmd




I'll further and present a few actual logic analyzer traces in support of the timing numbers.

In the first picture, you can see the time it takes to transmit a byte using asynchronous serial at 115200.
It shows up as 85uS which is within 2% of the calculated 87us theoretical data bit rate.

The rest of the captures are based on capturing 2 back to back data writes
using a HC595 run with two wires with the hd44780 interface in 4bit mode.85
When using two wires on a shift register, it has to be zeroed first then the nibble with
control data can be sent.
You can see the 4 enable strobes (2 enables for each nibble) of the two bytes.
You can also see two clock bursts for each nibble strobe. The first burst is the
zero, followed by the nibble data and control bits.

Here is a brief desription of each capture: (see time between T1 and T2)
- 85.0 uS - Time for a single byte transfer using async serial at 115200 baud
- 24.5 uS - Time for first nibble transfer to hd44780
- 54.0 uS Time for a byte transfer to hd44780
- 125.8 Us Time for 2 back to back data writes
(first write completed and 2nd write was sent to hd44780 interface)

Based on those numbers you can see that back to back data writes could be as fast as
125.8uS/2 or 62.9uS.

The measured 76uS data write xfer time I mentioned before is the measured time
of a single lcd.write() through all the software
(which is why it is higher than the 62.9uS low level SR/hd44780 timing)
It sends the data to the hd44780 interface but the low level code
does not wait for the write to finish as it only needs to wait long enough to ensure
that another immediate data/write will not violate the 37us data/cmd timing.

However, since the small blind wait is enough to ensure that that the transfer time +
the blind wait is 37us, then each lcd.write() will always be the same amount of time.
The reason that the lcd.write() time is not 37uS is that while it
is possible to hide some of overhead like the transfer time it is not possible to hide all
the overhead underneath the data/command processing time, with my current
library.
Note: I'm working on an implementation, where all the overhead not just
the transfer time can potentially be hidden under the 37uS timing so the
back to back time will be 37 uS or the total overhead (transfer + s/w)
whichever is longer.




Grumpy Mike,
If you have a source for less than 20 cent i2c i/o expanders I'd love to get some.

Also, if you have analyzer shots of the hd44780 interface driven by an i2c i/o expander, I'd
love to see the timing to see how an i2c implementation compares to a 2 wire SR
implementation.

If you want, I can even PM you a sketch that will report the byte transfer time in uS on the LCD display
using the lcd.write() api call of the LiquidCrystal API.
(It can run on any LCD interface that uses the LiquidCrystal API)
That timing in itself is quite useful as it indicates the true end to end
data transfer time as seen to the sketch, which is all that really matters when it comes
to updating the LCD display.


--- bill



bperrybap

Just a final follow up.
Here are actual numbers measured using real hardware for different ways
of talking to a hd44780 LCD and updating the LCD display.

Code: [Select]
Interface    ByteXfer    16x2FPS      Ftime
----------------------------------------------
4BIT          338uS        86.92     11.51ms (original Liquid Crystal library)
4BIT           98uS       298.58      3.35ms
SR2W           76uS       388.62      2.57ms
SR_2W          72uS       406.90      2.46ms
SR_3W          61uS       480.03      2.08ms
SR3W          102uS       287.92      3.47ms
I2C           957uS        30.74     32.25ms


ByteXfer is the time it takes to get a character updated to the LCD.
The FPS (frames per second) are the number of times a 16x2 display can be updated per second.
Ftime is the amount of time it takes to fully update a 16x2 display.

updates to the LCD were done using a 16Mhz AVR, using fm's LiquidCrystal replacement
library https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home and the
LCDiSpeed sketch that is included in the examples.

A "frame" udpate is:
set cursor to 0,0
write 16 characters
set cursor to 1,0
write 16 characters.

You can see the times for each interface and can clearly see that
the speed of the interface getting to the hd44780 LCD interface does matter.
It is the limiting factor of how fast the LCD can be updated.
The replacement LiquidCrystal library is about 3.5 times faster than the original
when using 4bit mode and using individual wires as in the OP that started this thread.
You can also see that an i2c interface using a pcf8574 can update a 16x2 display about 30 times
per second while a shift register can update a 16x2 display 400 to 500 times per second
depending on two wire or 3 wire modes.
Is the extra speed needed? maybe not, but clearly a shift register is much faster at
updating the LCD display than i2c.

As far as code size goes. The shift register also uses less code.
The final sketch using i2c was 834 bytes larger than when using
a shift register in 2 wire mode and 858 bytes larger than when
using a shift register in 3 wire mode.

So overall, using a shift register to talk to a hd44780 LCD interface is:

  • Cheaper

  • Faster

  • Uses less code


than using a pcf8574 i2c i/o expander.

--- bill

fm

Just to corroborate Bill's figure, here is a scope capture of a write I2C transaction.
Setup:

  • AVR: 32U4 @ 16MHz

  • I2C expansion ASIC: PCF8574 from NXP, 100KHz max I2C clock


Full transaction, physically takes 924us, additional software overhead for interrupt management routing and time stamping.
   

stafil

pls send me a schematic or link thet i found for SR_3W          61uS       480.03      2.08ms
thx

JD3

#25
Feb 07, 2013, 07:04 pm Last Edit: Feb 07, 2013, 07:06 pm by JD3 Reason: 1
Or forget about all the goofy libraries and programming.
Unified Microsystems ATS-1 shield uses digital pins D0 and D1 which are used for serial communication.

http://www.unifiedmicro.com/ats1-arduino-shield.html

or available on Tindie.com:

https://tindie.com/shops/garysxt/lcd-terminal-shield-for-arduino-model-ats-1/

Just plug it in and don't use ANY open digital pins.
That little black caterpillar you just stepped on will set you back a few bucks....

bperrybap


Or forget about all the goofy libraries and programming.
Unified Microsystems ATS-1 shield uses digital pins D0 and D1 which are used for serial communication.

http://www.unifiedmicro.com/ats1-arduino-shield.html

or available on Tindie.com:

https://tindie.com/shops/garysxt/lcd-terminal-shield-for-arduino-model-ats-1/

Just plug it in and don't use ANY open digital pins.

"Goofy libraries and programming"????? Hm......
I guess your idea of "goofy" and "programming" are different than mine.
I consider a LCD with a LiquidCrystal library to be very attractive and much less work to use than trying
to write sketch code to use a proprietary interface.
When a device has a LiquidCrystal compatible library, all the LiquidCrystal examples and 3rd party code
will "just work" with the devices library.
Yes there may be a slight tweak that has to be done to get the constructor correct but that is a one time thing
and does not affect any of the actual sketch code.

The ats-1 LCD solution uses the hardware serial pins, it is proprietary with no LiquidCrystal compatible library.
So the user will either have to write their own LiquidCrystal compatible library or send proprietary character
sequences to the device to control it.
It also means none of the existing lcd example sketches out there or 3rd party code that uses the LiquidCrystal
library API will work with it and will require a considerable amount of re-programming to get
an existing LiquidCrystal sketche to work with the ats-1.

Intelligent devices with "smart" interfaces are a mixed blessing.
While they often do some things for you like beep a buzzer or light an led,
often they don't implement the full capabilities of the LCD as is the case for this one.
For example, I see no way to use the the LCD "scroll" (pan) modes or the ability to define custom characters.
While many people don't use the scroll/pan modes, many do use custom characters.
The major draw back to intelligent devices is that not only do they tend cost more than the simpler (dumb devices)
but when the device does not implement needed functionality or has an issue, there is typically
no way for the user to correct it or update it.

Just my opinion but I consider that board pretty expensive given its limited functionality, missing capabilities,  and its speed.
At 4800 baud it will take around 40ms to paint a 16x2 screen whereas even i2c can do it in 32ms.
(at 40ms it would be a more than 15x slower than the 2 wire shift register solution)
It doesn't seem to support automatic line wrapping or vertical scrolling - which some other intelligent serial based shields in this price range or lower have
It doesn't support large font text or numbers which other intelligent shields or LCD backpacks support.
It doesn't have the ability to control the contrast from the serial interface like many other intelligent boards have
It doesn't have the ability to control the backlight or backlight brightness from the serial interface like many other intelligent boards have
It runs a slow baud rate and does not seem to have the ability to change it.
It is missing the ability to define custom characters,
It is missing LCD pan/scroll modes.


In terms of LCD support using a ready made backpack, for the money, i2c (PCF8574) based backpacks are a very good value.
They are not as fast as a Shift Register implementation, but can be had for as little as 1/10 the cost of the ATS1,
i2c will be a bit faster than the ATS1 at 4800 baud.
i2c offers more LCD functionality (full LCD functionality), and a LiquidCrystal API compatible library is already available.
Most of the PCF8574 based backpacks out there also support backlight control (on/off).

--- bill


JD3

To Bill - I get that you know what you are talking about.

That said, I wasn't asking for a long winded product review.  I was just giving an option to the original poster.
That little black caterpillar you just stepped on will set you back a few bucks....

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview