Pages: 1 ... 5 6 [7] 8   Go Down
Author Topic: A fast PCD8544 library (Nokia 5110)  (Read 21767 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

You don't have to remove it, SPI works with the LED onboard, and it blinks while transferring data. Since the data is transferred quite quickly, though, you usually won't really notice anything more than a little flash.
Logged


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

Pinout is ok...

I´ve tried:
Code:
lcd.begin(true, 0xB2, 0x04,0x12);
lcd.clear();
lcd.gotoXY(1,1);
lcd.print("TEST");
lcd.renderAll();
delay(3000);

I can see that the LCD is alive... When I use lcd.begin(false, 0xB2, 0x04,0x12);, it iverts the colors as it should do...
It flickers very fast and i can see the "shadow" of the "TEST" written... It seams that the LCD is reseting by itself. After the lcd.begin(false....) it doesn´t mantain the inverted state, just for a few mili-seconds and then came back clear.

Maybe my LCD was dead on arrival... Any clues? I´ve tried to change contrast and the other stuff as you mentioned on page 4...
Logged

Costa Rica
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Mechatronics student
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks so much! This is just what I needed! Very nice and clean library...  smiley-cool
Logged

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

Is it possible to map CS, RST or CE pin to Arduino Uno 12?

If I change this:
Code:
#define PIN_DC 0x01 // D8
#define PIN_RESET 0x02 // D9
#define PIN_CE 0x04 // D10
To this:
Code:
#define PIN_DC 0x10 // D12
#define PIN_RESET 0x02 // D9
#define PIN_CE 0x04 // D10

Or did I misunderstood the hex pin mapping? Is not pin 12 = 0x10?

Thanks, seems very nice library though. Too bad that most other libraries didn't use the hardware SPI, so I'm having some problems with remapping my project with this library.
Logged

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

D12 is the MISO pin of the ATmega328's hardware SPI. I don't think it's a good idea to use it as a CS pin.
Although I have to say that I haven't really tested it in this configuration.
Logged


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

Isn't MISO unused for this PCD8544(for some reason)? If it isn't used as MISO, why shouldn't I map it to some other use? None of the pins seem to work in MISO pin anyway though.
Logged

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

As always, the answer can be found in the datasheet.

So it seems D12 cannot be used as an output when SPI is enabled as master.
Logged


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

good work!
works fine, but i would like to have function more to scroll the display content up an down or move a bitmap on the screen.
would that be possible in fb mode?
I wrote the function to invert the diplay. Is it possilbe not to invert the whole screen? i would like to have the possibility to toggle invert mode before i print on the screen, so that only the new written area is inverted.

has someone a recommendation of a menu library for this library?
Logged

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

works fine, but i would like to have function more to scroll the display content up an down or move a bitmap on the screen.
would that be possible in fb mode?
Yes, possible. Question is detailed behaviour.
 What would you do if the bitmap crosses the end of the screen?
- wrap
- fall off the edge
- how about the "incoming pixels" if you move the whole screen? white/black?  replicate the pixels that where there?

Quote
I wrote the function to invert the diplay.
Please share!

[/quote]
 Is it possilbe not to invert the whole screen? i would like to have the possibility to toggle invert mode before i print on the screen, so that only the new written area is inverted.
[/quote]
Yes, especially in FB mode you could invert an area. (if I recall the code correctly smiley

Have no time to dive into the code for a definitive answer, but yes think so.
Drawback might be that code becomes complexer/slower.

Quote
has someone a recommendation of a menu library for this library?
no idea sorry.

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
Online Online
Shannon Member
*****
Karma: 217
Posts: 13705
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@theCoolest
you might need to add a header in the cpp/h file

I use this template, helps users to track the version of the library.
Code:
//
//    FILE: .ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE:
//    DATE:
//     URL:
//
// Released to the public domain
//
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

Sadly I don't really have the time to play with this anymore, as I have some other ongoing projects right now.
Feel free to modify the library as you see fit.
Rob has already covered the scroll question, I'll try answering the inversion question.
Thee PCD8544 supports an invert command where you can invert the whole screen without changing anything in memory.
Although you could probably run a 'NOT' loop on the content of the memory section you want to invert.
The library doesn't support it, but it shouldn't be too difficult to implement.
Logged


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

Hi,
Thanks for the library.
Maybe i am lucky/pushing my luck. But i am running my LCD without level shifter or resistors.
I connected all pins to arduino pro mini directly. (Measured 5V at LCD Vcc and Gnd).
This LCD is salvaged from old nokia phone.

Had to use ( lcd.begin(false, 0xB2, 0x05 , 0x14); ) otherwise LCD becomes completely black.
I tried 4-5 of these salvaged LCD's.  Looks like there are differences between each of them.



* IMG_20140419_233521.jpg (199.96 KB, 874x783 - viewed 36 times.)
Logged

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

@robtillaart
i would see two behaviours with the scroll functions. In one case i log rows of text to the screen, at the screenend the text should scroll up/down and the old messages could fall simply off the edge. incomming pixels could be blank. in the secound behaviour i want to draw a menu with more rows than visible. in this case i would need a secound buffer for the menuitems that are not in the screen to scroll them in. On the top of the screen theres a header bitmap which should not be scrolled.
Maybe some can post a function for moving rows in the m_Buffer?

@theCoolest
inversion is now done and could be added to the library...

I want to share some functions i added to the library.
Invert the hole screen, invert single pixels, invert a given area, draw a bargraph in horizontal and vertical orientation...

Copy Functionprototypes to public:   PCD8544_SPI_FB(); section in PCD8544.H
Code:
void invert(bool invert);
void invertPixel(uint8_t x, uint8_t y);
void invertArea(uint8_t x, uint8_t y, uint8_t width, uint8_t height);
void writeHBar(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t val);
void writeVBar(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t val);

Copy Functiondefinitions to PCD8544_SPI_FB.CPP
Code:
void PCD8544_SPI_FB::invertPixel(uint8_t x, uint8_t y)
{
if (x >= PCD8544_X_PIXELS || y >= PCD8544_Y_PIXELS) return;
uint8_t bank = y / 8;
uint8_t bitMask = 1 << (y % 8);
uint8_t &byte = this->m_Buffer[(PCD8544_X_PIXELS * bank) + x];
byte ^= bitMask;
}

void PCD8544_SPI_FB::invertArea(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
{
uint8_t myx, myy;
for (myx = x; myx < (x+width); myx++) {
for (myy = y; myy < (y+height); myy++) {
this->invertPixel(myx,myy);
}
}
}

void PCD8544_SPI_FB::invert(bool invert){
uint8_t invertSetting = invert ? 0x0D : 0x0C;
this->writeLcd(PCD8544_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
this->writeLcd(PCD8544_COMMAND, invertSetting); //Set display control, normal mode. 0x0D for inverse
}

void PCD8544_SPI_FB::writeHBar(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t val)
{
if (height < 3) {
return;
}
  this->writeRect(x, y, width, height, false);
  this->writeRect(x + 1, y + 1, map(val, 0, 255, 0, width), height - 2, true);
}

void PCD8544_SPI_FB::writeVBar(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t val)
{
if (width < 3) {
return;
}
  this->writeRect(x, y, width, height, false);
  this->writeRect(x + 1, y + 1 + map(255 - val, 0, 255, 0, height - 2), width - 2, height - 2 - map(255 - val, 0, 255, 0, height - 2) , true);
}
Logged

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

Thanks for the invert code!

tip: don't check every single pixel if OK that adds up!
Do the check on a higher level.

Code:
void PCD8544_SPI_FB::invertPixel(uint8_t x, uint8_t y)
{
  uint8_t bank = y / 8;
  uint8_t bitMask = 1 << (y % 8);
  uint8_t &byte = this->m_Buffer[(PCD8544_X_PIXELS * bank) + x];
  byte ^= bitMask;
}

void PCD8544_SPI_FB::invertArea(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
{
  uint8_t myx, myy;
  for (myx = x; myx < (x+width); myx++)
  {
    if (myx >= PCD8544_X_PIXELS ) break;
    for (myy = y; myy < (y+height); myy++)
    {
      if (myy >= PCD8544_Y_PIXELS) break;
      this->invertPixel(myx,myy);
    }
  }
}


it would be a serious speed up when it would be possible to invert 8 pixels in a row

Code:
void PCD8544_SPI_FB::invertEightPixels(uint8_t x, uint8_t y)
{
  uint8_t bank = y / 8;
  uint8_t &byte = this->m_Buffer[(PCD8544_X_PIXELS * bank) + x];
  byte ^= 255;
}
you would need to make invertArea "aware" of the byte boundaries in the inner loop.
Logged

Rob Tillaart

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

Offline Offline
Newbie
*
Karma: 0
Posts: 5
Mount Beauty, VIC, Australia C/C++, Assembler
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley-razz I grabbed this code a few months ago and made quite a few changes. Mainly, I have created a LCD font builder that works really well and takes a few seconds to create a font or bitmap and place in the program. Fonts are in progmem and you can change fonts on the fly with no real speed penalty.

Also added ability to have portrait or landscape orientation.

Basically portrait is the default and behaves as currently implemented. If landscape then X & Y dimensions are swapped and when it's rendered bytes are sent a different way to "flip" the screen 90 degrees.

Also implemented a bitmap blit function that will clip x & y.

Only just got the screens from China today (lol 3 @ $2 each! brand new) so will get more functionality completed. Prior to that, for testing was dumping a matrix of characters to the serial monitor >_>

I hope to release the LCD maker and modified code soon.

Logged

Pages: 1 ... 5 6 [7] 8   Go Up
Jump to: