Go Down

### Topic: Light and time dependent switch (Read 3475 times)previous topic - next topic

#### luxy

##### Apr 12, 2013, 10:41 am
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.

#1
##### Apr 12, 2013, 10:53 am

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?

#### luxy

#2
##### Apr 12, 2013, 11:13 am

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

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

#### fungus

#3
##### Apr 12, 2013, 11:30 am

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: [Select]
`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.

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

#### luxy

#4
##### Apr 12, 2013, 11:33 am
Great,

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

#### luxy

#5
##### Apr 22, 2013, 11:31 am
I was playing a while with millis counters but without luck. I have a lack of programming skills

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: [Select]
`#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);}`

#### lax123

#6
##### Apr 22, 2013, 06:03 pmLast Edit: Apr 22, 2013, 06:08 pm by lax123 Reason: 1
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

#### luxy

#7
##### Apr 22, 2013, 09:06 pm

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

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: [Select]
`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);}`

#### lax123

#8
##### Apr 22, 2013, 10:18 pmLast Edit: Apr 22, 2013, 10:24 pm by lax123 Reason: 1
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

#### luxy

#9
##### Apr 23, 2013, 12:27 pm
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;
}

#### lax123

#10
##### Apr 23, 2013, 03:39 pm

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?

#### luxy

#11
##### Apr 23, 2013, 05:02 pm
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.

#### luxy

#12
##### Apr 23, 2013, 05:36 pm
I just solved it.. I changed if state a little and now it's ok!

Code: [Select]
` 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;  }`

#### luxy

#13
##### Apr 30, 2013, 10:27 amLast Edit: Apr 30, 2013, 10:43 am by luxy Reason: 1
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: [Select]
`  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;  }`

#14
##### May 01, 2013, 12:00 am
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.

Go Up

Please enter a valid email to subscribe