5.A More Complex Circuit (to put together)

In case you do not want to use the Arduino Motor Shield, You can build your own circuit. Bellow are the circuit schematic and Fritzing (http://fritzing.org/) version of the circuit:

PLEASE keep in mind that the L293 H-Bridge chip is used for small motors, preferably the ones that need less than 500mA DC. Using a bigger motor can draw too much current that can make the L293 heat up too much and shut down.

Here is the schematic:

The actual circuit:

As you have noticed, I used a DIP14/16 heat sink for the L293 chip. It does produce a considerable amount of heat, but it has a thermal shutdown feature (http://www.ti.com/lit/ds/symlink/l293d.pdf) that will turn off the IC before it burns out. The amount of heat produced by the chip depends on the motors being used.

RC_L293_OnChange

Turns out that soldering the 9V battery wires to the prototype PCB was not a good idea. One of the wires ended up breaking. To solve this I just used an Arduino header. Before soldering the header, I cut the leg that would come in contact with the 5V rail. This makes it less possible to short the battery and mess the circuit. I also added 3 more decoupling capacitors, an extra 10uf capacitor to the Arduino's regulator. And a 10uf and a 100uf capacitor to the L293's regulator.

NOTE:

The circuit does not have reverse polarity protection. So when replacing the battery that powers the Arduino or the motors, make sure that the battery has been connected correctly and that the polarity is not reversed.

You will also need a different version of the Arduino code:

Be aware that these two programs makes use of a library. It makes the program much cleaner. Once you download the folder with the program, you will find a folder named "L293". This folder needs to be placed in the Arduino's "libraries" folder. The folder can be found in the same directory as the Arduino executable file.

RC_L293_Continuous

Just like the two programs used with the motor shield controlled car, this L293 controlled car also has two different version. One makes use of the continuous stream of data, while the other does not. This first program makes use of the continuous stream of data. The continuous stream of data lets it detect when the car has lost connection with the phone. But this continuous stream of data also means that it needs to filter the received data to dismiss repeated characters:

#include <L293.h>

#define pinLeft 10

#define pinRight 11

#define pinLftRgtEna 9

#define pinForward 5

#define pinBack 6

#define pinFwdBakVel 3

#define pinfrontLights 8

#define pinbackLights 7

//L293(pinLeft, pinRight, pinLftRgtEn, pinForward, pinBack, pinFwdBakVel);

L293 yellowCar(pinLeft,pinRight,pinLftRgtEna,pinForward,pinBack,pinFwdBakVel);

char command = 'S';

char prevCommand = 'A';

int velocity = 0;

unsigned long timer0 = 2000; //Stores the time (in millis since execution started)

unsigned long timer1 = 0; //Stores the time when the last command was received from the phone

void setup(){

Serial.begin(115200); //Set the baud rate to that of your Bluetooth module.

pinMode(pinfrontLights, OUTPUT);

pinMode(pinbackLights, OUTPUT);

}

void loop(){

if(Serial.available() > 0){

timer1 = millis();

prevCommand = command;

command = Serial.read();

//Change pin mode only if new command is different from previous.

if(command!=prevCommand){

//Serial.println(command);

switch(command){

case 'F':

yellowCar.forward_4W(velocity);

break;

case 'B':

yellowCar.back_4W(velocity);

break;

case 'L':

yellowCar.left_4W();

break;

case 'R':

yellowCar.right_4W();

break;

case 'S':

yellowCar.stopped_4W();

break;

case 'I':

yellowCar.forwardRight_4W(velocity);

break;

case 'J':

yellowCar.backRight_4W(velocity);

break;

case 'G':

yellowCar.forwardLeft_4W(velocity);

break;

case 'H':

yellowCar.backLeft_4W(velocity);

break;

case 'W': //Font ON

digitalWrite(pinfrontLights, HIGH);

break;

case 'w': //Font OFF

digitalWrite(pinfrontLights, LOW);

break;

case 'U': //Back ON

digitalWrite(pinbackLights, HIGH);

break;

case 'u': //Back OFF

digitalWrite(pinbackLights, LOW);

break;

case 'D': //Everything OFF

digitalWrite(pinfrontLights, LOW);

digitalWrite(pinbackLights, LOW);

yellowCar.stopped_4W();

break;

default: //Get velocity

if(command=='q'){

velocity = 255; //Full velocity

yellowCar.setSpeed_4W(velocity);

}

else{

//Chars '0' - '9' have an integer equivalence of 48 - 57, accordingly.

if((command >= 48) && (command <= 57)){

//Subtracting 48 changes the range from 48-57 to 0-9.

//Multiplying by 25 changes the range from 0-9 to 0-225.

velocity = (command - 48)*25;

yellowCar.setSpeed_4W(velocity);

}

}

}

}

}

else{

timer0 = millis(); //Get the current time (millis since execution started).

//Check if it has been 500ms since we received last command.

if((timer0 - timer1)>500){

//More tan 500ms have passed since last command received, car is out of range.

//Therefore stop the car and turn lights off.

digitalWrite(pinfrontLights, LOW);

digitalWrite(pinbackLights, LOW);

yellowCar.stopped_4W();

}

}

}

When the application is set to send data on change, the car needs a smaller program to operate. It no longer has to filter the incoming characters. It can't detect when the car's connection to the phone is lost either. You will notice that the program below is a copy of the [previous one. It only lacks the lines that filter repeated commands, and the lines that detect disconnection:Since we can't detect do not need to filter the incoming data

#include <L293.h>

#define pinLeft 10

#define pinRight 11

#define pinLftRgtEna 9

#define pinForward 5

#define pinBack 6

#define pinFwdBakVel 3

#define pinfrontLights 8

#define pinbackLights 7

//L293(pinLeft, pinRight, pinLftRgtEn, pinForward, pinBack, pinFwdBakVel);

L293 yellowCar(pinLeft,pinRight,pinLftRgtEna,pinForward,pinBack,pinFwdBakVel);

char command = 'S';

int velocity = 0;

void setup(){

Serial.begin(115200); //Set the baud rate to that of your Bluetooth module.

pinMode(pinfrontLights, OUTPUT);

pinMode(pinbackLights, OUTPUT);

}

void loop(){

if(Serial.available() > 0){

command = Serial.read();

switch(command){

case 'F':

yellowCar.forward_4W(velocity);

break;

case 'B':

yellowCar.back_4W(velocity);

break;

case 'L':

yellowCar.left_4W();

break;

case 'R':

yellowCar.right_4W();

break;

case 'S':

yellowCar.stopped_4W();

break;

case 'I':

yellowCar.forwardRight_4W(velocity);

break;

case 'J':

yellowCar.backRight_4W(velocity);

break;

case 'G':

yellowCar.forwardLeft_4W(velocity);

break;

case 'H':

yellowCar.backLeft_4W(velocity);

break;

case 'W': //Font ON

digitalWrite(pinfrontLights, HIGH);

break;

case 'w': //Font OFF

digitalWrite(pinfrontLights, LOW);

break;

case 'U': //Back ON

digitalWrite(pinbackLights, HIGH);

break;

case 'u': //Back OFF

digitalWrite(pinbackLights, LOW);

break;

case 'D': //Everything OFF

digitalWrite(pinfrontLights, LOW);

digitalWrite(pinbackLights, LOW);

yellowCar.stopped_4W();

break;

default: //Get velocity

if(command=='q'){

velocity = 255; //Full velocity

yellowCar.setSpeed_4W(velocity);

}

else{

//Chars '0' - '9' have an integer equivalence of 48 - 57, accordingly.

if((command >= 48) && (command <= 57)){

//Subtracting 48 changes the range from 48-57 to 0-9.

//Multiplying by 25 changes the range from 0-9 to 0-225.

velocity = (command - 48)*25;

yellowCar.setSpeed_4W(velocity);

}

}

}

}

}

Demonstration:

Disclaimer: Please use this reference at your own risk. I will not be held responsible for any damaged devices or injuries.