A fast PCD8544 library (Nokia 5110)

Hi.

I confess that I've not read all the info in this thread, I'm hoping that some can point me in the right direction.

I'm trying to use this library in conjunction with the jeelib so I can Use a 3310 display with na RFM12b radio transmitter/receiver sharing the SPI bus.

By default the jeelib uses pin D10 for SS and I changed (at least I'm trying to) it to D7 because I'm using D8, D9 and D10 for the display control pins that have to be in the same port.

I would change the ports or even use soft SPI on the 3310 display but I need the spare pins for other things.

Has anyone been able to accomplish this?

Cheers.

Hi,

This library has been exactly what I was after to make my project viable, just didn't have the ram for the other libraries, I'm grateful you posted your code TheCoolest and to robtillaart for your suggestions.

My question is regarding row formatting, what changes would I need to make to sacrifice a row in order to use that pixel space in between certain other rows?

It doesn't matter if the new spacing affects everything, I won't need to go back to normal spacing.

Cheers

This lib is worth bumping.
Is there any way to make characters smaller? @sierramike could you post your code?

Thank you for the library! I was able to shave a lot of space from the binary sketch by using it.

Few observations:
a) the 'flicker' when clearing the screen is because in nonFB mode the screen is 'cleared' by drawing empty string that covers the screen and this which takes a while. I had to switch to FB mode, then it acts normal by using clear(0).
b) even if there was a lot of discussion about what are the correct values for vop / bias, I actually had to use 0x98 for vop and 0x12 to get the Nokia 5110 screen I have to look nice.
c) the screen was also acting funny (characters would sometimes jump around, random pixels would turn on/off, shearing effects) and the board would lock up after hours of running. Even if initially I thought it might be a power related issue, I found the culprit to be the SdFat library.

Initially I was using the Arduino provided library wrapper for SdFat (using a DIY shield based on a sdcard/microsd adapter) - and the card would init, but fail to write the file. Then I have switched to SdFat directly, where writing to the file worked. But screen was acting funny as the time went by ... and was getting worse and worse and it almost became unreadable with patches of pixels everywhere, etc. Convinced it is a power issue and waiting for an LM1117 3.3 to arrive, I decided to optimize the code even more and I ended up using tinyFAT. This one had problems also (meaning the lines appended to the file were changed, for example 20:57 would be written as 08:23; append sometimes started in a middle of the file!) so I switched to the Fat16 library.

Now everything runs smooth. Screen is rock stable, no jumpiness / shearing, no random pixels, and the values are correctly written to the sdcard.

Having a capacitor as recommended on the previous posts helped a bit, and also, not powering the backlight of the Nokia screen also helped a bit. Meaning it would act less funny when the thing was turned on, but as the time went by (hours), the effects were more and more noticeable. This made me think it might be a power issue - however, now after a day with Fat16 and everything is normal ... I guess there were few problems on the SPI line.

I have also modified the library to display characters 2 times the size (The equivalent of setTextSize(2) from the Adafruit library), by using a 10x16 array which I fill iterating through the 5x8 equivalent of the letter that has to be written. Still very fast :slight_smile:

I am using this library for a really long time and I have to say I am extremely satisfied! I only have one question... how to change the contrast during run-time?

Re-initializing with a new lcd.begin() is not working, just pushes the screen to blank :frowning:

Dr_Ugi:
Hi Guys
Just a quick "Thank you" for this great library!

I hacked it about a little and used it for a Pong/Invaders game project that I did with my kids and some of their friends and it worked great:

If you're interested it's all now written up in This Instructable. Obviously I have credited you as the source of the library.

Thanks again!

Ugi

That's just awesome! I love the idea and the execution, I bet the kids loved it as well.
I'm really glad I could help make this happen. :smiley:

@TeLarC

I know it's been a long time, but as always, no email notifications about new posts...
So basically you would have to edit the 'size_t write' function, keep track of the Buffer position (in the FB version) or the column/row position (in the non-FB version) and simply skip the length of 1 row.
If you meant a single row of pixels, the same applies for the FB version, while the non-FB would require some more work.

@jacekPlacek666

Thanks :slight_smile:

@viulian

a) That's correct, while using FB, you only have to make a single consecutive write to the LCD. This takes a lot less time, it's more efficient and it prevents the artifacts/flickers.
b) This is LCD dependent, different units can require different parameters to work properly.
c) Can't comment on that, but it sounds like you had some issues with SPI conflicts. Glad to hear that a lib change fixed the issue, though.
d) Cool :slight_smile:

@aehimself

As I haven't worked with this stuff for a long time now, I don't really know why this happens.
The begin() function issues a series of commands to the LCD after it has been powered up to initialize it. I don't really know how it will react to these commands without being power-cycled.
You should look at the PCD8544 chipset datasheet to see if it's possible to change contrast after the LCD has been initialized, or if there's a proper 'full reset' sequence.

viulian:
so I switched to the Fat16 library.

Now everything runs smooth. Screen is rock stable, no jumpiness / shearing, no random pixels, and the values are correctly written to the sdcard.

Good to know that I am not alone - at least was. Most probably I must be missing something, as none of the SD libraries I tried so far seems to work correctly.

Using a simple code, only SD reader (CS on PIN4) and the Nokia display (on PINs 8-10+SPI)

#include <SPI.h>
#include <PCD8544_SPI.h>
#include <Fat16.h>

PCD8544_SPI lcd;
SdCard card;
Fat16 file;

bool Show1(const char* FileName) {
  SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
  Serial.print(F("Trying to open "));
  Serial.println(String(FileName));
  if (file.open(FileName, O_READ)) {
    int i = 0;
    uint8_t bmp[300];
    memset(bmp,0,sizeof(bmp));
    uint8_t w = 0;
    uint8_t h = 0;
    int16_t n;
    Serial.print(F("Read "));
    Serial.print(file.read(&w, sizeof(uint8_t)));
    Serial.print(F(" bytes, width is "));
    Serial.println(w);
    Serial.print(F("Read "));
    Serial.print(file.read(&h, sizeof(uint8_t)));
    Serial.print(F(" bytes, height is "));
    Serial.println(h);
    while (file.read(&bmp[i], sizeof(uint8_t)) > 0) {
      if (i % 10 == 0) { Serial.println(); }
      Serial.print(F("0x"));
      Serial.print(String(bmp[i], HEX));
      Serial.print(F(", "));
      i++;
    }
    Serial.println();
    Serial.print(F("Total of "));
    Serial.print(i);
    Serial.println(" bytes");
    file.close();
    SPI.endTransaction();
    SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
    lcd.clear();
    lcd.writeBitmap(bmp, 0, 0, w, h);
    SPI.endTransaction();
    memset(bmp,0,sizeof(bmp));
    return true;
  } else {
    SPI.endTransaction();
    SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
    lcd.clear(); // REMEMBER THIS LINE
//    lcd.print(F("Error opening"));
//    lcd.gotoXY(0,1);
//    lcd.print(String(FileName));
    SPI.endTransaction();
    Serial.print(F("Error opening "));
    Serial.println(String(FileName));
    return false;
  }
}

void setup() {
  lcd.begin(false, 0xBF, 0x02, 0x13);
  Serial.begin(9600);
  delay(5000);
  if (!card.begin(4)) {
    SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
    lcd.clear();
    lcd.print(F("Initializing"));
    lcd.gotoXY(0,1);
    lcd.print(F("SD card failed"));
    SPI.endTransaction();
    delay(5000);
    return;
  }
  if (!Fat16::init(&card)) {
    SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
    lcd.clear();
    lcd.print(F("Initializing"));
    lcd.gotoXY(0,1);
    lcd.print(F("FAT16 failed"));
    SPI.endTransaction();
    delay(5000);
    return;
  }
}

void loop() {
 Show1("bmp1.txt");
 delay(2500);
 Show1("bmp2.txt");
 delay(2500);
 Show1("Fake.txt");
 delay(2500);
}

Is producing the below output:

Trying to open bmp1.txt
Read 1 bytes, width is 18
Read 1 bytes, height is 1

{correct data removed here}
Total of 18 bytes
Trying to open bmp2.txt
Read 1 bytes, width is 42
Read 1 bytes, height is 5

{correct data removed here}
Total of 210 bytes
Trying to open Fake.txt
Error opening Fake.txt
Trying to open bmp1.txt
Read -1 bytes, width is 0
Read -1 bytes, height is 0

Total of 0 bytes
Trying to open bmp2.txt
Error opening bmp2.txt
Trying to open Fake.txt
Error opening Fake.txt
Trying to open bmp1.txt
Error opening bmp1.txt
Trying to open bmp2.txt
Error opening bmp2.txt
Trying to open Fake.txt
Error opening Fake.txt

Now... if I remove the line with the comment // REMEMBER THIS LINE everything starts to work perfectly... I just must not touch the LCD if something goes wrong... but why?! :frowning:

This is good work :slight_smile: ! While this is for speed sensitive graphical applications I was looking for something simple just to use this LCD for printing simple strings. Just in case anyone wants something like that then I have made my code reusable here:

https://github.com/nitins11/Arduino/tree/master/libraries/Nokia5110Lib

Hey everyone, I have some trouble with this library.

I am using an arduino uno and want to try this fast library with the nokia5110 screen, but it just gives me a blank screen! I re-checked the connected pins many times (8-13), but to no avail. This code works just fine (using the other pins accordingly).

I maybe think it has something to do with the SPI? :S I'm at a total loss...

Hopefully someone can help me. It would be very nice to use this fast library, have some great ideas to use it, but need the speed!

Hi
I just tried to install this library (I downloaded it from the link on page 1) but it doesn't appear in the library list of the IDE. Is there something I missed?
Sorry for that question, I'm quite new to Arduino... so thanks for your help.

Dartuino:
Hey everyone, I have some trouble with this library.

I am using an arduino uno and want to try this fast library with the nokia5110 screen, but it just gives me a blank screen! I re-checked the connected pins many times (8-13), but to no avail. This code works just fine (using the other pins accordingly).

I maybe think it has something to do with the SPI? :S I'm at a total loss...

Hopefully someone can help me. It would be very nice to use this fast library, have some great ideas to use it, but need the speed!

Dear god, I finally got it to work.

For someone to stumble upon the same problem, the solution is to change the 'bias' to 0x14 in the cpp files.

I changed

this->begin(invert, 0xB1, 0x04, 0x12);

to
this->begin(invert, 0xB5, 0x04, 0x14);.

I also upped to contrast to 0xB5.

Hope it helps someone.

lesept:
Hi
I just tried to install this library (I downloaded it from the link on page 1) but it doesn't appear in the library list of the IDE. Is there something I missed?
Sorry for that question, I'm quite new to Arduino... so thanks for your help.

Be sure to unzip the folder in a new folder inside the libraries folder of your sketchbook location.

E.g. unzip to "C:\Users<username>\Arduino\libraries<new folder>"
You can find this path in the File -> preferences menu in the IDE.

If you're new to Arduino, this might not be the best code to start with. There are some easy, default, examples you could try out first related to displays.

Dartuino:
Dear god, I finally got it to work.

For someone to stumble upon the same problem, the solution is to change the 'bias' to 0x14 in the cpp files.

I changed

this->begin(invert, 0xB1, 0x04, 0x12);

to
this->begin(invert, 0xB5, 0x04, 0x14);.

I also upped to contrast to 0xB5.

Hope it helps someone.

Thanks Dartuino
I got more proficiency and come back to this library. I had the same problem as you had, and checkef the wiring several times. The only difference is the VCC : I use 5V, as I did in another sketch which works correctly using the standard LCD library.
I tried to change the bias as you said, but there is no difference, I still get nothing displayed.
Where can I change the contrast?

OK, I found the contrast, but it didn't improve the result. The same by putting VCC to 3.3V.
Can anyone help?

Some more details: I have a nano, 2 joysticks and a Nokia 5110 LCD display (all bought online in China) and I did a Pong game which works great. I want to see if I can make it faster using this library.

The display is connected to the nano using resistors, like shown here:

http://randomnerdtutorials.com/complete-guide-for-nokia-5110-lcd-with-arduino/

I only tried to run the example sketch but the display stays blank, even if I try to change the bias and contrast values. I even tried to use the values from my game, but there is no change.

lesept:
I only tried to run the example sketch but the display stays blank, even if I try to change the bias and contrast values

I finally made it work, by increasing the contrast up to 0xC0.
Thanks for your great library!

sir. i am new to use graphic lcds and libraries.. can you plss send me list of function related to this library or function can use in this library with some information about function like working of function,parameters need to pass these functions etc.

Good afternoon. Where can I download the lcd 5110 helper? Just needed such a program.

I'm waiting to receive my display, but thought I'd get a head start on programming my project.
This library looks like one of the best out there. Thanks for all the work on this @TheCoolest and @robtillaart!

I'd like to know how to properly set the library to use Analog pins.
Will the following set A0, A1 and A2 as control pins?

#define PCD8544_PORT		PORTC
#define PCD8544_DDR			DDRC	// Should be DDRx, x = port name (B, C, D, etc.)
						
#define PIN_DC				0x01	// A0
#define PIN_RESET			0x02	// A1
#define PIN_CE				0x04	// A2

Thanks for your reply!

--EDIT--
Just received my display, and can confirm the above is correct.
I also had to set my contrast to 0xC0, by editing the .cpp files:

this->begin(invert, 0xC0, 0x04, 0x14);

Hi, i am new in display world.

i am using latte panda which contains Leonardo inbuilt.
does this library support it.
how to map pins in h file.

Hi there !! I have a question about the powerdown mode ....
I have tried clearing the screen, and setting the power down bits:

display.command( PCD8544_FUNCTIONSET | PCD8544_POWERDOWN);

But still, LCD is taking around 0.2mA (over the given specs).

is there any way to switch this guy off by software, or should I go for a hw method ? (i.e. digital power switch controlled by the arduino)

Thanks so much guys!