Today, we’re diving headfirst into the fascinating world of monochrome LCDs. Before we proceed, let’s take a moment to demystify these remarkable displays. Understanding the intricacies of LCD technology will be a cornerstone in our ongoing exploration. So, let’s get started!
What Are Monochrome LCDs?

Monochrome LCDs work on the fascinating principle of liquid crystals, which have the unique ability to align themselves between two differently polarized layers. This alignment allows them to either let light pass through or block it, creating the visual content you see on the screen.
These displays come in various configurations, with the most common being the 16×2 model, offering 16 characters across two rows. For those needing more display real estate, there’s also a 16×4 variant that provides a 16-character display spread over four rows.
Why Choose LCDs for Your Projects?
LCDs are compelling because of their ease of manufacture and cost-effectiveness. They are relatively inexpensive to produce in bulk and require minimal electrical current to function. This makes them the go-to choice for battery-operated projects, whether you’re working with Arduino, Raspberry Pi, or even need a display for serial monitoring.
Understanding LCD Display Pinouts
To get started with LCD projects, it’s crucial to understand the pinouts. A typical LCD display has 16 pins in total, stretching from Pin 1 on the far left to Pin 16 on the far right:
• Pin 1: Ground (GND)
• Pin 2: VCC (Supply Voltage)
• Pin 3: Adjusts screen brightness
• Pin 4: Register Select (RS)
• Pin 5: Read/Write (R/W)
• Pin 6: Enable (E)
• Pins 7-14: Parallel data input pins
• Pins 15-16: Control the anode and cathode of the backlight LED

Understanding these pinouts is foundational for any LCD project. Now that we’ve covered the basics, it’s time to dive into some practical experiments. So, without further ado, let’s get started!
Experiment 1: Displaying “Hello World” on a 16×2 LCD with Arduino
For our first experiment, we’ll integrate an LCD display with an Arduino Nano without using any I2C adapters.
Components Required:
• Arduino Nano Board: The heart of our experiment.
• LCD Display: Choose either the 16×2 or 16×4 variant.
• 10K Potentiometer and 220-ohm Resistor: For adjusting the display’s brightness.
• Small Breadboard and Jumper Wires: For easy and organized connections.
Wiring Your Display to Arduino
Let’s start by wiring the LCD display to the Arduino Nano board:
1. Power Connections:
• Connect the 5V output from the Arduino Nano to Pin 2 (VCC) on the LCD display.
• Connect the GND (Ground) from the Arduino Nano to Pin 1 on the LCD display.
2. Brightness Control:
• Attach both ends of the 10K potentiometer to the 5V and GND outputs of the Arduino.
• Connect the wiper pin (middle pin) of the potentiometer to Pin 3 on the LCD display.
3. Data Control Lines:
• Connect Arduino Pin 12 to Pin 4 (RS) on the LCD display.
• Ground Pin 5 (R/W) on the LCD display.
4. Enable Pin:
• Connect Pin 11 on the Arduino to Pin 6 (E) on the LCD display.
5. Data Lines:
• We’ll use 4-bit mode to save on wiring. Connect Arduino Pins 2, 3, 4, and 5 to LCD Pins 14, 13, 12, and 11, respectively.
6. Backlight Control:
• Connect Pin 15 on the LCD to 5V on the Arduino through a 220-ohm resistor.
• Connect Pin 16 on the LCD to GND on the Arduino.

With all the hardware connections in place, we’re ready to delve into the software portion of this experiment.
Uploading Code for the First Experiment
After successfully connecting the hardware, the next step is to upload code to the Arduino Nano to bring our LCD display to life. The Arduino IDE provides a built-in library called ‘LiquidCrystal’ that simplifies the process of programming LCDs.
1. Open Arduino IDE: If you haven’t already installed it, download it from the Arduino website.
2. Navigate to Examples: In the Arduino IDE, go to File > Examples > LiquidCrystal. This folder contains various sample sketches to get you started with LCD displays.
3. Load ‘Hello World’ Example: Inside the ‘LiquidCrystal’ folder, locate and open the ‘Hello World’ example sketch.
4. Understanding the Code:
• Pin Definitions: The code defines which Arduino pins are connected to the LCD display’s pins.
• Setup Function: Initializes the LCD display and sets the display’s column and row size.
• Loop Function: Sets the cursor position on the LCD and prints the ‘Hello World’ message along with a running counter displaying seconds elapsed.
5. Upload and Test: Connect your Arduino Nano to your computer via USB, and hit the ‘Upload’ button in the Arduino IDE. Your LCD should display ‘Hello World’ on the first line, with a running counter of seconds on the second line.
Experiment 2: Building a Weather Station and Desk Clock
In this experiment, we’ll take things up a notch by building a Mini Weather Station that displays temperature and humidity readings using a DHT22 sensor. It also functions as a desk clock, fetching time from the internet and displaying it in the desired format. We’ll familiarize ourselves with the I2C adapter, which significantly reduces the number of wires needed for your project.
Components Required:
• NodeMCU Board
• LCD Display with a pre-soldered I2C adapter
• DHT11 or DHT22 sensor
• Breadboard and Jumper Wires
Wiring Your Display to NodeMCU
Here’s how to wire your display:
• Connect the SDA pin from the I2C adapter to D2 on the NodeMCU, and the SCL pin to D1.
• Connect the VCC pin to a 3.3V pin on the NodeMCU, and the GND pin to the GND pin on the NodeMCU.
• Connect the DHT11 data pin to D4 on the NodeMCU. Lastly, connect the 3.3V and GND pins on the NodeMCU to the VCC and GND pins on the DHT11, respectively.

Uploading Your Code for the Second Experiment
For this project, we’ll write basic code that uses the DHT22 sensor to fetch temperature and humidity readings, displaying them on our I2C display. The code will also connect to an NTP server to fetch the current time and display it on the screen, serving as both a desk clock and a weather station, swapping each mode at 5-second intervals.
1. Importing Libraries: Various libraries for Wi-Fi, NTP (Network Time Protocol), the DHT sensor, and the LCD display are imported.
2. Defining Constants and Variables: Wi-Fi credentials (SSID and password) are defined, and the NTPClient is initialized with a time offset for your time zone.
3. setup() Function: The setup() function initializes the serial connection, Wi-Fi, NTP client, DHT sensor, and LCD display.
4. loop() Function: The loop() function updates the clock, scrolls text, and displays temperature and humidity readings.
// Include necessary libraries
#include <ESP8266WiFi.h>
#include <time.h>
#include <DHT22.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// WiFi credentials
const char* ssid = "YOUR WIFI ID"; //update your SSID
const char* password = "YOUR WIFI PASSWORD"; //update your password]
// Variables for storing time-related data
int currentHour;
String ampm;
String weekDayStr;
// DHT22 sensor pin
#define data 12
DHT22 dht22(data);
// Initialize LCD display
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Timing-related variables
unsigned long lastDHT22Update = 0;
unsigned long lastModeSwap = 0;
const long dht22Interval = 5000;
const long modeSwapInterval = 5000;
// Variable to control what is displayed (weather or time)
bool showWeather = false;
void setup() {
// Initialize the LCD and display the startup message
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("MaisonUp");
delay(2000);
lcd.clear();
// Connect to WiFi
lcd.setCursor(0, 0);
lcd.print("Connecting WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
// Display WiFi connected message
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Connected!");
delay(2000);
lcd.clear();
// Configure time
configTime(19800, 0, "pool.ntp.org");
while (time(nullptr) <= 0) {
delay(500);
}
}
// Function to get the name of the weekday
String dayOfWeek(int day) {
String days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
return days[day];
}
// Function to get the name of the month
String monthName(int month) {
String months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
return months[month];
}
// Function to display temperature and humidity on LCD
void showTemperatureAndHumidity(float t, float h) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: "); lcd.print(t, 1); lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Humidity: "); lcd.print(h, 1); lcd.print("%");
}
// Function to display time and date on LCD
void showTimeAndDate(struct tm* newtime, int currentHour, String ampm, String weekDayStr) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(currentHour); lcd.print(":");
if (newtime->tm_min < 10) lcd.print("0");
lcd.print(newtime->tm_min);
lcd.print(" "); lcd.print(ampm);
lcd.print(", "); lcd.print(weekDayStr);
lcd.setCursor(0, 1);
lcd.print(newtime->tm_mday); lcd.print(" "); lcd.print(monthName(newtime->tm_mon));
}
void loop() {
// Get current time in milliseconds
unsigned long currentMillis = millis();
// Get current time
time_t now = time(nullptr);
struct tm* newtime = localtime(&now);
// Check for valid time
if (newtime == nullptr || now <= 0) {
return;
}
// Determine AM or PM
ampm = "AM";
currentHour = newtime->tm_hour;
if (currentHour >= 12) {
ampm = "PM";
if (currentHour > 12) currentHour -= 12;
}
if (currentHour == 0) currentHour = 12;
// Get the day of the week
weekDayStr = dayOfWeek(newtime->tm_wday);
// Check if it's time to toggle the display mode (weather/time)
if (currentMillis - lastModeSwap >= modeSwapInterval) {
lastModeSwap = currentMillis;
showWeather = !showWeather;
}
// Check if it's time to read the DHT22 sensor
if (currentMillis - lastDHT22Update >= dht22Interval) {
lastDHT22Update = currentMillis;
float t = dht22.getTemperature();
float h = dht22.getHumidity();
// Display data on the LCD
if (isnan(t) || isnan(h)) {
lcd.print("Sensor Error");
} else if (showWeather) {
showTemperatureAndHumidity(t, h);
} else {
showTimeAndDate(newtime, currentHour, ampm, weekDayStr);
}
}
}
Once you’re satisfied with the code, ensure the correct board and port are selected, then click on ‘Upload’. If you’re new to the NodeMCU, we highly recommend watching our getting started video—link .
Conclusion
There you have it—successful integration of a monochrome LCD with your Arduino and NodeMCU projects. But that’s just the beginning! Stay tuned for more exciting experiments and tutorials. Thank you for joining us on this journey!