Featured Post

ARM- ADC and LCD Interface

In real world all natural quantities like temperature, pressure, light intensity etc. are analog. If we have to deal with such quantities us...

Friday, 7 May 2021

ARM- ADC and LCD Interface

In real world all natural quantities like temperature, pressure, light intensity etc. are analog. If we have to deal with such quantities using embedded systems, we have to convert these analog quantities which can be understood and proceed by digital signal. Devices used for this purpose is known as ADC. Special ICs such as ADC0804, ADC0808, ADC0809, Serial ADC MAX1112 etc. are handy for this. Nowadays, many controllers are having inbuilt ADC. LPC2138 of ARM7 family is one of the widely used controller and it also has multichannel ADC inbuilt. In this article, we will understand how to use inbuilt ADC of LPC2138.

ADCs acts as a bridge between the ANALOG real world and digital world of controllers. ADC converts analog voltage into a digital number which can be understood and proceed by controller. Let us understand this with an example.

LPC 2138 operates on 3.3V supply. If we use 10 bit ADC, 3.3V correspondences to 2^10=1023. Half of 3.3V= 1.65V can be represented by 512, 0V as digital value 0 and so on.

Before proceeding further, let us first understand few basic concepts related to ADC.

1 )  Resolution :

Analog voltage will be converted into a digital number. Number of bits required to store the digital number let say n bits is known as resolution. If a digital number is represented with n bits, the maximum value is 2n . So for 10 bit ADC resolution is 10 bit and maximum value is 210=1023.

2 ) Step Size : 

Minimum voltage which can be distinguished by controller is known as step size.

Step size= Maximum Voltage/ 2n

where n= resolution

For LPC 2138, Maximum voltage=3.3V and n=10, So step size=3.3/1023= 0.0032258064 V = 3.23 mv (Approx.)

Voltage between 0 and 3.23 mV will be identified as same for controller. This identifies the accuracy of ADC.

3 ) Conversion time : 

Converting analog voltage into a digital will not be done immediately. It will take few mili-seconds. Higher the resolution, higher is the conversion time. Now, let us start with ADC of LPC 2138. First let us have quick look at features of it.

· LPC 2138 has two inbuilt ADC modules known as ADC0 and ADC1.

· Maximum resolution of ADC is 10 bit. It is configurable by programming.

· ADC0 has 6 channels

· ADC1 has 8 channels

· Both ADC supports maximum clock frequency of 4.5 MHz (Operating frequency decides the conversion time)

Pins required for ADC are as follows.


Pins required for ADC

Let us understand all registers one by one : -

Registers Used to Configure ADC in LPC2138


The most important register for ADC is ADCR. Let us see the functions of each bit of this register.

The most important register for ADC is ADCR. Let us see the functions of each bit of this register.

Bit Value and Description of ADCR Register in LPC2138


 

Another important register is AD0GR and AD1GR. Bits of this register are as follows.

Bit Value and Description of ADCGR Register in LPC2138


Result of the conversion is stored in A/D Data register which has following structure.


Steps for programming ARM- ADC & LCD Interface : -

1 ) Configure input pin as analog input pin for ADC
2 )  Select channel of ADC
3 ) Start conversion
4 ) Wait till conversion is done
5 ) Read data of ADC Conversion output
6 ) Convert number into separate digits like 512 as separate 5,1 and 2
7 ) Display digits on LCD
8 ) Repeat above steps

The main Code for ARM- ADC and LCD Interface : it uses above lcd.h for lcd interfacing -

#include <LPC213x.h> /* LPC213x definitions */
#include "lcd.h"
void init_adc()
{
        PINSEL1 |= 0X01000000;
        ADCR = 0X00200602;
}
void delay(int n) /* generates one milisecond delay */
{
        int i,j;
        for (i=1; i<=n; i++)
        for(j=0; j<=10000; j++);
}

int read_adc(void)
{
        int val;
        ADCR |= 0x01000000; /* Start A/D Conversion */
        do 
        {
            val = ADDR; /* Read A/D Data Register */
        } while (!(val & 0x80000000)); /* Wait for end of A/D Conversion */
ADCR &= ~0x01000000; /* Stop A/D Conversion */
val >>=6;
val= val & 0x3FF;
return(val);
}

int main(void)
{
        int dat,i=0,int data,int da1=94;
        char buf[6];
        init_adc();
        init_lcd();
        lcd_command(0x01);
        lcd_command(0x80);
        printlcd("ADC Interfacing");
        lcd_command(0xC0);
        printlcd("with LPC2138");

        delay(20);
        lcd_command(0x01);
        lcd_command(0x80);
        printlcd("Digital Value");
        lcd_command(0xC0);
        while(1)
        {
                Delay(1000000);
                lcd_command(0xC0); // dipaying adc data at 2nd line of LCD
                dat = read_adc()*322;
                //data converted into digits
                buf[0]=dat%10;
                dat=dat/10;
                buf[1]=dat%10;
                dat=dat/10;
                buf[2]=dat%10;
                dat=dat/10;
                buf[3]=dat%10;
                dat=dat/10;
                buf[4]=dat%10;
                dat=dat/10;
                buf[5]=dat%10;
                buf[6]=dat/10;
                delay(10);
                lcd_data(buf[6]+'0');
                lcd_data(buf[5]+'0');
                lcd_data('.');
                lcd_data(buf[4]+'0');
                lcd_data(buf[3]+'0');
                lcd_data(buf[2]+'0');
                lcd_data(buf[1]+'0');
                lcd_data(buf[0]+'0');
        }
}

Circuit Diagram For ARM- ADC and LCD Interface : -

Circuit Diagram ARM-ADC And Interface


LCD Interface with ARM 2138 in 4 bit mode

The various LCD commands used to write data to LCD are given below : -

Various LCD commands used to write data to LCD

For Writing to LCD RS, RW and EN pins of a 16character 2 line LCD. It has 8 data pins can be configured in 4 bit and 8bit using proper commands. RS=1 for writing data, and RS=0 for register select for writing special character but for our program it is RS=1.

RW=0 I kept as such as we are writing data. EN=1 for enabling writing for 20 s and then EN=0 disabled.

Steps For LCD Interface With ARM 2138 In 4 Bit Mode

Step 1: initialize the LCD in 4 bit with 2 line.

Step2: create a library for writing a letter or strings.

The library is as follows.

Code For Creating Library For LCD Interface With ARM 2138 In 4 Bit Mode


#include <LPC21xx.h>

void Delay(unsigned long b)
{
    while (--b!=0);
}

void write_command(int cmd)
{
        IO1CLR |= 0x00f00000; // Clear Data pins
        IO1CLR |= 0x00040000; // RW = 0
        IO1CLR |= 0X00020000; // RS= 0,
        IO1SET |= 0x00f00000 & cmd; //Set Data pins
        IO1SET |= 0X00080000; // Enable = 1
        Delay(30000); // Provide Delay
        IO1CLR |= 0x00080000; // Set Enable=0
}

void write_data(int dat)
{
        IO1CLR |= 0x00f00000; // Clear Data pins4-D7
        IO1CLR |= 0x00040000; // RW= 0
        IO1SET |= 0X00020000; //RS= 1
        IO1SET |= 0x00f00000 & dat; // Set Data pins
        IO1SET |= 0X00080000; // Enable = 1
        Delay(30000); //Provide Delay
        IO1CLR |= 0x00080000; //Set Enable=0 
}

void lcd_data(char dat)
{
        write_data(dat << 16);
        write_data(dat << 20);
}

void lcd_command(char cmd)
{
        write_command(cmd << 16);
        write_command(cmd << 20);
}

void printlcd(char *CPtr)
{
        while(*CPtr != 0)
        {
                lcd_data(*CPtr);
                CPtr++;
                Delay(20000);
        }
}

void init_lcd(void)
{
        IO1DIR |= 0x00FE0000;
        Delay(200000) ;
        Delay(100000);
        write_command(0x30 << 16);
        Delay(100000);
        write_command(0x20 << 16);
        lcd_command(0x01); /* clear display */
        lcd_command(0x06); /* auto address inc */
        lcd_command(0x0c); /* cursor off */
        lcd_command(0x28); lcd_command(0x80); /* first location */

}

Then The Main Program For  LCD Interface With ARM 2138 In 4 bit Mode Calling This Header File As Follows To Write A String “Hello World” : -

#include <LPC21xx.h>
#include "lcd.h"

int main(void) 
{
        init_lcd();
        while(1)
        {
                lcd_command(0x01);
                lcd_command(0x80);
                printlcd("Welcome To");
                lcd_command(0xC0);
                printlcd("Hello World");
                Delay(50000000);
        }
}

Circuit Diagram For LCD Interface With ARM 2138 In 4 Bit Mode : -

Circuit Diagram For LCD Interface With ARM 2138 In 4 Bit Mode


ARM GPIO Programming- LED Running

 In all GPIO Programming,

First ARM ports are set to input and output using IODIR

For port 0: it will be IODIR0

Port1:IODIR1, and so on

Fr changing data or writing data to pin IOSET command is used

For PORT0: IOSET0 and for PORT 1 it is IOSET1


Similarly for clearing output pin IOCLR is used as in the following program.

Example For ARM GPIO Programming- LED Running : 

#include <lpc213x.h>

void delay_ms(unsigned int count)

{

    unsigned int j=0,i=0;

    for(j=0;j<count;j++)

    {

        for(i=0;i<3000;i++);

    }

}

/* start the main program */

int main()

    //unsigned int i;

    IODIR1 = 0xffffffff; //Configure the P1 pins as OUTPUT;

    while(1)

    {

        IOSET1=0xffffffff;

        delay_ms(1000);

        IOCLR1= 0xffffffff;

        delay_ms(1000);

    }

}

The Circuit arrangement is as given below


circuit arrangement for ARM GPIO - LED Running


Thursday, 5 November 2020

Heap Sort In C++

We use recursion to perform heap sort, firstly we heapify to create a min or max Heap to perform Descending or Ascending order of sorting, depending on the requirement.

In this article we are going to sort the given array in ascending order, so we have to perform max heapify operation. Once that is done we swap the current index element with the top element, and repeat the process until the entire array is sorted.

Time Complexity of Heap Sort is O( Log(n) ).


Code For Heap Sort In C++


#include<iostream>
using namespace std;

void heapify(int arr[] , int n , int i)
{
        int Largest = i;
        int l = 2 * i + 1;   
        int r = 2 * i + 2;

        if(l<n && arr[l] > arr[largest])
         largest = l;

        if(r<n && arr[r] > arr[largest])
         largest = r;

        if(largest != i)
        {
                swap(arr[i] , arr[largest]);
                heapify(arr , n , largest);
        }

}


// void heapify...


void HeapSort(int arr[] , int n)
{
        for(int i = n / 2  - 1 ; i <= n ; i++)
        {
                heapify( arr , n , i );
        }

        for(int i = n - 1 ; i >= 0 ; i--)
        {
                swap( arr[0] , arr[i]);
                heapify(arr , i , 0);
        }
}


// void HeapSort...


void showArr(int arr[] , int size)
{

        for(int i = 0 ; i < size; i++)
        {
                cout<< arr[i] << " ";
        }

cout<<endl;

}


// void showArr...


int main()
{

       int arr[] = {3 , 4 , 5 , 2 , 1 , 6 };
       int size = sizeof(arr) / sizeof(*arr);

        HeapSort(arr,size);
        showArr( arr , size );

return 0;

}


// int main...


Output for Heap Sort In C++


1  2  3  4  5  6

Iterative Merge Sort in C++

The Merge Sort that we've seen before in this blog was a recursive merge sort, but what if you were asked to implement merge sort using iteration. Well, we can implement iterative merge sort very easily using only 2 loops
.

Time Complexity Of Iterative Merge Sort


Time Complexity of iterative merge sort is  O(nLog(n)).

Code For Iterative Merge Sort In C++


#include<iostream>
using namespace std;

#define size 20

void Merge(int arr[] , int low, int mid, int high)
{
        int tempArr[size], tempPos,i,j;
        
        i=tempPos=low;
        j=high;

        while(i<=mid && j <= High)
        {
                if(arr[i] < arr[j])
                {
                        tempArr[tempPos++]=arr[i++];
                }
                else
                {
                        tempArr[tempPos++]=arr[j++];
                }
        }

if(i > mid)
{
        for( int k = j ; k <= high ; k++)
        {
                tempArr[tempPos++] = arr[k];
        }
}
else
{
      for( int k = i ; k <= mid ; k++)
        {
                tempArr[tempPos++] = arr[k];
        }
}
for(int p = low ; p <= high ; p++)
{
    arr[p] = tempArr[p];
}

}


//void merge...


void iterativeMergeSort(int arr[], int n)
{
        int p,i,l,m,h;
        
        for( p = 2 ; p <= n ; p *= 2)
        {
                for( i = 0 ; i + p - 1 <= n ; i += p)
                {

                    l = i;
                    h = i + p + 1;
                    m = ( l + h) / 2;

                    Merge( arr , l , m , h);

                }
        }

    if( p / 2 < n)
    {

            Merge( arr , 0 , p / 2 - 1 , n);

    }

}


// void iterativeMergeSort...


void showArr( int arr[] , int n)
{

        for( int i = 0 ;i < n; i++)
        {

                cout<<arr[i]<<" ";

        }

cout<<endl;

}
// void showArr...

int main()
{

      int arr[] = {3 , 4 , 2 , 5 , 6 , 7 , 1 , 9 , 8};
      int s = sizeof( arr ) / sizeof( *arr );

       
       iterativeMergeSort( arr , s );
       showArr(arr,s);

return 0;

}

//int main...

Output of Iterative Merge Sort Code 


1  2  3  4  5  6  7  8  9



Wednesday, 6 November 2019

Hashing With Separate Chaining In C.

As we know that in Hashing, we use a Hash Function that maps keys to certain values. Now, sometimes certain situation arises where these values which we obtain from our hash function collides, Well this conditions are termed as collisions. Now what can be done, so that collision can be prevented, well certain techniques are available which can prevent collisions and these techniques are as follows:

1 ) Closed Hashing, also called as Open Addressing.

2) Open Hashing, also called as Separate Chaining.

Separate Chaining / Open Hashing : 

The idea behind separate chaining is pretty straight forward, what we do in separate chaining is that we make each cell of hash table point to linked list data that corresponds to same hash value (i.e the value obtained from collision between to values.).

Following example can help us better understand the concept, lets create a hash function for N number of objects or numbers, that will be simply,

H.I = Key % N

Where,  H.I is the hash index.
               Key is any number from given set of numbers.
               N is the total of numbers of objects.

Now that we've a hash function let's take an example to start with the explanation, say we've the following sets of input for which we've to determine the hash table using separate chaining technique:

Let's take hash table with 7 buckets ( 0 , 1 , 2 , 3 , 4, 5 , 6 )  so value of N is 7, and the Keys being ( 14 , 16 , 21 , 24 , 18). Now to obtain the hash index for each of these keys we first need to put it in the H.I formula.

For Key = 14 and N =7  we have H.I = 0 ,
Similarly, for Key = 16 and N =7 , H.I = 2,
And for 21 H.I = 0 ,
For 24 H.I = 3 ,
Lastly for Key = 18 , H.I = 4

So, we can represent our Hash Table in like this.


As you can see in index 0 there is a collision between keys 14 and 21, but using separate chaining technique we simply linked the data(14 , 21) to the same hash value.

Hashing with separate chaining C code :


#include<stdio.h>
#include<stdlib.h>

//Declarations Necessary for the Implementation Part.
struct node
{
    int info;
    struct node*link;
};

//Function Declarations
int index(int item);
struct node * insert_sorted(struct node *index,int data);
void search(struct node * index,int item);
struct node*delete_node(struct node *index,int item);
void display(struct node * index);


int main()
{   int data,choice,ind,i;
    struct node * H[10];
    //Initialization
    for(i=0;i<10;i++)
    {
        H[i]=NULL;
    }

    while(1)
    {
        printf("Please select a choice\n");
        printf("1. Insert\n");
        printf("2. Search\n");
        printf("3. Delete\n");
        printf("4. Display\n");
        printf("5. Exit\n");
        scanf("%d",&choice);

    switch(choice)
    {
        case 1:
            {
                printf("Please enter the data\n");
                scanf("%d",&data);
                H[index(data)]=insert_sorted(H[index(data)],data);
                printf("\n\n");
                break;
            }
        case 2:
            {
                printf("Please enter the item\n");
                scanf("%d",&data);
                search(H[index(data)],data);
                printf("\n\n");
                break;
            }
        case 3:
            {
                printf("Please enter the item\n");
                scanf("%d",&data);
                H[index(data)]=delete_node(H[index(data)],data);
                printf("\n\n");
                break;
            }
        case 4:
            {
                printf("Please enter the index to display the link info's\n");
                scanf("%d",&ind);
                display(H[ind]);
                printf("\n\n");
                break;
            }

        case 5:
            {
                printf("Sankyu For Using the Program\n");
                printf("\n\n");
                return 0 ;
            }
        default:
            printf("Wrong Choice\n");
            printf("\n\n");
            break;
    }

    }
return 0;
}

//Function Definitions
int index(int item) //Hash Function
{
    return item%10;
}

struct node * insert_sorted(struct node *index,int data)
{
    struct node* temp=(struct node*)malloc(sizeof(struct node)),*p;
    if(temp==NULL)
    {
        printf("New Node Can't be created\n");
        return index;
    }
    //Inserting the Data.
    temp->info=data;

    //Creating the links.

    if(index==NULL)
        {
            temp->link=NULL;
            index=temp;
            return index;
        }
    else //Insertion in the rest nodes.
        {   //Inserting Data at the Beginning
            if(index->info>data)
                {
                    temp->link=index;
                    index=temp;
                    return index;
                }
            p=index;
            while(p->link!=NULL)
            {
                if(p->link->info<data) //This scans till the last node.
                    p=p->link;
                else
                {
                    temp->link=p->link;
                    p->link=temp;
                    return index;
                }
            }
            //This is to insert the data after the last node.
            p->link=temp;
            temp->link=NULL;
            return index;
        }
};

void search(struct node * index,int item)
{
    struct node *p=index;
    while(p!=NULL&&p->info<=item) //To decrease the search time by breaking
        //search when we get any data which is greater than the data. As after that data
        //We can't get the requested data since the nodes are sorted.
    {
        if(p->info==item)
        {
            printf("Successful Search\n");
            return; //So that the address of the node where the data is present is given to the user.
        }
        p=p->link;
    }

    printf("Unsuccessful Search\n");
    return;
};

struct node*delete_node(struct node *index,int item)
{   if(index==NULL)
    {
            printf("The Index is empty\n");
            return index;
    };

    struct node*p=index,* temp;
    //The starting node has the item itself
    if(p->info==item)
    {
        temp=p;
        index=temp->link;
        free(temp);
        return index;
    }
    while(p->link!=NULL)
    {
        if(p->link->info<=item) //So to stop search after getting a
                                //node greater than the data.
        {
            if(p->link->info==item)
            {
                temp=p->link;
                p->link=temp->link;
                free(temp);
                return index;
            }
            p=p->link;
        }
    }

    printf("Item doesn't exist\n");
    return index;
};

void display(struct node * index)
{
    if(index==NULL)
        {
            printf("Index is empty\n");
            return;
        }
    struct node*p=index;
    while(p!=NULL)
    {
        printf("%d ",p->info);
        p=p->link;
    }
    printf("\n");
    return;
};


Output for the above program is :


Tuesday, 22 October 2019

Merge Sort In C

Merge Sort is a sorting technique based on Divide and Conquer principle, in merge sort we first divide the array into two equal halves and merge them together into sorted manner. With worst case time complexity of O(n log n), it is one of the most respected algorithms.

Explanation :


Basically what we do in merge sort is pretty straight forward, we first divide the array into equal halves until we reach a point where no more division can take place and then sorting takes place, once sorting is done completely, we merge the sorted array and hence we obtain our sorted array.

Example:


Let's take an unsorted array to start with our example.

                                      4  2  6  1  7  5  3  8

we now divide the array into two equal parts , i.e of three parts, so after this step we've our array as..

                                     4  2  6  1  -  7  5  3  8
                         (Where the ' - ' signifies the two divided parts.)

we still can divide our array into two parts, so..

                                   4  2  -  6  1  -  7  5  -  3  8

Again we divide to obtain..

                             4  -  2  -  6  -  1  -  7  -  5  -  3  -  8

Now we observe that no further division of array can take place, so our next step will be to combine them in the exact same order in which they were broken down. Here we first compare the elements in each list and then combine them into another list in sorted manner. We observe that 4 and 2 are not sorted order so we swap there positions, same goes for 6 & 1, so we swap there positions too, also for 7 & 5, but 3 and 8 are in correct position, so we leave them as it is. So we've our array as follows after this step..

                                  2  4  -  1  6  -  5  7  -  3  8

Now after this step we've to check order for 2,4,1 and 6 we see correct order is 1,2,4 and 6 similarly for 5,7,3 and 8 correct order is 3,5,7 and 8. so after this step we've our array as follows....

                                   1  2  4  6  -  3  5  7  8

and you can guess how the final step will turn up so we get our sorted array..

                                    1  2  3  4  5  6  7  8

Well, this the mechanism for Merge Sort , next we'll be looking at its coding part in C so that we can implement the concept we just understood.

Merge Sort C Code :




Output of the above program is :



                                             if you find any problem in the above code, then kindly add a comment in the comment section.