Arduino Loop doesn't work properly :-/

Hey Guys,

I just tested my watering box and realised that it doesn't work properly ...
It's a simple setup, a water sensor combined with a magnetvault. So i thougt it's also easy coding.
Well, i still have my problems with it.

When i just read the sensor it works fine !
I get a new value every 200 ms when i use delay(200)

But as soon as i add the solenoidpin to the code the delay functions don't work properly anymore.
It doesn't interrupt the programm, just as if the delay function wouldn't be there.

Furthermore the loop doesn't work as fast as before.
Before adding the solenoid code i got a new value shown every 200 ms. Now with the if funtion i get a new value every minute or something like that.

Hope somebody knows what could be wrong :slight_smile:

#define RELAY1 3

const int soilMoisturePin = A0;
const int solenoidPin1 = 3;
const int wateringTime = 30000;
const float wateringThreshold = 25;

float soilMoistureRaw = 0;
float soilMoisture = 0;

void setup()
{
// Setup serial
Serial.begin(9600);
pinMode(RELAY1, OUTPUT);
}

void loop()
{
soilMoistureRaw = analogRead(soilMoisturePin); //reading water value part begins

Serial.println(analogRead(0));
delay(200ms);
if ((soilMoistureRaw < wateringThreshold)) // magnetvault/solenoid part begins
//water the garden
digitalWrite(RELAY1, LOW);
delay(wateringTime);
digitalWrite(RELAY1, HIGH);
delay(1000);

}

if ((soilMoistureRaw < wateringThreshold))

I’ve got a spare of these { } - it looks like you could use them

I’ve also found a spare pair of these [code][/code] at the back of my sock drawer - you need them too

Please post a circuit diagram (hand drawn, not Fritzing).

Note: you should never attempt to power relays, solenoids or motors from the Arduino, and you need flyback diodes across coils, to protect your circuitry from inductive voltage spikes.

Can you show the code that does work and the code that doesn't?

With the code you posted, I would expect that if the watering condition was triggered, the messages would be much less frequent, because of that 30 second delay....

const int wateringTime = 30000; ... 

...delay(wateringTime);

There's your 30 second delay, :wink:

P.S.
I don't see a problem... The way you've designed your code to always turn on the water for 30 seconds, there's no need to "run faster". ...If you've already decided to run the water for 30 seconds, there's no need to read the moisture again until that time is up.

If you want to monitor the moisture while the water is on, use the timing methods from [u]Blink Without Delay[/u]. With that technique you can have multiple timers running at the same time, so you could have one timer for reading the moisture and another timer holding the water on for 30 seconds, with no delays. Or, you could leave the 200mS delay.

const float wateringThreshold = 25;

float soilMoistureRaw = 0;

Those don't need to be floats. analogRead returns an integer.

float soilMoisture = 0;

You're not using that variable.

When you use delay the Arduino does nothing until the time has expired.

Thanks for the fast replies ! Cool :slight_smile:

Something about my setup, i got a vh 400 connected to 3,3v, ground and A0, and i have a relais connected to 3.

This is the Code that works perfect ! It just displays every 200 ms a new value from my moisture sensor. But the magnetvault is not included yet.

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(analogRead(0));
  delay(200);
}

Then i added the magnetvault and turned the code into this.

#define RELAY1  3 

const int soilMoisturePin = A0;
const int  solenoidPin1 = 3;
const int wateringTime = 30000; //Set the watering time (10 min for a start)
const float wateringThreshold = 50; //Value below which the garden gets watered

float soilMoistureRaw = 0; //Raw analog input of soil moisture sensor (volts)
float soilMoisture = 0; //Scaled value of volumetric water content in soil (percent)

void setup()
{
  // Setup serial
  Serial.begin(9600);
  pinMode(RELAY1, OUTPUT);    
}

void loop()
{
  soilMoistureRaw = analogRead(soilMoisturePin);

  Serial.println(analogRead(0));
  if ((soilMoistureRaw < wateringThreshold))
    //water the garden
  digitalWrite(RELAY1, LOW);
  delay(wateringTime);
  digitalWrite(RELAY1, HIGH);
  delay(1000);

}

In my opinion, it should read the value from the sensor, display it, then if soilmoistureraw < wateringthreshold => activate relais. Then comes a watering time delay, deactive relais and a 1 second delay and it should reloop again. Or if soilmoistureraw > wateringthreshold only 1 second delay and reloop again.

So i should get a new value shown through serial.printin every second if the soilmoistureraw is not smaller than wateringthreshold, but sometimes it lasts up to a minute for me to get a new value shown.

Read reply #1 again and use the at least the {}.

Ok, changed the code to this, thanks Awol :slight_smile:

#define RELAY1  3 

const int soilMoisturePin = A0;
const int  solenoidPin1 = 3;
const int wateringTime = 3000; //Set the watering time (10 min for a start)
const float wateringThreshold = 50; //Value below which the garden gets watered

float soilMoistureRaw = 0; //Raw analog input of soil moisture sensor (volts)
float soilMoisture = 0; //Scaled value of volumetric water content in soil (percent)

void setup()
{
  // Setup serial
  Serial.begin(9600);
  pinMode(RELAY1, OUTPUT);    
}

void loop()
{
  soilMoistureRaw = analogRead(soilMoisturePin);

  Serial.println(analogRead(0));
  if ((soilMoistureRaw < wateringThreshold))
    //water the garden
   {
  digitalWrite(RELAY1, LOW);
  delay(wateringTime);
  digitalWrite(RELAY1, HIGH);
   }
   else
    {
  digitalWrite(RELAY1, HIGH);
    }
  delay(wateringTime);

}

It now works perfect :). Thank you so much :slight_smile:
Very helpful community :slight_smile: