How to make more the 1 function work at a time

Hi there

I am new arduino code so please for give me.

I am tying to make a project that will fade up some leds when a pir is activated then run for a set time(millis) if no moment detected then fade back down.

i do have a sketch that does this just fine but i also need to turn on a relay when a water flow switch is made and stay on till the switch turns off but run on for a pre-set time (millis)

i do have a separate sketch that also does this on its own but i can not get them to run together

can some help me please.

here is my sketch of the led fade up and down. please amend were appropriate.

const int flowswitch = A0;
const byte led = 9; // connect to gate
const byte pir = 7; // PIR signal in
const byte turnOnTime = 2; // turn on/off time in seconds !(will be forced: 50 > time > 0)
const byte minutesToOff = 2; // minutes of 'silence' before "lights out" !! ALTER THIS VALUE
const boolean debug=false;
int stateRelay = LOW;
int stateButton =LOW;

boolean lightIsOn = false; // remember LED-status 'now'
unsigned long timeToTurnOff; // time when led will turn off
unsigned long timeNow; // current time
int Relay = 5;

void setup()
{

pinMode(led,OUTPUT);
pinMode(pir,INPUT);
}

boolean heWantsLightsOn()
{
return (digitalRead(pir)==HIGH);
}

void turnLightsOn(byte period)
{

long delayTime = period * 2 ;
for (byte i=0; i<255; i++)
{
analogWrite(led,i);
delay(delayTime);
}
digitalWrite(led,HIGH); // no PWM needed - turn on 100%
lightIsOn=true; // remember status
}

void turnLightsOff(byte period)
{

long delayTime = period*60 ;
for (byte i=254; i>0; i--)
{
analogWrite(led,i);
delay(delayTime);
}
digitalWrite(led,LOW); // no PWM needed - turn off
lightIsOn=false; // remember status
}

void loop()
{
timeNow=millis(); // note time now
if (heWantsLightsOn()) // if movement -> be light!
{
if (!lightIsOn) turnLightsOn(turnOnTime);

}

if (timeNow > timeToTurnOff) // is it time to turn off ??
{
if (lightIsOn) turnLightsOff(turnOnTime); // if light still are on: turn them off
}
}
//END********

here is the sketch of the relay

const int flowswitch = A0;
int Relay = 5;

int stateRelay = LOW;
int stateButton =HIGH;

int previous = LOW;
long time = 0;
long debounce = 0;
int stayON = 1000; //stay on for 180000 ms = 3mins

void setup() {
pinMode(flowswitch, INPUT);
pinMode(Relay, OUTPUT);
}

void loop() {
stateButton = digitalRead(flowswitch);
if(stateButton == HIGH && previous == LOW && millis() - time > debounce) {
if(stateRelay == HIGH){
digitalWrite(Relay, LOW);
} else {
digitalWrite(Relay, LOW);
delay(stayON);
digitalWrite(Relay, HIGH);
}
time = millis();
}

}

thanks

steve

Robin2's thread here will probably help with that.

You can't make two functions run at the same time.

You have to figure out how to make the functions run in small steps so that they can be interleaved together.

Instead of having a for loop to fade the LED all the way up or down all at once before anything else can happen, think about a function that simply checks to see if it is time to take the next fade step and only takes one step of the fade. That function could be called repeatedly from loop giving the same fade effect, but allowing you to also call the other function between fade steps.

See if the info at this link is helpful: Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Hi thanks for that.

I have already read that post but because i a am still new to this i dont now were to start.

will i need to start from scratch with my sketch or can it be adjusted.

Steve

Probably time to start from scratch.

No, don't start from scratch. Start from the Blink_Without_Delay example sketch.

MorganS:
Start from the Blink_Without_Delay example sketch.

Always a good idea to understand this technique at first principles. Once you have your mind round it, to simplify implementation you may find the elapsedMillis library useful. it does pretty much what BlinkWithOutDelay does, but just hides the arithmetic.

Hi again

I have tried to understand the principle but still dont now were to start with this. iam not asking someone write it for me but may be some one can get me started.

here is my sketch the problem is that only 1 of the leds will fade up then down but the other led will not fade up then down until the other led has finished. i need both to work with 2 push switch 1 for each led. when pressed 1 led starts to fade up if the other button is pressed the other led start to fade up and till the switches have been released then there is a millis and then fade down.

can some one help

Steve

const byte led2 = 10; // Shower Led
const byte led1 = 9; // Led connect to gate
const byte pir = A1; // PIR signal out
const byte flow = A0;
const byte turnOnTime = 2; // turn on/off time in seconds !(will be forced: 50 > time > 0)
const byte minutesToOff = 2; // minutes of 'silence' before "lights out" !! ALTER THIS VALUE

boolean lightIsOn = false; // remember LED-status 'now'
boolean LedIsOn = false; // remember LED-status 'now'

unsigned long timeToTurnOff; // time when led will turn off
unsigned long timeNow; // current time

void setup()
{
pinMode(led2,OUTPUT);
pinMode(led1,OUTPUT);
pinMode(pir,INPUT);
pinMode(flow,INPUT);
}

boolean heWantsLightsOn()
{
return (digitalRead(pir)==HIGH);
return (digitalRead(flow)==HIGH);
}

void turnLightsOn(byte period)
{

long delayTime = period * 2 ;
for (byte i=0; i<255; i++)
{

analogWrite(led1,i);
delay(delayTime);
}

digitalWrite(led1,HIGH); // no PWM needed - turn on 100%
lightIsOn=true; // remember status
}

void turnLightsOff(byte period)
{

long delayTime = period*20 ;
for (byte i=255; i>0; i--)
{

analogWrite(led1,i);
delay(delayTime);
}

digitalWrite(led1,LOW); // no PWM needed - turn off
lightIsOn=false; // remember status
}
//---------------------------------------------------------
boolean heWantsLedOn()
{
return (digitalRead(flow)==HIGH);
return (digitalRead(pir)==HIGH);
}

void turnLedOn(byte period)
{

long delayTime = period * 2 ;
for (byte i=0; i<255; i++)
{

analogWrite(led2,i);
delay(delayTime);
}

digitalWrite(led2,HIGH); // no PWM needed - turn on 100%
LedIsOn=true; // remember status
}

void turnLedOff(byte period)
{

long delayTime = period*20 ;
for (byte i=255; i>0; i--)
{

analogWrite(led2,i);
delay(delayTime);
}

digitalWrite(led2,LOW); // no PWM needed - turn off
LedIsOn=false; // remember status
}

//**********************************

void loop()
{
timeNow=millis(); // note time now
if (heWantsLightsOn()) // if movement -> be light!
{
if (!lightIsOn) turnLightsOn(turnOnTime);
}

if (timeNow > timeToTurnOff) // is it time to turn off ??
{
if (lightIsOn) turnLightsOff(turnOnTime); // if light still are on: turn them off
}
//-----------------------------------------------
{
timeNow=millis(); // note time now
if (heWantsLedOn()) // if movement -> be light!
{
if (!LedIsOn) turnLedOn(turnOnTime);
}

if (timeNow > timeToTurnOff) // is it time to turn off ??
{
if (LedIsOn) turnLedOff(turnOnTime); // if light still are on: turn them off
}

   boolean heWantsLightsOn()
{
   return (digitalRead(pir)==HIGH);  
   return (digitalRead(flow)==HIGH);  
}

You only get one return from a function. Anything after the first return never happens. It might as well just be deleted.

so is there away for this to work?

steve43:
so is there away for this to work?

you need to find or create a non-blocking fading method for this to work properly.

If you are interested in debugging a bit (this isn't tested), you can try like this, using a little Fade class that I wrote:

#include "Fade.h"
#define TIMEOUT 10000     // 10 second timeout for leds to fade down

const byte led2 = 10;          // Shower Led
const byte led1 = 9;           // Led connect to gate
const byte pir =  A1;          // PIR signal out
const byte flow =  A0;

Fade ledSet[] = {   // dimming pin, millis between steps
  {led1, 10},
  {led2, 10}}      
;

unsigned long flowTimer = 0;
unsigned long pirTimer = 0;

void setup()
{
  Serial.begin(9600);
  for(byte i = 0; i < sizeof(ledSet)/sizeof(ledSet[0]); i++)
  {
    ledSet[i].begin();
    ledSet[i].write(0);
  }
  pinMode(pir, INPUT);
  pinMode(flow, INPUT);
}

void loop()
{
  for(byte i = 0; i < sizeof(ledSet)/sizeof(ledSet[0]); i++)
  {
    ledSet[i].update();
  }
  
  if(checkFlow())
  {
    ledSet[0].write(255);
    flowTimer = millis();
  }
  if((millis() - pirTimer > TIMEOUT) && ledSet[0].setPoint() == 255)
  {
    ledSet[0].write(0);
    Serial.println(F("Flow Timer Expired..."));
  }
  
  if(checkMotion())
  {
    ledSet[1].write(255);
    pirTimer = millis();
  }
  if((millis() - flowTimer > TIMEOUT) && ledSet[1].setPoint() == 255)
  {
    ledSet[1].write(0);
    Serial.println(F("Motion Timer Expired..."));
  }
}

bool checkFlow()
{
  static bool flowState = LOW;
  bool state = digitalRead(flow);
  if(flowState != state)
  {
    if(state == HIGH)
    {
      Serial.println(F("Flow Sensor Triggered..."));
      return true;
    }
    flowState = state;
  }
  return false;
}

bool checkMotion()
{
  static bool motionState = LOW;
  bool state = digitalRead(pir);
  if(motionState != state)
  {
    if(state == HIGH)
    {
      Serial.println(F("Motion Sensor Triggered..."));
      return true;
    }
    motionState = state;
  }
  return false;
}

add this header file inside the directory of your sketch (Fade.h):

#ifndef Fade_h
#define Fade_h

#include "Arduino.h"

class Fade
{
  public:
    Fade() {};
    Fade(int pin, uint32_t timeStep = 15, uint8_t min = 0, uint8_t max = 255);
    void begin();
    void write(int to);
    void update();
    void update(uint32_t time);
    uint8_t setPoint();
    uint8_t read();
    uint32_t readSpeed();
    uint32_t writeSpeed(uint32_t time);
  private:
    uint8_t _min;
    uint8_t _max;
    uint8_t _targetFade;
    uint8_t _pwmRate;
    uint32_t _time;
    uint32_t _last;
    int _pin;
};

#endif

along with this implementation file (Fade.cpp):

#include "Arduino.h"
#include "Fade.h"

Fade::Fade ( int pin, uint32_t timeStep, uint8_t min, uint8_t max)
{
  _pin = pin;
  _time = timeStep;
  _min = min;
  _max = max;
  analogWrite(_pin, _min);
  _pwmRate = _min;
}

void Fade::begin()
{
  pinMode(_pin, OUTPUT);
}

void Fade::write(int to)
{
  _targetFade = (uint8_t) constrain(to, _min, _max);

  this->update();
}

uint8_t Fade::setPoint()
{
  return _targetFade;
}

void Fade::update()
{
  this->update(millis());
}

void Fade::update(uint32_t time)
{
  if (time - _time > _last)
  {
    _last = time;
    if (_pwmRate > _targetFade) analogWrite(_pin, --_pwmRate);
    if (_pwmRate < _targetFade) analogWrite(_pin, ++_pwmRate);
  }
}

uint8_t Fade::read()
{
  return _pwmRate;
}

uint32_t Fade::readSpeed()
{
  return _time;
}

uint32_t Fade::writeSpeed(uint32_t time)
{
  _time = time;
}

Start by seeing if it properly detects the sensor triggers....

Where do i put these fade.h and cpp? sorry i am quite new and interested in arduino.

If you're this new I would strongly recommend you spend some time reading and working through some of the simpler tutorials first. Since you appear to be new to the language, some tutorials on c++ are probably in order as well. Programming isn't the kind of thing you can just dive into and fake your way through. It takes some time to learn how the language works, how variables work, how functions work, and other basics. It's not something you can make up as you go along. But with a few days of good study you can quickly make sense of it.

i have added the 2 files to my sketch folder but it still reports an error when compiling.

Arduino: 1.6.7 (Windows XP), Board: "Arduino Nano, ATmega328"

C:\Documents and Settings\Steve\My Documents\Arduino\NewFade\NewFade.ino:1:18: fatal error: Fade.h: No such file or directory

#include "Fade.h"

^

compilation terminated.

exit status 1
Error compiling.

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.

they are both in this directory?

C:\Documents and Settings\Steve\My Documents\Arduino\NewFade\

can you see them in the IDE like this:

My son has made the two fade files work and the main sketch worked but the triggering is slightly incorrect. one sent of leds pulse rapidly

steve43:
My son has made the two fade files work and the main sketch worked but the triggering is slightly incorrect. one sent of leds pulse rapidly

not sure what you mean...

Can you post the output from the Serial Monitor when motion is detected?

Thanks a lot for the code there are some things that arnt quite right with it so it will need debugging like you said.
In serial moniter it says flow sensor triggered then after ten seconds flow timer expired and then the leds go out,but when you push the button again the leds flicker and the serial moniter says flow timer expired and flow sensor triggered repeatedly.
When pir is triggered the other set of leds flicker in the same way the serial moniter is then frozen and no more info is displayed the only way to unfreeze is to reset the arduino and restart serial moniter.

try debugging one at a time...

I commented out a block and added some more prints

Can you post the output from the Serial Monitor when it detects motion?

Make sure your pins are connected as indicated in the top of the sketch

#include "Fade.h"
#define TIMEOUT 1000

const byte led2 = 10;          // Shower Led
const byte led1 = 9;           // Led connect to gate
const byte pir =  A1;          // PIR signal out
const byte flow =  A0;

Fade ledSet[] = {   // dimming pin, millis between steps
  {led1, 10},
  {led2, 10}}      
;

unsigned long flowTimer = 0;
unsigned long pirTimer = 0;

void setup()
{
  Serial.begin(9600);
  for(byte i = 0; i < sizeof(ledSet)/sizeof(ledSet[0]); i++)
  {
    ledSet[i].begin();
    ledSet[i].write(0);
  }
  pinMode(pir, INPUT);
  pinMode(flow, INPUT);
}

void loop()
{
  for(byte i = 0; i < sizeof(ledSet)/sizeof(ledSet[0]); i++)
  {
    ledSet[i].update();
  }
  
//  if(checkFlow())
//  {
//    ledSet[0].write(255);
//    flowTimer = millis();
//  }
//  if((millis() - pirTimer > TIMEOUT) && ledSet[0].setPoint() == 255)
//  {
//    ledSet[0].write(0);
//    Serial.println(F("Flow Timer Expired..."));
//  }
  
  if(checkMotion())
  {
    ledSet[1].write(255);
    Serial.print(F("Set to max brite at "));
    Serial.println(millis());
    pirTimer = millis();
  }
  if((millis() - flowTimer > TIMEOUT) && ledSet[1].setPoint() == 255)
  {
    ledSet[1].write(0);
    Serial.println(F("Motion Timer Expired..."));
    Serial.print(F("Set to zero at "));
    Serial.println(millis());
  }
}

bool checkFlow()
{
  static bool flowState = LOW;
  bool state = digitalRead(flow);
  if(flowState != state)
  {
    if(state == HIGH)
    {
      Serial.println(F("Flow Sensor Triggered..."));
      return true;
    }
    flowState = state;
  }
  return false;
}

bool checkMotion()
{
  static bool motionState = LOW;
  bool state = digitalRead(pir);
  if(motionState != state)
  {
    if(state == HIGH)
    {
      Serial.println(F("Motion Sensor Triggered..."));
      return true;
    }
    motionState = state;
  }
  return false;
}