Pages: [1] 2   Go Down
Author Topic: Light and time dependent switch  (Read 1715 times)
0 Members and 1 Guest are viewing this topic.
Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am building some kind of a switch which is turned on for one period of time when it's dark.

When outside is dark (transition from day to night) i want to turn LED (for example) on and it should be on for 7 hours. After 7 hours LED should be turned off and next activation should be at next transition from day to night (transition is a prerequisite for turning on, not just dark, so this should happen next evening).

I am wondering if i could do this with internal counting (millis) or should i use RTC module. I want to realise this as simple as possible and with the minimum number of components.

Any idea is appreciated.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 208
Posts: 12932
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


LDR + resistor to differentiate between day and night (dark).  LED + resistor.  Arduino.  Five parts plus the power supply.  Does that constitute "the minimum number of components"?

Or are you after something sans Arduino?
Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for quick reply..

For light sensor i am using TEPT5700 from Vishay. I made circuit on breadboard but i am wondering if in code i can realise this function without RTC. If i can use internal counter (millis) and if, how to do that.

I tried with this function but without luck.. http://www.cmiyc.com/blog/2012/07/16/arduino-how-do-you-reset-millis/

I hope this question isn't more appropriate for "understanding the code" forum section smiley

Arduino itself it's not a problem (i will use stand-alone version in the end).
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5522
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For light sensor i am using TEPT5700 from Vishay. I made circuit on breadboard but i am wondering if in code i can realise this function without RTC. If i can use internal counter (millis) and if, how to do that.

Code:
unsigned long myMilliCounter, prevMillis;

void loop()
{
  unsigned long now = millis();
  unsigned long elapsedMillis = now-prevMillis;
  myMilliCounter += elapsedMillis;
  prevMillis = now;

  ...
}

"myMilliCounter" counts milliseconds, you can reset it to zero whenever you want to.

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great,

that's what i need.. Will try and report.
Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was playing a while with millis counters but without luck. I have a lack of programming skills smiley

I know where is the problem but i don't know how to solve it. When program starts it works because timer start counting from zero. LED turn on for specified interval and than turns off, also if switch is still in HIGH state - that's ok. Next time, when i put switch from high to low and high again, this should happen again. LED does not turn on because timer is bigger than my interval. I need to reset timer while switch is in LOW state so LED can be turned on for specified interval again, but i don't know how.

Here's my code.

Code:
#define interval 5000  // 5 seconds
     
unsigned long counter;
 
byte led = 3;
byte switcher = 2;
byte switchState;
         
  void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(switcher, INPUT);
}
   
     
  void loop()
{
  counter = millis();
   
  switchState = digitalRead(switcher);
 
  if ((switchState == HIGH) && (counter <= interval))
  {
    digitalWrite(led, HIGH);
   
      if (counter >= interval)
        {
          digitalWrite(led, LOW);
        }
  }
 
  else
  {
    digitalWrite(led, LOW);
  }
 
  delay(100);
}
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 226
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
http://www.hobbytronics.co.uk/arduino-tutorial3-timing

2nd example

 u need a 2nd variable to update the time


also: never use delay()
delay means u block the uC from doing anything else/freeze it, for delays u actually use millis too
« Last Edit: April 22, 2013, 11:08:39 am by lax123 » Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
http://www.hobbytronics.co.uk/arduino-tutorial3-timing

2nd example

 u need a 2nd variable to update the time


also: never use delay()
delay means u block the uC from doing anything else/freeze it, for delays u actually use millis too

Hello,

thank you for that great tutorial! I solved the problem smiley

Btw, i saw that if i don't use delay in code (just 100 ms for example) that state from HIGH is not always set totaly to LOW, when it should be. If i use small delay in whole code is ok but i can see little LED flicker (they are almost unseen but if i look directly into LED i can see it). Like some kind of output leaking? Anyone know why?

New, working code

Code:
unsigned long currentTime;
unsigned long loopTime;
 
byte led = 3;
byte switcher = 2;
byte switchState;
         
  void setup() 

  pinMode(led, OUTPUT);
  pinMode(switcher, INPUT);
 
  currentTime = millis();
  loopTime = currentTime;
}
   
     
  void loop()
{
  currentTime = millis();
   
  switchState = digitalRead(switcher);
 
  if (switchState == HIGH)
  {
    digitalWrite(led, HIGH);         
 
    if (currentTime >= (loopTime + 5000))
    {
      digitalWrite(led, LOW);
    }
  }   
 
  else
  {
    digitalWrite(led, LOW);
    loopTime = currentTime;
  }
   
delay(100);

}

Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 226
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

is ur switcher actually a button or really that sensor?

Can you rephrase ur last text? I dont really understand it.

If u use no delay in the code the led is flickering?
If u use delay of 100 there is no led flickering?
And if u use a very small delay of like 1 the led is flickering too?

As I said, using delay() in code is like blocking the arduino from doing anything else. That could also mean the led is still turned on because of the delay when in fact it would be off. Might relate to that flickering or other weird behaviour, not sure.

Try to work with millis instead of delay, just type into google "millis instead of delay" and u will find plenty of info.

I dont know about your circuit but maybe u need something like a pullup or pulldown resistor for the sensor
« Last Edit: April 22, 2013, 03:24:50 pm by lax123 » Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Today i made whole circuit with light sensor and FET for output. I also deleted delay from code and i am not getting flickers any more. The only thing i noticed is that when program is in one part of the code the led lights a little, although output state should be LOW. It's almost invisible but if i look directly into led i can see it. If i put circuit in other state, led is completely off (so this can't be FET leaking or something like that). Anyway, i think this should not be a problem but i am still wondering why this is happening.

I will show in which part of code this is happening.

if (light <= 160)
  {
    digitalWrite(fet, HIGH);  <------------ IN THIS STATE LED IS TURNED ON FOR INTERVAL TIME         
 
      if (currentTime >= (loopTime + interval))
    {
      digitalWrite(fet, LOW);  <------------ IN THIS STATE LED LIGHTS A LITTLE BUT SHOULD BE COMPLETELY OFF
    }
  }   
 
    else
  {
    digitalWrite(fet, LOW);  <------------ IN THIS STATE LED IS COMPLETELY TURNED OFF
    loopTime = currentTime;
  }
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 226
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

well idk excatly but your code reads to me like this:

if light below 160(
TURN ON
 (If intervall not exceeded TURN OFF))

so everytime that loop runs the light is turned on at first and then turned off after the intervall check, get what im thinking?
Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Exactly! That's what i need.

FET should be open (high state) only for a defined period of time and than should go in LOW state, no matter if light is still under 160. Everything works i am just wondering why led lights a little in that state and how could i solve it.
Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just solved it.. I changed if state a little and now it's ok! smiley

Code:
if ((light <= 160) && (currentTime <= (loopTime + interval)))
  {
    digitalWrite(fet, HIGH);         
  }
    else if ((light <= 160) && (currentTime >= (loopTime + interval)))
  {
    digitalWrite(fet, LOW);
  }       
    else
  {
    digitalWrite(fet, LOW);
    loopTime = currentTime;
  }

Logged

Slovenia, EU
Offline Offline
Full Member
***
Karma: 0
Posts: 153
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I almost finished my project. Everything works but i didn't try to run device for more than 50 days (to see whats happen on rollover). I want to be sure that in case of rollover the whole thing is not going to freeze.

I read a lot about millis rollover and if i understand it correctly.. I am wondering if in my case this should work. All i want to do is to reset my 3 variables to 0 on rollover.

Part of code..

Code:
 void setup()  
{
  unsigned long currentTime;
  unsigned long loopTime;  
  unsigned long onTime;    
  unsigned long offTime;      
  unsigned long interval;
 
  currentTime = millis();
  onTime = offTime = loopTime = currentTime;
}

// LOOP

  currentTime = millis();

  // VALUES RESET
    if (currentTime >= 4294967295)
  {
    loopTime = 0;
    onTime = 0;
    offTime = 0;
  }
    
  
  // SWITCHING
    if (((light <= border) && (currentTime <= (loopTime + interval)) && (currentTime >= (onTime + 5000))))  // 5 sec delay
  {
    digitalWrite(fet, HIGH);
    offTime = currentTime;    
  }
    else if ((light <= border) && (currentTime >= (loopTime + interval)))
  {
    digitalWrite(fet, LOW);
    offTime = currentTime;
    onTime = currentTime;
  }    
    else if ((light > border) && (currentTime >= (offTime + 5000)))  // 5 sec delay
  {
    digitalWrite(fet, LOW);
    loopTime = currentTime;
    onTime = currentTime;
  }
« Last Edit: April 30, 2013, 03:43:44 am by luxy » Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 208
Posts: 12932
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I read a lot about millis rollover and if i understand it correctly.. I am wondering if in my case this should work. All i want to do is to reset my 3 variables to 0 on rollover.

Resetting is never necessary if your code is correct.
Logged

Pages: [1] 2   Go Up
Jump to: