Pages

Friday, January 3, 2020

ARDUINO with GLCD




Here we are going to interface a 128 x 64 graphical LCD which consists of two KS0108 LCD controllers. This GLCD widely used in embedded system products. First of all, if we want to interface a graphical LCD then we have to, learn some basic principles of LCD working. You can consider an LCD as an array of led lights if you want to show something on the display you have to on or off the led in the required pattern. The 128 x 64 led has 128 pixels or you can say led in a row whereas 64 pixels (led) in the column. Now we only need to access these LEDs to on-off them in a required manner.

The 128 x 64 led has 2 KS0108 controllers so let’s try to understand the working of these controllers in GLCD.  See the below image which represents the GLCD pixel map -



In the above image, you can easily find out that the first controller controls the first half of display from the left side and the second one, the second half of the display. The first controller is responsible for the 64 bits in y-direction as well as in x direction also here we can see that the first half display is divided into 8 segments which are known as “Page”. So the x direction 64 bit is divided into 8 segments of 8 bit or page.

If we want to display an image than we have to, put the pixel values of that image in according to this LCD pixel distribution. Now let’s see the pin configuration of the GLCD and which pin is useful for us.
As in the above image, there are 8 pins which are known as data pins (DB0 – DB7). These pins are used to transmit or receive 8-bit data between CPU (Arduino) and GLCD Controllers. There are 5 Control signal pins which we will use to convey the GLCD about our requirements. The CS1 and CS2 pins are active high pins which we will use for selecting the controller from the two controllers (KS0108). The DI pin is known as data/instruction pin, this pin is used for the convening GLCD that, the transmitted data on data pins is a data or an instruction. The R/W pin is read/write pin which acknowledges that the CPU is going to write data on LCD or going to read data from the LCD. When this pin is high it means that CPU is going to read data from LCD whereas if this pin is low then CPU is going to write data on LCD, That’s why we will connect it to the ground because here we want to write data on LCD only. The E Pin stands for Enable pin which acts as gate opener, so we have to give a small pulse every time whenever we want to transmit the data.



After setting up all hardware we have to prepare code for GLCD. Here we are going to write code without using any GLCD library of ARDUINO. If you have interfaced a 16 x 2 LCD then it is very easy for you to interface a GLCD, but if you don’t then don’t worry I am here. If you want to interface an LCD then you have to follow just only two steps, first is, initialize the LCD by giving initial commands and then start feeding the data which you want to show. Here I am giving the table below which is used for initializing the GLCD.



Here I have cross marked all unnecessary commands. First of all, we have to initialize the LCD but before that, we have to define some control signal pins and data pins which is given below-

//-------------------------------------------------------------------------------------------------//
#define data PORTD //port for 8 Bit data #define en 13 // defined control signal pins #define rs 12 #define cs1 10 #define cs2 11 int x = 0; // some variables that will be used in the programming int p = 0; int z = 0; byte img[] = {}; //Put HEX code of an 128x64 image
//------------------------------------------------------------------------------------------------//

The setup function will be like this -

//-----------------------------------------------------------------------------------------------//
void setup() { DDRD = DDRD|B11111111; // Setting up port D as a 8 bit data out port pinMode(en, OUTPUT); // setting up all control signal pins pinMode(rs, OUTPUT); pinMode(cs1, OUTPUT); pinMode(cs2, OUTPUT); lcdon(); // function call to initialize LCD setx(0xb8); // this function sets the initial address for x (row) sety(0x40); // this function sets the initial address for y (column) }
//-----------------------------------------------------------------------------------------------//

Here the three function named lcdon(), setx(), sety() will be discussed later. Let’s start coding the function which we will use. First of all, we are taking enable function which is nothing but a single high pulse generator. In this function, we will make enable pin high for a few mill seconds and then we will make it low. The code for this given below.

//-----------------------------------------------------------------------------------------------//
void enable(){ digitalWrite(en, HIGH); // make en pin high delay(0.5); //delay 0.5ms digitalWrite(en, LOW); // make enable pin low delay(0.5); //delay 0.5ms }
//-----------------------------------------------------------------------------------------------//

Next, we are going to take lcdon function. In this function, we will send the LCD on command to GLCD. For this, first of all, we will pull up the CS1 and CS2 pin high as we want to initialize both the part of GLCD. After that, we will make DI pin low because the data we want to send is a command not manipulating data which is going to display on the LCD. Here we are going to send 0x3f hex data which will initialize the LCD. The 0x3f hex is taken from initializing command data which is given above you can refer that. After all this, we are going to call enable function because it works like gate opener for the GLCD controller.

//-----------------------------------------------------------------------------------------------//
void lcdon(){ digitalWrite(cs1, HIGH); //select 1st KS0108 digitalWrite(cs2, HIGH); //select 2nd KS0108 digitalWrite(di, LOW); // make di low for command data = 0x3f; //glcd initializing hex data enable(); }
//-----------------------------------------------------------------------------------------------//

Similarly, we will send set the control signals in setx and sety function but just we will change the command hex code according to the function like for setting up x display address we will send 0xb8 which sets the x address to page 0 (First page).

//-----------------------------------------------------------------------------------------------//
void sety(byte datay){ digitalWrite(cs1, HIGH); //select 1st KS0108 digitalWrite(cs2, HIGH); //select 2nd KS0108 digitalWrite(di, LOW); //make di low for command data = datay; //set data which is hold by datax enable(); } void setx(byte datax){ digitalWrite(cs1, HIGH); //select 1st KS0108 digitalWrite(cs2, HIGH); //select 2nd KS0108 digitalWrite(di, LOW); // make di low for command data = datax; //set data which is hold by datax enable(); }
//-----------------------------------------------------------------------------------------------//

The value of datax and datay will be given by passing the value at the time of function call according to our needs.

The next functions are writ1 and writ2 which are used for holding the data into a variable from the image data array. The writ1 function holds the data from 0 to 63 for the first page of the first controller and writ2 holds the data from 64 to 127 of the next controller. Here we will pull up the DI signal pin as now the transmitted hex code is not a command.

//-----------------------------------------------------------------------------------------------//
void writ1(int c1){ digitalWrite(cs1, HIGH); //select first controller digitalWrite(cs2, LOW); // deselect the second controller digitalWrite(di, HIGH); // Pull up di high as the hex data is now not a command data = img[c1]; //copy img array data into "data" variable enable(); } void writ2(int c2){ digitalWrite(cs1, LOW); //deselect first controller digitalWrite(cs2, HIGH); // select the second controller digitalWrite(di, HIGH); data = img[c2]; enable(); }
//-----------------------------------------------------------------------------------------------//

Draw function is a very simple function which is used for placing the data into the display which was putted into a variable in the writ1 and writ2 functions. It uses 8 similar blocks for 8 rows or pages. It puts the value of image data one by one into their respective pixel address.


//-----------------------------------------------------------------------------------------------//
void draw(int p){ if(p==0){ //for first page for (x=0; x<64; x++){ // loop for 64 times writ1(x); //writ1 function call int y = 64+x; // for first page 2nd controller writ2(y); // call function writ2 } x=0; //reset the counter value } if(p==1){ // for page second setx(0xb9); // set the x address of second page sety(0x40); // set the y address of second page for (x; x<64; x++){ // loop for 64 times writ1(128+x); //writ1 function call int y = 192+x; // for second page 2nd controller writ2(y); // call function writ2 } x=0; } if(p==2){ // for page 3 setx(0xba); sety(0x40); for (x; x<64; x++){ writ1(256+x); int y = 320+x; writ2(y); } x=0; } if(p==3){ //for page 4 setx(0xbb); sety(0x40); for (x; x<64; x++){ writ1(384+x); int y = 448+x; writ2(y); } x=0; } if(p==4){ //for page 5 setx(0xbc); sety(0x40); for (x; x<64; x++){ writ1(512+x); int y = 576+x; writ2(y); } x=0; } if(p==5){ //for page 6 setx(0xbd); sety(0x40); for (x; x<64; x++){ writ1(640+x); int y = 704+x; writ2(y); } x=0; } if(p==6){ //for page 7 setx(0xbe); sety(0x40); for (x; x<64; x++){ writ1(768+x); int y = 832+x; writ2(y); } x=0; } if(p==7){ // for page 8 setx(0xbf); sety(0x40); for (x; x<64; x++){ writ1(896+x); int y = 960+x; writ2(y); } x=0; } }
//-----------------------------------------------------------------------------------------------//




//-----------------------------------------------------------------------------------------------//
byte img[] = { 0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xC4, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x10,0x30,0x30,0x50,0x90,0x10,0x18,0x07,0x00, 0x07,0x18,0x10,0x90,0x50,0x30,0x30,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1E,0x11,0x08,0x04,0x04, 0x04,0x08,0x11,0x1E,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x22,0x22,0x22,0x22,0x00, 0x00,0xFE,0xFE,0x00,0x00,0xE0,0xB0,0x90,0x90,0xB0,0xE0,0x00,0x00,0xE0,0x30,0x10, 0x10,0x30,0x00,0x10,0xF8,0xFC,0x10,0x00,0xF0,0xF0,0x10,0x10,0x00,0xE0,0x30,0x10, 0x10,0x30,0xE0,0x00,0x00,0xF6,0xF6,0x00,0x10,0xF8,0xFC,0x10,0x00,0xF0,0xD0,0x90, 0xB0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x10,0x10,0xF0, 0xE0,0x10,0x10,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x04,0x04,0x04,0x04,0x00, 0x00,0x07,0x07,0x00,0x00,0x03,0x06,0x04,0x04,0x06,0x02,0x00,0x00,0x03,0x06,0x04, 0x04,0x06,0x00,0x00,0x07,0x07,0x04,0x00,0x07,0x07,0x00,0x00,0x00,0x03,0x06,0x04, 0x04,0x06,0x03,0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x04,0x02,0x06,0x04,0x04, 0x07,0x01,0x00,0x03,0x07,0x04,0x04,0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07, 0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x30,0x0E, 0x0C,0x30,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x04,0xE4,0x18,0x80,0x80,0x40,0x40, 0x40,0x40,0x80,0x80,0x18,0xE4,0x04,0x02,0x01,0x01,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x21,0x21,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x21,0x21,0x23,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0x00,0x00 }; // sample image array
//-----------------------------------------------------------------------------------------------//

___________________________________________________________________________________________________________________________

I have putted all my efforts to convey the GLCD interfacing with Arduino but, if you want more help for better understanding then feel free to comment and ask for the help and if you also think anything is wrong then you can tell me.

___________________________________________________________________________________________________________________________

No comments:

Post a Comment

For You!

KiCad (PCB Layout)

I n this tutorial, we will continue the previous tutorial where we were discussed about how to design a schematic of the circuit. 1...