ATTINY & LCD

i have searched for this topic, without any luck. my question is simple enough. can i use an attiny to drive an LCD character display (using the arduino library) ?

Which Attiny? If you used serial or I2C you probably can. SPI even. The LCD would need a suitable interface.

Which LCD do you have in mind?

i have both tiny 85's and tiny 85v's. but heck, to get it working with an LCD i'll get whatever i need to.
as far as the LCD goes, i would like to use a NEWHAVEN 12x2 (NHD-0212WH-ATMI-JT#). i exchanged emails with them today, and they said that it should work with an HD44780 compatible driver (library i guess). but again, to get it working, i will get what is necessary.
i would like to use 2 pins on the tiny as analog sense pins (from a pot as v. divider).

Hi,

The HD44780 controller will need 6 or 7 pins which the ATTiny85 doesn't have available (actually at a pinch you might get away with the 6 using the reset for one and hard wiring the RW pin to GND, but that will leave you with no legs spare for your other 2 sensor pins). If you had an I2C backpack for it you might be able to use the TinyWireM libary to interface it that way. The backpacks are available on eBay for under $10 postage paid, but you'll probably find a version of that LCD display with the I2C interface on it for a combined cheaper price.

Or...choose an ATTiny with more legs :slight_smile:

Cheers ! Geoff

Example I2C/SPI character LCD backpack:

($10).

thanks for the good tips fellas. i have since been reading, both on adafruit and newhaven about I2C LCD displays.
with the adafruit version in mind, do i understand correctly that the LCD plugs into the backpack, and that only 2 wires (plus vdd & grd) connect the backpack to the m.c. ?
if so, will an attiny (8 pin) do the trick and allow me to output text to the LCD ?

pratto:
do i understand correctly that the LCD plugs into the backpack, and that only 2 wires (plus vdd & grd) connect the backpack to the m.c. ? if so, will an attiny (8 pin) do the trick and allow me to output text to the LCD ?

Yes for how it's connected, though you will need a pair of 4k7 pull-up resistors on the two communications lines (read about I2C and you'll find out what that is about). I've not actually tried what you're attempting but it looks feasible.

The TinyWireM library will provide the I2C master functionality for you - I have the required bits here so tonight I'll run up a sketch and see what headaches emerge - will report back here.

Cheers ! Geoff

Edit: it must be possible - there's even a library modified to run the LCD on ATtiny85 :slight_smile: here (link from this playground article).

pratto,
It is no problem.
You can drive it with only 2 pins including backlight on/off control.
It will take some additional external hardware : a shift register a resistor, a diode,
and a transistor another resistor and a cap, if you want backlight control.
but it is cheap since shift registers cost about 20 cents and resistors, diodes
and caps are about 1 cent.

Go get this library: https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
You will want to use the LiquidCrystal_SR2W interface.
(I'm the author of the SR2W code)
If you look at the file LiquidCrystal_SR2W.h it has a wiring diagram with parts.

The SR2W code will drive a hd44780 display faster than the stock LiduidCrystal can
even though the SR2W code is using a shift register and the stock LiduidCrystal code is
using 4 bit mode.

Below is a more recent set of diagrams that are not yet available in the release:

// Wiring for a 74LS164
// ---------------------
//                          4.7k
//              +--------[ Resistor ]--------+---(LCD Enable)
//              |                            |
//              |          74LS164    (VCC)  |
//              |        +----u----+    |   _V_ diode 1N4148
// (data pin)---+---+--1-|A     VCC|-14-+    |
//                  |    |         |         |
//                  +--2-|B      Q7|-13------+
//                     3-|Q0     Q6|-12--(LCD D7)
// (BL circuit)--------4-|Q1     Q5|-11--(LCD D6)
// (LCD RS)------------5-|Q2     Q4|-10--(LCD D5)
// (LCD D4)------------6-|Q3    /MR|--9--(VCC)
//                   +-7-|GND    CP|--8--(clock pin)
//                   |   +---------+ 
//                   |      0.1uf
//                 (gnd)-----||----(vcc)
// 
// ---------------------------------------------------------------------------
//
// Wiring for a 4094
//-------------------
// 
// NOTE: pin 1 is not connected to pin 2
// 
//                          4.7k
//                 +----[ Resistor ]----------------+---(LCD Enable)
//                 |                                |
//                 |      74HC4094                  |
// (data pin)------+       HEF4094    (VCC)         |
//                 |     +----u----+    |           |
// (clock pin)+----|---1-|STR   VCC|-16-+           |
//            |    |     |         |    |           |
//            |    +---2-|D      OE|-15-+          _V_ diode 1N4148
//            |          |         |                |
//            +--------3-|CP    QP4|-14--(LCD D5)   |
//                     4-|QP0   QP5|-13--(LCD D6)   |
// (BL circuit)--------5-|QP1   QP6|-12--(LCD D7)   |
// (LCD RS)------------6-|QP2   QP7|-11-------------+
// (LCD D4)------------7-|QP3   QS2|-10
//                   +-8-|GND   QS1|--9
//                   |   +---------+
//                   |      0.1uf
//                 (gnd)-----||----(vcc)
// 
// 
// ---------------------------------------------------------------------------
// 
// Wiring for a 74HC595
// --------------------
// NOTE: the 74HC595 is a latching shift register. In order to get it to operate
// in a "non latching" mode, RCLK and SCLK are tied together. The side effect of this
// is that the latched output is one clock behind behind the internal shift register bits.
// To compensate for this the wiring is offset by one bit position lower.
// For example, while the backlight is hooked to Q0 it is still using bit 1 of
// of the shift register because the outputs are 1 clock behind the real internal shift
// register.
// 
//                         74HC595    (VCC)
//                       +----u----+    |  +-----------------------(BL circuit)
// (LCD RS)------------1-|Q1    VCC|-16-+  |  +--------------------(data pin)
// (LCD D4)------------2-|Q2     Q0|-15----+  |      4.7k
// (LCD D5)------------3-|Q3    SER|-14-------+---[ Resistor ]--+--(LCD Enable)
// (LCD D6)------------4-|Q4    /OE|-13--(gnd)                  |
// (LCD D7)------------5-|Q5   RCLK|-12-------+                 |
//                       |         |          |                 |
//              +------6-|Q6   SCLK|-11-------+--(clock pin)    |
//              |      7-|Q7    /MR|-10--(VCC)                  |
//              |    +-8-|GND   Q6'|--9                         |
//              |    |   +---------+                    diode  _V_ 1N4148
//              |    |      0.1uf                               |
//              |  (gnd)-----||----(vcc)                        |
//              +-----------------------------------------------+
// 
//
// Backlight Control circuit
// -------------------------
// Because the shift resiter is not latching the outputs, the backlight circuitry
// will "see" the output bits as they are shifted into the shift register which
// can cause the backlight to flicker rather than remain constantly on/off.
// The circuit below slows down the transitions to the transistor to remove
// the visible flicker. When the BL input is HIGH the LCD backlight will turn on.
//
//                (value depends on LCD, 100ohm is usually safe)
// (LCD BL anode)---[ resistor ]---(vcc)
//
// (LCD BL cathode)-------------------------------+
//                                                |
//                                                D
//                                                |
// (BL input)----[ 4.7k Resistor ]----+-------G-|-<  (2N7000 FET)
//                                    |           |
//                          (0.1uf)   =           S
//                                    |           |
//                                  (gnd)        (gnd)

BTW, with a couple of more caps and resistors, and some fancy, very timing precise code,
it is even possible to use the same shift register and drive it with only 1 wire/pin!

--- bill

some fancy, very timing precise code,

I don't think they are fancy at all - you can take a regular driver and change it quickly for this purpose.

Timing sensitive? yes.

dhenry:

some fancy, very timing precise code,

I don't think they are fancy at all - you can take a regular driver and change it quickly for this purpose.

Timing sensitive? yes.

Fancy... perhaps not. So, Ok, I'll give you that.
But you definitely can't take a "regular driver" and change it quickly for this.
Doing a 1 wire interface that gets good performance using a cheap shift register
requires carefully designing a pair of RC networks for the hw,
doing port i/o, and using cycle accurate timing delays.
Port i/o and cycle accurate timing delays are things
that are not offered by Arduino or the AVR libC that currently ships with the Arduino s/w.

The times I'm dealing with are sub 5us, which is shorter than the time
for a single digitalWrite() and requires higher delay resolution than the standard minimum delays
provided by <util/delay.h>
The beauty of this is that the final implementation
using 1 wire is actually faster than the LiquidCrystal library using 4 bit mode.

--- bill

But you definitely can't take a "regular driver" and change it quickly for this.

Show me a typical 3-wire hc164 solution and I can make limited changes to get to run on 2 wires and then 1wire.

The beauty of this is that the final implementation
using 1 wire is actually faster than the LiquidCrystal library using 4 bit mode.

That will depend on how many wires you want to reduce. The growth in duration is exponential with the number of pins to be reduced, and it is actually quite difficult to implement in applications where other interrupts are going on.

But putting aside LiquidCrystal, I can update a 16-char line on a less than 2ms, using a shift register and on a 1MIPS avr.

dhenry:

But you definitely can't take a "regular driver" and change it quickly for this.

Show me a typical 3-wire hc164 solution and I can make limited changes to get to run on 2 wires and then 1wire.

reduction to 2 wires yes. Reduction to 1 wire, probably not with limited changes or at least not that
quickly, particularly if the code was an Arduino library using digitalWrite().

  • And even then you will need some self adjusting cycle accurate delay routines.
    Keep in mind that I'm talking a "portable" implementation that self adjusts depending on the processor
    and processor speed (AVR and pic32 so far) so it can be used as an "end user" Arduino library.

The beauty of this is that the final implementation
using 1 wire is actually faster than the LiquidCrystal library using 4 bit mode.

That will depend on how many wires you want to reduce. The growth in duration is exponential with the number of pins to be reduced, and it is actually quite difficult to implement in applications where other interrupts are going on.

For connection to the AVR/Arduino, other than the 2 power connections,
I'm talking about 1 wire using 1 AVR pin to control a shift register which controls the LCD.

As far as other interrupts go, except for some limited applications, it shouldn't be an issue.
The code does have to block interrupts during 1 time critical piece of code but that is only for 5us.

But putting aside LiquidCrystal, I can update a 16-char line on a less than 2ms, using a shift register and on a 1MIPS avr.

No doubt that a full custom implementation can get great performance with little resources.
The 1 wire code I'm referring to is a replacement for the Arduino LiquidCrystal library
and fully backward compatible with it from an Arduino sketch perspective.

--- bill

Keep in mind that I'm talking a "portable" implementation that self adjusts depending on the processor
and processor speed (AVR and pic32 so far) so it can be used as an "end user" Arduino library.

It took me about 15 minutes to port liquidcrystal to a 3-wire imlementation, using hc164/hc595.

Going from there to a 2/1-wire implementation would not be difficult, as the changes are limited to one/two routines.

The code does have to block interrupts during 1 time critical piece of code but that is only for 5us.

It can be much longer than that. In a 2-wire implementation, you will need to protect the transmission of a '1' bit - time to perform a test, branching and then flipping pins if necessary.

In a 1-wire implementation, each transmission has to pass through two rc filters' time constants so that you can affect changes on the mosi pin without any impact on the sck / rs pin. It is going to be long.

dhenry:

The code does have to block interrupts during 1 time critical piece of code but that is only for 5us.

It can be much longer than that. In a 2-wire implementation, you will need to protect the transmission of a '1' bit - time to perform a test, branching and then flipping pins if necessary.

In a 1-wire implementation, each transmission has to pass through two rc filters' time constants so that you can affect changes on the mosi pin without any impact on the sck / rs pin. It is going to be long.

Sure it could be longer than 5us but it doesn't have to.
The numbers I'm talking about are for a real working implementation that I have
done which only blocks interrupts for 5us with a 1 wire implementation.
And yes there are two rc filters used for a 1 wire implementation.
And yes there are other delays but those other delays can be interrupted
forever and a day and won't affect operation other than slow it down.

Not sure what you are thinking about with a 2 wire implementation but
a two wire implementation, just like a 3 wire implementation
never has to block interrupts as there are no time critical sections or bits
that have to be protected since there are no rc filters involved when
using 2 or 3 wires to run a shift register.
The processor just sets the pins appropriately and
there are no timing constraints. Faster is better but slower or interrupted
by interrupts doesn't matter. It still works.

Like I said, you might not consider the code for a 1 wire shift register design "fancy",
but it is some very timing precise code that takes a while to design, write, and get it
working correctly and reliably along with the matching hardware design.
Definitely not a 15 minute job, particularly if you want it to work
as an Arduino library on different CPUs like both AVR and pic32 and still be
fully backward compatible with the LiquidCrystal library.

--- bill

hmm, very interesting, and over my head. i was going to give up and just buy a NANO to accomplish reducing the footprint and driving an LCD, but the shift register sounds very interesting.
i have put off learning about them (associated them with counters and adders), but maybe now is the time.

geoff, when you do get a chance to hook it up, i am interested to know what you found.

bill, thanks for posting that. i have begun to study it. but i have the sinking feeling that, after soldering it all together, my product will be bigger than a NANO, tho cheaper.

pratto:
bill, thanks for posting that. i have begun to study it. but i have the sinking feeling that, after soldering it all together, my product will be bigger than a NANO, tho cheaper.

Perhaps, depending on what you use for a proto board.
Here is an example project that uses the same library but an alternate s/w device interface.

It uses LiquidCrystal_SR vs LiquidCrystal_SR2W
Gives you an idea of a real world implementation.

What I'd do instead, is use a strip board but wire up the LCD wires all to one side so it
has all the 16 lcd pins along one edge. That way the board with the LCD can be used as a backpack
and soldered to the LCD.
Then there is only 4 wires going to the AVR/Arduino. (power, gnd, data, clock)
It makes for a nice clean project.

Here is another exmaple that is more of what I was thinking:
While it uses a 3 wire interface instead of a 2 wire interface it shows
what I mean about creating a "backpack":

Even if you don't decide to go down the shift register route,
Here is place where you can get really cheap parts.
http://www.taydaelectronics.com/
Thins like shift registers, proto/strip boards, caps, resistors, diodes, transistors,
one wire temperature sensors, leds, etc...

If you are thinking going down the alternative custom/small pre-made board route.
Take a look at the teensy boards. Teensy USB Development Board
About same price but offers a bit more ram, eeprom, pins, and native USB as well.

--- bill

now that was a helpful comment. i have already spent about an hour looking at your various links and considering your suggestions. it looks as tho it can be made much smaller than the NANO. that's for me.

gracias amigo

Not sure what you are thinking about with a 2 wire implementation but
a two wire implementation, just like a 3 wire implementation
never has to block interrupts as there are no time critical sections or bits
that have to be protected since there are no rc filters involved when
using 2 or 3 wires to run a shift register.

I see the disconnect here.

The 3-wire connection I was talking about uses mosi/rs, sck and enable. Data pins are tied to Q0..7 on the shift register. No resistor / diode. It works with HC164, as well as HC595 - no code changes. The benefit is that 1) it can be driven by a typical spi driver, and 2) it allows 8-bit mode as well as 4-bit mode.

So to reduce that solution down to 2-wire, you have to use a rc filter on the mosi / rs line.

I will post the code in a separate thread.

pratto:
geoff, when you do get a chance to hook it up, i am interested to know what you found.

Hi,

Sorry 'bout the break in comms there.

Well tonight I've set up a test and the results haven't been good at the first pass. For displays I've got 3x I2C character LCDs that I've used:

It appears the two DFRobot products use the very same I2C interface module so this probably is like testing the same product twice...but they were both handy.

Initially I've set up with the hello world test sketch on an Arduino Uno, using the LiquidCrystal_I2C library I already had installed, which was the DFRobot-provided one. It worked as advertised on the two DFR displays. This Uno is a Freetronics Eleven, and I am using ATTINY85-20PU.

I then exited the IDE, installed the TinyWireM library, zipped up the existing LiquidCrystal_I2C library, and installed the modified one that adds ATTiny85 support (without losing existing functionality aparently). Went back into the IDE, uploaded the Hello World sketch to the Uno, but that no longer worked on any display. The top row of characters were lit up as bright blocks but nothing in the low row. Suspecting the Uno support might have been broken I pressed on hoping the ATTiny experience would be better. But it hasn't been.

I won't go into the details, but so far I'm getting the same result on the ATTiny as the Uno. I'm pretty sure since the Uno and ATTiny85 exhibit the same problem, I'm staring at the solution but am just not seeing it. I will continue to tinker and hopefully once I solve the Uno the ATTiny will be resolved too. Will report back here when all's well.

Cheers ! Geoff

Hi,

Just some further notes from this. The DFR modules work perfectly with the library provided on the DFRobot site. However the ATTiny85 compatible library is a modification of this LiquidCrystal_I2C library (V2.0) and the DFRobot displays aren't responding to that at all.

The flickering issue was resolved when I noticed the DFR example files use I2C address 0x27 but the examples that were subsequently overwritten used address 0x20. The correct address results in no dark flickering screen, nor the row of bright blocks, but a solid backlight without text. I've so far not got the DFR displays working with the generic v2 library, nor the ATTiny one (which on closer inspection only appears to have some changed definitions which shouldn't impact the Uno at all, as advertised.

I've yet to get the eBay backpack to get past a bright backlight with no text for all 3 libraries.

This is pointing to me having incompatible displays so I've not been any great assistance at all. I might come back to this tomorrow with fresh eyes - will let you know here if I have a win.

Geoff