Friday, April 29, 2011

Projects: Line Follower

Project: Line Follower
Author: Gaurav Upreti





If you are making the same project and wish to contact the author for help, please send a mail to blogger_engg@gmail.com with the subject line: Line_follow@gaurav_upreti.

Thursday, April 28, 2011

Interfacing LCD

LCD or Liquid Crystal Display is fast becoming a preferred choice for use as interface device for displaying over 7-Segment.


Every LCD needs a driver to interface between the microcontroller and LCD module. This driver is included on the LCD module.





The LCD we are using here is a 16x2 LCD. That means it has 16 columns and 2 rows.


Pin number 1 and 16 will be written behind the LCD.


The Pin Configuration of the LCD is given below


 (open image in separate tab to expand)


The LCD uses three control lines, EN, RS and RW.


The EN line is called 'Enable'. This control line is used to tell the LCD that you are sending it data. To send the data to the LCD, your program should make sure this line is low (0) and then set the other two control lines and/or put data on the data bus. When the other lines are completely ready, bring EN high (1) and wait for the minimum amount of time required ( about 200ns), and end by bringing it low(0) again.


The RS line is the 'Register Select' line. When RS is low(0), the data is to be treated as a command or special instruction (such as clear screen, position cursor, etc.). When RS is high (1), the data being sent is text data which should be displayed on the screen. For example, to display the letter 'T' on the screen you would set RS high(1).


The RW line is the 'Read/Write' control line. When RW is low (0), the information on the data bus is being written to the LCD. When RW is high (1), the program is effectively querying (or reading) the LCD. All commands are write commands except for 1 ('Get LCD status'), which is a read command. Thus, RW will almost always be low.


4 bit Mode / 8 Bit mode:


The LCD can work in either 8 bit parallel mode, i.e, then entire 8 bit data can be sent at once, or it can be used in 4 bit mode. In 4 bit mode the 8 bit data is broken into packets of 4 bit data and sent (higher 4 bits first, then lower 4 bits). 4 bit mode simplifies the circuit.
Upon power on, the LCD is automatically in 8 bit mode.

Here, we are using the LCD in 4-bit mode.


Initializing the LCD


Before you may really use the LCD, you must initialize and configure it. This is accomplished by sending a number of initialization instructions to the LCD.



  • The first instruction we send must tell the LCD we'll be communicating with it with a 4-bit data bus (4-bit mode). We also need to select a 5x8 dot character font. These two options are selected by sending the command 20h ( 'h' denotes hexadecimal format) to the LCD as a command. 
  • We've now sent the first byte of the initialization sequence. The second byte of the initialization sequence is the instruction 0Fh. This commmand is sent to instruct the the LCD to, 'Display on, Cursor Blinking'.
  • Other commands are also available. Send higher nibble first, then lower nibble.

This circuit diagram can be used as a reference.






You can download a header file for your use from here. The pin connections are mentioned in the header file.

For any further clarification please leave a comment below or mail us at blogger.engg@gmail.com

Wednesday, April 27, 2011

Starting WinAVR

Setup of WinAVR can be downloaded from this link.

Once you are done installing, open the start menu and search for Programmer's Notepad. Click on it to open.
It should look something like this.


The bar on the left side may or may not be there.
The program is written in the large white area ( 'notepad' ).
The window at the bottom is called the output window.
The language in which the program is being written can be selected as shown.


Once the language has been selected, the program should be written in the notepad.


Once the program is written. Make a new folder and save this program with the extension .c. for example, main.c

For every program you write create a separate folder for it.

Once this is done, an mfile has to be created.

Search for 'mfile' in the start menu.
It'll look something like this.



After that, click on 'Makefile' and select 'Main File Name'.

A small window will open up. Write the name of the file you have saved. Don't write the extension of the file. For example, if the name of your file is main.c, write main in that window.


After that, in 'Makefile' select 'MCU type' and select the microcontroller you are using.


Then in 'Makefile' go to 'port' and select the port that is being used for programming. This depends on whether the programmer you are using. It may use a USB programmer or COM port or others. If you are not sure, contact the person you bought it from. If it is still not clear, please contact us at blogger.engg@gmail.com, or post your doubt as a comment below and we'll contact you.


After that select the programmer you are using.


Some programmer like USBASP are not mentioned in this. To select those programmers, select any programmer you want, then click on enable editing of makefile in 'Makefile' and in place of the text highlighted in yellow write the programmer you are using, in small letters (e.g usbasp)


Once you have selected enable editing of makefile, scroll up to find the text as shown in the picture below, and change the entry encircled below to the frequency of the crystal you are using.


After this go to 'File' in the mfile box only, and click 'Save As'. This file should be saved in the same folder that your .c file has been saved with the name 'Makefile'. If this name is already displayed, don't change it. This file should not be saved with any other name. 

Go back to programmer's notepad, go to 'Tools', select  'Make All'. This creates the hex file ( this file will be present in the folder) which is required to program your microcontroller. Syntax or mfile related errors, if any, are shown in this step in the the output window.
Make sure that your programmer is connected, and then go to 'Tools' and select 'Program'. 
That's it. Your microcontroller is programmed!

If you are not sure how to use your programmer, contact the person you bought it from. If it is still not clear, or you have any doubts in the above steps please contact us at blogger.engg@gmail.com, or post your doubt as a comment below and we'll contact you.

Monday, April 25, 2011

Using a switch with a Microcontroller

, w
Suppose you want to use a switch with a microcontroller. 

Please go through this article on ' Pull Ups and Pull Downs ' before starting.



We'll assume that the switch will give a 0 when it is pressed and that the switch is connected at PB.0 .


Thus, the pin of the Microcontroller at which the switch is connected will get a 0 when the switch is pressed.

If that pin is already at 0, in this case the microcontroller will not be able to detect that a switch is pressed as there will be no change on the status of the pin.

So, to positively detect a switch press at PB.0 we need to set it to 1, i.e pull-it-up.




Since, we have to check/detect/receive an input on PB.0, we need to make that as an input port, i.e 
DDRB=0b00000000;   
Since I am not using the other pins of PortB, it does not matter whether I write 1 or 0 to them. If the other pins are being used as output, then we should set PB.0 as input using the unary OR, denoted by ' | ', operator.

after DDRB, we need to give the PORT command,

PORTB=0b00000001;   // make PB.0 as 1.

The following picture shows, what happens when we give a 1 to a pin, declared as output, to which LED are connected. Notice the intensity of the LED.




In the next picture we declared the pins connected to the LED as input and then set the pins to 1.


Notice the change in intensity?
In the case when the port is declared as input and we still try to give an output to it, a small amount of current is provided on those pins as compared to when the port has been declared as output.


Now, using the same logic in case of switches.
We'll declare the pin to which the switch is connected as input and give an output on it, so that a small current is provided on it. Thus, every time the switch is pressed, the pin receives a definite 0.


#include<avr/io.h>
#include<util/delay.h>
void main()

   DDRC=0b11111111;        // assuming that LED's are connected at PortC.
   DDRB=0x00;   
// making PB.0 as input (here, other pins will also become input, but since we // are not using them, it doesn't matter)


  PORTB=0b00000001;   // give a 1 on PB.0 to provide a small current on it.


  while(1)
  {  if(PINB==0b00000000)   // 'PIN' is used for checking input
     {                                  // when switch is pressed, entire port becomes 0
         PORTC=0xff;             // we could also have written if(PINB==0)
     }                         
     else
     PORTC=0x00;
  }
}


In the above program, LED glow only when the switch is pressed.






Sunday, April 24, 2011

Playing with LED

 .

In this post we'll make a scrolling pattern on the LED's (watch the video).

Just like last time, we'll consider that we have 8 LED's connected to PortC.

Now, the LED have to be turned ON, only one at a time, and they should remain ON for some time (say, 500 milliseconds).

#include<avr/io.h>
#include<util/delay.h>   // header file for generating delay
void main()
{ DDRC=0b11111111;    // Since, PortC is output, thus, all 8 bits are declared 1
  PORTC=0x00;             // initially all LED will be off. 

/*
Note: If on your development board, the LED are connected in Active Low configuration, they will turn ON when a '0' is given. If the LED are active high, they will turn ON when '1' is given. If you are not sure whether your LED are active high or active low, just give 1 and see what happens.
Here, I am assuming that LED are active high.

*/

  while(1)   // infinite loop so that the process inside is executed all the time.
 {  
   PORTC=0b00000001;
   _delay_ms(500);
   PORTC=0b00000010;
   _delay_ms(500);
   PORTC=0b00000100;
   _delay_ms(500);

   PORTC=0b00001000;
   _delay_ms(500);

   PORTC=0b00010000;
   _delay_ms(500);

   PORTC=0b00100000;
   _delay_ms(500);
    PORTC=0b01000000;

   _delay_ms(500);
    PORTC=0b10000000;

   _delay_ms(500);
 }
}

In the above program, we make only one LED on at a time, give a delay, and then turn on the next LED and switch off the other LED by writing 1 to the LED which we want to turn ON and the rest are 0.

The above program, though simple, is cumbersome to write.
We'll write the above program in a different way utilizing the vast potential of C.

#include<avr/io.h>
#include<util/delay.h>
volatile unsigned char x=0;  
void main() 
{
DDRC=0b11111111;   // Declare entire PortC as output
PORTC=0b00000000;   // Make PortC initially 0.
while(1)
{ x=0;
  while(x<8)               // execute this part till x is less than 8
  { PORTC=(1<<x);    // shift 1 by 'x' spaces.
    _delay_ms(500);
x=x+1;           // increment x.
  }
}

We would like to point out one very important thing about Embedded C at this point. 
Notice the 'volatile unsigned char x=0' before the main() ?
In embedded C, all variables that are to be used should be defined and initialized before the main() starts.





Sunday, April 3, 2011

Our First Program

Let's write a program to simply turn on LED's.
We will use the Programmer's Notepad of WinAVR. 
WinAVR can be downloaded from this link.
Once WinAVR is installed, open Programmer's Notepad and start typing. Save the file with a .c extension. example, led.c .
We will assume that we have 8 LED's, connected to the 8 pins of Port C.

Step 1: Declare the Ports to be used as output or input (as required).
           In this case the LED’s connected to Port  C have to be turned ON, i.e a current has to be supplied to the LED. Thus, Port C should be OUTPUT.
Thus, the Data Direction Register for Port C is 

thus, we can write
 DDRC=0b1111111;

This statement makes the PortC output port. Since, we need only PortC in this particular case, we are not going to specify for other Ports.

Step 2:  Turn ON the LED
Now, to turn on the LED's, we need to give a '1' to the Port.
thus,
PORTC=0b11111111;

Thus, the program can be written like this:

#include<avr/io.h> // standard library to be included when using WinAVR
void main()
{   
   DDRC=0b11111111;   // Declare PortC as output Port
   PORTC=0b11111111;
}

This program will turn on the LED's connected to PortC.

Here we have considered 8 LED's. If, let's say 3 LED's were connected to PC0, PC1, PC2, then only these 3 pins need to be written '1', the rest can be '0' or '1' (if they are not being used anywhere else)
thus,
DDRC=0b00000111;
PORTC=0b00000111;


Once you have installed WinAVR, in the libraries folder, there will be a folder 'util' which will contain a file 'delay.h'. This file contains pre-defined functions to generate delays of the order of milli-seconds and micro-seconds.


Let's modify the program by turning the LED's ON and OFF with a delay of 500 milli-seconds.


#include<avr/io.h>
#include<util/delay.h>  // include this header file to use the functions defined 
                                  // for generating a delay
void main()

  DDRC=0b11111111;    // Declare PortC as output Port
  PORTC=0b11111111;  // Give a '1' to all the pins of PortC thus turning ON the LED's
while(1)                      // this is an infinite loop.
 {  PORTC=0b11111111;  // Give a '1' to all the pins of PortC thus turning ON the LED's
    _delay_ms(500);       // hold the LED ON for 500 millisecond
    PORTC=0b00000000;   // Turn OFF all the LED's
    _delay_ms(500);        // hold the LED OFF for 500 millisecond
  }
}


The function _delay_ms(x) generates a delay of x milli-seconds.
The above program will blink the LED's.
We used an infinite loop in the above program because we wanted the LED's to continue blinking forever. Had we not written the part for blinking the LED's inside the infinite loop, the LED's would have blinked just once.




In the video above, only 4 LED are blinking. 


In the next post we will again play around with the LED's, generating some new patterns and probably some 'disco LED'  :D