In complex project using Arduino that requires 16x2 LCD for display it can be problematic. Because using a 16x2 requires at least 6 digital pin (RS, EN, D4, D5, D6, and D7). Your digital pins and analog pins maybe exhausted because you have potentiometer and other sensors already connected. So in large projects with Arduino I/O pins quickly runs out. One may use a I2C LCD as inArduino Nano I2C LCD Interfacing & Programming, but you may have already used it for connecting other peripheals to the available I2C pins. Such problem forces hobbyists to either upgrade to boars like Arduino Mega or sacrifice features to keep the LCD display.
The problem of I/O pin exhaustion can be solved using the 74HC595 shift register. By using the 74HC595 "Serial-In, Parallel-Out" (SIPO) architecture, you can control all the data and control lines of the display using only 3 digital pins (Data, Clock, and Latch). You can send the data like Analog sensor data to the 74HC595 in a serial stream and the shift register unpacks and sends out in parallel data to the 16x2 LCD. This effectively frees up three additional pins for other sensors or actuators while maintaining a fast, responsive interface for real-time data visualization.
An example circuit is shown below. Here Arduino Nano is used to read the POT value and sends the data to shift register IC serially. The Arduino 3 pins D2,D3 and D4 is connected to the shift register DS,STCP and SHCP pins respectively. The LCD16x2 pins D7 to D4 are connected to the shift register Q1 to A4 pins, the EN and RS pins are connected to the Q5 and Q6 respectively.
#include <LiquidCrystal_74HC595.h>
// Shift Register Pins
const int dataPin = 2;
const int latchPin = 3;
const int clockPin = 4;
// Potentiometer Pin
const int potPin = A0;
// Mapping: (data, clock, latch, RS, E, D4, D5, D6, D7)
// RS=6, E=5, D4=4, D5=3, D6=2, D7=1
LiquidCrystal_74HC595 lcd(dataPin, clockPin, latchPin, 6, 5, 4, 3, 2, 1);
void setup() {
lcd.begin(16, 2);
lcd.print("Voltage Meter");
delay(1000);
lcd.clear();
}
void loop() {
// Read the raw value (0 to 1023)
int rawValue = analogRead(potPin);
// Convert raw value to voltage (0.0 to 5.0)
// Formula: (Raw Value * Input Voltage) / Max Resolution
float voltage = (rawValue * 5.0) / 1023.0;
// Display on LCD
lcd.setCursor(0, 0);
lcd.print("Raw: ");
lcd.print(rawValue);
lcd.print(" "); // Clear trailing digits
lcd.setCursor(0, 1);
lcd.print("Volt: ");
lcd.print(voltage, 2); // Display with 2 decimal places
lcd.print(" V ");
delay(200); // Small delay to make the screen readable
}
This code creates a digital voltmeter using an Arduino. It reads an analog signal from a potentiometer and displays both the raw digital value and the calculated voltage on an LCD screen.
Because standard LCDs use many pins, this code uses a 74HC595 Shift Register to control the screen using only three digital pins from the Arduino.
1. Library and Pin Configuration
The code starts by including the specific library needed to talk to an LCD through a shift register.
Shift Register Pins:
dataPin,latchPin, andclockPinare the three wires that send data from the Arduino to the 74HC595 chip.The Constructor: The line
LiquidCrystal_74HC595 lcd(...)tells the library exactly how the shift register pins are wired to the LCD's pins (RS, Enable, and Data lines).
2. The Setup Phase
The setup() function runs once when the Arduino powers on:
lcd.begin(16, 2): Initializes the screen size (16 columns, 2 rows).Splash Screen: It prints "Voltage Meter" for one second before clearing the screen to start measurements.
3. Reading and Converting Data
Inside the loop(), the Arduino performs the math required to turn electricity into numbers.
analogRead(potPin): The Arduino's Analog-to-Digital Converter (ADC) converts the voltage (0V to 5V) into a whole number between 0 and 1023.The Math: To get the actual voltage back, we use this formula:
$$V_{out} = \frac{\text{Raw Value} \times 5.0}{1023}$$Using
floatensures the result includes decimal points (e.g., 3.45V) rather than just rounding to the nearest whole number.
4. Updating the Display
The code updates the screen every 200 milliseconds:
setCursor(0, 0): Moves the "typing cursor" to the top-left.
print(voltage, 2): The
2tells the Arduino to show exactly two digits after the decimal point.Trailing Spaces: You’ll notice
lcd.print(" "). This is a clever trick to "erase" old characters. For example, if the value drops from "1000" to "99", the extra spaces ensure the "0" from the old number isn't left behind on the screen.
Related

