Go Down

Topic: New LiquidCrystal library - LCD library (Read 26 times) previous topic - next topic

floresta

Quote
Maybe he will chime in.

Ding-Dong

I think John took care of all this in LiquidCrystal440. 

This will handle most displays and should be the default:
00
40
14
54

This is for the 16x4:
00
40
10
50

(all are in hex)


Don

fm

Hi Don, thanks for ringing in, I will make good note to have that in the code for next release.
   

fm

Release 1.2.0 of the New LiquidCrystal library is available for download.

This version has very nice features added:
- substantial performance improvements for the Shiftregister class and the 4BIT mode has been polished.
- configuration and backlight control through the library.
- support for a wide range on shift register LCDs, currently completing a 1 wire SR mode.
- new methods to control the backlight
- new methods to move the cursor left and right.
- mayor library refactoring which makes it very easy to add support for other HW LCD controllers.

You can download version 1.2.0 from: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

Benchmarks

Execution time

               LiquidCrystal    4BIT        ShiftRegister    ShiftRegister SR_LCD3     I2C
benchmark1      11055 us         2966 us     3132 us          5355 us                   47809 us
benchmark2      125770 us        34660 us    34982 us         60446 us                  541634 us
benchmark3      13660 us         3616 us     3824 us          6564 us                   59071 us
benchmark4      13643 us         3597 us     3804 us          6544 us                   59051 us

Average LCD write operation time

               LiquidCrystal      4BIT        ShiftRegister     ShiftRegister SR_LCD3     I2C
write op.       325 us             87 us       91 us             156 us                    1406 us

Performance ratio vs LiquidCrystal library

               LiquidCrystal      4BIT        ShiftRegister     ShiftRegister SR_LCD3     I2C
Performance     1                  3.72        3.57              2.08                      0,23
   

bperrybap

A few things that need updating and couple of suggestions for enhancements/improvements.



Needed updates:
------------------------
You can't get away with not masking interrupts during
fio_digitalWrite_xxx() routines.

You run the risk of corrupting registers by doing this.
If the user is using other bits/pins in the port for other things and touch the port bits
during their ISRs then the lcd library will corrupt their port bits.




Other Suggestions:
--------------------------

I wouldn't use LOW in shiftOut1() in this if statement:
Code: [Select]
// assume that pin is HIGH (smokin' pot all day... :) - requires initialization
if(LOW==!!(value & (1 << i)))

This assumes LOW is 0.
This is a case where 0/1 or zero/non-zero really is needed.

- Bit ordering in shiftout()
I'd eliminate the bit ordering support in the fio_shiftout() routine.
The output bits of the SR are defined based on a bit ordering
so there should not be a need to support shifting
either direction. I'd pick a direction and only support that one way.
(just like in the fio_shiftOut1() routine)

- reduced interrupt mask time in shiftOut1()
The critical times that need interrupt masking are during
fio_digitalWrite_xxx() calls (to prevent port bit corruptions) and during the timing for the 0 and 1 bit clocking
(to ensure proper 1 to 0 discharge timing).
There is no need to mask interrupts during the 0 to 1 recharge time or during
either delay during the latch cycle. Those delays can be any time as long as they
are at least as long as the requested delay.

The current routine will block interrupts for close to 1ms which IMO is too long.
(worst case is sending a 0 byte)
What you want to do is mask interrupts when you set the clock/data bit and
when you time the 1 to 0 discharge time but then unmask it after you turn the bit back to 1
during the recharge time.

Here is what I'm talking about for shiftOut1()
(untested, but this is pretty much the same code I'm using in my 1 wire lcd code)

Code: [Select]
void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value, boolean noLatch)
{
        /*
         * this function are based on Shif1 protocol developed by Roman Black (http://www.romanblack.com/shift1.htm)
         *
         * test sketches:
         *      http://pastebin.com/raw.php?i=2hnC9v2Z
         *      http://pastebin.com/raw.php?i=bGg4DhXQ
         *      http://pastebin.com/raw.php?i=tg1ZFiM5
         *    http://pastebin.com/raw.php?i=93ExPDD3 - cascading
         * tested with:
         *      TPIC6595N - seems to work fine (circuit: http://www.3guys1laser.com/
         *                   arduino-one-wire-shift-register-prototype)
         *      7HC595N
         */

        // Track interrupt state for later
        uint8_t oldSREG;
        oldSREG = SREG;

        // iterate but ignore last bit (is is set when latch is done)
        for(int8_t i = 7; i>0; --i)
        {

                // assume that pin is HIGH (smokin' pot all day... :) - requires initialization
                if(value & _BV(i))
                {
                        // HIGH = 1 Bit
                        cli();
                        fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
                        fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH); // clock in bit, no delay needed to clock high bit
                        SREG = oldSREG;
                        delayMicroseconds(15); //hold pin HIGH for at least 15us to recharge
                }
                else
                {
                        // LOW = 0 Bit
                        cli();
                        fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
                        delayMicroseconds(15);                                    // hold pin LOW for 15us to create low bit
                        fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH); // clock in bit
                        SREG = oldSREG;                                           // hold pin HIGH for at least 30us to recharge
                        delayMicroseconds(30);
                }
        }
        if(!noLatch)
        {
                // send last bit (=LOW) and Latch command
                cli();
                fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
                SREG = oldSREG;
                delayMicroseconds(199);                          // Hold pin low for at least 200us to lower latch signal
                cli();
                fio_digitalWrite_HIGH(shift1Register,shift1Bit); // latch all bits to output
                SREG = oldSREG;
                delayMicroseconds(299);                          // Hold high for at least 300us to recharge and leave it that way
        }
}


BTW, there are ways to speed up the 1 wire mode by a factor 5 to 10 which
will make it faster than the 2 wire mode when 2 wire mode uses the standard shiftout()
function.
But it requires a different hardware design and closer attention to the charge/discharge times.
Ideally the charge/discharge delays could be configurable in the constructor to allow different
hardware designs.

--- bill





fm

Bill, thanks for your comments and support. I will pass on the comments which I am sure will be seen on 1.2.1.
   

Go Up