if ((Batt_volt < 11.0) or (Solar_volt > 3.0))
{
digitalWrite(9,LOW);
}
if ((Batt_volt > 11.0) && (Solar_volt < 3.0))
{
digitalWrite(9,LOW);
}
}
These limits are too close together.
Think of a heater thermostat. The temperature to turn off is higher than the temperature to turn on.
The difference must be far enough apart to not engage the starter too often or it burns out.
Another example is digital I/O pins of your Arduino.
To go from LOW to HIGH the Voltage must pass, I think 3V or 3.2V. You can check.
But to go from HIGH to LOW it must be about 1.1V or lower.
Once switched to LOW it must reach all the way to HIGH to switch again.
The word for this is Hysteresis. Without it we would not have stable I/O pins.
So you need this stable region in between where no change until it is crossed, maybe just the battery.
What battery do you have that you don't charge to 12V or more? Car battery can take 14V safely.
Rajdeep, you have not posted the sketch that is running on the Arduino. It cannot be, because there are at least 2 obvious errors that mean the sketch would not compile and even if that was corrected, the load would never be switched on.
Thank you dear Rob Tillaart and GoForSomke, I will give a try with greater difference between the thresholds.
Dear Paul,
As I was trying with different combination of digitalWrite(9,LOW) / (9,HIGH) in both conditions, hence this sketch contains both conditions as "LOW". Yes, you are absolutely correct, with this current sketch the load is permanently OFF. I am sorry for the inconvenience.
I shall correct the code as below with greater differences:
if ((Batt_volt < 10.8 ) or (Solar_volt > 3.2 ))
{
digitalWrite(9,LOW);
}
if ((Batt_volt > 11.2) && (Solar_volt < 2.8 ))
{
digitalWrite(9,HIGH);
}
I have solar lights and what I do not like is that in the winter, they do not get enough sun to charge fully. this means they come on and turn off too soon.
I have thought about this as a simple project, just use a timer so that the lights would come on about the time I get home. no need for them to come on earlier. something could be either based on average start and stop times to get the sunlight or some such.
Well I tried with greater difference between the thresholds with below code:
if ((Batt_volt > 12.0) && (Solar_volt < 3.2))
{
digitalWrite(9,HIGH);
}
if ((Batt_volt < 11.0) or (Solar_volt > 2.8 ))
{
digitalWrite(9,LOW);
}
the switching ON and OFF still continues to be a challenge. One change is observed by this conditions :
now the switching frequency of the Load has changed. Earlier the ON and OFF rate was very high, now the rate has gone down, however the issue remains the same.
Your charging 12V batteries, the solar panel at 3.2V is doing nothing for the batteries. Until the solar panel is above 12+V it won't charge the batteries and without a blocking diode it can drain the batteries in the dark or low light conditions. The typical working voltage for your panel is between 12 and 15 volts depending on the battery's charge state.
if ((Batt_volt > 12.0) && (Solar_volt < 3.2))
{
digitalWrite(9,HIGH);
}
if ((Batt_volt < 11.0) or (Solar_volt > 2.8 ))
{
digitalWrite(9,LOW);
}
Should be something like this:
if ((Batt_volt > 12.35) && (Solar_volt < 12.0)) // 12.35V 50% of battery charge
{
digitalWrite(9,HIGH);
}
if ((Batt_volt < 11.8) or (Solar_volt > 12.8 )) // 11.80V 25% of battery charge
{
digitalWrite(9,LOW);
}
At the evening solar voltage will reduce from 15 volts and at a point it will reach 3.2 volts. At the same time if the battery voltage is greater than 12 volts then the Load will turn ON automatically (without using any LDR or photodiode). Solar volt will be zero at night time.
and
if ((Batt_volt < 11.0) or (Solar_volt > 2.8 ))
{
digitalWrite(9,LOW);
}
assuming the battery voltage is greater than 11 volts and its early morning time, the moment solar volt will become greater than 2.8 volts, the Load will turn OFF automatically.
however, when LOAD is ON during night and as the battery voltage decreases to 10.9 volts the LOAD is OFF.
the moment LOAD is OFF, battery voltage rises to 12 volts resulting the LOAD to be ON.
this continuous ON and OFF is what I want to remove.
raj6084:
however, when LOAD is ON during night and as the battery voltage decreases to 10.9 volts the LOAD is OFF.
the moment LOAD is OFF, battery voltage rises to 12 volts resulting the LOAD to be ON.
this continuous ON and OFF is what I want to remove.
regards
Rajdeep
10.9V is the "loaded voltage", the rise to 12+V is the battery's "resting" voltage.
This ON and OFF cycle will always happen as you are being dependent on a variable that as you have seen changes as the load is removed. An LDR is the better way to control the load, or an RTC set to certain ON OFF times.
Or, check to see what battery voltage when the load is on brings the resting voltage to below 11.8V when the load is off. Then you can read the "loaded voltage" and know that when switched OFF the "resting voltage" won't rise above 11.8V. As an 11.8V "resting voltage" is the lowest you want to discharge you battery.
// discharged battery function
void LoadOFF1()
{
digitalWrite(9,LOW);
while(true)
{
// will check about 3x a minute
CheckVoltages();
unsigned long timeNow = millis();
unsigned long timeEnd = timeNow + 20000;
while (millis() < timeEnd)
{
if(Solar_volt > 3.2)
{
LoadOFF2();
}
}
}
}
// solar volt above threshold function, now charging battery
void LoadOFF2()
{
digitalWrite(9,LOW);
while(true)
{
// will check about 3x a minute
CheckVoltages();
unsigned long timeNow = millis();
unsigned long timeEnd = timeNow + 20000;
while (millis() < timeEnd)
{
if((Solar_volt < 2.8) && (Batt_volt > 12.35))
{
LoadON();
}
}
}
}
void LoadON()
{
digitalWrite(9,HIGH);
while(true)
{
// will check about 3x a minute
CheckVoltages();
unsigned long timeNow = millis();
unsigned long timeEnd = timeNow + 20000;
while (millis() < timeEnd)
{
// first check if battery is discharged below 25%
if (Batt_volt < 11.8 )
{
LoadOFF1();
}
// second check if solar voltage is above it's ON threshold
if (Solar_volt > 3.2 )
{
LoadOFF2();
}
}
}
}
These each block execution and what's worse the while(true){}'s have NO exit!
First time the sketch runs any of them, it's going to lock inside the while loop!
If you re-arrange the code, you might be able to have them check once a second without locking the rest of the sketch out or even making it pause noticeably.
Actually it's even worse than that! The tests inside the the timed parts are checking variables that don't read anything and don't change.
Also the time tests assume the unit won't run more than 49 days straight. I'll leave that for someone else to explain why.
Yup, will lock inside the while loop until the only condition available is met to go to the next function.
LoadOFF1(); will only exit if the solar panel voltage is > 3.2V, if the battery is discharged then that's the only logical reason to break the while loop. Not like it would recharge without the sun.
LoadOFF2(); will only exit when the sun goes down and the battery is fully charged. Otherwise no need to go further. Don't need to run during the day or if the battery is discharged.
LoadON(); is pretty self explanatory in the functions comments.
The tests inside the timed parts do read variables that change, every 20 seconds so not constantly reading the pins for no reason.
My mistake on the timed code, sorry about that. Live and learn, glad no one or their animals were hurt be my ignorance.
Here's the correction:
// place these above setup
unsigned long interval=20000;// time to wait between readings
unsigned long previousMillis=0;
//************corrected timed functions**************
// discharged battery function
void LoadOFF1()
{
digitalWrite(9,LOW);
while(true)
{
// once every 20 seconds voltages will be read
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval)
{
previousMillis = currentMillis;
CheckVoltages();
}
if(Solar_volt > 3.2)
{
LoadOFF2();
}
}
}
// solar volt above threshold function, now charging battery
void LoadOFF2()
{
digitalWrite(9,LOW);
while(true)
{
// once every 20 seconds voltages will be read
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval)
{
previousMillis = currentMillis;
CheckVoltages();
}
if((Solar_volt < 2.8) && (Batt_volt > 12.35))
{
LoadON();
}
}
}
void LoadON()
{
digitalWrite(9,HIGH);
while(true)
{
// once every 20 seconds voltages will be read
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval)
{
previousMillis = currentMillis;
CheckVoltages();
}
// first check if battery is discharged below 25%
if (Batt_volt < 11.8 ) // change this to the minimum "loaded voltage" you feel comfortable with
{
LoadOFF1();
}
// second check if solar voltage is above it's ON threshold
if (Solar_volt > 3.2 )
{
LoadOFF2();
}
}
}
Now every 20 second it will update the needed variables.
No need to return to loop() unless the Arduino is reset.
void setup()
{
Serial.begin(9600);
pinMode(9,OUTPUT);
digitalWrite(9,LOW);
}
bool batteryFlat=false;
void loop()
{
float B_sensor = analogRead(A0);
float BS_volt = B_sensor *(5.0 / 1023.0);
float Batt_volt = (5468 * BS_volt)/1000;
Serial.print("Battery voltage :");
Serial.println(Batt_volt);
float S_sensor = analogRead(A1);
float SS_volt = S_sensor * (5.0 / 1023.0);
float Solar_volt = (5468 * SS_volt)/1000;
//Serial.print("Solar Voltage :");
//Serial.println(Solar_volt);
if (Batt_volt<11)
{digitalWrite(9,LOW);
batteryFlat=true;
//Load will not turn on again until batter is charged
}
if ((!batteryFlat) && (Solar_volt < 3.0))
{//turn on lights if it's dark but battery isn't flat
digitalWrite(9,HIGH);
}
//Only set the state of the batter as not flat once it's charged
if(Solar_volt>12)
batteryFlat=false;
}
KenF, the problem the OP is having is that when the battery's loaded voltage gets to 10.9V it turns the load off like it should, but when the battery rests it rises above 12V again and turns the load back on.
This cycle continues.
The OP should figure out what the cutoff voltage needs to be so that the battery's resting voltage doesn't rise above 12V.
elac:
KenF, the problem the OP is having is that when the battery's loaded voltage gets to 10.9V it turns the load off like it should, but when the battery rests it rises above 12V again and turns the load back on.
This cycle continues.
The OP should figure out what the cutoff voltage needs to be so that the battery's resting voltage doesn't rise above 12V.
... or a bigger battery that doesn't load drop so much when the load is applied. That way when the load is removed, it won't rise so much.
My Low Voltage Disconnects (LVD) on my solar panel chargers disconnect the load at about 10.5 volts, and reconnect at 12.5 volts.
elac:
KenF, the problem the OP is having is that when the battery's loaded voltage gets to 10.9V it turns the load off like it should, but when the battery rests it rises above 12V again and turns the load back on.
This cycle continues.
The OP should figure out what the cutoff voltage needs to be so that the battery's resting voltage doesn't rise above 12V.
That's EXACTLY why I suggested my code. If she uses that it will NOT turn on again when the resting voltage goes back up. It will only turn back on, IF the battery has recieved some charge. (the batteryFlat variable will only be reset if SOLAR_VOLTS go up high enough.