For any project, there are a lot of things that all have to go right, and any one of these problems could cause it not to work:
- Power supply
- LCD contrast adjustment
- Interface wiring
- Command timing
- Defective hardware
- Firmware/software design errors
- Hardware design errors
Looks like the HD44780 (or equivalent) controller is driving the panel in 1x16 mode, with 5x8 black pixel grid for each character. Those are the initial, default settings before the display has been configured. So this indicates that the panel is receiving power. But there could be problems with the contrast, the interface, the timing, etc.
LCD contrast adjustment
When the LCD panel shows either a "ghost grid" where all the pixels are barely visible, or a dark grid (like in the photo) where all of the pixels are dark, that suggests a problem with LCD contrast. This is also affected by viewing angle. Normally you would have to adjust the trimpot until there is good contrast between the pixels.
But, this problem is more difficult if the panel hasn't been successfully initialized yet -- the panel may be displaying a blank grid, and it's hard to properly adjust contrast unless you know some pixels are "on" and some are "off". So you may have to try adjusting the contrast after every experiment, because you can't tell whether it's blank because of a contrast problem or an initialization problem. If you run the "hello world" program (see below) that should give you a visible pattern for contrast adjustment.
Some panels require negative voltage for contrast, but most modern panels use contrast between the VDD/GND supply rails. You can find out if the display has a datasheet, but if it's something from a sketchy "marketplace" like alibaba or amazon marketplace (not amazon itself) or banggood or ebay, these vendors often don't include datasheets. If you're going to try testing negative contrast, use a large value resistor in series (like 100k) to protect against excessive current -- if it's not a negative voltage panel, applying negative bias (without current limiting) could damage the panel.
Looks like you've got it wired for nybble mode (DB7-DB4). That's not the default configuration; the panel will require a certain initialization sequence to work. But it's a pretty commonly used configuration, and it's well supported.
Typical initialization sequence for nybble mode looks like this:
- D7-D4 connected
- D3-D0 no connect
- high nybble is sent first
- Function set DL=0.
0001_0000 function set: 4 bit interface, one line, 5x7 font
0000_1111 Display on, cursor on, blink on
0000_0110 entry mode set: increment, no shift
0000_0001 clear display and set index to 0
You've got the R/W control line tied to ground, so it's a read-only interface. Sometimes firmware designers do this to save a pin, but it has another cost: you can't read back anything from the display. No way to read the ready/busy status, so the firmware has to wait the maximum time for each command. And there's no way for the firmware to detect whether or not the display is connected, without the R/W control line.
Since you've got the R/W control line tied to ground, there's no way to read the LCD ready/busy status... it's a write-only configuration... so timing problems are likely unless you allow sufficient time before and after each command; 1.0usec would be generous. You're using an Arduino UNO, which is a pretty slow microcontroller board.
The Adafriut "LiquidCrystal Library - Hello World" that comes with the Arduino platform (Examples - LiquidCrystal - Hello World) uses nybble mode; it runs slow enough on stock Arduino UNO, and is a good place to start, given that you're using a solderless breadboard.
I don't recognize any logos on your display panel; it's not optrex or any other brand-name panel. For a one-off prototype that you're not selling, it's probably ok, but it's anyone's guess whether it works. No refunds.
(For context, I'm an applications engineer at an IC manufacturing company, and I know of one specific case where a customer found a defect where our part didn't perform to a published datasheet specification. We had to fix it, recall material, improve the test program, issue refund, etc. There was never any question about whether we had to make it right, fixing it was the top priority. But a part with no datasheet really carries no warranty.)
Hopefully your display panel isn't the problem.
Firmware/software design errors
Starting with a known-good "hello world" program is a good first step. If you start from scratch with new hardware and new firmware, it's hard to locate faults.
The Adafriut "LiquidCrystal Library - Hello World" that comes with the Arduino platform (Examples - LiquidCrystal - Hello World) is a good working example to start with. You may have to verify that the rs,en,d4,d5,d6,d7 pin assignments match up with what you've wired in your hardware.
Hardware design errors
Can't really evaluate the hardware since you don't have a schematic shown. But I'm guessing that you're using resistance values to differentiate between different buttons, another commonly used pin-sharing technique.
An LCD display is complicated enough that it's best to bring it up by itself, and validate that it's working, before trying to add on other features.