Málaga, Spain
Offline
Edison Member
Karma: 34
Posts: 2031
|
 |
« Reply #120 on: January 06, 2013, 07:04:47 pm » |
If you look in the project's wiki you will see that the 2 wire SR version of the library is about 4,5 times faster than the stock parallel LiquidCrystal an almos 40 times faster than the I2C versio.
|
|
|
|
|
Logged
|
|
|
|
|
Dallas, TX USA
Offline
Edison Member
Karma: 27
Posts: 1657
|
 |
« Reply #121 on: January 06, 2013, 07:09:15 pm » |
So, a final change to:- LiquidCrystal_I2C lcd(0x27, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // addr, EN, RW, RS, D4, D5, D6, D7, BacklightPin, POLARITY lcd.setBacklightPin(7, NEGATIVE); lcd.setBacklight(1); And.....VOILA! Everything working as it should. tack, Cool. Yep on i2c, and the SR interfaces the constructor values are all output bit numbers. Makes sense if you think about it. Glad it worked. Your i2c board matches mjkdz i2c board that I have. When using the newer constructors that specify the backlight pin/bit and backlight polarity, there is no need for the setBacklightPin(). The constructor sets up everything. There really is no need to ever use setBacklightPin() if you use the full constructor that includes backlight information. This is true for all the interfaces that support backlight control: 4bit, i2c, SR2W, SR3W (SR does not support backlight control) i.e for i2c, all you need is the constructor: LiquidCrystal_I2C lcd(0x27, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // addr, EN, RW, RS, D4, D5, D6, D7, BacklightPin, POLARITY By default, duiring the initialization in begin(), the backlight will be turned on if you set up the constructor with backlight information. After begin() you can use the backlight functions. To turn on/off the backlight: lcd.backlight(); // turn on backlight with full brightness lcd.noBacklight(); // turn off backlight
If you wan to use the setBacklight() function which is for dimming, then use: lcd.setBacklight(brightnessvalue); lcd.setBacklight(BACKLIGHT_ON); // full on lcd.setBacklight(BACKLIGHT_OFF); // full off
A brighnessvalue of 1 will be full on for devices that don't support dimming or when an Arduino pin that does not support dimming is used. The reason to use BACKLIGHT_ON vs 1 to turn on the backlight is that you want to write your lcd code to be portable across other interfaces that support PWM dimming. Using a value of 1 will create a very dim backlight when pwm dimming is supported, whereas BACKLIGHT_ON will be full brightness on all devices/interfaces. --- bill
|
|
|
|
« Last Edit: January 06, 2013, 07:21:57 pm by bperrybap »
|
Logged
|
|
|
|
|
Dallas, TX USA
Offline
Edison Member
Karma: 27
Posts: 1657
|
 |
« Reply #122 on: January 06, 2013, 07:20:06 pm » |
If you look in the project's wiki you will see that the 2 wire SR version of the library is about 4,5 times faster than the stock parallel LiquidCrystal an almos 40 times faster than the I2C versio.
Just don't try to convince GrumpyMike....  Tack, GrumpyMike argued and argued that the display update rate to the LCD was in no way impacted by the interface used to talk to it. He flatly didn't believe our transfer numbers and update rates vs 4bit and i2c. And then for costs, he said i2c was just as effective and the same cost as using a shift register. I showed him how you could build a HC595 based board for $1 USD QTY 1 ordering parts from tayda electronics (20 cent 595s and cheap strip boards) and to show me where I could find 20 cent PCF8574s. He never replied.... To see the update rate, run the LCDiSpeed sketch I wrote. It is included in the examples. You will have to modify the i2c constructor for your i2c board. --- bill
|
|
|
|
|
Logged
|
|
|
|
|
Málaga, Spain
Offline
Edison Member
Karma: 34
Posts: 2031
|
 |
« Reply #123 on: January 06, 2013, 07:29:14 pm » |
I still have to fine tune the 4bit version of the library to use fastIOs. Just a few micro seconds gain to reach the limit of the LCD. Just don't try to convince GrumpyMike... Simple facts, numbers are normally fairly objective. You could argue as much as you like but those figures talk for them selfs.
|
|
|
|
« Last Edit: January 06, 2013, 07:32:59 pm by fm »
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 9
Posts: 356
|
 |
« Reply #124 on: January 06, 2013, 07:38:44 pm » |
tack, Cool. Yep on i2c, and the SR interfaces the constructor values are all output bit numbers. Makes sense if you think about it. Glad it worked. Your i2c board matches mjkdz i2c board that I have.
When using the newer constructors that specify the backlight pin/bit and backlight polarity, there is no need for the setBacklightPin(). The constructor sets up everything.
Yes, it does make perfect sense now. It was just frustrating trying to work it out. LOL. As for the SR vs I2C issue, the cheapest I've managed to find 8674 SMD is about $0.65, wheras a 100 595N cost me $12.00 or $0.12 each. To me, in the UK, that works out about 40p cheaper per board. I also need fewer headers (for my flexible setting address, backlight via I2C/Pin(PWM) and Contrast via Trimmer/Pin(PWM). That all adds up to maybe more than halve the build cost against using 8574 for I2C. If you look in the project's wiki you will see that the 2 wire SR version of the library is about 4,5 times faster than the stock parallel LiquidCrystal an almos 40 times faster than the I2C versio.
Wow, that's some difference. I actually expected it to be slower for some reason. No real basis for that though, other than I guess some intuition that a cheaper method using generic SR would be slower than a specific implementation like I2C, or a parallel interface using a lot more pins. I'll definitely give that a try at some point as I have plenty of 595N's coming. I think I'll be off to design a new 2W SR based backpack. ;-) I guess the only difference is with controlling multiple LCD's. With 2W SR would I need another 2 pins for a an LCD displaying different data? How does the library handle daisy chained SR? Does it, or would it be possible, to support multiple LCD's by writing 16, 24, 32 bits across multiple SR to display the same or different data on each? I'm thinking of this from the way ShiftPWM works. If you actually have 2 SR connected, but specify only 1 then the data gets repeated on the second. Maybe the SR constructor could include a NUM_SR data to effectively specify how many LCD's. I suppose you'd need some kind of reference to each one for lcd.write() etc, such as lcd1.write, lcd2.write like you would if declaring multiple constructors normally.
|
|
|
|
|
Logged
|
|
|
|
|
Dallas, TX USA
Offline
Edison Member
Karma: 27
Posts: 1657
|
 |
« Reply #125 on: January 06, 2013, 08:18:45 pm » |
If you look in the project's wiki you will see that the 2 wire SR version of the library is about 4,5 times faster than the stock parallel LiquidCrystal an almos 40 times faster than the I2C versio.
Wow, that's some difference. I actually expected it to be slower for some reason. No real basis for that though, other than I guess some intuition that a cheaper method using generic SR would be slower than a specific implementation like I2C, or a parallel interface using a lot more pins. There are some things to consider as well. The default i2c clock 100 khz - That is according to the I2C spec. And that is the clock rate that Arduino programs the i2c interface to clock at. That is pretty slow. Some of the newer i2c chips support higher speed and can can clock up to 10mhz. (I bet wiring and pullups/termination becomes much more critical at those speeds) So there is some room there if you use a faster i2c chip and put in an Arduino hack to speed up the i2c bus. (But that might interfere with other slower i2c devices if present). On the parallel mode, it is a bit unfair in that the serial shift register code is using indirect port i/o while not as fast as direct port i/o, it is MUCH faster than using the SLOW digitalWrite() functions in the Arduino core code. Currently the 4bit code is not using the indirect port i/o functions. This would be a small change to the code and would speed up the 4bit code quite a bit. I'll definitely give that a try at some point as I have plenty of 595N's coming. I think I'll be off to design a new 2W SR based backpack. ;-)
I guess the only difference is with controlling multiple LCD's. With 2W SR would I need another 2 pins for a an LCD displaying different data?
How does the library handle daisy chained SR? Does it, or would it be possible, to support multiple LCD's by writing 16, 24, 32 bits across multiple SR to display the same or different data on each? I'm thinking of this from the way ShiftPWM works. If you actually have 2 SR connected, but specify only 1 then the data gets repeated on the second.
Maybe the SR constructor could include a NUM_SR data to effectively specify how many LCD's. I suppose you'd need some kind of reference to each one for lcd.write() etc, such as lcd1.write, lcd2.write like you would if declaring multiple constructors normally.
There are three different SR device layer interfaces. SR - output bits and wiring is hard coded but supports 2 wire or 3 wire mode. Currently no backlight support. SR2W - (I did this this one) output bits and wiring is hard coded for 2 wire mode (clock, data) but supports backlight control and has ASCII wiring diagrams in the header file for using various shift registers and a sample backlight control circuit. Because the output bits/pins are hard-coded and can take advantage of certain optimizations, it is actually faster than the SR3W code. As expected, less flexibility = faster. (byte xfer time of 76us for SR2W vs 102us for SR3W) SR3W - runs with 3 wires (data, clock, latch) and allows configuring output bits to allow any wiring - supports backlight. The obvious down side of SR modes vs i2c is the number of pins. I2c adds no additional pins for additional devices whereas SR modes do. For driving multiple LCDs with the the existing SR code, you can share data and latch pins but not clock pins. So the total numbers of Arduino pins doesn't have to be replicated for each additional LCD. It will be I+(N-1) pins. Where I is the initial number of pins (2 or 3) and N is the total number of displays. So for 4 displays in 2 wire mode it would be 2+(4-1) or 5 pins. --- bill
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 9
Posts: 356
|
 |
« Reply #126 on: January 06, 2013, 09:05:20 pm » |
I'll certainly play with the SR modes as well.
Noted on the number of pins required for multiple LCD's via SR.
Could you not cascade by connecting Q7S of one into DS of the next, with Latch and Clock shared. If you kept track of whih LCD was to be updated the could you not shift in the required number of bits, with unchanged LCD(s) having the SR bit set to state that would cause no change?
Would that not effectively allow you to daisy chain more and more displays for no extra pins? It might have a speed effect if you had many many displays, but how many would seriously affect update speed by causing so many bits to be shifted in?
I'm not conversant with the low level driving of the LCD's, but it just occurs to me that you might control LCD3, for example, by only changing bits 8-15. With bits 0-7 and 16-31 in a 'neutral' state then LCD's 1, 2 & 3 wouldn't be driven by their SR.
When we you want to drive one display you have to do a full write across all SR but the bits for the others are just set to cause no change?
|
|
|
|
|
Logged
|
|
|
|
|
Dallas, TX USA
Offline
Edison Member
Karma: 27
Posts: 1657
|
 |
« Reply #127 on: January 06, 2013, 09:43:19 pm » |
Many things are theoretically possible. The issue with cascading the shift registers is that the low level library functions would somehow have to know about this. The current model is that each lcd object is separate and the configuration data for each lcd device is contained within its object. None of the lcd objects know about each other.
The challenge is that you can't really change the other outputs (at least not the backlight output) when updating any given lcds outputs. So the code that handles the updating/writing to the SR would somehow have to have knowledge of all the devices attached and a bit of knowledge of their current state.
The general method the LCD is controlled for writes (which is all that is happening here) is that the data and control lines are setup. (d4-d7, RS, RW) and then EN is raised high and then EN is lowered.
The lcd ignores the signals while EN is low.
BTW, I mad a mistake on the sharing of pins above. It should be 2 wire mode: data pins can be shared but not clock. 3 wire mode: data and clock pins can be shared but not latch.
Sharing pins is actually kind of cheating in that multiple devices are told the pins belong to them. Since there is no multitasking you can get away with sharing some of the pins between devices.
--- bill
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 9
Posts: 356
|
 |
« Reply #128 on: January 07, 2013, 06:26:51 pm » |
What If you has a software buffer, 8 bits for each LCD that held the last state it was set to.
In each constructor you have a total_lcds and this_lcd item so that each constructor know how many lcds (buffers 1 to x) there are and what it's own position is. When you write to this LCD, say lcd3, you update buffer 3 and just take the contents of all other buffers and do the full x bit shift out with the buffer data in the correct order, before latching for transfer to outputs.
I guess that there is a sequence of events that occurs, so all other LCD buffers would basically need to obtain data that doesn't alter their respective LCD state, such as setting the RW line to read, or not setting Enable like, for example, while the sequence is carried out with buffer(x) data being shifted to the 'active' LCD.
I'm just think in general terms as a question as to whether the methodology sounds like something achievable.
Being able to get a 2 wire implementation, with daisy chained displays, that is faster than I2C with the same wiring benefits, would be quite an achievement.
|
|
|
|
|
Logged
|
|
|
|
|
Dallas, TX USA
Offline
Edison Member
Karma: 27
Posts: 1657
|
 |
« Reply #129 on: January 07, 2013, 07:03:17 pm » |
Being able to get a 2 wire implementation, with daisy chained displays, that is faster than I2C with the same wiring benefits, would be quite an achievement.
But I2C can be much faster than 100kbit if you use faster i2c chips and bump the clock rate. Another way to communicate for use on an output only device like an LCD backpack would be to use the AVR USART's multi-processor mode. That way you only use 1 pin and can address up to 256 slaves. --- bill
|
|
|
|
|
Logged
|
|
|
|
|
Seattle
Offline
Newbie
Karma: 0
Posts: 45
|
 |
« Reply #130 on: January 08, 2013, 10:24:09 pm » |
I'm using an MJKDZ board I2C SPI LCD serial interface http://www.ebay.com/itm/170926744803?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649for a 20x4 display... The following program works for me: Program: #include <Wire.h> #include <LiquidCrystal_I2C.h>
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // Set the LCD I2C address
// Creat a set of new characters const uint8_t charBitmap[][8] = { { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 }, { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 }, { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 }, { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 }, { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 }, { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 }, { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 }, { 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 } };
void setup() { int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
lcd.begin(20,4); // initialize the lcd
for ( int i = 0; i < charBitmapSize; i++ ) { lcd.createChar ( i, (uint8_t *)charBitmap[i] ); }
lcd.home (); // go home lcd.print("Hello, ARDUINO "); lcd.setCursor ( 0, 1 ); // go to the next line lcd.print (" FORUM - fm "); delay ( 1000 ); }
void loop() { lcd.home (); // Do a little animation by writing to the same location for ( int i = 0; i < 2; i++ ) { for ( int j = 0; j < 16; j++ ) { lcd.print (char(random(7))); } lcd.setCursor ( 0, 1 ); } delay (200); }
The display backlight comes on, which suggests that the I2C is communicating, however I was not able to see anything but the backlighting. The potentiometer is a multiturn one with little resistance or feedback so I thought perhaps it was damaged. Using a multimeter I was able to see it reducing resistance after many turns, and finally I saw an image. So if you're just getting backlighting - try adjusting the contrast even if it looks like it's not changing. FM - thanks for the new library! --creatrope
|
|
|
|
« Last Edit: January 08, 2013, 10:34:18 pm by creatrope »
|
Logged
|
|
|
|
|
Germany
Offline
God Member
Karma: 69
Posts: 840
If you believe something is right, you won't see what's wrong (David Straker).
|
 |
« Reply #131 on: February 13, 2013, 01:06:16 am » |
Hi I just wanted to mention that i have updated the menu und user interface library M2tklib fo support your New LiquidCrystal Library. A beta release of M2klib for New LiquidCrystal can be downloaded from the M2tklib project page http://code.google.com/p/m2tklib/downloads/list. New LiquidCrystal needs to be installed before using M2tklib. All in all, adding support for New LiquidCrystal was really easy and the transition was without any problems. Thank you for the excellent library and the great documentation. Oliver
|
|
|
|
|
Logged
|
|
|
|
|
Málaga, Spain
Offline
Edison Member
Karma: 34
Posts: 2031
|
 |
« Reply #132 on: February 14, 2013, 02:41:44 pm » |
That is a very cool contribution! Nice one.
|
|
|
|
|
Logged
|
|
|
|
|
|