Pages: 1 2 3 [4] 5 6 ... 8   Go Down
Author Topic: A fast PCD8544 library (Nokia 5110)  (Read 22024 times)
0 Members and 1 Guest are viewing this topic.
NYC
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... it says that over 8.5v is dangerous only when your ambient temperature is lower than -25C.

Well, I'm ESL (maybe it is a good thing as I can better interpret Dutch originated data sheet), but I'm pretty sure that what it says that 8.5V is dangerous at any temperature. What they tried to express is that at -25C voltage boost to compensate for contrast might (more likely) put it over 8.5V, depending on original voltage and compensation curve selected.
Unfortunately Fig.7 only qualitative, no numbers. We can only estimate how much it will affect Vop.

Mux ratio: typical for these kind of displays are 1:48 ( notice that most examples for that exact number). Increasing mux ratio will run it at higher frequency (on most controllers, not sure about this one) and makes it more sensitive to temperature. Depending on application, muxing at different ratios may yield longer life or better performance (faster on/off, higher contrast). All muxed LCDs will have residual DC and eventually will wear, tho good controller will minimize that. Why it is important here? - Contrast will drift over time! More or less but it will. isn't this is why Nokia had option to adjust contrast on these old phones?  Formula can olny put in in ballpark.
So, for projects that expected life span in years - contrast adjustment is desirable.

Need to adjust contrast also depends on application. In my case I'm making a few home thermostats. I certainly can tweak each once separately, but I prefer to have identical firmware and to have personalized settings in EEPROM, available to user. And I also hope to use them for years. And if LCD dies - I prefer to swap without recompiling code.
I certainly can use "begin()" in the middle of the code for adjusting contrast, but that would make code less readable and intuitive and more prone to wrong value used for contrast.

While this library set so many records, I hate to make it heavier even by single line or byte, but I do need contrast.

So those are my thoughts. You have author's right to keep it the way you see fit. And I can always change it to better fit my needs.

If so few requests for contrast - it might be just me. I will stop trolling this very useful thread with my contrast requests.

Either way this is the best library, I think, for 5110, at least for me. And once again I would like to thank you for spending time working on it and releasing to all of us.


Cheers!
Logged

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

Ok, you have a point smiley (many actually)
I'll add contrast support into the next version, it should be easy simple enough.
The only question remaining is what do we do with the range? For 'safety' we might want to limit the contrast level to something like 0x20 - 0x3F. But on the other side I also want to give the user full control. Decisions, decisions... Any ideas? Maybe make 2 separate functions, something like contrast() and contrastUnsafe()?
Logged


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
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
While this library set so many records, I hate to make it heavier even by single line or byte, but I do need contrast.

You can always make code conditional available in the library by preprocessor directives.

#define EXTENDED_PCD8544

...


#ifdef EXTENDED_PCD8544

void ::contrast() ...

#endif

Logged

Rob Tillaart

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

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
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
Any ideas? Maybe make 2 separate functions, something like contrast() and contrastUnsafe()?
2 separate functions is maybe more unsafe as people might use the wrong one

users who want another range can mod the library explicitly - so they know they're tweaking -
Code:
// warning ...
#define CONTRAST_MIN  ..
#define CONTRAST_MAX ..

::contrast(int value)
{
  value = constrain(value, CONTRAST_MIN, CONTRAST_MAX);
  ...
}
Logged

Rob Tillaart

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

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

Ok, you have a point smiley (many actually)
I'll add contrast support into the next version, it should be easy simple enough.
The only question remaining is what do we do with the range? For 'safety' we might want to limit the contrast level to something like 0x20 - 0x3F. But on the other side I also want to give the user full control. Decisions, decisions... Any ideas? Maybe make 2 separate functions, something like contrast() and contrastUnsafe()?

I suggest single "contrast" function. For advanced developers you may add different, "extended()" command with no limits on values, especially because other stuff can be controlled by it. Or, single argument contrast() will limit (and map?) values and second argument, only if used, will relax it to full (and unmapped?) range.
As we have quite a crowd here - we can test if safe range is sufficient, you may provide instructions for less advanced coders, how to extend it.
Risking bloating it I can suggest to auto switch contrast range depending on mux ratio and temp curve, ...actually no, this is too much, let "advanced coders" to mess on their own with those, let's keep library light.
My personal preference, for future reuse, to have contrast values mapped to standard range starting from 0 and up. 255 is too much, most steps will do nothing. 15 is good. But as we have already have to think in special ranges for bit map coordinates, in parallel with that mapping is not necessary.
Logged

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

Hi, All!

Pretty dumb question: I've tried not to connect lcd screen via 4050, but to connect it directly. Nothing worked. Double checked all connections. Should I really use 4050?

I've sucessfully ran same 5110 screen with this sketch: http://blog.stuartlewis.com/2011/02/12/scrolling-text-with-an-arduino-and-nokia-5110-screen/ . Any ideas what went wrong?
Logged

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

@Zeddy:
The LCD requires 3.3v signals, it isn't 5v tolerant as far as I know.
I know some people have used 1k or 10k (can't remember exactly) resistors to achieve the same effect, but my personal recommendation is to use a proper voltage level shifter to get things working.
Also note that you MUST connect VCC and backlight to 3.3v output on your Arduino, it won't like 5v on those inputs.

@SuperLAVA:
I'll think of something. Thank you for the input.
« Last Edit: September 16, 2013, 04:27:57 pm by TheCoolest » Logged


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

What would you suggest me to set PIN_CE to, so i get another free pin? Because i only have one spi device and i need more pins to switch some relays?
Logged

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

The default configuration uses pins D8 - D13. All of the other pins are free.
If you need D10 for some reason, you will have to remap DC and RST pins as well to either D0-D7 or A0 - A5.
Logged


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

I see. I ask because i wonder what happens if i put CE to something non existig. But i dont want the programm to be unsafe.
He says one can put CE to -1 to get one free pin:
http://www.avdweb.nl/arduino/hardware-interfacing/nokia-5110-lcd.html


Another thing: what about the A6 A7 of the arduino nano board? What bus are they on? http://arduino.cc/en/Hacking/PinMapping168 what is their binary address?
« Last Edit: September 17, 2013, 08:20:02 am by bumsbert » Logged

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

Ok, I see what you mean now. You can simply set PIN_CE to to 0x00 (basically 0).
When you ground the CE pin on the LCD itself it'll always be in "write" mode, so it should work.

A6 and A7 aren't on any port, they are analog inputs only and cannot serve as digital IO.
Logged


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

And that is great news. I can finish my project now. Its awesome. Your library kicks ass! maybe you can add the 0x00 option info to your comments. I guess some more noobs like me could use this info.

A6 and A7 aren't on any port, they are analog inputs only and cannot serve as digital IO.

That is funny because I was convinced I killed them because they were not working as digital outputs.  smiley-mr-green I must have always underread that
« Last Edit: September 17, 2013, 09:11:19 am by bumsbert » Logged

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

Hey guys,

thanks for the libary. First it was working fine, but now I have some problems. The text I want to print in my setup Funktion is not printed. Well if you look in an sharp angel you can see that there is somthing printed, but really light. The same with the other text in the coolTempControll() Funktion. When I add a SPI.setClockDivider(SPI_CLOCK_DIV2); the text in the coolTempControll() Funktion ist printed correctly, but still not the text in my setup funktion.

Do someone of you know were the problem is?

Thanks alot!

Code:
//LCD Initialisierung ----------------------------------------------
#include <SPI.h>
#include <PCD8544_SPI.h>
PCD8544_SPI lcd;


//Encoder Initialisierung ----------------------------------------------
#include <Encoder.h>
Encoder myEnc(5, 6);
long oldPosition  = -999;
int number = 0;
int oldNumber = 0;
int control = 0;
int switchValue = 0;
int minValue;
long maxValue;
long encValue;
long encStart;


//Taster------------------------------------------------------------------
const int BUTTON = 4;
long startTime = 0;

//Kühltemperatur-----------------------------------------------------------------
int coolTemp = 10;






void setup(void)
{
       
        SPI.setClockDivider(SPI_CLOCK_DIV2);
Serial.begin(9600);

        pinMode(BUTTON, INPUT);                    // Pin für Taster
        digitalWrite(BUTTON, HIGH);                // Turn on internal pullup resistor
       
       
        lcd.begin();
        lcd.clear();
        lcd.gotoXY(20,1);
lcd.print("EUMEL'S");
        lcd.gotoXY(4,2);
        lcd.print("BRAUMASCHINE");
       
delay(2000);
        lcd.clear();
}



void loop(void)
{
       
        coolTempControll();
               
       
        //Serial.println(newPosition);
       
       
        /*lcd.clear();
        lcd.gotoXY(4,2);
        lcd.print(newPosition);*/
       
 
}

// Funktion Tastendruck keyPressed-----------------------------------------------
long keyPressed () // returns duration of key_press so far
{
  long duration=0;
  if(digitalRead(BUTTON) == LOW)
  {
    if (startTime > 0) // war schon gedrueckt?
    {
      duration = millis() - startTime;
    } else {
      startTime = millis(); // nicht gedrueckt
    }
  } else {
    startTime = 0;
  }
  return duration;
}

int coolTempControll(){
 
  //lcd.clear();
  lcd.gotoXY(5,1);
  lcd.print("Gaer Waechter");
  coolTemp = switchPos(-3 , 31, 10);
  lcd.gotoXY(5,3);
  lcd.print("soll");
 
  if (coolTemp < 10)  {lcd.gotoXY(35,3); lcd.print(" "); lcd.gotoXY(41,3);}
  if (coolTemp >= 10 || coolTemp < 0)  lcd.gotoXY(35,3);
 
 
  lcd.print(coolTemp);
 
  lcd.gotoXY(5,4);
  lcd.print("ist");
 
  lcd.gotoXY(41,4);
  lcd.print(coolTemp);
 
 


int switchPos(long minValue, long maxValue, long encStart){
       
       
      number = myEnc.read();
   
      if (number >= oldNumber+3){   
        oldNumber = number;
        encValue++;
       
        if (encValue >= maxValue){
          encValue=maxValue;
          myEnc.write(maxValue);
        }
      }
      else if (number <= oldNumber-3){
        oldNumber = number;
        encValue--;
       
        if (encValue <= minValue){
          encValue=minValue;
          myEnc.write(minValue);
        }
      }
     
     

     
     
      return encValue;
}
Logged

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

First of all, the PCD8544 controller supports SPI speed of 4MHz. This means you have to use SPI_CLOCK_DIV4 or leave it at default.
I tried your sketch and my screen didn't display anything with SPI_CLOCK_DIV2.

The second possible issue is that you don't have any delays/pauses in your loop. If the values change often it won't look right.
One more thing is you *might* need to play with the contrast values in the PCD8544_SPI::init (or PCD8544_SPI::begin) function.
Logged


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

+ Added a timed refresh for the LCD, twice per second  (as the coolest proposed)
+ CTRL-T auto formatting for readability

give it a try
Code: (not tested)
//LCD Initialisierung ----------------------------------------------
#include <SPI.h>

#include <PCD8544_SPI.h>

PCD8544_SPI lcd;


//Encoder Initialisierung ----------------------------------------------
#include <Encoder.h>

Encoder myEnc(5, 6);

long oldPosition  = -999;
int number = 0;
int oldNumber = 0;
int control = 0;
int switchValue = 0;
int minValue;
long maxValue;
long encValue;
long encStart;


//Taster------------------------------------------------------------------
const int BUTTON = 4;
long startTime = 0;

//Kühltemperatur-----------------------------------------------------------------
int coolTemp = 10;


uint32_t lastScreen = 0;

void setup(void)
{
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  Serial.begin(9600);

  pinMode(BUTTON, INPUT);                    // Pin für Taster
  digitalWrite(BUTTON, HIGH);                // Turn on internal pullup resistor

  lcd.begin();
  lcd.clear();
  lcd.gotoXY(20,1);
  lcd.print("EUMEL'S");
  lcd.gotoXY(4,2);
  lcd.print("BRAUMASCHINE");

  delay(2000);
  lcd.clear();
}

void loop(void)
{
  if (millis() - lastScreen > 500)
  {
    lastScreen = millis();
    coolTempControll();
  }

  //Serial.println(newPosition);

  /*
  lcd.clear();
  lcd.gotoXY(4,2);
  lcd.print(newPosition);
  */
}

// Funktion Tastendruck keyPressed-----------------------------------------------
long keyPressed () // returns duration of key_press so far
{
  long duration=0;
  if(digitalRead(BUTTON) == LOW)
  {
    if (startTime > 0) // war schon gedrueckt?
    {
      duration = millis() - startTime;
    }
    else
    {
      startTime = millis(); // nicht gedrueckt
    }
  }
  else {
    startTime = 0;
  }
  return duration;
}

int coolTempControll()
{
  //lcd.clear();
  lcd.gotoXY(5, 1);
  lcd.print("Gaer Waechter");
  coolTemp = switchPos(-3 , 31, 10);
  lcd.gotoXY(5, 3);
  lcd.print("soll");

  if (coolTemp < 10)  
  {
    lcd.gotoXY(35, 3);
    lcd.print(" ");
    lcd.gotoXY(41, 3);
  }
  if (coolTemp >= 10 || coolTemp < 0)  
  {
    lcd.gotoXY(35, 3);
  }

  lcd.print(coolTemp);

  lcd.gotoXY(5, 4);
  lcd.print("ist");

  lcd.gotoXY(41, 4);
  lcd.print(coolTemp);
}  

int switchPos(long minValue, long maxValue, long encStart)
{
  number = myEnc.read();

  if (number >= (oldNumber+3))
  {  
    oldNumber = number;
    encValue++;

    if (encValue >= maxValue)
    {
      encValue=maxValue;
      myEnc.write(maxValue);
    }
  }
  else if (number <= (oldNumber-3))
  {
    oldNumber = number;
    encValue--;

    if (encValue <= minValue)
    {
      encValue=minValue;
      myEnc.write(minValue);
    }
  }
  return encValue;
}
Logged

Rob Tillaart

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

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