I'm working on a self-balancing robot. The self-balancing is not the issue. The issue is that the motors don't respond as they are supposed to.
I would understand if it were unable to balance, but the motors are not reacting to the tilt at all. The motors aren't responding to the lines of code that are telling them to move, despite being wired correctly.
I turn on the system and it spins one motor and usually in one direction, but at times it will slow down or change direction. This change does not occur consistently which I am sure of. Moving the robot to the exact same rotation and back gives different results each time.
I have checked the voltage with a multimeter, 4.9V at the Arduino 5V pin. I have a 9V battery connected to the barrel jack (Vin) 8.26V in. I know this Arduino and MPU5060 are not broken and are in fact connected correctly because when I run the serial monitor it shows me the tilt in degrees on my laptop.
A list of tests I did and what they showed me:
1: All voltages were what they should be at 5V pin and Vin according to my multimeter. The 5V on the MPU6050 was also the same as the 5V on the Arduino obviously as it's the same node.
2: I tried a blink sketch to see if the Arduino was working when plugged into the battery (9V) instead of the computer cord. It blinked as it should, showing that indeed it had sufficient power from the battery and was working correctly. I now know the Arduino is working and is not underpowered.
3: I tested if the MPU6050 was functioning on the battery power (powered off Arduino which is powered off the 9V). I made a sketch that turned on the onboard LED if the MPU6050 was past 0 degrees. This test worked consistently When it was tilted between -1 and -90 degrees it turned the LED on. When I positioned it back up to 0 degrees or past 0 it turned the light off. So now I know conclusively that the Arduino and MPU6050 are functioning and not being underpowered.
4: I tested both motors individually disconnected from the l298n, with a 6V 4AA battery pack and both spun like they should.
5: When I disconnect the two PWM pins and put the tiny jumpers on the l298n back in place both wheels turn in the same direction at a consistant speed but do not react to the tilt at all. They continuously move in that direction and nothing stops them from spinning until I unplug it.
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include "math.h"
#define leftMotorPWMPin 5
#define leftMotorGoForward 6
#define leftMotorGoBack 7
#define rightMotorGoForward 8
#define rightMotorGoBack 9
#define rightMotorPWMPin 10
int16_t accY, accZ;
float accAngle;
MPU6050 mpu;
void setup() {
// set the motor control and PWM pins to output mode
pinMode(leftMotorPWMPin, OUTPUT);
pinMode(leftMotorGoForward, OUTPUT);
pinMode(leftMotorGoBack, OUTPUT);
pinMode(rightMotorGoForward, OUTPUT);
pinMode(rightMotorGoBack, OUTPUT);
pinMode(rightMotorPWMPin, OUTPUT);
// set the status LED to output mode
mpu.initialize();
Serial.begin(9600);
}
void loop() {
//delay(100);
accZ = mpu.getAccelerationZ();
accY = mpu.getAccelerationY();
accAngle = atan2(accY, accZ)*RAD_TO_DEG;
if (isnan(accAngle));
else
Serial.println(accAngle);
if ((accAngle <= 5) && (accAngle > 0)) {
analogWrite(leftMotorPWMPin, 42.5);
digitalWrite(leftMotorGoForward, HIGH);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 42.5);
digitalWrite(rightMotorGoForward, HIGH);
digitalWrite(rightMotorGoBack, LOW);
}
else if (accAngle == 0) {
analogWrite(leftMotorPWMPin, 0);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 0);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, LOW);
}
else if ((accAngle <= 15) && (accAngle > 5)) {
analogWrite(leftMotorPWMPin, 85);
digitalWrite(leftMotorGoForward, HIGH);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 85);
digitalWrite(rightMotorGoForward, HIGH);
digitalWrite(rightMotorGoBack, LOW);
}
else if ((accAngle <= 30) && (accAngle > 15)) {
analogWrite(leftMotorPWMPin, 127.5);
digitalWrite(leftMotorGoForward, HIGH);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 127.5);
digitalWrite(rightMotorGoForward, HIGH);
digitalWrite(rightMotorGoBack, LOW);
}
else if ((accAngle <= 45) && (accAngle > 30)) {
analogWrite(leftMotorPWMPin, 170);
digitalWrite(leftMotorGoForward, HIGH);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 170);
digitalWrite(rightMotorGoForward, HIGH);
digitalWrite(rightMotorGoBack, LOW);
}
else if ((accAngle <= 65) && (accAngle > 45)) {
analogWrite(leftMotorPWMPin, 212.5);
digitalWrite(leftMotorGoForward, HIGH);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 212.5);
digitalWrite(rightMotorGoForward, HIGH);
digitalWrite(rightMotorGoBack, LOW);
}
else if ((accAngle <= 90) && (accAngle > 65)) {
analogWrite(leftMotorPWMPin, 255);
digitalWrite(leftMotorGoForward, HIGH);
digitalWrite(leftMotorGoBack, LOW);
analogWrite(leftMotorPWMPin, 255);
digitalWrite(rightMotorGoForward, HIGH);
digitalWrite(rightMotorGoBack, LOW);
}
//These next bunch are identical but for the negative (if it falls backwards)
if ((accAngle >= -5) && (accAngle < 0)) {
analogWrite(leftMotorPWMPin, 42.5);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, HIGH);
analogWrite(leftMotorPWMPin, 42.5);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, HIGH);
}
else if ((accAngle >= -15) && (accAngle < -5)) {
analogWrite(leftMotorPWMPin, 85);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, HIGH);
analogWrite(leftMotorPWMPin, 85);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, HIGH);
}
else if ((accAngle >= -30) && (accAngle < -15)) {
analogWrite(leftMotorPWMPin, 127.5);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, HIGH);
analogWrite(leftMotorPWMPin, 127.5);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, HIGH);
}
else if ((accAngle >= -45) && (accAngle < -30)) {
analogWrite(leftMotorPWMPin, 170);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, HIGH);
analogWrite(leftMotorPWMPin, 170);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, HIGH);
}
else if ((accAngle >= -65) && (accAngle < -45)) {
analogWrite(leftMotorPWMPin, 212.5);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, HIGH);
analogWrite(leftMotorPWMPin, 212.5);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, HIGH);
}
else if ((accAngle >= -90) && (accAngle < 65)) {
analogWrite(leftMotorPWMPin, 255);
digitalWrite(leftMotorGoForward, LOW);
digitalWrite(leftMotorGoBack, HIGH);
analogWrite(leftMotorPWMPin, 255);
digitalWrite(rightMotorGoForward, LOW);
digitalWrite(rightMotorGoBack, HIGH);
}
}
I am aware this is an unconventional way of programming for a self balancing robot, that is not my problem so don't mention it please and thank you!
Anyone have any ideas to what could be the source of the issue? Is it possible one of the libraries is using the PWM pins in the background?
All out of ideas, the motor controller board is practically brand new I highly doubt it's broken.
Schematic:
leftMotorPWMPin
where I would expect to seerightMotorPWMPin
, which is unused beyond being set to output. That doesn't explain all that you're describing though. – timemage Feb 26 at 1:37