About the Project
This project focuses on controlling the speed and direction of a DC motor using tilt data from the MPU6050 sensor. By measuring the tilt angle, the motor’s movement is adjusted, allowing forward, backward, or stop commands based on the tilt degree.
Gyro Accelerometer
The Gyro Accelerometer is a sensor that integrates both an accelerometer and a gyroscope. It measures linear acceleration and rotational velocity along three axes (X, Y, Z). This sensor is widely used in motion-sensing applications, such as drones, robotics, and gaming devices, for tracking movement and orientation.
MPU 6050 Module Pin Diagram
The MPU-6050 is a motion tracking sensor combining a 3-axis gyroscope and a 3-axis accelerometer.
MPU6050 Working
This project utilizes an MPU6050 sensor connected to an Arduino Uno to measure and analyse tilt angles. The MPU6050 combines a gyroscope and accelerometer to capture rotational speed and linear acceleration along the X, Y, and Z axes. By detecting rotational rates and changes in velocity, the sensor provides detailed data on both the device’s orientation and movement.
DC Motor
A DC motor is a device that turns electrical energy into mechanical motion. When you run electricity through the motor, it creates a magnetic field that makes a part of the motor spin. This spinning motion is what powers things like fans, toys, and even electric cars.
The direction of motion in a DC motor is determined by the direction of the electrical current flowing through the motor’s windings. Changing the polarity of the voltage applied to the motor (i.e., swapping the positive and negative connections) will reverse the direction of the current flowing through the motor’s windings.
The speed of a DC motor is directly proportional to the applied voltage. Increasing the voltage increases the motor speed, while decreasing the voltage reduces the motor speed.
Geared DC motors are commonly used in many applications. The gear reduction in these motors allows for lower output speeds while maintaining high torque. This is essential for applications that require precise and controlled movements, such as robotics, conveyor belts, and automated machinery.
L298N
The L298N is a popular dual H-bridge motor driver integrated circuit (IC) that allows you to control the speed and direction of two DC motors or control one stepper motor.
Jumpers in L298N Motor Driver Module
Understanding the jumpers on the L298N motor driver module is crucial for proper configuration and use. Whether you’re running motors at full speed or controlling their speed with PWM, setting the jumpers correctly is key to achieving desired functionality.
Circuit Wiring
Library Installation
To use the Wire, Adafruit_MPU6050, and Adafruit_Sensor libraries in your Arduino project, you need to install them in the Arduino IDE. Here’s a step-by-step guide on how to install these libraries:
- Install the Wire Library
The Wire library is a core library included with the Arduino IDE, so you don’t need to install it separately. It provides support for I2C communication, which is used to interface with the MPU6050 sensor.
- Install the Adafruit_MPU6050 Library
This library is specific to the MPU6050 sensor and is provided by Adafruit. Follow these steps to install it:
- Open the Arduino IDE.
- Go to the Library Manager:
- Click on Sketch in the top menu.
- Select Include Library > Manage Libraries….
- Search for the Library:
- In the Library Manager, type Adafruit MPU6050 into the search box.
- Install the Library:
- Find the Adafruit MPU6050 library in the search results.
- Click on it to select it.
- Click the Install button to add it to your Arduino IDE.
- Install the Adafruit_Sensor Library
The Adafruit_Sensor library is a dependency for the Adafruit_MPU6050 library and provides a common interface for various Adafruit sensors.
- Open the Arduino IDE.
- Go to the Library Manager:
- Click on Sketch in the top menu.
- Select Include Library > Manage Libraries….
- Search for the Library:
- In the Library Manager, type Adafruit Sensor into the search box.
- Install the Library:
- Find the Adafruit Sensor library in the search results.
- Click on it to select it.
- Click the Install button to add it to your Arduino IDE.
Program Code
// www.matthewtechub.com
// Control DC Motor Speed and Direction with MPU6050 Tilt
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
Adafruit_MPU6050 mpu;
// Define motor control pins
const int motorPWM = 10; // PWM pin for speed control
const int motorDir1 = 9; // Direction pin 1
const int motorDir2 = 8; // Direction pin 2
void setup() {
Serial.begin(9600);
while (!Serial)
delay(10); // Wait for Serial Monitor to open
// Initialize motor control pins
pinMode(motorPWM, OUTPUT);
pinMode(motorDir1, OUTPUT);
pinMode(motorDir2, OUTPUT);
// Try to initialize the MPU6050
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
// Set the accelerometer range
mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
// Set the gyro range
mpu.setGyroRange(MPU6050_RANGE_250_DEG);
// Set the filter bandwidth
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
delay(100);
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Calculate tilt angle in degrees for Y-axis
float angleY = atan2(-a.acceleration.x, a.acceleration.z) * 180.0 / PI;
// Print tilt angle
Serial.print("Tilt Angle Y: ");
Serial.print(angleY);
Serial.println("°");
// Control motor speed and direction based on tilt angle
if (angleY > 5) {
// Positive tilt - move forward
digitalWrite(motorDir1, HIGH);
digitalWrite(motorDir2, LOW);
int speed = map(angleY, 5, 90, 0, 255); // Map tilt angle to PWM range
analogWrite(motorPWM, speed);
Serial.println("Motor moving forward with speed: " + String(speed));
}
else if (angleY < -5) {
// Negative tilt - move backward
digitalWrite(motorDir1, LOW);
digitalWrite(motorDir2, HIGH);
int speed = map(angleY, -5, -90, 0, 255); // Map tilt angle to PWM range
analogWrite(motorPWM, speed);
Serial.println("Motor moving backward with speed: " + String(speed));
}
else {
// Between -5 and +5 degrees - stop motor
analogWrite(motorPWM, 0);
Serial.println("Motor stopped.");
}
delay(100);
}
This code continuously reads tilt data from the MPU6050 sensor and adjusts the speed and direction of a DC motor based on the Y-axis tilt angle:
- Tilting forward increases the speed in the forward direction.
- Tilting backward increases the speed in reverse.
- If the tilt angle is between -5° and +5°, the motor stops.
Code Explanation
Libraries and MPU6050 Initialization
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
Adafruit_MPU6050 mpu;
- Wire Library: Used for I2C communication between the Arduino and the MPU6050 sensor.
- Adafruit_MPU6050 and Adafruit_Sensor Libraries: These allow you to interact with the MPU6050 sensor, simplifying the process of collecting accelerometer and gyroscope data.
- mpu: Creates an instance of the sensor object for the MPU6050.
Motor Control Pins
const int motorPWM = 10; // PWM pin for speed control
const int motorDir1 = 9; // Direction control pin 1
const int motorDir2 = 8; // Direction control pin 2
- motorPWM: This pin is used to control the motor speed using Pulse Width Modulation (PWM).
- motorDir1 and motorDir2: These two pins control the direction of the motor. Setting them HIGH or LOW determines whether the motor moves forward or backward.
Setup Function
void setup() {
Serial.begin(9600);
while (!Serial) delay(10); // Wait for Serial Monitor to open
pinMode(motorPWM, OUTPUT); // Set motor pins as output
pinMode(motorDir1, OUTPUT);
pinMode(motorDir2, OUTPUT);
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) delay(10); // Loop forever if MPU6050 is not found
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_2_G); // Set range for accelerometer
mpu.setGyroRange(MPU6050_RANGE_250_DEG); // Set range for gyroscope
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); // Set filter bandwidth to remove noise
delay(100); // Wait for the MPU6050 to stabilize
}
- begin(9600): Initializes serial communication to monitor output via the Serial Monitor.
- pinMode(): Configures the motor pins as output pins.
- begin(): Initializes the MPU6050. If it fails, the program enters an infinite loop, and the message “Failed to find MPU6050 chip” is printed.
- setAccelerometerRange() and mpu.setGyroRange(): Sets the accelerometer and gyroscope sensitivity ranges. This helps define how sensitive the sensor is to movements and rotation.
- setFilterBandwidth(): Sets a filter to reduce high-frequency noise from the sensor data.
Main Loop Function
void loop() {
sensors_event_t a, g, temp; // Variables to store sensor data
mpu.getEvent(&a, &g, &temp); // Get data from accelerometer (a), gyroscope (g), and temperature (temp)
// Calculate tilt angle along the Y-axis
float angleY = atan2(-a.acceleration.x, a.acceleration.z) * 180.0 / PI;
// Print tilt angle to the Serial Monitor
Serial.print("Tilt Angle Y: ");
Serial.print(angleY);
Serial.println("°");
- getEvent(): Reads sensor data from the accelerometer (`a`), gyroscope (`g`), and temperature (`temp`).
- atan2(): Computes the tilt angle along the Y-axis using the arctangent of the accelerometer readings for the X and Z axes. This provides the angle of tilt in degrees (`* 180.0 / PI` converts radians to degrees).
- print(): Outputs the calculated tilt angle to the Serial Monitor for observation.
Motor Control Based on Tilt
if (angleY > 5) {
// Tilt angle greater than 5°: Move forward
digitalWrite(motorDir1, HIGH);
digitalWrite(motorDir2, LOW);
int speed = map(angleY, 5, 90, 0, 255); // Map angle to motor speed (0-255)
analogWrite(motorPWM, speed); // Set motor speed
Serial.println("Motor moving forward with speed: " + String(speed));
}
else if (angleY < -5) {
// Tilt angle less than -5°: Move backward
digitalWrite(motorDir1, LOW);
digitalWrite(motorDir2, HIGH);
int speed = map(angleY, -5, -90, 0, 255); // Map angle to motor speed (0-255)
analogWrite(motorPWM, speed); // Set motor speed
Serial.println("Motor moving backward with speed: " + String(speed));
}
else {
// Angle between -5° and 5°: Stop motor
analogWrite(motorPWM, 0); // Set motor speed to 0 (stop motor)
Serial.println("Motor stopped.");
}
delay(100); // Short delay before the next reading
}
- Forward Movement (Tilt > 5°*:
- digitalWrite(motorDir1, HIGH) and digitalWrite(motorDir2, LOW): Sets the motor to move forward.
- map(): Converts the tilt angle (from 5° to 90°) to a speed range from 0 to 255 (PWM value). The more you tilt, the faster the motor moves forward.
- Backward Movement (Tilt < -5°):
- digitalWrite(motorDir1, LOW) and digitalWrite(motorDir2, HIGH): Sets the motor to move backward.
- map(): Converts negative tilt angles (from -5° to -90°) to a speed range from 0 to 255, controlling the motor speed in reverse.
- Motor Stop (Tilt between -5° and 5°):
- **analogWrite(motorPWM, 0)**: Stops the motor when the tilt is within the neutral zone between -5° and 5°.
- **delay(100)**: Introduces a short delay between readings to prevent excessive output.