Lesson 1 Moving Control
Lesson 1 Moving Control
M o ving r o l
Con t
Introduction:
In this lesson, there are three parts. First, we will teach you how to drive the motor and make our car run.
Preparations:
one car(with a battery)
one USB cable
Part 1: Tumbller Moving Control:
1.1 Hardware Design
In our kit, the motion of the car is controlled by two DC motors.
(As shown in figure 1.1.1~1.1.3)
However, DC motor is inductive load with large current (load with inductive parameters), while the IO of Arduino
Nano, the single chip microcomputer we use, has weak load capacity (i.e. output current capacity), and its driving
capacity is not enough to supply enough electric current for motor to rotate.
Therefore, we choose to use TB6612FENG motor driver chip.(As shown in figure 1.1.4~1.1.5):
Figure 1.1.4 The real object of motor Figure 1.1.5 Model picture of TB6612FENG
is a DC motor driver, which has a high current MOSFET-H bridge structure. Two output channels
drive two motors at the same time.
Maybe you are more familiar with L298N, in fact, the use of the two is basically the same. Compared with L298N's
heat consumption and peripheral diode continuous current circuit, it does not need additional heat sink, the
peripheral circuit is simple, only external power filter capacitor is needed. It can directly drive the motor, which is
beneficial to reduce the system size and the frequency up to 100kHz is enough to meet most of our needs.
Features
• Power supply voltage: VM = 15 V(Max)
• Output current: IOUT=1.2 A(ave) / 3.2 A (peak)
• Output low ON resistor: 0.5Ω (upper+lower Typ. @VM ≥ 5 V)
• Standby (energy-saving) system
• CW / CCW / short brake / stop function modes
• Built-in thermal shutdown circuit and low voltage detecting circuit
• Small panel package (SSOP24: 0.65 mm Lead pitch)
• Response to PB-free packaging
According to the TB6612 IC data sheet:Open the Related chip information -> TB6612FNG
MOTOR A :
Red part controls motor A, blue part controls motor B, A01, A02 are respectively connected to + and -.
In this kit,
MOTOR A:
PWMA is connected to D5
AIN1 is connected to D7
MOTOR B:
PWMB is connected to D6.
Bin1 is connected to D12. (As shown in figure 1.1.6)
According to the truth table, when the motor is rotating, AIN1 is high level, AIN2 is always low level, and when
AIN1is low level, AIN2 is always high level.
When the motor rotates, the input signals of AIN1 and AIN2 are always opposite.
So in order to save IO resources, we add SN74LVC2G14 Two-Way Schmitt
Trigger Reverser (As shown in figure 1.1.7), the input terminal is connected to
AIN1, and the output terminal is connected to AIN2, so that the level state of the
input terminal and the output terminal is always inverted.
Figure 1.1.7 The schematic
Same for Bin1 and BIN2. of SN74LVC2G14
In order to achieve the balance function in the later courses, we need to obtain the motor speed and rotation
direction, so we also need to drive two hall sensors on the motor to achieve the speed detection and rotation
direction detection function.(As shown in figure 1.1.8~1.1.9)
The reduction ratio is 1:30, which means that the input speed of the motor is 30 and the output shaft is 1 revolution.
Figure 1.1.8 Encoder drive pin on motor Figure 1.1.9 Corresponding pin connected to Nano
We can see four files in this program: (As shown in figure 1.2.1)
// in Motor.h
/*Motor pin*/
#define AIN1 7
#define PWMA_LEFT 5
#define BIN1 12
#define PWMB_RIGHT 6
#define STBY_PIN 8
//in Motor.cpp
void Motor::Pin_init()
{
pinMode(AIN1, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(PWMA_LEFT, OUTPUT);
pinMode(PWMB_RIGHT, OUTPUT);
pinMode(STBY_PIN, OUTPUT);
digitalWrite(STBY_PIN, HIGH);
}
void setup()
{
Motor.Pin_init();
......
}
When the pin initialization is completed, we can control the motor by changing the state of the pin, and let the
motor rotate in our ideal way.
Let's take a look at the overall implementation framework of the car motion. (As shown in figure 1.2.2)
It can be seen from the formula that the rotation speed is directly proportional to the number of pulses output by
the encoder in a certain period of time, so we only need to obtain the number of pulses.
First, we add the library file "PinChangeInt.h" of external interrupt. Then we initialize the external interrupt:
set the external interrupt pin, set the external interrupt function name, and set the external interrupt as the level
change interrupt.
//in Measuring_speed.cpp
#include "PinChangeInt.h"
//in Measuring_speed.cpp
void Motor::Encoder_init()
{
attachInterrupt(digitalPinToInterrupt(ENCODER_LEFT_A_PIN), EncoderCountLeftA, CHANGE);
attachPinChangeInterrupt(ENCODER_RIGHT_A_PIN, EncoderCountRightA, CHANGE);
}
void setup()
{ ......
Motor.Encoder_init();
......
}
Motor.Forward(SPEED);
delay(2000);
Motor.Back(SPEED);
delay(2000);
Motor.Left(SPEED);
delay(2000);
Motor.Right(SPEED);
delay(2000);
Because we found that the parameters of these four functions are the same, in order to make the loop() function
more concise, we can write it as an array of function pointers in the class, initialize it in the constructor, and call
these four different functions in the for() loop.
//in Motor.h
public:
Motor();
......
void (Motor::*MOVE[4])(int speed);
......
//in Motor.cpp
Motor::Motor()
{
MOVE[0] = &Motor::Forward;
MOVE[1] = &Motor::Back;
MOVE[2] = &Motor::Left;
MOVE[3] = &Motor::Right;
}
In the end, we print out the number of left and right encoder pulse signals obtained in the external interrupt
function every 2 seconds.
//in Motor.cpp