Sunday, 24 August 2014

Obstacle avoiding robot using IR module


                Every embedded enthusiast would have certainly done this project when he/she started to think about moving robot vehicles….! This is my first robot too…….

The main part of this project is the sensor that senses the objects in front of it. For this purpose there are two popular sensors available in the market. One is the Ultrasonic sensor and the other is the Infrared (IR) sensor. Here we are going to learn about IR sensor.

                All you should do for the project is to have these parts,

1.       IR module

2.       GR – Sakura (or any Arduino Compatible Boards)

3.       Two DC motors with wheels

4.       An omni-directional wheel

5.       L293D Motor Driver

6.       Chassis

IR module:

                Here is the IR module that I bought it from a local electronic shop (Rs.125).

 
Working of an IR module is given below
In the module that I use, the digital output would be 1 if there is no object in front of it and when there is an obstacle, the module gives logic 0 as output. Read your module datasheet for more details.

Chassis and wheel setup:

 
L239D Motor Driver:
                For tutorial on L293D motor interface, visit this post – Motor interface with L293D
I have made my own L293D motor driver board. Here is the picture,

Robot Full Setup:

 

From the picture you can see that I have used two 9V batteries to power up. A single 9V battery is enough to power up the robot, if the battery is a new one.

Note: These 9V batteries may drain out quickly and hence the motors won’t function properly. This is a common issue, and many of them would think that it was either a software / hardware problem.


On the other hand, if you connect two batteries in parallel, then their current capacity would get added up. That’s why I have added two battery packs to increase the current capacity.



Code:


// Motor 1 – connected left side

// Motor 2 – connected right side

#include<rxduino.h>
void obstacle();

main()

{
                pinMode(30,INPUT);             // IR module data

                pinMode(7,OUTPUT);                   
                pinMode(6,OUTPUT);

                pinMode(5,OUTPUT);

                pinMode(4,OUTPUT);
                pinMode(PIN_LED0,OUTPUT);

                digitalWrite(7,0);
                digitalWrite(6,0);

                digitalWrite(5,0);
                digitalWrite(4,0);

                while(1)
                {
                                if(digitalRead(30)==0)        // if IR module data is 0 (obstacle detected)

                                {
                                                obstacle();
                                }

                                digitalWrite(PIN_LED0,1);

                                digitalWrite(7,1);           // motor 1 forward
                                digitalWrite(5,1);          // motor 2 forward
                }
}

void obstacle()
{
                digitalWrite(PIN_LED0,0);

                digitalWrite(7,0);

                digitalWrite(5,0);
                delay(10);

                digitalWrite(6,1);                // motor 1 reverse
                digitalWrite(4,1);                // motor 2 reverse

                delay(700);
                digitalWrite(6,0);

                digitalWrite(4,0);
                int randomno=random(10);            //random number generator from 0 to 9

                if((randomno%2)==0)                     // if even number turn right
                {
                                digitalWrite(7,1);            //  turn right side

                                delay(1100);                   // turning time - can be varied according to your needs
                                digitalWrite(7,0);          
                }

                if((randomno%2)==1)              // if even number turn left
                {
                               digitalWrite(5,1);           //  turn left side

                                delay(1100);                   // turning time - can be varied according to your needs
                                digitalWrite(5,0);

                }
}

I have a used a random number generator to make it turn either left or right when an obstacle is detected. You can even use any other concepts to make it happen.........

Video demo:

 

Friday, 22 August 2014

Driving DC motors using L293D

DC Motor Basics:


                A DC motor has two terminal pins for supply. Direction of rotation of motor can be reversed by changing the polarities. This is depicted as follows,
 
Motors require high currents to operate. The current and voltage from a microcontroller’s output cannot drive a dc motor. Hence we require an external driving circuit.
A simple motor driving circuit is shown below.,


Diode 1 is used to prevent reverse current flow from the motor to the controller (Protection Diode). When the microcontroller’s output is logic HIGH or ‘1’, then the motor will start to rotate. However the circuit is for only unidirectional control of DC motor i.e, the motor rotates in only single direction and can’t be reversed. For this purpose we will be using a H – bridge.

H – bridge:




             When a logic HIGH or ‘1’ is applied (from microcontroller) at CW, then the transistors T1 and T4 will get shorted and current flows from Vcc - T1 – motor – T4 – Gnd, thus making the motor to rotate in clockwise direction.


On the other hand, when a logic HIGH or ‘1’ is applied (from microcontroller) at CCW, then the transistors T2 and T3 will get shorted and current flows from Vcc – T3 – motor – T2 – Gnd, thus making the motor to rotate in counter clockwise direction (reverse).


                When the input at both CW and CCW is logic ‘0’ or LOW, then no transistor gets shorted and hence no conduction of current from Vcc to Gnd. When the inputs at both CW and CCW is logic ‘1’ or HIGH, then all the transistors gets shorted and all the current goes from Vcc to Gnd through transistors without going through the motor. Hence motor will not rotate in neither directions.


CW
CCW
Output
0
0
Stop
1
0
CW rotation
0
1
CCW rotation
1
1
Brake / Stop


Interfacing with L293D:


                There are several custom made H bridge IC’s available in the market. Commonly used IC by electronic hobbyists is L293D.


Note: if you buy L293B, then you have to put protection diodes additionally, because there is no protection diode inside the IC. L293D has inbuilt protection diodes.

L293D pinout:




Here is the datasheet – L293D

L293D has the capacity to drive two DC motors bi-directionally (2 channels). You may consider IC’s left side pins (Enable 1, Input 1, Output 1, Output 2, Input 2) as channel 1 and right side pins (Enable 2, Input 3, Output 3, Output 4, Input 4).

  • Enable pin is to enable the corresponding channel (Normally 5V – max 7V).
  • Input pins receive logic HIGH or Low from the controller (Normally 5V – max 7V).
  • Output pins are connected to the motors.
  • Vss – logic supply voltage (Normally 5V – max 36V)
  • Vs – Motor supply voltage, as per motor specifications (Normally 5V – max 36V)
  • Gnd pins – All of these ground pins are connected internally and hence they need not be interconnected externally.

General Connection diagram:

 

 If you use a 5V DC motor, the pin 8 (Vs) should be connected to 5V and similarly for different motor ratings. Various colour wires have been used to differentiate between the connctions.

With GR-Sakura (Arduino Compatible):

 

Pins 5, 4, 7 and 6 of sakura board are used as L293D Input pins 1, 2, 3 and 4 respectively.


Pins 5 and 4 – Input 1 and 2 of channel 1 / CW and CCW of motor 1

Pins 7 and 6 – Input 3 and 4 of channel 2 / CW and CCW of motor 2

Since I have used two 5V DC motors, 5V from sakura is connected to Vs of L293D.

Code:


#include<rxduino.h>
main()
{
                pinMode(7,OUTPUT);
                pinMode(6,OUTPUT);
                pinMode(5,OUTPUT);
                pinMode(4,OUTPUT);
                while(1)                                   // repeating / infinite loop
     {
                                digitalWrite(5,1);     // rotates motor 1 Clockwise
                                digitalWrite(7,1);     // rotates motor 2 Clockwise
                                digitalWrite(4,0);   
                                digitalWrite(6,0);
                                delay(5000);             // After 5 seconds
                                digitalWrite(5,0);
                                digitalWrite(7,0);
                                digitalWrite(4,1);     // rotates motor 1 Counter Clockwise
                                digitalWrite(6,1);     // rotates motor 2 Counter Clockwise
}
}



Feel free to comment regarding doubts...............

Sunday, 17 August 2014

Reading key switches by eliminating bouncing problems

Here is a tutorial for beginners to know about key interfaces and bouncing problems.....

The image below shows the key switch that I use. They are called as mini push buttons / mini tactile switches. These are not like our home switches that are used to turn On or OFF electrical appliances. These tactile switches gets shorted while pressed and becomes open while released.
You may wonder why there are four pins (Since only two is enough – one for input and one for output). The pin are interconnected as given in the picture,
 
You can find out yourself the interconnected pins by using the Short Circuit test in a Multimeter.

A simple circuit using switch:



The LED will glow as long as the switch is pressed. As soon as you release the switch, the LED turns OFF.
 

Key interface to microcontroller:

 

In the above circuit, if the switch is in open state, then you will receive HIGH / Logic ‘1’ at the microcontroller input. Hence the default input to the microcontroller from the switch would be logic ‘1’. If the switch is pressed, then it gets shorted to the ground and the entirre current flows to the ground. Hence you will receive a logic ‘0’ at the microcontroller input. Thus microcontroller will read either logic ‘1’ or ‘0’ according to switch state.
Here is a simple key interface with GR-sakura (Arduino Compatible) to turn ON anf OFF the onboard LED. The controller will read ‘1’ at its input as default. If it reads a ‘0’ (occurs once the switch is pressed), then the state of the LED is changed.

Code:



#include<rxduino.h>
int main()
{
                int state=0;
                pinMode(7,INPUT);
                pinMode(PIN_LED0,OUTPUT);
                while(1)
                {
                                if(digitalRead(7)==0)
                                {
                                                state=!state;
                                                digitalWrite(PIN_LED0,i);
                                }
                }
}
                But the LED will turn On and Off rapidly because of a problem called “Bouncing”.

Bouncing Problems :

 
One problem that we face while interfacing key switches with microcontrollers is the switch bouncing i.e., the output will turn on and off repeatedly, for a short period of time (in milli seconds).
Example – if you press ‘1’, you may read ‘111111’ rather than ‘1’.

In circuit 1, once the switch is pressed the LED will turn ON and OFF (bounce) for a few milli seconds and then be turned ON until the switch is released. This switch bouncing also happens in our electrical switches in home. Since the bouncing lasts only for certain milli seconds, they are not noticed by human eyes. But with microcontrollers, the situation is different. It will read every bounced state (ON and OFF) as valid input. That’s why you will read as ‘1111111’ if you press 1. The bouncing time varies from one switch type to another.

This bouncing can be taken care in software by introducing a certain delay in the code. Each switch bouncing takes place for around 100 ms (approximation). Hence, once the switch is pressed, if you read that switch again after that 100 ms bouncing time, the problem can be solved.

The normal code for reading switch is,

While(1)
{
                if(digitalRead(7)==0)
                          {
                                                state=!state;
                                                digitalWrite(PIN_LED0,i);
                       }
}

Type 1:

The above code can be changed for debouncing as

While(1)
{
              if(digitalRead(7)==0)   // checks whether switch pressed
                                {
                                        delay(100);  // wait for 100 milli second
                                         if(digitalRead(7)==0)  // agains checks whether switch pressed
                                         {
                                                             state=!state;
                                                            digitalWrite(PIN_LED0,i);
                                        }
                            }
}

The feature of above code is that if you long press the switch, the LED will turn ON and OFF repeatedly for every 100 ms (Usage – for scrolling purposes). The delay 100 ms is only an approximate value. If you didn’t get the correct output, try with different delays (switch bouncing time varies with different switches). For me, 200ms proves to be a right one.

Type 2:

But if you want to change the state of LED only once even if you long press the key, follow the below code.

While(1)
{
            if(digitalRead(7)==0)   // checks whether switch pressed
              {
                       delay(100);  // wait for 100 milli second
                       if(digitalRead(7)==1)  // checks whether switch is released
                       {
                                         state=!state;
                                         digitalWrite(PIN_LED0,i);}
}
}

In this code, the controller first checks whether the key is pressed. After the bouncing delay, the controller checks whether the pressed key is released. If the key is released, the following code gets executed. If the key is not released, the controller waits until the key is released and then executes the following code i.e., the LED changes its state only once for every key press, even if it is long pressed.

By these two techniques, the debouncing problem with key interfaces can be eliminated.

Hope it’s useful for beginners……..!!!!!!!