Motor Driver Shield
Contents
Introduction
This is an extension shield that can drive 4 servos, 2 DC motors and one stepper motor. All you need to do is plug the shield into the Uno or Mega2560 board. It is powered by two sources – when connected to a control board, it’s powered by the output of the board; to drive a large-current motor, you can connect an external supply for the Motor Driver Shield and the control board. There's an indicator LED on the shield. When it's not in use, you can power the shield off by the switch and it won't influence the use of the control board. The working voltage is 6.5V-12V.
Schematic Diagram
Power Supply
This shield is a dual-supply one. It can be connected directly to the Uno or Mega2560 board which then serves as the supply. But if you want to drive a DC motor of 5V or higher, you need an external power then. S1 is a single-pole double-throw (SPDT) switch and controls the power of the shield. Pull it to OFF and the whole shield will not work. S2 is a 6-pin self-lock button switch that controls the external power supply. When you press down the button, the external power source is connected to shield and will also supply the control board. Thus, the external power can be no higher than 12V.
When the Motor Driver Shield is not in use, just pull S1 to OFF. And the shield will not affect the control board.
Connecting DC Motor
L293D
The two DC motors connected are controlled by the L293D chip.
The L293D is a 4-channel monolithic integrated motor driver chip of high voltage and high current. L293D has two pins (Vs and VSS) for power supply. Vs is used to supply power for the motor, while VSS, for the chip. If a small DC motor is used, connect both pins to +5V. If you use a higher power motor, you need to connect Vs to an external power supply.
See the schematic diagram of the L293D chip below. EN is an enable pin – active when high level is received. A represents inputs, and Y, output. The relationship between the two pins are shown in the table below. When EN is High, if A is High, Y output is High; if A is Low, Y is Low too. When EN is Low, the L293D does not work.
Pricinple
Pin EN1,2 and EN3,4 are controlled by the pin pwm1 (pin 5 of the control board) and pwm2 (pin 6 of control board), when IN1 and IN2, by dir1 (pin 7 of the control board). When EN1,2 is High, if IN2 is also High, the transistor is energized, thus making IN1 Low and the motors connected to out1 and out2 start spinning; if IN2 is Low, by default IN1 is High, so the motors will rotate in the opposite direction.
IN3 and IN4 are controlled by dir2 (pin4 of the control board). When EN3,4 is High, if IN4 is High too, the transistor is energized, thus making IN3 Low and the motors connected to out3 and out4 start spinning; if IN4 is Low, by default IN3 is High, so the motors will rotate in the opposite direction.
Test Code
/**************************************************** * Name: DC Motor * Function: the motor rotate clockwise 1s and rotate counterclockwise 1s *****************************************************/ //Email:support@sunfounder.com //Website:www.sunfounder.com #define PWM1 6 //pwm1 connects to pin6 #define PWM2 5 //pwm2 connects to pin5 #define DIR1 7 //dir1 connects to pin7 #define DIR2 4 //dir2 connects to pin4 void setup() { //set all the pin as OUTPUT pinMode(PWM1, OUTPUT); pinMode(PWM2, OUTPUT); pinMode(DIR1, OUTPUT); pinMode(DIR2, OUTPUT); } void loop() { //1 represent the motor connect to out1 and out2 ctlDCMotor(1, 255); ctlDCMotor(2, 255); delay(1000);//delay 1s ctlDCMotor(1, -255); ctlDCMotor(2, -255); delay(1000);//delay 1s } //set the motors rotate direction void ctlDCMotor(byte MotorID, int speeds) { //motor1 rotate if (MotorID == 1) { if (speeds > 0) { digitalWrite(DIR1, HIGH); } else { digitalWrite(DIR1, LOW); } if (abs(speeds) > 255) { speeds = 255; } analogWrite(PWM1, abs(speeds)); //Serial.print("...........................................................left:"); //Serial.println(abs(speeds)); } //motor2 rotate else if (MotorID == 2) { if (speeds > 0) { digitalWrite(DIR2, HIGH); } else { digitalWrite(DIR2, LOW); } if (abs(speeds) > 255) { speeds = 255; } analogWrite(PWM2, abs(speeds)); //Serial.print("...........................................................right:"); //Serial.println(abs(speeds)); } }
Stepper Motor
ULN2003
On the Motor Driver Shield, the stepper motor is controlled by the ULN2003. The ULN2003 chip is an array of high-voltage and high-current Darlington transistors. Each chip consists of seven NPN Darlington pairs that feature high-voltage outputs with common-cathode clamp diodes for switching inductive loads. When the base (B) of the NPN transistor is High, the transistor is electrified. If the emitter (E) is connected to GND, the collector (C) will output High.
- ULN2003 NPN Darlington transistor
Pins and Functions
Principle
PWR is the power source and connected with the COM pin of the stepper motor. Pin 1B, 2B, 3B, and 4B are controlled by pin A, B, C, and D (pin A0 to A3 of the control board) respectively. The emitter of all the channels are connected to GND. When a High level is given to the base, the collector will output Low. Therefore, you can control the motor to move by just controlling the logical level of pin 1B, 2B, 3B, and 4B respectively.
Test Code
/******************************************************* * Name:Stepper Motor * Function: the Stepper Motor rotate clockwise * and then rotate counterclockwise *******************************************************/ //Email:support@sunfounder.com //Website:www.sunfounder.com int pwm; const char tab1[] = { 0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09 }; const char tab2[] = { 0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03 }; void setup() { pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); pinMode(A3, OUTPUT); } void loop() { ctlStepMotor(360, 1); //the motor rotate counterclockwise every 1ms StepMotorStop(); //stop the stepper motor delay(1000); //delay 1s ctlStepMotor(-360, 1);//the motor rotate clockwise every 1ms StepMotorStop();//stop the stepper motor delay(1000);//delay 1s } void ctlStepMotor(int angle, char speeds )//the stepper motor rotate from 0 to angle, { for (int j = 0; j < abs(angle) ; j++) { if (angle > 0) { for (int i = 0; i < 8; i++) { digitalWrite(A0, ((tab1[i] & 0x01) == 0x01 ? true : false)); digitalWrite(A1, ((tab1[i] & 0x02) == 0x02 ? true : false)); digitalWrite(A2, ((tab1[i] & 0x04) == 0x04 ? true : false)); digitalWrite(A3, ((tab1[i] & 0x08) == 0x08 ? true : false)); delay(speeds); } } else { for (int i = 0; i < 8 ; i++) { digitalWrite(A0, ((tab2[i] & 0x01) == 0x01 ? true : false)); digitalWrite(A1, ((tab2[i] & 0x02) == 0x02 ? true : false)); digitalWrite(A2, ((tab2[i] & 0x04) == 0x04 ? true : false)); digitalWrite(A3, ((tab2[i] & 0x08) == 0x08 ? true : false)); delay(speeds); } } } } //stop the stepper motor void StepMotorStop() { digitalWrite(A0, 0); digitalWrite(A1, 0); digitalWrite(A2, 0); digitalWrite(A3, 0); }
Servo
The Motor Driver Shield can control 4 servos once. They are controlled by pin 8, 9, 10, and 11 of the control board respectively. So just write some different angles to the four pins and you can control the servo to move.
Test code
/************************************************ * name:Servo * Function:the 4 servos rotate clockwise and counterclockwise synchronously ******************************************************/ //Email:support@sunfounder.com //Website:www.sunfounder.com /************************************************/ #include <Servo.h> /************************************************/ Servo myservo[2][2];//create servo object to control a servo /************************************************/ const int servo_pin[2][2]={ 8,9,10,11}; void setup() { for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { myservo[i][j].attach(servo_pin[i][j]); delay(100); } }
} /*************************************************/
void loop()
{
servorotate();
} //the 4 servo rotate clockwise and counterclockwise
void servorotate()
{
//4 servos rotate clockwise for (int i=0; i <= 180; i+=1)// goes from 0 degrees to 180 degrees { myservo[0][0].write(i); delay(1); //delay 1ms myservo[0][1].write(i); delay(1); myservo[1][0].write(i); delay(1); myservo[1][1].write(i); delay(1); } //4 servos rotate counterclockwise for(int i = 180; i>=0; i-=1) // goes from 180 degrees to 0 degrees { myservo[0][0].write(i); delay(1); myservo[0][1].write(i); delay(1); myservo[1][0].write(i); delay(1); myservo[1][1].write(i); delay(1); } } }
/*************************************************/
void loop()
{
servo1rotate();
}
void servo1rotate() { for (int i=0; i <= 180; i+=1) { myservo[0][0].write(i); delay(1); myservo[0][1].write(i); delay(1); myservo[1][0].write(i); delay(1); myservo[1][1].write(i); delay(1); } for(int i = 180; i>=0; i-=1) // goes from 180 degrees to 0 degrees { myservo[0][0].write(i); delay(1); myservo[0][1].write(i); delay(1); myservo[1][0].write(i); delay(1); myservo[1][1].write(i); delay(1); // waits 15ms for the servo to reach the position } }