Arduino mega crash everytime i excute this command

Hi all,

So I have two pumps that I control with a motor driver and 14 solenoid valves that I'm controlling using 7 2-relay modules.
I have a function called withdraw, basically, this function opens up all valves and both pumps in the reverse direction, but once i send the command to switch off everything, the Arduino restarts just as if i pressed the reset button.

I'm powering Arduino through the Vin pin using a 5 volts source

I cannot understand the cause of this, according to google usually this issue is coming from incorrect wiring, but I'm sure of my wiring and also when i control 4 valves only or say 10 valves only, i don't have any problem
The problem comes only when i control the two pumps and the 14 valves all together.

EDIT: i added the Serial.println functions to see where is the problem exactly, the Serial print get the I go A and the I go to B shown in the code, but the arduino restarts before the C and D show off

Here is the code:

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {23, 25, 27, 29};
byte colPins[COLS] = {31, 33, 35, 37};
Keypad kpd = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


const int waterpumpA = 3;                           // the pump connected to the water tank
const int waterpumpB = 2;                           // the pump connected to the water tank
const int methpumpA = 4;                            // the pump connected to the other tank
const int methpumpB = 5;                            // the pump connected to the other tank

const int wvalve[] = {19, 18, 17, 16, 15, A10, 13}; // valves connected to tank1
const int mvalve[] = {12, 11, 10, 9, 8, 7, 6}; // valves connected to tank 2

uint8_t state; // state machine
const uint8_t mainmenue = 1;
const uint8_t firstmainmenue = 2;
const uint8_t stoppingofnot = 3;



void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  state = firstmainmenue;
  Serial.begin(9600);
  for (int i = 0; i < 7; i++)
  {
    Serial.print("we are at setup now and i=   ");
    Serial.println(i);
    Serial.println(wvalve[i]);
    pinMode(wvalve[i], OUTPUT);
    pinMode(mvalve[i], OUTPUT);
    digitalWrite(wvalve[i], HIGH); //high means closed for this valve
    digitalWrite(mvalve[i], HIGH);
  }

  pinMode(waterpumpA, OUTPUT);
  pinMode(methpumpA, OUTPUT);
  pinMode(waterpumpB, OUTPUT);
  pinMode(methpumpB, OUTPUT);

}

void loop() {
  if (state == firstmainmenue)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Press C to start");
    state = mainmenue;
  }
  ///////////////////////////////////////////////////
  //////////////////////////////////////////////////
  else if (state == mainmenue)
  {
    //Serial.println("Main menue");
    char key = kpd.getKey();
    if (key)
    {
      Serial.println(key);

      if (key == 'C')
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Withdrawing..");
        lcd.setCursor(0, 1);
        lcd.print("press # to stop");
        for (int i = 0; i < 7; i++)
        {
          digitalWrite(wvalve[i], LOW); //opens the valves
          digitalWrite(mvalve[i], LOW); // opens the valves
        }
        //    digitalWrite(waterpumpB, HIGH); //switch on the pump 1 in the reverse direction
        //  digitalWrite(methpumpB, HIGH);//switch on the pump 2 in the reverse direction
        state = stoppingofnot;
      }
    }
  }
  ///////////////////////////////////////////////////
  //////////////////////////////////////////////////
  else if (state == stoppingofnot)
  {
    char key3 = kpd.getKey();
    if (key3)
    {
      if (key3 == '#') //my problem us here, this works actually and they all switch off but then the arduino crashes as soon as everything is off
      {
        Serial.println( " I got to A"); //this one works
        pumpstop();
        Serial.println( " I got to B"); //works!!
        delay(100);
        valvestopall();
        Serial.println( " I got to C"); //never printed
        delay(100);
        state = firstmainmenue;
        Serial.println( " I got to D"); //never printed 
      }
    }
  }

}
///////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void valvestopall()
{
  for (int i = 0; i < 7; i++)
  {
    Serial.print("We are at closing loop and the vlaue of i=   "); //just to see if the whole loop is being excuted or not
    Serial.println(i); //all of them were printed 
    Serial.println(wvalve[i]);
    digitalWrite(wvalve[i], HIGH);
    delay(100);
    digitalWrite(mvalve[i], HIGH);
    delay(100);
  }
}
///////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void pumpstop()
{
  digitalWrite(waterpumpA, LOW);
  delay(100);
  digitalWrite(waterpumpB, LOW);
  delay(100);
  digitalWrite(methpumpA, LOW);
  delay(100);
  digitalWrite(methpumpB, LOW);
  delay(100);
}

If You post schematics and links to the datasheets of the unknown items You switch it would be possible to tell.

How are the relays, values and pumps powered ?

Please post a schematic of your project

machine.pdf (4.8 MB)

The arduino is powered from the same 12v to 5v step down used to power the other side of the 2-rely modules, (Not shown here)

Does it make sense that supplying my Arduino with more voltage would solve the issue? Since the recommended is 7-12 volts, and i'm supplying with 5 only

The 7-12V supply relates to powering the Arduino through the barrel jack or Vin pin. You are better off supplying 5V at adequate current through a 5V pin

I am sorry, but your diagram is just about incomprehensible with its riot of colours.

A traditional schematic would be so much easier to read

There is something interesting just happened, when i control only half of the valves, the arduino didn't crash

I simply did this to the code:

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {23, 25, 27, 29};
byte colPins[COLS] = {31, 33, 35, 37};
Keypad kpd = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


const int waterpumpA = 3;                           // the pump connected to the water tank
const int waterpumpB = 2;                           // the pump connected to the water tank
const int methpumpA = 4;                            // the pump connected to the other tank
const int methpumpB = 5;                            // the pump connected to the other tank

const int wvalve[] = {19, 18, 17, 16, 15, A10, 13}; // valves connected to tank1
const int mvalve[] = {12, 11, 10, 9, 8, 7, 6}; // valves connected to tank 2

uint8_t state; // state machine
const uint8_t mainmenue = 1;
const uint8_t firstmainmenue = 2;
const uint8_t stoppingofnot = 3;



void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  state = firstmainmenue;
  // put your setup code here, to run once:
  for (int i = 0; i < 7; i++)
  {
    pinMode(wvalve[i], OUTPUT);
    pinMode(mvalve[i], OUTPUT);
    digitalWrite(wvalve[i], HIGH); //high means closed for this valve
    digitalWrite(mvalve[i], HIGH);
  }
  pinMode(waterpumpA, OUTPUT);
  pinMode(methpumpA, OUTPUT);
  pinMode(waterpumpB, OUTPUT);
  pinMode(methpumpB, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (state == firstmainmenue)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Press C to start");
    state = mainmenue;
  }
  ///////////////////////////////////////////////////
  //////////////////////////////////////////////////
  else if (state == mainmenue)
  {
    Serial.println("Main menue");
    char key = kpd.getKey();
    if (key)
    {
      Serial.println(key);

      if (key == 'C')
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Withdrawing..");
        lcd.setCursor(0, 1);
        lcd.print("press # to stop");
        for (int i = 0; i < 7; i++)
        {
          digitalWrite(wvalve[i], LOW); //opens the valves
      //    digitalWrite(mvalve[i], LOW); // opens the valves
        }
        digitalWrite(waterpumpB, HIGH); //switch on the pump 1 in the reverse direction
        digitalWrite(methpumpB, HIGH);//switch on the pump 2 in the reverse direction
        state = stoppingofnot;
      }
    }
  }
  ///////////////////////////////////////////////////
  //////////////////////////////////////////////////
  else if (state == stoppingofnot)
  {
    char key3 = kpd.getKey();
    if (key3)
    {
      if (key3 == '#') //my problem us here, this works actually and they all switch off but then the arduino crashes as soon as everything is off
      {
        pumpstop();
        delay(100);
        valvestopall();
        delay(100);
        state = firstmainmenue;
      }
    }
  }

}
///////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void valvestopall()
{
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(wvalve[i], HIGH);
    delay(100);
  //  digitalWrite(mvalve[i], HIGH);
    delay(100);
  }
}
///////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void pumpstop()
{
  digitalWrite(waterpumpA, LOW);
  delay(100);
  digitalWrite(waterpumpB, LOW);
  delay(100);
  digitalWrite(methpumpA, LOW);
  delay(100);
  digitalWrite(methpumpB, LOW);
  delay(100);
}

So means, the crash is only happening when i'm sending commands to all valves together, when i canceled the other set of valves nothing happened
Also, i tried canceling the commands to the pumps while keeping the commands to the 14 valves only and the crash remains there.
My problem is now at the valves control only, it is somehow too heavy for the Arduino to handle, does that make sense?

More likely it is too heavy for the power supply to handle. What happens if you stagger the closing of the valves one second apart ?

I just made the delay for 1000 but it still crashed as soon as it closed the last valve in order

The weird thing is that i start the program with closing all the valves at void setup ()
But then opening them and closing them back is what causing this problem.

Please note this:
1- the relays are powered from a module that steps down voltage from 12v to 5v
2- the power source is a 12v and 30A
3- even when i don't do anything for the pumps i still get this issue

It should make no difference, but try putting the valve closing code in a function and call it from setup() and later in the code when required. Some delay()s and Serial.print()s in strategic places in the code may help identify exactly where the problem occurs

I notice A10 is being used as a digital pin but setup() has no provision to program A10 as a digital pin; pinmode().

What do you get in the serial monitor after adding a serial print?

Serial.println( " I got to A");
pumpstop();
Serial.println( " I got to B");
        delay(100);
        valvestopall();
Serial.println( " I got to C");
        delay(100);
        state = firstmainmenue;
Serial.println( " I got to D");

Which one(s) prints out? which one(s) don't?

But what about this statement?

Doesn't this go through all of it including the A10?

A and B are printed out only

In const int wvalve[] = {19, 18, 17, 16, 15, A10, 13}; there are 7 elements in a zero based array.

This for (int i = 0; i < 7; i++) will count from 0 to 7 in an array.

wvalve[0] = 19
wvalve[1] = 18
wvalve[2] = 17
wvalve[3] = 16
wvalve[4] = 15
wvalve[5] = A10
wvalve[6] = 13

What would wvalve[7] contain?

Nothing, wvalve[7] won't be called at all, will it?

doesn't this mean less than 7, which means 7 is not included?

for (int i = 0; i < 7; i++)
  {
Serial.println( i );
Serial.println( wvalve[i] );
    pinMode(wvalve[i], OUTPUT)

to see where in the function things stop.

I added this to both setup and the closing function.

So the code it:

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {23, 25, 27, 29};
byte colPins[COLS] = {31, 33, 35, 37};
Keypad kpd = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


const int waterpumpA = 3;                           // the pump connected to the water tank
const int waterpumpB = 2;                           // the pump connected to the water tank
const int methpumpA = 4;                            // the pump connected to the other tank
const int methpumpB = 5;                            // the pump connected to the other tank

const int wvalve[] = {19, 18, 17, 16, 15, A10, 13}; // valves connected to tank1
const int mvalve[] = {12, 11, 10, 9, 8, 7, 6}; // valves connected to tank 2

uint8_t state; // state machine
const uint8_t mainmenue = 1;
const uint8_t firstmainmenue = 2;
const uint8_t stoppingofnot = 3;



void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  state = firstmainmenue;
  Serial.begin(9600);
  for (int i = 0; i < 7; i++)
  {
    Serial.print("we are at setup now and i=   ");
    Serial.println(i);
    Serial.println(wvalve[i]);
    pinMode(wvalve[i], OUTPUT);
    pinMode(mvalve[i], OUTPUT);
    digitalWrite(wvalve[i], HIGH); //high means closed for this valve
    digitalWrite(mvalve[i], HIGH);
  }

  pinMode(waterpumpA, OUTPUT);
  pinMode(methpumpA, OUTPUT);
  pinMode(waterpumpB, OUTPUT);
  pinMode(methpumpB, OUTPUT);

}

void loop() {
  if (state == firstmainmenue)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Press C to start");
    state = mainmenue;
  }
  ///////////////////////////////////////////////////
  //////////////////////////////////////////////////
  else if (state == mainmenue)
  {
    //Serial.println("Main menue");
    char key = kpd.getKey();
    if (key)
    {
      Serial.println(key);

      if (key == 'C')
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Withdrawing..");
        lcd.setCursor(0, 1);
        lcd.print("press # to stop");
        for (int i = 0; i < 7; i++)
        {
          digitalWrite(wvalve[i], LOW); //opens the valves
          digitalWrite(mvalve[i], LOW); // opens the valves
        }
        //    digitalWrite(waterpumpB, HIGH); //switch on the pump 1 in the reverse direction
        //  digitalWrite(methpumpB, HIGH);//switch on the pump 2 in the reverse direction
        state = stoppingofnot;
      }
    }
  }
  ///////////////////////////////////////////////////
  //////////////////////////////////////////////////
  else if (state == stoppingofnot)
  {
    char key3 = kpd.getKey();
    if (key3)
    {
      if (key3 == '#') //my problem us here, this works actually and they all switch off but then the arduino crashes as soon as everything is off
      {
        Serial.println( " I got to A");
        pumpstop();
        Serial.println( " I got to B");
        delay(100);
        valvestopall();
        Serial.println( " I got to C");
        delay(100);
        state = firstmainmenue;
        Serial.println( " I got to D");
      }
    }
  }

}
///////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void valvestopall()
{
  for (int i = 0; i < 7; i++)
  {
    Serial.print("We are at closing loop and the vlaue of i=   ");
    Serial.println(i);
    Serial.println(wvalve[i]);
    digitalWrite(wvalve[i], HIGH);
    delay(100);
    digitalWrite(mvalve[i], HIGH);
    delay(100);
  }
}
///////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void pumpstop()
{
  digitalWrite(waterpumpA, LOW);
  delay(100);
  digitalWrite(waterpumpB, LOW);
  delay(100);
  digitalWrite(methpumpA, LOW);
  delay(100);
  digitalWrite(methpumpB, LOW);
  delay(100);
}

wait i just tried again, and i got the full set of i values:

11:04:09.119 -> we are at setup now and i= 0
11:04:09.166 -> 19
11:04:09.166 -> we are at setup now and i= 1
11:04:09.212 -> 18
11:04:09.212 -> we are at setup now and i= 2
11:04:09.258 -> 17
11:04:09.258 -> we are at setup now and i= 3
11:04:09.305 -> 16
11:04:09.305 -> we are at setup now and i= 4
11:04:09.305 -> 15
11:04:09.305 -> we are at setup now and i= 5
11:04:09.350 -> 64
11:04:09.350 -> we are at setup now and i= 6
11:04:09.398 -> 13
11:04:12.366 -> C
11:04:15.282 -> I got to A
11:04:15.660 -> I got to B
11:04:15.755 -> We are at closing loop and the vlaue of i= 0
11:04:15.804 -> 19
11:04:15.992 -> We are at closing loop and the vlaue of i= 1
11:04:16.039 -> 18
11:04:16.176 -> We are at closing loop and the vlaue of i= 2
11:04:16.222 -> 17
11:04:16.362 -> We are at closing loop and the vlaue of i= 3
11:04:16.409 -> 16
11:04:16.597 -> We are at closing loop and the vlaue of i= 4
11:04:16.643 -> 15
11:04:16.785 -> We are at closing loop and the vlaue of i= 5
11:04:16.833 -> 64
11:04:16.972 -> We are at closing loop and the vlaue of i= 6
11:04:17.020 -> 13
11:04:19.081 -> we are at setup now and i= 0
11:04:19.128 -> 19
11:04:19.128 -> we are at setup now and i= 1
11:04:19.128 -> 18
11:04:19.128 -> we are at setup now and i= 2
11:04:19.174 -> 17
11:04:19.174 -> we are at setup now and i= 3
11:04:19.220 -> 16
11:04:19.220 -> we are at setup now and i= 4
11:04:19.266 -> 15
11:04:19.266 -> we are at setup now and i= 5
11:04:19.266 -> 64
11:04:19.313 -> we are at setup now and i= 6
11:04:19.313 -> 13

The only thing is that the "I go to C" and "I go to D" don't show up