This circuit is designed to control a pair of DC motors using an Arduino UNO microcontroller in conjunction with an L298N DC motor driver. The Arduino UNO is also interfaced with a VL53L0X time-of-flight distance sensor to measure distances. The speed of the motors is regulated through a PID (Proportional-Integral-Derivative) control algorithm implemented in the Arduino's firmware, which uses distance measurements as feedback to adjust the motor speeds. A 12V battery is used to power the motor driver, which in turn powers the motors.
Arduino UNO
VL53L0X
L298N DC Motor Driver
Battery 12V
Motor and Wheels (2 instances)
Pushbutton
Resistor
#include <Wire.h>
#include <VL53L0X.h>
// Define pin assignments
int button = 3;
int motorpin1_1 = 9;
int motorpin1_2 = 10;
int enablemotor1 = 11;
int motorpin2_1 = 8;
int motorpin2_2 = 7;
int enablemotor2 = 6;
// Initialize variables for PID control
int timebefore = 0;
int setspeed = 200;
int motorspeed = 0;
int last_error = 0;
int Kp = 283, Kd = 500, Ki = 0.2;
// Create an instance of the VL53L0X sensor
VL53L0X sensor;
// Function prototypes
int PID_control();
void setup() {
Serial.begin(9600);
Wire.begin();
if (!sensor.init()) {
Serial.println("Failed to detect and initialize sensor!");
while (1);
}
sensor.setTimeout(500);
sensor.startContinuous();
// Set motor control pins as outputs
pinMode(motorpin1_1, OUTPUT);
pinMode(motorpin1_2, OUTPUT);
pinMode(enablemotor1, OUTPUT);
pinMode(motorpin2_1, OUTPUT);
pinMode(motorpin2_2, OUTPUT);
pinMode(enablemotor2, OUTPUT);
pinMode(button, INPUT);
}
void loop() {
int currentstate = digitalRead(button);
if (currentstate == 1 && last_button_state == 0) {
int timeconsumed = (millis() - timebefore);
uint16_t distance = sensor.readRangeContinuousMillimeters();
int distance_cm = distance / 10;
if (timeconsumed > 0) {
motorspeed = (distance / 1000.0) / (timeconsumed / 1000.0);
Serial.print("Motor Speed: ");
Serial.println(motorspeed);
}
if (sensor.timeoutOccurred()) {
Serial.println("Timeout!");
} else {
Serial.print("Distance: ");
Serial.print(distance);
Serial.println("mm");
delay(100);
}
if (distance_cm < 10) {
digitalWrite(enablemotor1, LOW);
digitalWrite(enablemotor2, LOW);
} else {
PID_control();
}
}
last_button_state = currentstate;
delay(10);
}
int PID_control() {
unsigned long currenttime = millis();
int error = setspeed - motorspeed;
unsigned long delta_time = (currenttime - timebefore) / 1000;
int integral = error * delta_time;
int derivative = (error - last_error) / delta_time;
last_error = error;
timebefore = currenttime;
long int PID_output = Kp * error + Ki * integral + Kd * derivative;
PID_output = constrain(PID_output, 0, 255);
analogWrite(enablemotor1, PID_output);
analogWrite(enablemotor2, PID_output);
return PID_output;
}
This code is responsible for reading the distance from the VL53L0X sensor and controlling the speed of the motors using a PID control loop. The motors are driven by the L298N motor driver, which receives PWM signals from the Arduino UNO. The button is used to start the motion control process, and the PID algorithm adjusts the motor speed based on the distance measurements to maintain a set speed.