A fast PCD8544 library (Nokia 5110)

Thanks,

after the changings the display works fine. Now Iam already a step further in my projekt and I added an SD card.
The SD card workes fine. it loggs my data correctly. The display also shows the right text. The only thing is, that printed charakters on the display are disturbed. Looks like the SD card is causing that problem.
In my Loop() the part of my SD card looks like this:

digitalWrite(10, HIGH);
  digitalWrite(7,LOW);

  time_t timeStamp = now();  
  if( timeStamp >= nextTrigger)
  { 
    printDateTime(timeStamp);
    printTemp(actualTemp, coolTemp);
    LogFile.println();
    // write the data to the card at the end of every line 
    if (!LogFile.sync()) 
      error(4); 

    nextTrigger = timeStamp + logInterval;// schedule the next log time        
    Serial.print("logging");
  }
 
  digitalWrite(7, HIGH);
  digitalWrite(10,LOW);

So, do I have to disable somthing else that my display doesn't get influenced by the SD card?

Thanks in advance!

Is digitalWrite(10, HIGH); and digitalWrite(10, LOW); meant for the LCD? If it is, you don't need that as the library already sets the appropriate pins automatically.
What do you mean by "disturbed"?
Also leaving SCE low without sending the text right after it (right after it = next command) is not a very good idea, any kind of interference on the SPI bus could potentially cause the display to go a bit haywire.
One more suggestion is to put decoupling capacitors across vcc/gnd pins of the lcd and the sd card, as close to the devices as you can. Something like a 0.1uf on each can help with decreasing interference.

Thanks,
for the fast reply. Pin 10 is the LCD cs and Pin 7 is the SD cs.
so this means I dont have to manipulate the cs pin of the lcd?
With disturbed I mean, the printed words/numbers or part of the words/numbers jumping left/right or beeing deletet for
couple of ms.
Thanks!

That's right, you don't have to manipulate Pin 10. I'm not sure what library you are using for the SD card, but as far as I can remember the default SD library in Arduino doesn't need you to manipulate its pin either.

Regarding the character problems, that sounds to me like a biasing problem, or perhaps contrast.
I sort of adjusted the code to run well on my LCD, but different displays could be different and require other configuration to work properly.
This library allows you to supply your own configuration values to the display, this is 'low level' stuff, but as there are different kinds of displays, I felt that this more advanced option should be available to the user in cases like this.
There are two begin() functions, one which takes no parameters and it initializes the LCD with default values, and another which takes the configuration values from the users. This is how it's declared.

void begin(bool invert, uint8_t vop, uint8_t tempCoef, uint8_t bias);
  • Invert is a boolean value which lets you choose whether the display will show dark characters on light background (false, no-invert) or light characters on dark background (true, inverted). The default configuration is no-invert.
  • vop mainly controls the contrast of the display, usually the value range for this should be between 0xB0 and 0xBF (hexadecimal values). You can go a bit over that, but it isn't recommended and usually isn't needed. I found that my display works best with 0xB6 or 0xB7.
    *tempCoef stands for temperature coefficient. You probably shouldn't change it and leave it at the default value of 0x04.
    *bias (together with vop) controls the voltage level which powers the LCD itself (glass part, with the crystals). I found that on my display a value of 0x12 works the best, but from looking online I saw recommended values of 0x13 and 0x14.
    So what you have to do is "play" around with vop and bias to find a combination which works best for your display.
    What I'd suggest you to do is the following:
  1. Replace your "lcd.begin();" call with "lcd.begin(false, 0xB7, 0x04, 0x12);" and see if there's an improvement.
  2. If there is not try changing bias to 0x13 and/or to 0x14 and see if there is an improvement.
    I recommend you not to go over the values I mentioned to make sure you don't damage the LCD.
    VOP --> 0xB0 to 0xBF should be fine.
    BIAS --> 0x12 to 0x14 should be fine.
    Try a few combinations, and you will probably find the one which works best with your display.

Sorry for the long post, but I hope it helps you understand why this problem occurs and how sort it out.

Hey TheCoolest,

thanks a lot for the explanaition. I played around with the values. Now I have better contrast and the letters are darker.
Thanks, looks way better :wink: But still the problem occures. What I found out. If I remove the SD card this disturbances disappering. If I enter the SD card again it starts again. Is it possible that the display get values during the spi comunicates with the SD card? But on the other Hand if I increase logInterval to lets say 10 sec. It still disturbes.
Or could it be a hardware problem?
The supply for both devices comes from the 3,3V pin of the UNO. SCLK und MOSI of SD and lcd use the same input of the 4050 level shifter. Should I seperate them?

I think it's possible that the SD introduces interference. If the text itself on the LCD isn't affected (as in no new text added) then it probably has to do with interference on the power lines rather than the data lines, so the 4050 has nothing to do with it.
You should remember that the Arduino's 3.3v line can only supply about 50mA max, and SD cards can chew up much more than that, causing voltage to sag and cause all sorts of disruptions.
Now that I think about it I had a "flickering" issue when I ran an SD card and a 5V HD44780 display. When the card was reading or writing the display would go dim and sort of flicker.
In my next project which will involve using an SD card, I will be using a dedicated 3.3v voltage regulator just for that reason.

Hello again,

after my last post I had change my hardware and now I#m using an seperate voltage regulator for the SD card. After the Hardware change it run just nice. But yesterday the Problem started again. I tried every Idea I have. I used decoupling C of 100nF but it seems to be worse after adding them. I also tried another SD Card which definitive makes the problem a lot worse. The display than flickers really bad and even shows weired things on the display and finaly shows nothing. I really don't know were to find the problem.
Does someone have another idea to fix that problem. Its really a pain in the ass since it was working for the last couple of days without any issues.

Thanks in advance!

I'm not certain what the problem can be, any chance that you could post a schematic of how everything is wired up in your project (including capacitors/resistors/whatnot)?

Hey TheCoolest,

thanks so much for your help. I hope we are going to fix that problem :slight_smile:
Here are the schematics I have got so far. The LCD is the Nokia5110, the red one.
The SD Shield is from LC Studio a blue one. Maybe you can find something.

thanks!

I'm not sure what could be wrong. I can't see anything obvious. The SD card module already has a voltage regulator and filter/decoupling caps.
Did you add a 100nF cap between the vcc and gnd pins of the 4050?

Hello,

First of all let me state that I'm really new to Arduino and to this forum aswell :slight_smile:
I was really happy when I found your library. I'm using Adafruit's one but I feel it too "heavy" and resource consuming, which (considering the low memory of microcontrollers) can be frightening.

I have an Arduino Leonardo board. Following the instructions lead me to the following PIN layout:

  • DC of Nokia display goes to Leonardo PIN 8
  • RST of Nokia display goes to Leonardo PIN 9
  • CE of Nokia display goes to Leonardo PIN 10
    Here comes the tricky part. I understand that the hardware SPI pins are not mapped on Leonardo as it was used to be, but they can be found on the ICSP header. So I connected:
  • DIN of Nokia display goes to Leonardo ICSP PIN 4 (MOSI)
  • CLK of Nokia display goes to Leonardo ICSP PIN 3 (SCK)

Unfortunately when I upload the benchmark - nothing is shown on the Nokia display.
The device itself must be fully functional as using the previous library I still can do magic :slight_smile:

Any ideas, what am I doing wrong?

Thanks, and keep up the good work! :slight_smile:

The pins on the Atmega32u4 (Leonardo) are mapped differently than on Atmega328p chips.

For the configuration you described (pins 8, 9, 10), replace this part of the PCD8544_SPI.h

#define PIN_DC				0x01	// D8
#define PIN_RESET			0x02	// D9
#define PIN_CE				0x04	// D10

With this:

#define PIN_DC				0x10	// D8
#define PIN_RESET			0x20	// D9
#define PIN_CE				0x40	// D10

Hello,

Thanks for the prompt reply! I did the mentioned changes in the PCD8544_SPI.h file, but unfortunately my Nokia screen is still dark and silent. While trying to figure out what could be wrong a question popped up in my mind. As mentioned on Adafruit's forum:

The SPI pins for the Micro, Leonardo, and Esplora (the 32u4 chip powered devices) do map the SPI pins but different than the Uno.
MISO - Digital 14
SCK - Digital 15
MOSI - Digital 16
SS - Digital 17

I could not find these references in the file above. Are they hardcoded? Should't those also be changed somewhere?

The Library uses the chips SPI hardware, so there is no need to define which pins SPI is on. On the Leonardo you can only use the ICSP header to access hardware SPI, so the only way is to use ICSP pins 3 and 4.

Since the port/pin mapping is different between the Atmega328P and the Atmega32u4 (Leonardo) chips, you need to edit the control pins the library uses (as I mentioned in my previous post). If you did that and it still isn't working, I'm not sure why that happens. I don't have a Leonardo to try this library on, so I can't try it out and debug if there is indeed something wrong with the code.

Too bad :frowning:
I'll try to make some investigations and/or tests but - as I'm a newbie - I doubt I'll even know what should I check first :slight_smile:

Thanks for the help anyway, I hope one day I'll be able to use your library!

I actually can't belive it but it seems my problem is solved. The solution can come in handy for someone else, so here it comes:

Adding a SPI.setClockDivider(SPI_CLOCK_DIV8); (changing SPI clock speed to 2 MHz instead of the default 4) right after SPI.begin(); in both PCD8544_SPI.cpp and SCD8544_SPI_FB.cpp put life back to the screen. It's slower than yours in the demo but it works!

If I will be brave enough I'll try to remove the 10k resistors from the CLK and DIN pins to see if it can run on 4 MHz that way, but I already turned a Nokia screen to a smoke machine before, so I'm a bit afraid.

Thank you for the awesome library, I'm really looking forward to rebuild my test projects with it! :slight_smile:

You can try using a voltage divider with lower value resistors, such as 2.2K and 4.7K to get very close to 3.3v.
Although I would still highly recommend using a voltage level shifter. A CD4050BE works well for me (there are other 4050 variants as well), but any shifter which can handle the frequency will do the job.

Can anyone provide me a full working code of a simple Hello World at line 1 ??

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

PCD8544_SPI_FB lcd;

void setup(void)
{
	lcd.begin();
	lcd.print(F("Hello world"));
	lcd.renderAll();
}

void loop(void) 
{
}

I don't know whats wrong...

Used the code below and nothing happened, the led doesn't even blinks...

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

PCD8544_SPI_FB lcd;
int led = 13;

void setup(void)
{
	lcd.begin();
	lcd.print(F("Hello world"));
	lcd.renderAll();
pinMode(led, OUTPUT);
}

void loop(void) 
{
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);       
}