Hi everyone,
I want to build a light detection system but I have issues with the code. When I test it, it doesn't do what it's supposed to... I'm not a programmer so I definetly lack some basics...
The goal:
I want to build a light detection system to connect to my home domotica system. When sun goes down and light is below certain threshold, I need a pulse on a DO so that my domotica system turns lights ON. When the sun is rising and ligh is above another threshold, I need a pulse on another DO so that my domotica system turns the lights OFF.
The problem I 1st had was; assuming it's sunset, once the light is below treshold value, everytime the arduino reads the analog input (photoresistor), it sees that condition is met, and it sends a pulse to the DO. Same for sunset...
Thanks to everyone who will take the time to read this post and help me
Raffaele
Got it, thanks!
Again I want to tell I'm not a programmer so be soft with your remarks reading my code please
I tried to use a lot the serialmonitor to see where the code might not be working correctly but...
So in this code, I was trying to take 2 measurement of the AnalogInput with 1h in between. The idea was to detect if the sun was rising or going down. Then based on that, send 1 pulse if light passes the threshold value until sun changes direction which... I don't know if the logic is good or if there is something better to do...
Anyways, here is the code
#include <arduino.h>
// Constant declaration.
const int PIN_Screens = 2;
const int PIN_Sensors = 3;
// Variables.
int PIN_LightSensor = A0;
int LightSensorValue = 0;
int LightSensorValue1 = 0;
int LightSensorValue2 = 0;
int LightStatus = 0; // Lights are OFF. If = 1 >> Lights ON
int SunDirection = 99; // SunDirection = 0 means SunSet. If = 1 means SunRise
int PrevSunDirection = 999;
void setup() {
pinMode(PIN_Screens, OUTPUT);
pinMode(PIN_Sensors, OUTPUT);
Serial.begin(9600);
delay(100);
}
void loop() {
LightSensorValue1 = analogRead(PIN_LightSensor);
Serial.println("----------");
Serial.print("1st AnalogRead >> ");
Serial.println(analogRead(PIN_LightSensor));
Serial.println("10sec delay");
delay(10000);
Serial.print("2nd AnalogRead >> ");
LightSensorValue2 = analogRead(PIN_LightSensor);
Serial.println(analogRead(PIN_LightSensor));
Serial.println("----------");
Serial.print("SunDirection >> ");
Serial.println(SunDirection);
Serial.print("PrevSunDirection >> ");
Serial.println(PrevSunDirection);
Serial.println("----------");
if (LightSensorValue1 > LightSensorValue2) { //Means this is SunSet time
Serial.println("TEST1");
SunDirection = 0;
if (SunDirection != PrevSunDirection) {
Serial.println("TEST2");
Serial.print("SunDirection in SunSet loop >> ");
Serial.println(SunDirection);
Serial.print("PrevSunDirection in SunSet loop >> ");
Serial.println(PrevSunDirection);
Serial.println("----------");
LightsON();
PrevSunDirection = 0;
} else {
}
} else {
if (LightSensorValue1 < LightSensorValue2) { //Means this is SunRise time
Serial.println("TEST3");
SunDirection = 1;
if (SunDirection != PrevSunDirection) {
Serial.println("TEST4");
Serial.print("SunDirection in SunRise loop >> ");
Serial.println(SunDirection);
Serial.print("PrevSunDirection in SunRise loop >> ");
Serial.println(PrevSunDirection);
Serial.println("----------");
LightsOFF();
PrevSunDirection = 1;
} else {
}
}
}
}
void LightsON() {
const int SEUIL_1 = 400;
LightSensorValue = analogRead(PIN_LightSensor);
Serial.println("----------");
Serial.println("SunSetLoop ");
Serial.println("----------");
Serial.print("AnalogReadout >> ");
Serial.println(analogRead(PIN_LightSensor));
if (LightSensorValue < SEUIL_1 && LightStatus == 0)
{
Serial.println("----------");
Serial.println("Lights ON");
Serial.println("----------");
digitalWrite (PIN_Screens, HIGH);
delay(1000) ;
digitalWrite (PIN_Screens, LOW);
delay(1000);
PrevSunDirection = 0;
LightStatus = 1; // Lights are ON
}
}
void LightsOFF() {
const int SEUIL_2 = 600;
LightSensorValue = analogRead(PIN_LightSensor);
Serial.println("----------");
Serial.println("SunRiseLoop ");
Serial.println("----------");
Serial.print("AnalogReadout >> ");
Serial.println(analogRead(PIN_LightSensor));
if (LightSensorValue > SEUIL_2 && LightStatus == 1)
{
Serial.println("----------");
Serial.println("Lights OFF");
Serial.println("----------");
digitalWrite (PIN_Sensors, HIGH);
delay(1000) ;
digitalWrite (PIN_Sensors, LOW);
delay(1000);
PrevSunDirection = 1;
LightStatus = 0; // Lights are OFF
}
}
The logic is probably a little flawed. For example if the sun goes behind a cloud, it will appear as sunset has occurred. This could happen over and over throughout the day.
Maybe you would be better off sampling for a day or two to confirm what values represent daytime and night time. Then set a threshold value and check against that. You probably want to also have a buffer value that you need to exceed before switching on/off.
So for example... let's say you determine that a value of 500 is the point where day time becomes night time.
Yes I know this isn't great logic. That's why I was also asking if someone would have a beter idea how I could achieve the goal.
I was thinking 1h (10s in the code for testing purposes) between 2 samples would reduce/avoid false detection of sundirection change but of course this isn't foolprooof.
For the buffer value as you propose, I believe this is what I was trying to achieve in the code by using 400 for SunSet threshold and 600 for SunRise threshold. Sort of hysteresis.
But so instead of fixing this code, like you said logic needs to be improved. So I 1st would like to hear what better logic I should try to develop to match the requirements
What you really need to understand is what happens in the real world. I suggest you do some testing... take a value every 5 minutes for a week. Look at the data, and make some decisions based on that. You need to determine when it is dark enough to turn the light on... and when it is light enough to turn the light off. That can really only be done by evaluating the data.
I wonder if it would be feasible to invoke some maths here. Use a real time clock chip to tell you the date, and do some sun-related calcs (this page might help) to determine sunrise and sunset on that day, with no guesswork. Wouldn't surprise me if someone has an Arduino library for that? Various religions rely on the time of sunset and sunrise- someone must have figured it out for Arduino already.
Hi,
Can you please post a circuit diagram, showing all component names, pin labels and power supplies?
Please no Fritzy images.
A picture of a hand drawn schematic will be fine.