Go Down

Topic: How to make more the 1 function work at a time (Read 2398 times) previous topic - next topic

steve43

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

JimboZA

Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

Delta_G

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:  https://forum.arduino.cc/index.php?topic=223286.0
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

steve43

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

Delta_G

|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

MorganS

No, don't start from scratch. Start from the Blink_Without_Delay example sketch.
"The problem is in the code you didn't post."

JimboZA

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.
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

steve43

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.

steve43

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
}


Delta_G

Code: [Select]
   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. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

steve43


BulldogLowell

#11
May 07, 2016, 05:53 pm Last Edit: May 07, 2016, 07:12 pm by BulldogLowell
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:

Code: [Select]
#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):
Code: [Select]
#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):
Code: [Select]
#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....

steve43

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

Delta_G

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.
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

steve43

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.

Go Up