Stuck with rain sensor activating motor for one cycle.

Hi Guys,

As many others on here i am new to Arduino, have done a few small projects and now trying to do a rain sensing clothesline. and stuck on the code

Once the analog rain sensor reads that the value is below 400 i would like the led to come on and the motor to lower once.

And then once dried up and back past analog reading of 400 i would like the motor to raise the frame.

I have been trying to figure this out and seem to be stuck.

it works for one cycle but then will not change state’s back again to reset the cycle.

If anyone could help what i am doing wrong would be very greatly appreciated.

#include<AFMotor.h>
AF_DCMotor motor1(1);


const int analogPin = A8;    // pin that the sensor is attached to
const int ledPin = 11;       // pin that the LED is attached to
int threshold = 400;   // threshold to decide raining vs not raining
int lastValue,newValue;

void setup()  
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  motor1.setSpeed(250);
}

void loop() {

  int analogValue = analogRead(analogPin); // read the value of the Rain Sensor:

newValue=analogRead(analogPin);
  if (newValue-lastValue > threshold)  
  {
    Raise();
  } 
  
  if (lastValue-newValue > threshold)
  {
    Lower();
  }

  // print the analog value:
  Serial.println(analogValue);
  delay(2000);        // delay in between reads for stability
}

void Raise(){
  motor1.run(FORWARD);
    delay(1500);
    motor1.run(RELEASE);
    delay(1000);
    digitalWrite(ledPin, HIGH);
    Serial.println(newValue);
    lastValue=newValue;
}

void Lower(){ 
  motor1.run(BACKWARD);
    delay(1500);
    motor1.run(RELEASE);
    delay(1000);
    digitalWrite(ledPin, LOW);
    Serial.println(newValue);
    lastValue=newValue;
}

Perhaps I just don't understand your sensor but shouldn't you be performing the action based just on the current value? Why do you need all the lastValue-newValue newValue-lastValue stuff?

When you start, with newValue and lastValue both 0 it works. But then it looks like if the value gets down to say 350 you Lower and make lastValue=350. Then you won't run Raise until the newValue-350 > 400 i.e. newValue is over 750. Is that what you intended?

Steve

have you run some data logging to see the actual thresholds while it is dry, then raining, then dry again ?

also, you should always use hysteresis so that you do not dither at a value.

I would think you would have two end stops.
if it rains,
the value changes
motor runs
check the end stop if the end stop goes closed, then stop the motor

in the days before micro's we would run the power through the end stop switch.
once the end stop is reached, it would open the circuit and the motor would not be able to move in that direction any further.

the result would be that the motor runs to the end stop.
if it is raining, it would run until the end stop on the wet end is activated
when dry, it would run until the end stop on the dry end was activated.

Hi
Does your motor drive code work on its own, in other words have you got code that JUST tests the motor to prove you have that bit of code and connections correct?

Have you got code that JUST concerns the moisture sensor and make sure it works and your threshold statement works?

What model Arduino are you using?

Have you got sensors/limit switches to detect if the clothesline is fully up or fully down?

Thanks… Tom… :slight_smile:

One thing about your code: you have two variables, called lastValue and newValue. lastValue never gets set, so remains at zero. This means the moment newValue (the direct result of analogRead) goes over 400, you trigger Raise(). However lastValue will never be more than 400 greater than newValue so you never trigger Lower().

You probably planned to set lastValue to newValue at the end of loop(), to check whether it changed the next time loop() runs.

Even not knowing your sensor I am quite confident it will still not work, as the analogRead() calls are done every 2 seconds, and it’s not likely the sensor changes that quickly.

What you should do is something like this:

const byte sensorPin = A8; // Do give it a descriptive name!
bool raised;

// Hysteresis to prevent raising/lowering a lot when the wetness is around the threshold point
const int dryLevel = 600;
const int wetLevel = 400;

void loop() {
  wetness = analogRead(sensorPin);
  if (wetness > dryLevel && raised == false) {
    Raise();
    raises = true;
  }
  if (wetness < wetLevel && raised == true) {
    Lower();
    raised = false;
  }
}

That will trigger your motor to raise and lower your line as needed. You just check the current level, you don’t need to care about past levels, as what’s important is how it is now. Also I added a flag that makes sure you don’t try to raise when it’s raised already, as that’s something that probably is important to keep track of.

Thanks so much for your help everyone,

Exactly what i was after, as mentioned i am new to this and was unsure of how to write this,

wvmarie you are spot on. i believe i had confused myself with the newValue lastValue, and couldn't see how to fix it.

Thanks again for the help.

Still curious as of what sensor you have exactly.

https://www.jaycar.com.au/arduino-compatible-rain-sensor-module/p/XC4603

this is the exact sensor i have bought from my local Jaycar