Arduino Mega Stops Completely When Motors Are Powered

Hi everyone, this is my first post here so i am figuring things out. I am trying to make a autonomous robot, and i have a single 12v LIPO that i am using to power the motors (controlled using a L298N), and i am using a buck converter to turn the 12 v to 9 volts to feed to the Arduino Vin pin (it is a adjustable controller so if there is any better method to do this please suggest). I also have a little cooling fan over the linear regulator as it was getting quite hot. All the other sensors (like gps, bluetooth, compass etc) are powered by the arduino 5v and 3.3v rails. The problem is i have a little switch that pulls pin 13 to ground when i want the arduino to sit stable and look for satelites then when i press the button it will disconnect ground and follow the waypoints. But when i press the button it will turn on the motors and then completely freeze (it seems it runs for a split second where it reads from the compass and turns the motors in the right direction then completely dies). If i press the reset it will resume working only when pin 13 is pulled to ground and again same behaviour continues. I tried putting a 4700uf capacitor as well but that didnt help either. Any suggestions are appreciated.

Welcome to the group.


Always show us a good schematic of your proposed circuit.
Show us good images of your ‘actual’ wiring.
Give links to components.


In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.
Use the < CODE / > icon from the ‘posting menu’ to attach the copied sketch.

Welcome to the forum

Can I make a suggestion ?
I realise that English may not be your first language but when you post a slab of text as you did it can be difficult to read and understand. It would be better broken into paragraphs, perhaps with some sentences split into two. This might encourage users to read it

Maybe something like this

Hi everyone, this is my first post here so i am figuring things out. I am trying to make a autonomous robot. I have a single 12v LIPO that i am using to power the motors, controlled using a L298N, and I am using a buck converter to turn the 12 v to 9 volts to feed to the Arduino Vin pin. it is an adjustable controller so if there is any better method to do this please suggest.

I also have a little cooling fan over the linear regulator as it was getting quite hot. All the other sensors, like gps, bluetooth, compass etc, are powered by the arduino 5v and 3.3v rails.

The problem is I have a little switch that pulls pin 13 to ground when I want the arduino to sit stable and look for satelites then when i press the button it will disconnect ground and follow the waypoints. However, when I press the button it will turn on the motors and then completely freeze. It seems it runs for a split second where it reads from the compass and turns the motors in the right direction then completely dies.

If I press the reset it will resume working only when pin 13 is pulled to ground and again same behaviour continues. I tried putting a 4700uf capacitor as well but that didn't help either.

Any suggestions are appreciated.

7V were better, and even better a 5V converter to feed the Arduino and all other 5V peripherals.

An Arduino is not a power source. Use dedicated buck converters for all voltages.

Your battery seems too weak for the motors. Also the L298N dinosaur will drop up to 4V from the battery voltage. Better use a modern MOSFET motor driver.

sure here is the code:
`
#include <TinyGPS++.h>

static const uint32_t GPSBaud = 9600;
TinyGPSPlus gps;

// Compass navigation
#include <Wire.h>
#include <QMC5883LCompass.h>
QMC5883LCompass compass;
int targetHeading;
int currentHeading;
int headingError; // signed (+/-) difference between targetHeading and currentHeading

#define HEADING_TOLERANCE 5 // tolerance +/- (in degrees) within which we don't attempt to turn to intercept targetHeading

#include "math.h"
#include <Adafruit_GPS.h>
Adafruit_GPS GPS(&Serial3);
float currentLat,
currentLong;

int distanceToTarget, // current distance to target (current waypoint)
originalDistanceToTarget; // distance to original waypoing when we started navigating to it

#define WAYPOINT_DIST_TOLERANE 1 //tolerance in meters to waypoint; once within this tolerance, will advance to the next waypoint
#define stopwaypoint 5 //second
int current_waypoint = 0;

float waypointList[10][2] = {
{ 23.202905, 72.658213},
{ 23.202849, 72.658091},
{ 23.202746, 72.658156},
{ 23.202841, 72.658310},
{ 23.202839, 72.658197},
};

float presetWaypointList[10][2] = {
{ 23.201336, 72.660916},
{ 23.201501, 72.660902},
{ 23.201659, 72.660930},
{ 23.201779, 72.660978},
{ 23.201927, 72.661102},
// ... you can continue for up to 10 waypoints
};

float targetLat = waypointList[0][0];
float targetLong = waypointList[0][1];

const int IR1 = 8;
const int IR2 = 9;

long duration;
int distance;

String bluetoothCommand = ""; // to accumulate characters from Bluetooth

void setup()
{
Serial.begin(9600); //Debug
Serial3.begin(9600); //GPS
Serial2.begin(9600); //Bluetooth

pinMode(13, INPUT_PULLUP);
setup_motor();

GPS.begin(9600); // 9600 NMEA default speed
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // turns on RMC and GGA (fix data)
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
GPS.sendCommand(PGCMD_NOANTENNA); // turn off antenna status info
delay(1000);

compass.init();
compass.setCalibration(-1215, 1033, -1236, 1112, -890, 0);

pinMode(IR1, INPUT);
pinMode(IR2, INPUT);

Serial.println("Start");

Serial.println(waypointList[0][0], 6);
Serial.println(waypointList[0][1], 6);

Serial.println(waypointList[1][0], 6);
Serial.println(waypointList[1][1], 6);

}

String inputString = "";
String inputdata = "";
bool stringComplete = false;
int id = 0;
int mode;

String val[5];
int nprint = 0;
int aprint = 0;

void loop()
{
int sensorVal = digitalRead(13);

while (Serial3.available() > 0)
if (gps.encode(Serial3.read()))
processGPS();

if (stringComplete)
{
Serial.println(inputString);
int n = 0;
for (int i = 0; i < 30; i++)
{
if (inputString[i] == 0)
{
n++;
if (n == 4)
break;
}
else
{
val[n] += inputString[i];
}
}

if (val[1] == "1")
{
  targetLat = val[2].toFloat();
  targetLong = val[3].toFloat();
}


inputString = "";
val[1] = "";
val[2] = "";
val[3] = "";
stringComplete = false;

}

if (sensorVal == LOW)
{
berhenti();
// Serial.print("la "); Serial.print(currentLat, 6);
// Serial.print("_lo "); Serial.print(currentLong, 6);
// Serial.print("_la "); Serial.print(targetLat, 6);
// Serial.print("_lo "); Serial.print(targetLong, 6);
// Serial.println();
nprint++;
if (nprint == 10000)
{
nprint = 0;

  Serial2.print("la "); Serial2.print(currentLat, 6);
  Serial2.print("_lo "); Serial2.print(currentLong, 6);
  Serial2.print("_la "); Serial2.print(targetLat, 6);
  Serial2.print("_lo "); Serial2.print(targetLong, 6);
  Serial2.print("_ch "); Serial2.print(currentHeading);
  Serial2.print("_st "); Serial2.print(gps.satellites.value(), 6);
  Serial2.println();
}   
processBluetoothCommand();

}
else if (sensorVal == HIGH)
{
// if(IR1==HIGH && IR2==HIGH){
if (currentLong > -1 && targetLong > -1)
{

  currentHeading = readCompass();
  calcDesiredTurn();
  move_robot();

  //      Serial.print("_ch "); Serial.print(currentHeading);
  //      Serial.print("_th "); Serial.print(targetHeading);
  //      Serial.print("_eh "); Serial.print(headingError);
  //      Serial.print("_di "); Serial.print(distanceToTarget);
  //      Serial.println();


  aprint++;
  if (aprint == 200 )
  {
    aprint = 0;
    Serial2.print("wp "); Serial2.print(current_waypoint);
    Serial2.print("_ch "); Serial2.print(currentHeading);
    Serial2.print("_th "); Serial2.print(targetHeading);
    Serial2.print("_eh "); Serial2.print(headingError);
    Serial2.print("_di "); Serial2.print(distanceToTarget);
    Serial2.println();
  }

}
else
{
  berhenti();
  Serial2.println("Check GPS");
}
/*}
else{
  berhenti();
  Serial2.println("Obstacle Detected");
}*/

}
}

void processGPS()
{
if (gps.location.isValid())
{
currentLat = gps.location.lat();
currentLong = gps.location.lng();

// update the course and distance to waypoint based on our new position
distanceToWaypoint();
courseToWaypoint();

}
}

// returns course in degrees (North=0, West=270) from position 1 to position 2,
// both specified as signed decimal-degrees latitude and longitude.
// Because Earth is no exact sphere, calculated course may be off by a tiny fraction.
// copied from TinyGPS library
int courseToWaypoint()
{
float dlon = radians(targetLong - currentLong);
float cLat = radians(currentLat);
float tLat = radians(targetLat);
float a1 = sin(dlon) * cos(tLat);
float a2 = sin(cLat) * cos(tLat) * cos(dlon);
a2 = cos(cLat) * sin(tLat) - a2;
a2 = atan2(a1, a2);
if (a2 < 0.0)
{
a2 += TWO_PI;
}
targetHeading = degrees(a2);
return targetHeading;
}

// returns distance in meters between two positions, both specified
// as signed decimal-degrees latitude and longitude. Uses great-circle
// distance computation for hypothetical sphere of radius 6372795 meters.
// Because Earth is no exact sphere, rounding errors may be up to 0.5%.
// copied from TinyGPS library
int distanceToWaypoint()
{
float delta = radians(currentLong - targetLong);
float sdlong = sin(delta);
float cdlong = cos(delta);
float lat1 = radians(currentLat);
float lat2 = radians(targetLat);
float slat1 = sin(lat1);
float clat1 = cos(lat1);
float slat2 = sin(lat2);
float clat2 = cos(lat2);
delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
delta = sq(delta);
delta += sq(clat2 * sdlong);
delta = sqrt(delta);
float denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
delta = atan2(delta, denom);
distanceToTarget = delta * 6372795;

// check to see if we have reached the current waypoint
if (distanceToTarget <= WAYPOINT_DIST_TOLERANE-1)
{
berhenti();
delay(stopwaypoint*1000);
nextWaypoint();
}
return distanceToTarget;
}

int readCompass()
{
compass.read();
int a;
a = compass.getAzimuth();
return (a);
}

void nextWaypoint()
{
current_waypoint++;
targetLat = waypointList[current_waypoint][0];
targetLong = waypointList[current_waypoint][1];

if ((targetLat == 0 && targetLong == 0)) // last waypoint reached?
{
berhenti();
Serial2.println("FINISH");
while (1); //PRESS RESET BUTTON
}
else
{
processGPS();
distanceToTarget = originalDistanceToTarget = distanceToWaypoint();
courseToWaypoint();
}
}

int error_output;
void calcDesiredTurn(void)
{
headingError = targetHeading - currentHeading; // calculate where we need to turn to head to destination

// adjust for compass wrap
if (headingError < -180)
headingError += 360;
if (headingError > 180)
headingError -= 360;

// calculate which way to turn to intercept the targetHeading
if (abs(headingError) <= HEADING_TOLERANCE) // if within tolerance, don't turn
error_output = 0;
else if (headingError < 60 && headingError > -60)
{
error_output = headingError;
}
else if (headingError >= 60)
error_output = 100;
else if (headingError <= -60)
error_output = -100;

}
float Kp, Kd;
void move_robot()
{
if (error_output == 0)
{
forward();
}
else if (error_output < 60)
{
if (error_output < 0)
left();
else
right();
}
else if (error_output == 100)
{
sharpright();
}
else if (error_output == -100)
{
sharpleft();
}
}

void processBluetoothCommand()
{
if (bluetoothCommand == "swp1")
{
waypointList[0][0] = currentLat;
waypointList[0][1] = currentLong;
}
else if (bluetoothCommand == "swp2")
{
waypointList[1][0] = currentLat;
waypointList[1][1] = currentLong;
}
else if (bluetoothCommand == "swp3")
{
waypointList[2][0] = currentLat;
waypointList[2][1] = currentLong;
}
else if (bluetoothCommand == "swp4")
{
waypointList[3][0] = currentLat;
waypointList[3][1] = currentLong;
}
else if (bluetoothCommand == "swp5")
{
waypointList[4][0] = currentLat;
waypointList[4][1] = currentLong;
}
else if (bluetoothCommand == "pswp")
{
for (int i = 0; i < 10; i++)
{
waypointList[i][0] = presetWaypointList[i][0];
waypointList[i][1] = presetWaypointList[i][1];
}
Serial2.println("Waypoint list swapped to preset!");
}
targetLat = waypointList[0][0];
targetLong = waypointList[0][1];
}

void serialEvent2() //bluetooth
{
while (Serial2.available())
{
char inChar = (char)Serial2.read();
if (inChar == '\n') // Assuming newline marks the end of a command
{
processBluetoothCommand();
bluetoothCommand = ""; // Clear the command for the next one
}
else
{
bluetoothCommand += inChar;
}
}
}`

I will upload the schematic and the photos as soon as i get some time to. As for the components i just order from a local website (India only) as well as some local shops.

Sure thanks for the suggestion i will keep this in mind.

7V were better, and even better a 5V converter to feed the Arduino and all other 5V peripherals.

Thanks for the suggestion but i read somewhere that for the full size boards (ie Mega, UNO, etc) we cant feed 5v to 5v pin and when i feed 5v to the vin pin it becomes completely unstable.

An Arduino is not a power source. Use dedicated buck converters for all voltages.

I have 2 of the buck converters so should i have 1 convert to 5v for the other sensors and other one to say 7v for the arduino?

Your battery seems too weak for the motors. Also the L298N dinosaur will drop up to 4V from the battery voltage. Better use a modern MOSFET motor driver.

I am using a LIPO battery so the amperage shouldent be a problem. I tried measuring the voltage and i couldent read any drops when i turn the switch. Can you suggest some better way to test that? Also what controller would you recomend? For now i only have the L298N so can you suggest some way to get that to work?

Any one except L29xxx.

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use [color = red]code tags[/color] (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum

This is the easiest way to tidy up the code and add the code tags

Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.