Pages: [1] 2 3   Go Down
Author Topic: Help programing - Turn on/off based on input  (Read 1912 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone help me with coding? Below is what I have, but I would like to replace the delay() function to millis()

Any help would be appreciated  smiley

 int relayPin = 13;  // relay connecte to digital pin 13
 int inPin = 7;      // sensor input source connecte to digital pin 7
 int val = 0;        // variable to store the read value

void setup()
{                
  // initializes
  pinMode(relayPin, OUTPUT);        // sets the digtial pin 13 as output
  pinMode(inPin, INPUT);            // sets the digital pin 7 as input
}

void loop()
{
  val = digitalRead(inPin);            // read the input pin
  
  if(val == HIGH)
  {
    delay(10000);                      //wait 10secs.
    digitalWrite(relayPin, HIGH);
  }
  else
  {
    delay(2000);                      //remain on for 2secs
    digitalWrite(relayPin, LOW);
  }
 
    
}
Logged

0
Offline Offline
Shannon Member
****
Karma: 161
Posts: 10442
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Firstly you want to record the times at which things are to happen, not actually wait.
Code:
  if (val == HIGH)
  {
    relay_turn_on = true ;
    relay_on_time = millis () + 10000 ;
  }
  if (val == LOW && relay_turn_on)
  {
    relay_turn_off = true ;
    relay_off_time = millis () + 2000 ;
  }

And you also need to check if these events are due

Code:

  if (relay_turn_on && millis () - relay_on_time >= 0)
  {
     digitalWrite (relayPin, HIGH) ;
     relay_turn_on = false ;
  }
  if (relay_turn_off && millis () - relay_off_time >= 0)
  {
    digitalWrite (relayPin, LOW) ;
    relay_turn_off = false ;
    relay_turn_on = false ;  // cancel pending turn on event since we've just turned it off.
  }

Something like that - although I haven't tested this and I'm a bit wary about how the events interact as they are not independent - I've assumed that the need to turn off the relay is only if its already scheduled to turn on - but I'm not sure exactly what you want the behaviour to be.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the basic idea what I wanted the program to do. I have sensor that monitor the water level, High in air and Low in water.

So when water low; sensor is High, turn on relay (pump) but before it turn on, because water fluctuate delay for 10secs before it really turn on. Once it is on remain on for 2secs and then shut off relay.

I also would like a the relay to stay on for 30secs after that program should stop execute until manually Reset.
Logged

New Jersey
Online Online
Faraday Member
**
Karma: 48
Posts: 3419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not quite sure I understand the requirement. Is it "if the sensor is confirmed high over a ten second period, run the pump for 2 seconds, but limit total pumping until a restart to 30 seconds?"

That would certainly give some protection against a flood caused by the level sensor going bad. Once you have that working, you might consider instituting a daily (or longer) pumping limit so you don't have to do the manual restart so frequently. Also consider whether you need to defend against the arduino getting reset if the power goes out.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

2 seconds plus whatever time it take for the pump to fill up the water to reach the sensor (sensor read Low). In other words after sensor comfirmed High, run the pump, fill up the water, sensor read Low...remain on for 2 seconds before shut off.

The 30 seconds (just a make up number for now) is the fault protection is for the bad sensor or the water reservoir empty, this to prevent the pump running too long when water is empty.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So in theory, I dont have to reset as often...unless water run out or sensor go bad.
Logged

New Jersey
Online Online
Faraday Member
**
Karma: 48
Posts: 3419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think you're going to need some extra logic to handle the sensor bad/out of water condition. Otherwise, when one of those things occurs, you're going to run the pump for 30 seconds every time you check the level sensor, possibly burning out the pump once it exhausts the reservoir.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well 30 seconds is the cut off time, if pump still on (meaning no water in the reservoir) shut it off. Assuming it take 20 seconds to fill up the water, so it never have to reach the 30 seconds limit.

Does that make sense?
Logged

New Jersey
Online Online
Faraday Member
**
Karma: 48
Posts: 3419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not entirely. Now I think it's "if the sensor is confirmed high over a ten second period, run the pump until sensor is low and then for another 2 seconds. If that pumping is still happening after 30 seconds, stop the pump and use the infinite loop to stop all subsequent operations until reset"
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes! that is pretty much what I wanted to do :-)
Logged

New Jersey
Online Online
Faraday Member
**
Karma: 48
Posts: 3419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Requirement is defined (pretty much) so it's time to look at state machines - you'll find examples in the forums. Enumerate your states (I count five),  figure out what you have to do in each state, what causes transitions between them and what to do when you transition. Loop() becomes a switch statement with the states as cases. Add in some variables to tell you when timed events started and you're most of the way there.
Logged

Victoria, BC, Canada
Offline Offline
Full Member
***
Karma: 0
Posts: 222
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

To use a timer instead of a delay, you use code like MarkT showed already.

If you're short on space, one way to manage is to use a variable for each item's timer, and use zero to represent an unused event (that is, not currently active).

For example, say you want a light on for 5 seconds, then turn off. Use a variable 'timerLight' to hold the milliseconds to stop in the future:

Code:
unsigned long timerLight=0;
void loop()
{
  unsigned long msec=millis();
  if ( ourNotYetWrittenHelperFunctionToDetectIfWeWantTheLightOn() )
  {
    timerLight=msec+5000; // when to stop in the future

// now turn on light

  }
  if ( timerLight && timerLight<msec ) // time to turn off?
  {
    timerLight=0;// turn off timer so we don't check again
       
// turn off light (somehow)
   
  }
}

Now the code loop will stay active without delays, yet still catch events.

You can also gang up the events - for example, after you turn off one light, you could turn on another:

Code:
unsigned long timerLight1=0, timerLight2=0;
void loop()
{
  unsigned long msec=millis();
  if ( ourNotYetWrittenHelperFunctionToDetectIfWeWantTheLightOn() )
  {
    timerLight1=msec+5000; // when to stop in the future

// now turn on light

  }
  if ( timerLight1 && timerLight1<msec ) // time to turn off 1st light?
  {
    timerLight1=0;// turn off timer so we don't check again
       
// turn off light1 (somehow)

    // now next light - turn it off in 10 seconds
    timerLight2=msec+10000; // when to stop #2 in the future

// turn ON light2 (somehow)

   
  }
  if ( timerLight2 && timerLight2<msec ) // time to turn off 2nd light?
  {
    timerLight2=0;// turn off timer so we don't check again
       
// turn off light2 (somehow)
   
  }
}

The result is a you can a number of events in whichever order you want - just remember to add on and off code in the appropriate sections.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the feedback guys.

My computer currently not working, so will have to wait few days to test out the codes.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok! I got this codes to do what I wanted, but I need a timeout code within this codes. I want to say if "val" still read HIGH after 1 minute, write LOW to relayPin.

Can someone help me?


unsigned long relay_on_time;
unsigned long loopTime;

int relayPin = 13;  // relay connected to digital pin 13
int inPin = 7;      // sensor input source connected to digital pin 7
int val = 0;        // variable to store the read value

void setup()
{
  relay_on_time = millis();
  loopTime = relay_on_time; 
 
  pinMode(relayPin, OUTPUT);        // sets the digtial pin 13 as output
  pinMode(inPin, INPUT);            // sets the digital pin 7 as input
}

void loop()
{
  relay_on_time = millis();
 
  if (relay_on_time >= (loopTime + 10000))
  {
    val = digitalRead(inPin);
   
    if (val == HIGH)
    {
      digitalWrite(relayPin, HIGH);
    }
   
    if (val == LOW)
    {
      digitalWrite (relayPin, LOW);
    }
    loopTime = relay_on_time;
  }
 
}
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perhaps the (untested) sketch below will get you closer.
see the BlinkWithoutDelay example sketch if you need more on using millis to determine a timeout period

Code:
int relayPin = 13;   // relay connected to digital pin 13
int waterLowPin = 7; // pint goes high when water level is low
int val = 0;         // variable to store the read value

long relay_on_time;

void setup()
{
  pinMode(relayPin, OUTPUT);       // sets the digtial pin 13 as output
  pinMode(waterLowPin, INPUT);     // sets the digital pin 7 as input
}

void loop()
{
  if( digitalRead(waterLowPin))
  {
    // here if the water level is low
    delay(1000 * 10); // wait ten seconds
    if( digitalRead(waterLowPin))  // check again
    {
       // here if water level is still low   
       digitalWrite(relayPin, HIGH); // turn on relay       
       relay_on_time = millis();
       while( millis() - relay_on_time < (1000 * 30) )
       {   
         if( digitalRead(waterLowPin) == false)  // check if level is now high
         {
            delay(1000 * 2); // wait two seconds
            digitalWrite(relayPin, LOW); // turn off relay
            break; // exit the while loop
         }
       }
       // here if pump on for more than 30 seconds
       digitalWrite(relayPin, LOW); // turn off relay
    }
  }
}
Logged

Pages: [1] 2 3   Go Up
Jump to: