Analog pins don't run LCD

I have a sketch that uses the standard 16x2 LCD. The original sketch works with the LCD being defined as:
LiquidCrystal lcd(12, 13, 7, 6, 5, 4);

I would like to use some of the digital pins for a PWM output, so I thought I could use some PORTC pins (ADC input) for run the LCD. After poking around online a bit, it seems that the definition:
LiquidCrystal lcd(12, 13, 18, 17, 16, 15); should have worked, but there is no display on the LCD.
What am I missing?

Also - I'm curious to know why the pinout for the display in 4-bit mode id D4..D7, (i.e. more significant bits as you go left to right) but the library definition has the opposite (i.e. less significant bits as you go left to right). I tried looking at the source code in the library folder, and it is even more confusing, as the only code I could find that seemed to deal with the 4-bit mode had D0-D3, with zeros in the D4-D7 positions. Obviously, as a non-OOP user, I am pretty much lost when it comes to class definitions, so any simple explanation would be appreciated!

LiquidCrystal lcd(12, 13, 18, 17, 16, 15);
 //LiquidCrystal lcd(12, 13, A4, A3, A2, A1);

Your constructor works for me. Are you sure you are wired to A4 to D4 , A3 to D5, A2 to D6, and A1 to D7?

You can use the analog nomenclature A0-A5 for the pins even when using them digitally, and you do not need the 14-19 numbers. The numerical mapping certainly works on a UNO, but it is not universal across all boards.

The reason why D4-D7 are used in the 4 bit mode is a function of the HD44780 controller.http://www.spickles.org/download/4bit_lcd/HD44780.pdf

From the data sheet:

Interfacing to the MPU
The HD44780U can send data in either two 4-bit operations or one 8-bit operation, thus allowing
interfacing with 4- or 8-bit MPUs.
• For 4-bit interface data, only four bus lines (DB4 to DB7) are used for transfer. Bus lines DB0 to DB3
are disabled. The data transfer between the HD44780U and the MPU is completed after the 4-bit data
has been transferred twice. As for the order of data transfer, the four high order bits (for 8-bit
operation, DB4 to DB7) are transferred before the four low order bits (for 8-bit operation, DB0 to
DB3).
The busy flag must be checked (one instruction) after the 4-bit data has been transferred twice. Two
more 4-bit operations then transfer the busy flag and address counter data.
• For 8-bit interface data, all eight bus lines (DB0 to DB7) are used.

cattledog:

LiquidCrystal lcd(12, 13, 18, 17, 16, 15);

//LiquidCrystal lcd(12, 13, A4, A3, A2, A1);




Your constructor works for me. Are you sure you are wired to A4 to D4 , A3 to D5, A2 to D6, and A1 to D7?

Yes, the wiring is correct. I've checked several times.

You can use the analog nomenclature A0-A5 for the pins even when using them digitally, and you do not need the 14-19 numbers. The numerical mapping certainly works on a UNO, but it is not universal across all boards.

I tried both ways, the code compiles & loads without any errors, just no LCD activity.

The reason why D4-D7 are used in the 4 bit mode is a function of the HD44780 controller.http://www.spickles.org/download/4bit_lcd/HD44780.pdf

Actually, the question I had was more of why is bit weighting reversed in the original sketch? To wit:
LiquidCrystal lcd(12, 13, 7, 6, 5, 4);
According to this setup, D7 goes to the LSB of the port pins, rather then the MSB, and so on down the line. That seems backwards - why doesn't D7 got to digital pin 7, D6, to pin 6, etc?

From the data sheet: 

Interfacing to the MPU
The HD44780U can send data in either two 4-bit operations or one 8-bit operation, thus allowing
interfacing with 4- or 8-bit MPUs.
• For 4-bit interface data, only four bus lines (DB4 to DB7) are used for transfer. Bus lines DB0 to DB3
are disabled. The data transfer between the HD44780U and the MPU is completed after the 4-bit data
has been transferred twice. As for the order of data transfer, the four high order bits (for 8-bit
operation, DB4 to DB7) are transferred before the four low order bits (for 8-bit operation, DB0 to
DB3).
The busy flag must be checked (one instruction) after the 4-bit data has been transferred twice. Two
more 4-bit operations then transfer the busy flag and address counter data.
• For 8-bit interface data, all eight bus lines (DB0 to DB7) are used.

OK, I found out something interesting - MSB/LSB doesn't seem to matter, if I reverse the order, it still works, as long as the appropriate pins are correctly connected.
However, more interestingly - using the analog pins worked when I used the lowest nybble - A0..A3, instead of A1..A4. It seems the class doesn't like jumping nybble bounds???

I tried both ways, the code compiles & loads without any errors, just no LCD activity.

To solve this, you will need to post a photograph which clearly shows the connections between your display and Arduino. Also, please post the exact code you are attempting to run. What Arduino are you using? What liquid crystal library?

It's usually not a good idea to be using pin 13 because of the connection to the led, so I would recommend moving the Enable line to another pin like 11.

Actually, the question I had was more of why is bit weighting reversed in the original sketch? To wit:
LiquidCrystal lcd(12, 13, 7, 6, 5, 4);
According to this setup, D7 goes to the LSB of the port pins, rather then the MSB, and so on down the line. That seems backwards - why doesn't D7 got to digital pin 7, D6, to pin 6, etc?

I'm not sure I understand your question. The library and the constructor tell the Arduino what data to put on what digital pin for its connection to D4-D7. There is no relationship between the pin arrangement on the Arduino port registers and the data lines of the lcd. You can connect any Arduino pin to D4-D7 of the lcd as long as you tell the library about it through the constructor.

You can play around with different wiring arrangements and constructors to prove that to yourself. You can get this to work. It's running on my desk right now.

LiquidCrystal lcd(12, 13, 18, 17, 16, 15);
 //LiquidCrystal lcd(12, 13, A4, A3, A2, A1);

There is no relationship between the pin arrangement on the Arduino port registers and the data lines of the lcd. You can connect any Arduino pin to D4-D7 of the lcd as long as you tell the library about it through the constructor.

You can play around with different wiring arrangements and constructors to prove that to yourself. You can get this to work. It's running on my desk right now.

I think the comments in the following code examples express this key point a little more clearly:

These are all equivalent ways to define the pins (although I wouldn't recommend the third one):

//LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(12, 13, 18, 17, 16, 15);      // put your pin numbers here
//LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(12, 13, A4, A3, A2, A1);      // put your pin numbers here
//LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(12, 13, A4, 17, 16, A1);      // put your pin numbers here

Don

@cattledog: OK, I understand that a pin assignment should theoretically not affect the output - that one should be able to assign pins more-or-less randomly, and count on the constructor to resolve the connection issues.

However - as I mentioned above, using analog pins 1,2,3,4 did NOT work - the LCD (generic 16x2 Hitachi module) just had a blank screen. When I changed the pin assignments to analog 0,1,2,3 (and obviously shifted the interconnect wires!) the LCD worked & displayed normally. Since the initial case (A1,2,3,4) case crossed a nybble boundary for the, it makes me wonder if that is an issue in the constructor?

Also, since I'm not using a "real" Arduino (I have an ATmega328 with the bootloader programmed in) pin A0 is available for my projects.

At any rate, at this point, I can get the LCD to display, and I have a PWM pin available for my project, but the whole pin assignment issue is just one that makes me wonder what is going on.

You can mix any pins in the constructor().

A1, 2, 3, 4 is very different to A1, A2, A3, A4

It does not matter whether you have a genuine UNO, a clone, or a bare mega328P, ...
The Arduino libraries will work fine. In fact they will also work on all the other "supported" AVRs.

David.

Since the initial case (A1,2,3,4) case crossed a nybble boundary for the, it makes me wonder if that is an issue in the constructor?

No, it is not.

To resolve your anomaly, I would recommend testing the A1,A2,A3,A4 outputs to the lcd with simple digital write commands. You can run the wires to another pin and do a digital read, or use a multi meter to see if they are live. There could be a problem with your chip, its mountings, the wires, a bread board hole or a solder joint.

To resolve your anomaly, I would recommend testing the A1,A2,A3,A4 outputs to the lcd . . .

In this case it might be easier for him to start with a working configuration and change one wire at a time and make the appropriate constructor change as well of course.

Don

Well shoot me and call me stupid! After hours of fiddling with moving wires, and finally running the simple test program as @cattledog suggested, I found the problem - I had a jumper to Vcc on A4 that I had missed when examining the wiring. After removing that jumper, I can use A1..A4 to run the LCD.
My face is red, but my LCD works, so thank you to all who gave advice and counsel, it made a difference!
Good job, all!

davetelling:
My face is red, but my LCD works, so thank you to all who gave advice and counsel, it made a difference!

I daresay we knew that actually - that you had a wrong connection. That's why

cattledog:
To solve this, you will need to post a photograph which clearly shows the connections between your display and Arduino.

But you didn't do that, did you? That's why helpers here get frustrated and tend to ignore you.

I would like to know why you would have a jumper from A4 to VCC which should never have been there for any reason whatsoever?

@Paul_B - I didn't post a photograph of the LCD connections, as they were, in fact, correct. The error was a leftover jumper from a previous project (as I mentioned, I'm not using an actual Arduino board - I have a mega328 that I programmed with a bootloader, and a homebrew serial interface for uploading the sketch) and it was not immediately visible, as it was behind the serial interface board I'm using. A photo would not have helped much. I have designed a number of projects in my previous employment that used a variety of Atmel uC's, and I cannot even rremember what this board may have been used for previously.

At any rate, I got my AD9850 boards today & have been having a wonderful time designing my latest project. However, it looks as if I'll need to step up to a larger device,m as I think I may need more I/O than the mega328 provides.

As a general rule, you should never connect a GPIO pin directly to VCC or GND.

If you want to provide a signal to some external electronics, use an externnal pull-up or pull-down resistor. e.g. 10k.

Admittedly, you do not upset an Analog pin in this way.

Paul's advice for a photo is always wise. Many fresh pairs of eyes can often spot wiring errors

David.

davetelling:
However, it looks as if I'll need to step up to a larger device, as I think I may need more I/O than the mega328 provides.

Generally, you only "step up" to a larger device if and when you need more code space or RAM.

Adding extra I/O is usually better done using port expanders such as the PCF8574 which uses - shares - the I2C interface or simply shift registers such as the 74HC595 or TPIC6B595 which share as few as three pins for multiple devices.

Now using port expanders actually reduces PCB complexity as they become "satellites" which require few lines to interface, but can be located closer to where the multiple ports are needed.

I strongly disagree. If you need more GPIO use a bigger Arduino like the Mega2560. More pins, more memory. Life is a lot simpler with a single MCU.

Before you make the change, think very carefully about your needs. You can have multiple devices on the SPI bus and multiple on the I2C bus.

Whereas it is easier to monitor sensors from your main MCU, it is worthwhile using an intelligent display and keyboard. ..e.g. an I2C adapter for your 20x4 lcd or an SPI graphics display.

This will give you plenty of spare pins for your inputs and outputs.

David.