Project 1 - Interfacing a 16*2 LCD with Arduino using I2C protocol
//Master
#include //Library for I@C Communication
#include //Library for LCD display functional
LiquidCrystal lcd(12,11,5,4,3,2); //Define LCD Module Pins (RS, E, D4, D5, D6, and D7 )
void setup()
{
lcd.begin(16,2); //initializes the LCD display with 16 columns and 2 rows.
lcd.setCursor(0,0); //sets the cursor to the first column of the first row.
lcd.print("skill lync"); //prints the string "skill lync" on the LCD display.
lcd.setCursor(0,1); //sets the cursor to the first column of the second row.
lcd.print("I2C ARDUINO 2 ARDUINO"); //prints the string "I2C ARDUINO 2 ARDUINO" on the LCD display
for(int i=0; i<16; i++) //for loop , Repeating 16 times
{
lcd.scrollDisplayLeft(); //scrolls the entire display to the left by one character
delay(100); //every 100 milliseconds
}
delay(2000); //delay for 2 sec
lcd.clear(); // clears the LCD display.
Serial.begin(9600); //initializes serial communication at a baud rate of 9600.
Wire.begin(); //initializes the I2C communication at pin(A4,A5)
}
void loop()
{
Wire.requestFrom(8,1); //requests 1 byte of data from the slave device with the address 8
byte MasterReceive = Wire.read(); // stores the received 1 byte of data in the MasterReceive variable.
int potvalue = analogRead(A0); // reads the value of the potentiometer connected to analog pin A0 and stores it in the potvalue variable.
byte MasterSend = map(potvalue,0,1023,0,127); //maps the range of values (0 to 1023) to the range of bytes (0 to 127)
//or Convert digital value (0 to 1023) to (0 to 127) and stored in the MasterSend variable
Wire.beginTransmission(8); //begins an I2C transmission to the slave device with the address of 8,
Wire.write(MasterSend); //sends one byte converted POT value to slave
Wire.endTransmission(); //stop transmitting
lcd.setCursor(0,0); // sets the cursor position to the beginning of the first row of the LCD display
lcd.print(">> The Master << "); //prints the string ">> The Master <<" on the first row
lcd.setCursor(0,1); //sets the cursor position to the beginning of the second row
lcd.print("Slave Value: "); //prints the string Slave Value:
lcd.print(MasterReceive); //pritns MasterReceive in LCD received from Slave
Serial.print("Master received from slave :"); //prints in serial monitor
Serial.print(MasterReceive);
Serial.print("\n");
delay(500); // delay of 500 milliseconds
lcd.clear(); // clears the LCD display
}
//slave
#include //Libraray for I2C Communication function
#include //Library for LCD display function
LiquidCrystal lcd(12,11,5,4,3,2); //Define LCD Module Pins(RS,EN,D4,D5,D6,D7)
byte SlaveReceived = 0; //declares a variable SlaveReceived to hold the byte of data received from the master
void setup()
{
lcd.begin(16,2); //sets up the LCD display by initializing it with 16 columns and 2 rows
lcd.setCursor(0,0); //sets the cursor to the first column of the first row.
lcd.print("Skill lync"); //prints the string "skill lync" on the LCD display
lcd.setCursor(0,1); //sets the cursor to the first column of the second row
lcd.print("I2C ARDUINO"); //prints the string "I2C ARDUINO" on the LCD display
delay(5000); //Delay for 5 seconds
lcd.clear(); //Clear LCD display
Serial.begin(9600); //initializes serial communication at a baud rate of 9600.
Wire.begin(8); //initializes the I2C communication with slave address as 8 at pin(A4,A5)
Wire.onReceive(receiveEvent); //Function call when slave receives value from master
Wire.onRequest(requestEvent); //Function call when Master request value from Slave
}
void loop(void)
{
lcd.setCursor(0,0); //sets Cursor at line one of LCD
lcd.print(">> The Slave <<"); //prints >> Slave << at LCD
lcd.setCursor(0,1); //sets Cursor at line two of LCD
lcd.print("Master value: "); //Prints Master value: in LCD
lcd.print(SlaveReceived); //prints SlaveReceived value in LCD received from Master
Serial.print("Slave Received From Master : "); //prints in Serial Monitor
Serial.print(SlaveReceived);
Serial.print("\n");
delay(500);
lcd.clear(); //clears the LCD display
}
void receiveEvent(int howMany) //function which is called when the master sends data to the slave.
{
SlaveReceived = Wire.read(); //function reads the received byte from the master and stores it in the SlaveReceived variable
}
void requestEvent() // function which is called when the master requests data from the slave
{
int potvalue = analogRead(A0); //reads the analog value from the potentiometer connected to analog pin A0
byte SlaveSend = map(potvalue,0,1023,0,127); // maps the range of values (0 to 1023) to the range of bytes (0 to 127)
Wire.write(SlaveSend); //The resulting byte is then sent to the master using the Wire.write() function
}
EXPLANATION
The LiquidCrystal library allows you to control LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface.
The LCDs have a parallel interface, meaning that the microcontroller has to manipulate several interface pins at once to control the display. The interface consists of the following pins:
A register select (RS) pin that controls where in the LCD's memory you're writing data to. You can select either the data register, which holds what goes on the screen, or an instruction register, which is where the LCD's controller looks for instructions on what to do next.
A Read/Write (R/W) pin that selects reading mode or writing mode
An Enable pin that enables writing to the registers
8 data pins (D0 -D7). The states of these pins (high or low) are the bits that you're writing to a register when you write, or the values you're reading when you read.
There's also a display contrast pin (Vo), power supply pins (+5V and GND) and LED Backlight (Bklt+ and BKlt-) pins that you can use to power the LCD, control the display contrast, and turn on and off the LED backlight, respectively.
The process of controlling the display involves putting the data that form the image of what you want to display into the data registers, then putting instructions in the instruction register. The LiquidCrystal Library simplifies this for you so you don't need to know the low-level instructions.
The Hitachi-compatible LCDs can be controlled in two modes: 4-bit or 8-bit. The 4-bit mode requires seven I/O pins from the Arduino, while the 8-bit mode requires 11 pins. For displaying text on the screen, you can do most everything in 4-bit mode, so the example shows how to control a 16x2 LCD in 4-bit mode.
Hardware Required
Arduino Board -2 no's
LCD Screen (compatible with Hitachi HD44780 driver)
pin headers to solder to the LCD display pin
220-ohm resistor
hook-up wires
breadboard
Before wiring the LCD screen to your Arduino board we suggest to solder a pin header strip to the 14 (or 16) pin count connector of the LCD screen, as you can see in the image further up.
To wire your LCD screen to your board, connect the following pins:
LCD RS pin to digital pin 12
LCD Enable pin to digital pin 11
LCD D4 pin to digital pin 5
LCD D5 pin to digital pin 4
LCD D6 pin to digital pin 3
LCD D7 pin to digital pin 2
LCD R/W pin to GND
LCD VSS pin to GND
LCD VCC pin to 5V
LCD LED+ to 5V through a 220-ohm resistor
LCD LED- to GND
Additionally, wire a 10k potentiometer to +5V and GND, with it's wiper (output) to LCD screens VO pin (pin3).
The I2C protocol involves using two lines to send and receive data: a serial clock pin (SCL) that the Arduino Controller board pulses at a regular interval, and a serial data pin (SDA) over which data is sent between the two devices. As the clock line changes from low to high (known as the rising edge of the clock pulse), a single bit of information - that will form in sequence the address of a specific device and a command or data - is transferred from the board to the I2C device over the SDA line. When this information is sent - bit after bit -, the called upon device executes the request and transmits it's data back - if required - to the board over the same line using the clock signal still generated by the Controller on SCL as timing.
Because the I2C protocol allows for each enabled device to have it's own unique address, and as both controller and peripheral devices to take turns communicating over a single line, it is possible for your Arduino board to communicate (in turn) with many devices, or other boards, while using just two pins of your microcontroller.