Potential Pin Conflict Help

New to this Arduino world, but loving it so far. I have a Mega2560 with a DFRobot Ethernet Shield (W5200 V1.1) and a Cytron LCD Keypad Shield. I’d put together a working code snippet that initiated the ether connection, connected to a MySQL DB running on a Raspberry PI on my LAN, and inserted record into a particular table. This is all working just fine. When the LCD Shield came in the mail I happily popped to on top of the ethernet shield and added some simple LCD sample code from the Cytron web site. I tried to determine if there were any pin conflicts between the Ethernet shield and the LCD shield and didn’t think there were. However, after loading the updated sketch and opening the serial console my code appears to hang at the “Starting Ethernet Connection…” display. I’ve looked at the user guides for both shields and from what I can tell there’s not overlapped pins, but as a newbie to this world I’m guessing the fault is mine, and there is a conflict. Here’s the sketch, which worked fine before I added the “new code”. The new code blocks are marked with comments. Any help would be appreciated. Processing basically stops once I initialize the ethernet connecting and as that code is a black box to me I’m stuck.

/*
Arduino Ethernet based MySQL Connector
Gary M
2019-02-13
*/

// Bring in the needed Serial, Ethernet, MySQL, LCD libraries
#include <SPI.h>
#include <EthernetV2_0.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <LiquidCrystal.h> //NEW CODE

// Assign psuedo MAC address to Ethernet Hat
// Note, if this changes then my DHCP network reservation IP address may not work
byte mac_addr = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xBF };

// Create needed DB connection objects and parms
IPAddress server_addr(192,168,1,100); // IP of the Raspberry Pi MySQL Server
char user = “arduino”; // MySQL user login username
char password = “XXXXX”; // MySQL user login password

// Build simple test query
char INSERT_SQL = “INSERT INTO welldb.well_tank (inches,gallons) VALUES (50,1234.56)”;

//Establish Ethernet and MySQL objects
EthernetClient client;
MySQL_Connection conn((Client *)&client);

//NEW CODE BEGIN
/* Set up LCD pins

  • RS Pin to digital pin 8
  • Enable pin to digital pin 9
  • D4 pin ti digital pin 4
  • D5 pin to digital pin 5
  • D6 pin to digital pin 6
  • D7 pin to digital pin 7
  • LCD R/W pin to ground */

LiquidCrystal lcd(8,9,4,5,6,7);
int analogPin = A0;
int adc_key_old;
int adc_key_in;
int NUM_KEYS = 5;
int key=-1;
int adc_key_val[5] ={30,150,360,535,760};
char msgs[5][15] = {"Right Key OK ","Up Key OK ","Down Key OK ","Left Key OK ","Select Key OK "};
//NEW CODE END

void setup() {
Serial.begin(115200);
while (!Serial); // wait for serial port to connect
Serial.println(“Starting Ethernet Connection…”);
Ethernet.begin(mac_addr);
Serial.println(“Starting MySQL Connection…”);
if (conn.connect(server_addr, 3306, user, password)) {
delay(5000);
}
else
Serial.println(“Connection failed.”);
//NEW CODE BEGIN
//Set up LCD
lcd.begin(16,2);
lcd.clear();
lcd.print(“Crytron Tech.”);
lcd.setCursor(0,1);
lcd.print(“LCD Shield”);
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Yo World”);
lcd.setCursor(0,1);
lcd.print(“Press a Button”);
adc_key_old = analogRead(analogPin);
//NEW CODE END
}

void loop() {
delay(4000);
Serial.println(“Recording data.”);
// Initiate the query class instance
MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
// Execute the query
cur_mem->execute(INSERT_SQL);
// Since this is an insert do not need to read any data
// But this should check for an error condition
// Delete the cursor to free up memory
delete cur_mem;

//NEW CODE BEGIN
//Use the LCD Keys and Display Info

adc_key_in = analogRead(analogPin);
adc_key_in = get_key(adc_key_in);
lcd.setCursor(0,1);
lcd.print(msgs[adc_key_in]);
//NEW CODE END
}

//NEW CODE BEGIN
// Definue get_key function
int get_key(unsigned int input) {
int k;
for (k=0;k<NUM_KEYS;k++)
{
if (input < adc_key_val[k])
{ return k; } //Valid key pressed
}
if (k >= NUM_KEYS)
{ k = -1;} //No valid key pressed
return k;
}
//NEW CODE END

What pin is this?

 *  LCD R/W pin to ground */

I have a very vague recollection (although it might be my imagination) that's pin 10 on some LCD shields. For SPI to work, pin 10 has to be an output, becasue once you take pin 10 low, the Arduino becomes an SPI slave and it needs to be a master.

(Or I might be thinking of the backlight pin being pin 10, sorry I'm a bit vague. Bottom line though is that you can't take pin 10 low and have SPI working.)

(edit: Thinking about it further, it won't be anything to do with that r/w pin being grounded, since that's not an Arduino pin; it's just a pin on the LCD going to ground. But I do think it may be due to the backlight pin, which may likely be pin 10. Does the lcd shield documentation say anything about pin 10?)

LCD doco says the following...

Analog 0 - Button (select, up, right, down and left)
Digital 4 - DB4
Digital 5 - DB5
Digital 6 - DB6
Digital 7 - DB7
Digital 8 - RS (Data or Signal Display Selection)
Digital 9 - Enable
Digital 10 - Backlight Control

So yes, 10 is backlight control.

If the LCD board is using 10 to turn on (or off) backlight and if there’s no way to change it via driver config because it’s part of the schematic, could I simply clip the pin and live without (or with) backlight?

MadMacks:
So yes, 10 is backlight control.

Might have something to do with that then. For SPI to work, Uno's pin 10 must be an output... by default pins are inputs. But then I guess if it's for the backlight control it should also be an output?

I don't see anything in your code making it an output, so perhaps with it defaulting as an input, the shield is pulling it low and making it an SPI slave, effectively stopping SPI.

So maybe stick a pinMode in there to make pin 10 an output explicitly?

(Also read the sticky at the top of the Display sub forum, about problems with the way pin 10 is used in some designs of LCD shield. If I recall, there's a test sketch in there to see if a particular shield suffers from the fault or not.)

Ok, thx. I’ll try the pinMode option and see how it goes. Sounds like I bought the wrong LCD for use with an Ethernet shield.

Another thing just struck me, which might be more likely actually, and that’s that the e’net shield might use pin 10 as its slave select, and so the backlight being on (pin 10 high) is deselecting the e’net shield which if it is using pin 10, will expect a low to work.

It may be a bit confusing…

The Arduino itself needs to have pin 10 as an output, else if it’s an input and pulled low will make it a slave. (And we don’t want that, the Arduino needs to be the master here.)

But then, since pin 10 needs to be an output for that reason, it’s often used to be an input on the peripherals such as shields so as not to waste the pin. It may well be that the e’net shield has pin 10 as its SS Slave Select, in which case yes it’s a clash with the LCD’s use as backlight.

What does the e’net shield doc say about SS?

Ahem!

MadMacks:
I have a Mega2560

SPI SS is pin 53, not 10.

oqibidipo:
Ahem!

SPI SS is pin 53, not 10.

Crap... good catch, my bad.

I've never used a Mega, but don't the shields have the "Uno footprint". Doesn't that just mean the whole shield is renumbered... I wonder what pins number the LCD will use for backlight and the enet will use or its SS. Might still be the same conflict just moved to another pin.

I added the following at the top of setup()...

pinMode(10,OUTPUT); //Force Pin 10 to be output and make it low voltage...
digitalWrite(10, LOW); //Hopefully fixes the ethernet problem...

Recompiled and loaded and get the same result. I assume the "LiquidCrystal lcd(8,9,4,5,6,7)" statement is also triggering the Pin 10 issue as part of its initial set up process. I'd have thought adding the two statements above would have reset 10 to output and LOW and undone the LCD set up created problem. But, does the ethernet hardware go slave mode as soon as pin 10 is touched by the LiquidCrystal and then would need a board reset after I set it to OUTPU and LOW? If so I don't know what the ethernet board reset command is, but if there is one I assume it would go right after the two statement I already added.

Or, if it really is PIN 10 I can just de-solder it and live without (or with) backlight.

I also read the mentioned sticky and am a bit confused. It looks like it may be possible to add a library (mentioned in the post) and fix this via software config. How the heck can you override a hardware problem this way? Are the standard ethernet drives tweaked so they don't use Pin 10 to force slave mode?

FYI, being impatient guy I am I just bent Pin 10 out and reinstalled the shield. Sadly, same result, hangs at ethernet connection. Even after commenting out the pinMode and digitalWrite statements. Just to confirm there wasn’t some other hidden code error or hardware issue I commented out all the LCD code, reloaded, and things work as expected; ethernet connection starts, DB connection works, and row writes are good. Ugh… With Pin 10 on the LCD shield bent away doesn’t that eliminate it as causing the issue?

And...can anyone recommend a LCD shield that won't have this issue when used along with the DFRobot W5200 V1.1 shield? While I'd like to understand and learn I also want to get this project done, and a couple bucks for a working shield would work.

FYI Background... I live off grid in a very remote area and just had a well drilled (600'). Unfortunately the only place I could get it drilled was about 1,300 feet (with a 300 ft rise) from where the "cabin" is, more or less on top of the mountain. Solar well pumps (that I can afford) can only lift and push the water so far so I have to use a two pump system.

I am driving the well pump with solar panels so it runs as sunlight is available and fills a 1,500 gallon tank located by the well head. I have a pump in that tank to push the water to the top of the mountain. To avoid needing a bunch more solar panels to run that pump I'm using my little Pi/Arduino set up (with a Weatherproof Ultrasonic Sensor w/ Separate Probe) to measure the water level in the 1,500 gallon tank, and then when it's full switch the solar panel power over to the tank pump. The tank pump will then start pumping water from the tank to the top of the mountain and fill a 2,500 gallon tank near the cabin.

I want the LCD to display the current gallons in the lower tank. I'm using the ethernet based DB write process to push measurements into a log table so I can monitor it all via a status page running on my Raspberry Pi (and I can access that anywhere with my phone). Having the LCD down at the lower tank will be a convenience when I'm down there so I can just look at the display and see the calculated gallons in the tank. It's not critical, but now that I'm on this path I want to solve this issue rather than just ignore it. My stubborn side coming out.

This is a great project for me and I'm learning a lot about Arduino...once I get my water problem solved I'm looking forward to spending a lot more time playing with the Arduino(s) I have and exploring the projects I can do with my "Most Complete Starter Kit".

All help one is really appreciated!

I just bought a couple Freetronics LCD displays from RobotShop. According to reviews found here (in Display section) these don't have the Pin 10 (or other Pin) issue and are compatible with Ethernet shields. I hope so, two of them shipped was $40! But if they work I figure my time is worth at least minimum wage and I've spent more than 4-5 hours on this so far. Still, anyone with a suggestion is welcome to post it.

I did remove the ethernet shield and try the Cytron LCD shield by itself, and it worked just fine, so I can use it for some other non-connected project...

Still stumped...

I am still using the DFRobot Ethernet Shield W5200 V1.1 but I have switched over the the Freetronics LCD Keypad Shield (SH-16X2LCD)

AFAIK the ethernet shield uses SPI and digital pins 10,11,12,13.

The Freetronics shield uses digital 8,9,4,5,6,7 and A0 for button control.

I specifically bought the Freetronics because it says it does not use digital 10 for backlight control (it can use D3 for that, if desired).

According to this there should not be a conflict on the pins being used. So, if that's true, then I should be able to stack these shields and things should work. I am double checking my code to make sure I'm not directly screwing things up in my code. But is there something in the Ethernet drivers or the LiquidCrystal drivers that is using pins that are not obvious to me? I'm trying to learn how to read the schematics but that capability is not currently in my wheelhouse. ugh...

OK, so I found a great site called shieldlist.org that shows the Freetronics LCD uses:

A0: Buttons
D3: LCD backlight
D4: LCD bit 4
D5: LCD bit 5
D6: LCD bit 6
D7: LCD bit 7
D8: LCD RS
D9: LCD Enable

It doesn't list the DFRobot Ethernet shield I have but it does list the following:

D13 / SCK
D12 / MISO
D11 / MOSI ~
D10 / SS ~
D2 - unspesified usage
A0 - unspesified usage
A1 - unspesified usage

I looked at other ethernet shields that are listed and found some also use D4.

So, I mapped the LCD shield A0 to use A2 pin and D4 to use A4 and reloaded the sketch. Now, when the sketch loads I do get a reset of the LCD and the initial display, and I get an ethernet connection and one write to the MySQL DB. Then, things hang up. I'm still looking at the code but it appears that something is happening when the ethernet write happens. Does anyone know if the ethernets driver does anything internally with pins to indicate a good or bad response? Making progress but this is strange.

I also ordered new Arduino ethernet shields to remove the DFRobot shields as potential problems...