Export to GitHub

pcd8544 - issue #2

patch for hw SPI & custom pins


Posted on Mar 10, 2011 by Helpful Monkey

This is a great library, but it's use of hard coded pins and forced use of software SPI causes a lot of problems when using it with other SPI enabled devices like SD cards. This patch does two things:

  1. Default to using hardware SPI on pins 13-11. You can enable software SPI by first #define'ing PCD8544_SOFTWARE_SPI before #including the PCD8544 header.

  2. Allow users to easily customize which pins are used for software SPI and the extra pins (D/C, Select, Reset).

I'm using this for my own project with great results.

Attachments

Comment #1

Posted on Mar 15, 2011 by Grumpy Elephant

(No comment was entered for this change.)

Comment #2

Posted on Mar 16, 2011 by Grumpy Elephant

I think a better approach is to let the user specify the pins beforehand, and if SCLK and MOSI coincide with the hardware SPI pins, enable hardware SPI automatically upon "begin()".

I'll look into this shortly.

Comment #3

Posted on Mar 19, 2011 by Helpful Monkey

Would you go for something like:

define PCD8544_SCLK_PIN

define PCD8544_MOSI_PIN

// other pin defaults (including Select) can be overridden as well

include

PCD8544 LCD; void setup() { LCD.begin(Select_PIN); // or just LCD.begin(); }

I'm trying to avoid creating additional functions since I'm already low on memory. Would be pretty much 100% backwards compatible that way.

Comment #4

Posted on Mar 22, 2011 by Helpful Monkey

Ugh, forgot the PCD8544 library is compiled separately and won't see those #defines for the pins if they're defined in the main program's .pde file.

I guess the best way is to define some class variables for the common SPI/DC/RST pins and then pass in the SPI SELECT pin on begin(). Would that work for you?

Comment #5

Posted on Mar 22, 2011 by Helpful Monkey

Comment deleted

Comment #6

Posted on Mar 23, 2011 by Helpful Monkey

Here's an updated patch which places the 4 common LCD pins in the class and keeps the per-LCD specific SELECT pin in begin(). Use the set_pins() class method to set the 4 pins prior to calling begin(). Theoretically should work with multiple LCD's (assuming each has a unique select pin), but I haven't tested that.

Attachments

Comment #7

Posted on Apr 10, 2011 by Grumpy Elephant

There is one significant problem with this approach. It doesn't initialize SPI, and thus does not work standalone (at least I can't get it to work).

So, right now the choice seems to be between keeping software SPI only, which means not saving two pins if another SPI device is being used, or make this library require another library to initialize the SPI bus.

We could always initialize SPI on every "send", which is the correct thing to do, but other users of the SPI bus must do the same, or they'll break.

I'm not seeing a safe and generic solution for this. Any ideas?

Comment #8

Posted on Apr 10, 2011 by Helpful Monkey

Ah, you're right. I've been initializing the SD library first which takes care of that for me. Seems like the way around it is to add a method call like LCD.init_spi() which people can optionally call between set_pins() and begin() as necessary. Looks like it would be pretty easy to copy the SD library initialization code in Sd2Card::init().

That or everyone who is writing Arduino libraries which talk SPI get together and agree that users init the SPI library first and then pass in that object into the constructor of libraries like the SD/PCD8544/etc or some other solution which allows for multiple libraries to use SPI at the same time. I know SPI supports multiple speeds/modes, but in my limited experience I don't know how much different hardware requires different settings.

Comment #9

Posted on Apr 10, 2011 by Grumpy Elephant

But doesn't the SD library also need changes to work together with this one? I seem to recall the SD library initializes the SPI bus to a speed too fast for these displays to work.

Comment #10

Posted on Apr 10, 2011 by Helpful Monkey

Not that I'm aware of... seems to work fine for me. Possible I may have edited the SD library and fixed that, but I don't remember doing anything like that. I'll check and get back to you.

Comment #11

Posted on May 20, 2013 by Swift Lion

I'm not seeing a safe and generic solution for this. Any ideas?

Big software world knows solution for quite a long time - http://en.wikipedia.org/wiki/Inversion_of_control and http://en.wikipedia.org/wiki/Dependency_injection . Those techniques say there's no need to be "smarter" than user, or provide false courtesy. "Smartness" under come circumstances will become dumb, and "courtesy" will become great burden the user. It's only top-level user code knows which speed settings a user wants for SPI. It's only top-level user code knows if there're more than one device on SPI, so either speed should be selected to accommodate both, or SPI should be reinitialized at right times to work with one or another. Etc, etc.

Of course, you may say that well-proven component software techniques hardly apply to Arduino toybox, and will be right ;-).

Status: New

Labels:
Type-Enhancement Priority-Medium