Arduino skipping over certain lines of code

I am writing software that reads soil moisture levels and checks every hour (right now it's set to every minute) if it's below a certain percentage. If it is, it initiates a function that turns on a water pump for 5 seconds. Outside of checking, it also changes an RGB LED from red to green (more water = more green) after reading the moisture level. I have 2 plants and therefore am using 2 RGB LEDs and a servo to aim the water at each plant.

I am having issues with initiating the watering function waterPlant(). Whenever the program gets to it, it seems to break the whole program (motor doesn't turn on, waterLED doesn't turn off, RGB LEDs freeze, etc). I tried giving enough delay time throughout the function but it still breaks.

Code:

#include <Servo.h>

Servo servo;

const int servoPin = 8;
const int base = 90;
const int plant1 = 170;
const int plant2 = 10;

const int wet1 = 288;
const int dry1 = 640;
const int wet2 = 310;
const int dry2 = 633;

const int wet1o = 288;
const int dry1o = 629;
const int wet2o = 302;
const int dry2o = 620;

int soil_1, soil_2;

const int redPin1 = 6;
const int greenPin1 = 11;

const int redPin2 = 3;
const int greenPin2 = 5;

const int waterLED = 4;

const int servDelay = 1250;
const int waterDelay = 5000;

const int pump1 = 12;

unsigned long curTime;

unsigned long checkDelay = 60000;   //Check water concentration every hour

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(pump1, OUTPUT);

  servo.attach(servoPin);
  servo.write(base);

  pinMode(redPin1, OUTPUT);
  pinMode(greenPin1, OUTPUT);

  pinMode(redPin2, OUTPUT);
  pinMode(greenPin2, OUTPUT);

  pinMode(waterLED, OUTPUT);

  curTime = millis();
}

void loop() {
  // put your main code here, to run repeatedly:

  soil_1 = abs(map(analogRead(A0), dry1, wet1, 0, 100));
  soil_2 = abs(map(analogRead(A1), dry2, wet2, 0, 100));

  if (digitalRead(pump1) == LOW) {
    soil_1 = abs(soil_1 - 3);
    soil_2 = abs(soil_2 - 4);
  }

  onLED(soil_1, redPin1, greenPin1);
  onLED(soil_2, redPin2, greenPin2);

  //  Serial.println(soil_1);
  //  Serial.println(soil_2);
  //  Serial.println(" ");
  delay(100);

  Serial.println(millis());   // Debugging line
  if (millis() - curTime >= checkDelay) {
    if (soil_1 < 60) {
      waterPlant(plant1);
    }
    delay(5000);
    if (soil_2 < 60) {
      waterPlant(plant2);
    }
    curTime = millis();
  }
}

void onLED(int perc, int rp, int gp) {
  // Changes RGB LED based on moisture reading
  analogWrite(rp, 100 - perc);
  analogWrite(gp, perc);
}

void waterPlant(int aim) {
  // Waters a specific plant
  digitalWrite(waterLED, HIGH);
  servo.write(aim);
  delay(servDelay);
  digitalWrite(pump1, HIGH);
  delay(waterDelay);
  digitalWrite(pump1, LOW);
  servo.write(base);
  delay(servDelay);
  digitalWrite(waterLED, LOW);
}

Could you post a wiring diagram and an image or 2 of your project.

My guess is there is a power issue of some sort.

How are you powering the servo? If it off the Arduino and it takes a lot (for some value of "lot") of current is could be pulling the voltage down to where the Arduino crashes.

Specifically, do you have a power supply for the Servo? :face_with_raised_eyebrow:

The servo is being powered by the 5v line from the Arduino. I've used this method before and it seemed to work fine.

I have also attached a wiring diagram. I apologize if it's hard to follow. I'm new to this stuff.

You need to get an external power supply.

Using 5 volts from the Arduino like you are doing, will damage your Arduino.

You can get away with it sometimes with micro 9g servos, but it's never a good idea. I have a few 9g servos, and one of them always reboots the Arduino; two others can happily run together. Shouldn't do it though, even with a micro servo, and never with any bigger ones.

Put a serial print in setup() to say "hello... I'm starting" and see if the Arduino is resetting.

edit:

  1. And it's not just the servo you're powering I see. You also energise the relay coil and the power the pump.
  2. The pump needs a flyback diode.

Hello avats
Your sketch looks like it has grown a bit organically.
How do you handle a access conflict to the servo if it is time for watering the flower reported by both sensors?

Have a nice day and enjoy programming in C++ and learning.
Дайте миру шанс!

I swapped the servo with a small one and it seemed to fix everything. If you are suggesting this is still not safe then I will look into buying another power supply.

The relay is a module so I assumed a diode was built it.

I simply go one by one. If plant 1 is in need of water, the servo will rotate the water hose to point at the plant and the same with plant 2. It first checks plant 1 and then plant 2 so there aren't any conflicts if both need watering. I believe that's what you're referring to? If not, please let me know so I can learn the proper method. Thanks!

Yes, it is.
I´ve tried to understand the coding but a millis() based timer and multilayered calls of delay()´s I was derailed to follow the logical structure of the sketch.

Have a nice day and enjoy programming in C++ and learning.
Дайте миру шанс!

I wasn't talking about the relay though: I said the pump needs a diode. The diode in the relay module relates to the relay coil. Doesn't the motor need one too, to protect the relay contacts?- I'm not sure.

Yes and no, for two reasons.

  1. The relay contacts are pretty robust, especially for 5 V circuits.
  2. Motors do not generally cause the same "kickback" as inductors - because they are motors.
1 Like

Servos pull quite a lot of current, especially under load. Unfortunately, there are a gazillion tutorials that show servos powered by the Arduino. You can just about get away with it if you're powering via USB and the servo is small and lightly loaded, but you're pulling more current through the microscopic PCB traces on the board than is sensible.

Most telling perhaps, is that well over ninety percent of servo problems we hear about here are power related.

Hey no, nice diagram!

a7

Apart from not following the convention of having power + at the top and ground at the bottom, and signals where possible going across.

You really should use drivers for the motors and relays, opto coupled is preferred, given you don't know what can happen with external devices.
The diode across the relay is called flywheel diode, so that it does not back feed current into the circuit when power is removed and most purchased relay boards have this as standard. Basically a relay is just another motor, that generates power when power is removed.
Motors such as slow moving servos, do not really need them, given they stop turning when power is removed.

The reasoning about having opto couple drivers, is that a motor is just an inductor connected directly to the MPU pin, which can give odd effects and should be decoupled with a suitable capacitor.Motors generate noise when in operation which could damage the Arduino.
opto coupling these isolates any of these problems.

Finally a decent supply for all devices or two simple supplies to keep everything isolated from each other.

Keep learning, its good for you :slight_smile:

Yeah I also kinda made a game of untangkling all the crossed wires, in my head anyways.

The use of colour helped, and red and black like it was meant to be.

a7

As a post script comment. You should really have a delay between watering times.

A plant needs three things, light, water and air. The last means air around the roots. A plant that has its roots constantly in water, does not survive very well.

I grow hydroponically, however that does mean either having aerated water over the roots or turning the water off for periods.

Take a tomato plant. It should only be watered every few days as over watering will stunt its growth and lead to less fruit.

As far as drawing circuits, there are many decent little schematic editors you can either use on line or download for free use.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.