Pages: 1 2 [3] 4 5 ... 8   Go Down
Author Topic: A fast PCD8544 library (Nokia 5110)  (Read 21840 times)
0 Members and 2 Guests are viewing this topic.
Israel
Offline Offline
Sr. Member
****
Karma: 5
Posts: 282
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

These numbers are for the FrameBuffered version.
Here's what I get with the non-FB version:

The time it clear the screen is: 1980
The time it took to print 84 chars is: 2628
The time it took to draw a 25x3 (25x18) bitmap is: 276


Current FB version:

The time it clear the screen is: 1708
The time it took draw a rect and 3 lines: 1960
The time it took to print 84 chars is: 2316
The time it took to draw a 25x3 (25x18) bitmap is: 1560
The time it took to run setPixel on all 4032 pixels and render it:    18252
Logged


NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here my 5 cents, if anybody interested:

As different displays required different contrast settings, it is also preferable to have contrast settings available to sketch, I did mod library to have it:


Added to header file declaration of public function
Code:
void contrast(uint8_t cnt);// argument range 0 to 15
[Added to CPP files, function
Code:
void PCD8544_SPI::contrast(uint8_t cnt)
{
this->writeLcd(LCD_COMMAND, 0x21); //Tell LCD that extended commands follow
cnt = map(cnt, 0, 15, 0xB0, 0xBF); // full range  = 0x80, 0xFF
    this->writeLcd(LCD_COMMAND, cnt); //Set LCD Vop (Contrast)
this->writeLcd(LCD_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
this->writeLcd(LCD_COMMAND, 0x0C); //Set display control, normal mode. 0x0D for inverse

}
    Logged

    Global Moderator
    Netherlands
    Offline Offline
    Shannon Member
    *****
    Karma: 217
    Posts: 13718
    In theory there is no difference between theory and practice, however in practice there are many...
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    NIce addition SuperLava,

    one change - see code

    Code:
    void PCD8544_SPI::contrast(uint8_t cnt)
    {
    this->writeLcd(LCD_COMMAND, 0x21);          //Tell LCD that extended commands follow
            this->writeLcd(LCD_COMMAND, 0XB0 + cnt);  //Set LCD Vop (Contrast)
    this->writeLcd(LCD_COMMAND, 0x20);          //We must send 0x20 before modifying the display control mode
    this->writeLcd(LCD_COMMAND, 0x0C);          //Set display control, normal mode. 0x0D for inverse
    }
    Logged

    Rob Tillaart

    Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
    (Please do not PM for private consultancy)

    Israel
    Offline Offline
    Sr. Member
    ****
    Karma: 5
    Posts: 282
    View Profile
    WWW
     Bigger Bigger  Smaller Smaller  Reset Reset

    The issue with getting the contrast right is that you may also have to play around with the bias and temp coefficient.
    I need to open up the datasheet and see whether this->writeLcd(LCD_COMMAND, 0x0C); is actually needed after the changes.
    Logged


    NYC
    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 21
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    For this display/controller there is no actual CONTRAST function, but in all references I was able to find on the Web, changing of this register used for contrast adjustment. It will change some ref voltage and recalling from data sheet (I read it few weeks ago) thee are limitations to range of these values, they can damage display/controller. The range I did map to appeared to be safe under all conditions and from my experiments it did cover quite a variety of samples, always from very pale to all dark (I've tried 5 displays from different lots), so I assume this range is very sufficient. My values are from 4 to 12. Now, reading again http://arduino.cc/en/Reference/map apparently MAP  still not safe and constrain() must be added to avoid dangerous range of values. Well, unless you are certain that bad argument will never make it to this function.

    Code:
            this->writeLcd(LCD_COMMAND, 0XB0 + cnt);  //Set LCD Vop (Contrast)

    If more people using it - let's make it safe. Right?

    Temperature coefficient:

    Thought to play with it. But in my application it is used as home networked thermostat. By definition, unlike original cellphone application, my project should see very minor changes in temperature and, in addition, I assume default coefficient probably close enough. I don't see problem with it yet, so I don't think it have to be resolved. If each display to get it's own settings - testing it would be difficult without enviromental chamber and messing with it might do more harm. But once again, as this library get more traction, for the rest out there, it might worth to look at.

    Good thing about these functions - they are for setup only and do not affect speed of this nice library.  smiley
    Logged

    Israel
    Offline Offline
    Sr. Member
    ****
    Karma: 5
    Posts: 282
    View Profile
    WWW
     Bigger Bigger  Smaller Smaller  Reset Reset

    I have posted version 1.2, with the bug fixes and optimizations pointed out yesterday.

    @ SuperLAVA
    There is a datasheet here: http://st4.divshare.com/launch.php?f=19490578&s=db2
    Read from page 14.
    Your code for setting the 'contrast', which is the Vop settings should be as follows:

    Code:
    // Valid values are 0x00 - 0x7F.
    void PCD8544_SPI::contrast(uint8_t cnt)
    {
    this->writeLcd(LCD_COMMAND, 0x21);          //Tell LCD that extended commands follow
    this->writeLcd(LCD_COMMAND, 0X80 | cnt);  //Set LCD Vop (Contrast)
    }
    « Last Edit: September 15, 2013, 07:29:36 am by TheCoolest » Logged


    Global Moderator
    Netherlands
    Offline Offline
    Shannon Member
    *****
    Karma: 217
    Posts: 13718
    In theory there is no difference between theory and practice, however in practice there are many...
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    Quote
    If more people using it - let's make it safe. Right?
    You're right, but that should then be done for all functions including constructor.

    The code TheCoolest posted is robust for all values of cnt even above 0x7F - although 0x80 has the same effect as 0x00 etc
    by dividing cnt by 2 it becomes (more) natural imho

    Code:
    void PCD8544_SPI::contrast(uint8_t cnt)
    {
            cnt = cnt/2;
    this->writeLcd(LCD_COMMAND, 0x21);          //Tell LCD that extended commands follow
    this->writeLcd(LCD_COMMAND, 0X80 | cnt);  //Set LCD Vop (Contrast)
    }

    @TheCoolest,
    Time to add a new youtube?
    Logged

    Rob Tillaart

    Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
    (Please do not PM for private consultancy)

    Israel
    Offline Offline
    Sr. Member
    ****
    Karma: 5
    Posts: 282
    View Profile
    WWW
     Bigger Bigger  Smaller Smaller  Reset Reset

    I don't think that dividing by 2 is really necessary. I haven't really looked at libraries for this display, so I'm not sure whether adjusting Vop, bias and temp coefficient is supported by them or not. The actual Vop data is 7 bits long, therefore 0x00 - 0x7F. But you can still make a call such as lcd.contrast(0xB0); and it will work just fine, making the call with 0x30 as the value will have the same effect.

    One thing to note, these displays are not the same as the simpler HD44780 LCDs where you control the contrast with a pot or with a PWM signal (with an LPF). The Bias and temperature coefficient settings are important and I had to play with all 3 values to get the display to look right on my LCD. It may be different in your case. Therefore I think that only allowing the user to change the Vop may not be enough, this is why I've added all three values to the optional begin() method.

    @TheCoolest,
    Time to add a new youtube?

    To show the new and improved performance results?
    « Last Edit: September 15, 2013, 10:00:06 am by TheCoolest » Logged


    Global Moderator
    Netherlands
    Offline Offline
    Shannon Member
    *****
    Karma: 217
    Posts: 13718
    In theory there is no difference between theory and practice, however in practice there are many...
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    yes, to show the progress!
    Logged

    Rob Tillaart

    Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
    (Please do not PM for private consultancy)

    Israel
    Offline Offline
    Sr. Member
    ****
    Karma: 5
    Posts: 282
    View Profile
    WWW
     Bigger Bigger  Smaller Smaller  Reset Reset

    Cool, I'll update it a bit later.
    « Last Edit: September 15, 2013, 02:21:56 pm by TheCoolest » Logged


    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 15
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    I am stoked to use this library. smiley No flaws so far. Nice information on pin mapping in the .h file. smiley-kiss Thank you!!!!
    Logged

    NYC
    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 21
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    Quote
    If more people using it - let's make it safe. Right?

    The code TheCoolest posted is robust for all values of cnt even above 0x7F - although 0x80 has the same effect as 0x00 etc


    For "safe" I meant not to exceed Vop (max 8.5V) to avoid damaging displays. With fill range control it is possible to violate requirements and set Vop as high as 10.68V.
    You can't use value of 0x00 as MSB for this control must be set to 1 to control Vop, see "Table 1 Instruction set".
    0xB0 to 0xBF fits nicely into the range to not exceed Vop under any conditions and apparently provided sufficient contrast range for all conditions. That makes it "safe". So looks like "constrain()" is the right way to do it.

     "
    from data sheet - 8.9
    Caution, as V  increases with lower temperatures,
    care must be taken not to set a V  that will exceed the
    maximum of 8.5V when operating at -25 °C.
    "
    Logged

    Israel
    Offline Offline
    Sr. Member
    ****
    Karma: 5
    Posts: 282
    View Profile
    WWW
     Bigger Bigger  Smaller Smaller  Reset Reset

    You may be right, but again as I said all displays are different and what works for one doesn't necessarily mean it will work for another.
    If you want to 'constrain' the values you can simply do cnt &= 0x0F; and then this->writeLcd(LCD_COMMAND, 0XB0 | cnt);.
    Logged


    NYC
    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 21
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    You may be right, but again as I said all displays are different and what works for one doesn't necessarily mean it will work for another.
    If you want to 'constrain' the values you can simply do cnt &= 0x0F; and then this->writeLcd(LCD_COMMAND, 0XB0 | cnt);.

    TheCoolest,

    I support your statements.

    So, will you add contrast control to your next revision?
    Logged

    Israel
    Offline Offline
    Sr. Member
    ****
    Karma: 5
    Posts: 282
    View Profile
    WWW
     Bigger Bigger  Smaller Smaller  Reset Reset

    I'm not convinced that adding this as an extra function is really needed. You really only have to find the right setup once I think.
    Also if you take a look at the datasheet, it says that over 8.5v is dangerous only when your ambient temperature is lower than -25C. Unless you're at the north/south pole, I don't think many will operate such a display in such extreme conditions.
    If you read the datasheet again you'll notice that there's a formula to calculate the optimal Vop for your LCD. My LCD works best with a 1:65 bias, putting that into the formula I came up with 0x3F (0xBF) as the optimal Vop, but after some testing I came to the conclusion that at the current ambient temperature 0x37 or 0x38 works best.
    So the contrast is directly dependent on the Bias System.
    For LCDs using 1:48 the range of 0x30 - 0x3F might be OK, but could potentially be limiting because 0x30 could still be too high.
    Logged


    Pages: 1 2 [3] 4 5 ... 8   Go Up
    Jump to: