Hello, I made a robot but am encountering issues with it. My wheels don’t go backwards and my robot does avoid obstacles like it’s supposed to. I attached my diagram and code below.
The robot is doing exactly what it was coded to do.
The function moveReverse() takes at most 50 microseconds to execute, then stopMotors() is called. How far would you expect the robot to move in 50 microseconds?
When testing motion control, test each part of the control individually, for long enough to see how the robot behaves, without mixing in sensors, other motions, etc.
Note: do not instantaneously reverse motors, as that burns out motor drivers. When going forward, stop the robot completely before executing reverse, and vice-versa.
This is not a PWM pin. It will only be HIGH/255 or LOW/0.
Using your pin numbers (use pin 7 as DIO and replace the PWM with a good pin), try this motors-only sketch. The first four sections test one motor in one direction. The second four motors test two motors in all directions. Watch the Serial Monitor for descriptions.
// Motor steering simulating Arduino Cars with L298N style motor driver boards
// NOT for LAFVIN car (LDR, IR, SONAR, line follow, IRremote)
// LEFT motor
int IN1 = 8; // LEFT motor forward, DIO pin, only HIGH or LOW
int IN2 = 7; // LEFT REVERSE, DIO pin, only HIGH or LOW
int ENA = 6; // ENABLE (and disable) left motor, PWM pin, speed = 0 - 255
// RIGHT motor
int IN3 = 2; // RIGHT motor forward, DIO pin, only HIGH or LOW
int IN4 = 4; // RIGHT motor reverse, DIO pin, only HIGH or LOW
int ENB = 3; // ENABLE (and disable) right motor, PWM pin, speed = 0 - 255
// adjustable PWM, range 0 (no speed) - 255 (full speed)
// useful factors of 255 = 1, 3, 5, 15, 17, 51, 85...
int speed = 51; // slow
// int speed = 127; // medium
// int speed = 255; // maximum
int ON = speed;
int OFF = 0;
int thisDelay = 3000; // delay during motor movement
void setup() {
Serial.begin(9600); // for Serial Monitor
pinMode(ENA, OUTPUT); // configure ENABLE pins for output
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT); // configure MOTOR DRIVER pins for output
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
digitalWrite(ENA, speed); // PWM speed control, 0 - 255
digitalWrite(ENB, speed);
eightSteeringModes();
}
void loop() {
}
void basicSteering() {
enableMotors(ON);
forward(); delay(1000); allStop();
reverse(); delay(1000); allStop();
rotateLeft(); delay(1000); allStop();
rotateRight(); delay(1000); allStop();
enableMotors(OFF);
}
void eightSteeringModes () {
enableMotors(ON);
allStop();
// single motor
forwardSkidLeft();
reverseSkidRight();// placed this out of order to keep car stationary
forwardSkidRight();
reverseSkidLeft();
// double motors
rotateLeft();
rotateRight();
forward();
reverse();
allStop();
enableMotors(OFF);
}
//**************************************************
// L298N MOTOR DIRECTIONS
//**************************************************
// ENA ENB IN1 IN2 IN3 IN4
// HIGH HIGH HIGH LOW LOW HIGH forward - left forward, right forward
// HIGH HIGH LOW HIGH HIGH LOW reverse - left reverse, right reverse
// HIGH HIGH LOW HIGH LOW HIGH face left - left reverse, right forward
// HIGH HIGH HIGH LOW HIGH LOW face right - left forward, right reverse
// HIGH HIGH HIGH LOW LOW LOW skid left - stop left, forward right
// HIGH HIGH LOW LOW LOW LOW stop - all LOW
// HIGH HIGH HIGH HIGH HIGH HIGH brake - all HIGH - do not use, over current
// LOW LOW N/A N/A N/A N/A stop - both ENABLE LOW
//
// *** LEFT motor and RIGHT motor are facing opposite directions ***
// *** LEFT motor will use HIGH, LOW to go forward ***
// *** RIGHT motor will use LOW, HIGH to go forward ***
//**************************************************
// MOTOR FUNCTIONS
//**************************************************
void driveMotor(bool p1, bool p2, bool p3, bool p4) {
digitalWrite(IN1, p1);
digitalWrite(IN2, p2);
digitalWrite(IN3, p3);
digitalWrite(IN4, p4);
delay(thisDelay);
}
void enableMotors(int enab) {
if (enab) {
Serial.print("Enable motors... ");
delay(thisDelay / 2);
}
else
Serial.print("... Disable motors.");
digitalWrite(ENA, enab);
digitalWrite(ENB, enab);
}
void allStop() {
Serial.print("All motors Stop. (L STOP R STOP)");
driveMotor(LOW, LOW, LOW, LOW);
delay(thisDelay / 2); // allow motor to be stopped
}
void forwardSkidLeft() {
Serial.print("\n\tForward Skid-Left. (L STOP R FWD)");
digitalWrite(ENA, 0);
digitalWrite(ENB, speed);
driveMotor(LOW, LOW, LOW, HIGH); // left motor stop, right motor forward
}
void forwardSkidRight() {
Serial.print("\tForward Skid-Right. (L FWD R STOP)");
digitalWrite(ENA, speed);
digitalWrite(ENB, 0);
driveMotor(HIGH, LOW, LOW, LOW); // left motor forward, right motor off
}
void reverseSkidLeft() {
Serial.print("\tReverse Skid-Left. (L REV R STOP)\n");
digitalWrite(ENA, speed);
digitalWrite(ENB, 0);
driveMotor(LOW, HIGH, LOW, LOW); // left motor reverse, right motor stop
}
void reverseSkidRight() {
Serial.print("\tReverse Skid-Right. (L STOP R REV)\n");
digitalWrite(ENA, 0);
digitalWrite(ENB, speed);
driveMotor(LOW, LOW, HIGH, LOW); // left motor off, right motor reverse
}
void rotateLeft() {
Serial.print("\tRotate Left.\t (L REV R FWD)");
digitalWrite(ENA, speed);
digitalWrite(ENB, speed);
driveMotor(LOW, HIGH, LOW, HIGH); // left motor reverse, right motor forward
}
void rotateRight() {
Serial.print("\tRotate Right.\t (L FWD R REV)\n");
digitalWrite(ENA, speed);
digitalWrite(ENB, speed);
driveMotor(HIGH, LOW, HIGH, LOW); // left motor forward, right motor reverse
}
void forward() {
Serial.print("\tForward.\t (L FWD R FWD)");
digitalWrite(ENA, speed);
digitalWrite(ENB, speed);
driveMotor(HIGH, LOW, LOW, HIGH); // left motor forward, right motor forward
}
void reverse() {
Serial.print("\tReverse.\t (L REV R REV)\n");
digitalWrite(ENA, speed);
digitalWrite(ENB, speed);
driveMotor(LOW, HIGH, HIGH, LOW ); // left motor reverse, right motor reverse
}
void pwmDrive() {
// Move motor with changing speed
int dutyCycle;
forward();
while (dutyCycle <= 255) {
digitalWrite(ENA, dutyCycle);
dutyCycle += 51; // useful factors of 255 = 1, 3, 5, 15, 17, 51, 85
delay(250);
}
reverse();
while (dutyCycle > 0) {
digitalWrite(ENA, dutyCycle);
dutyCycle -= 51;
delay(250);
}
}
so i updated my code and now my robot can go backwards but it doesn’t seem to be able to turn directions when it sense obstacles in front of it, here’s my schematic and updated code
i changed the ENB to the correct pin but now it doesn't move straight, i reworked my dc motors to my l298n motor to give it the ability to turn and now all it does is move clockwise
Your "lookAround()" function really does nothing but rotate a servo. You should include the "obstacleDetected()" function inside the "lookAround()" function and do this...
Look left and record the distance.
Look forward and record the distance.
Look right and record the distance.
Steer to the best direction (largest distance)
Move in that direction
Does that make sense, both "lookAround" doing nothing and how to determine where to send the vehicle?
so i changed my code to this, is this what you meant?
#include <Servo.h>
// Define pin numbers
const int trigPin = 8;
const int echoPin = 9;
const int servoPin = 10;
const int motor1Pin1 = 2;
const int motor1Pin2 = 3;
const int motor2Pin1 = 4;
const int motor2Pin2 = 5;
const int enaPin = 6;
const int enbPin = 11;
// Create servo object
Servo myservo;
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(servoPin, OUTPUT);
pinMode(enaPin, OUTPUT);
pinMode(enbPin, OUTPUT);
// Attach servo to pin
myservo.attach(servoPin);
}
void loop() {
if (obstacleDetected()) {
stopMotors();
int direction = lookAround();
steer(direction);
moveForward();
} else {
moveForward();
}
}
bool obstacleDetected() {
long duration, distance;
// Send pulse to trigger pin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read echo pin
duration = pulseIn(echoPin, HIGH);
// Calculate distance
distance = duration * 0.034 / 2;
// Print distance
Serial.print("Distance: ");
Serial.println(distance);
// Check if obstacle is detected
return distance < 20; // Adjust threshold as needed
}
int lookAround() {
int distanceLeft, distanceForward, distanceRight;
// Look left
myservo.write(0);
delay(500);
distanceLeft = measureDistance();
// Look forward
myservo.write(90);
delay(500);
distanceForward = measureDistance();
// Look right
myservo.write(180);
delay(500);
distanceRight = measureDistance();
// Determine best direction
if (distanceLeft > distanceForward && distanceLeft > distanceRight) {
return -1; // Left
} else if (distanceRight > distanceForward && distanceRight > distanceLeft) {
return 1; // Right
} else {
return 0; // Forward
}
}
void steer(int direction) {
// Steer based on direction
if (direction == -1) { // Left
// Steer left
digitalWrite(enaPin, HIGH);
digitalWrite(enbPin, HIGH);
digitalWrite(2, LOW); // Motor 1 reverse
digitalWrite(3, HIGH); // Motor 1 reverse
digitalWrite(4, HIGH); // Motor 2 forward
digitalWrite(5, LOW); // Motor 2 forward
delay(500); // Adjust turn duration as needed
} else if (direction == 1) { // Right
// Steer right
digitalWrite(enaPin, HIGH);
digitalWrite(enbPin, HIGH);
digitalWrite(2, HIGH); // Motor 1 forward
digitalWrite(3, LOW); // Motor 1 forward
digitalWrite(4, LOW); // Motor 2 reverse
digitalWrite(5, HIGH); // Motor 2 reverse
delay(500); // Adjust turn duration as needed
} else { // Forward
// No steering needed
}
}
void moveForward() {
// Move forward
digitalWrite(enaPin, HIGH);
digitalWrite(enbPin, HIGH);
digitalWrite(2, HIGH); // Motor 1 forward
digitalWrite(3, LOW); // Motor 1 forward
digitalWrite(4, HIGH); // Motor 2 forward
digitalWrite(5, LOW); // Motor 2 forward
}
void stopMotors() {
// Stop motors
digitalWrite(enaPin, LOW);
digitalWrite(enbPin, LOW);
}
int measureDistance() {
long duration;
// Send pulse to trigger pin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read echo pin
duration = pulseIn(echoPin, HIGH);
// Calculate distance
return duration * 0.034 / 2;
}
But now my motor 2 will not move, i connected the motor 2 directly to a power source and it spun around but now evern with the simplest code only motor 1 spinds, imunsure where to go form here seeing as this project is due tmrw
This initializes "direction" inside "loop()" meaning the scope of this "direction" is only valid inside "loop()"...
"lookAround" only returns a value with a range of 0 to 255, but not a "best direction to move with the farthest obstacles" then "steer(direction);" tries to use "direction" from the return of "lookAround()".
You have two motors with forward, backward and variable speed. Which motor, direction and speed is "42?"
You can use global variables to help the problem of scope, but to return many data points (direction of obstacle or which motor, which direction, which speed) from a function, you will need to pass a structure. I think you should start with using global variables before tackling structures.
Not my problem. I don't care.
The logic of "loop()" looks good, but "lookAround()" needs to give your "steer(direction)" more information (which motor, which direction, what speed).
Here is my "worst program, evAr" which shows the mis-use of one variable name, showing scope as "global" and "local," and the many levels of "local."
Never code like this...
// The many layers of variable scope shown on the Serial Monitor output.
int a = 9600; // global "a"
void setup() {
Serial.begin(a); // using the global variable value of "a"
Serial.println(a); // global "a"
int a = 2; // this new "a" is locally defined here, in "setup()"
for (int a = 7; a < 9; a++) { // this new "a" is local only inside "for"
Serial.println(a); // this "a" is local to "for"
}
Serial.println(a); // this "a" is local from the definition inside "setup"
}
void loop() {
Serial.println(a); // this is the global "a"
while(1);
}
Your motors look like they can use the same method as the TB6612FNG motor driver - IN1, IN2, ENA for each motor. This forum page has TEN motor tests that begin by testing one motor in one direction and end in both motors in both directions at varying speeds. When on the page, search "motors" and see "1 of 10" through "10 of 10" tests.