//I/O configuration
#define L1 6 //pinout 4
#define L2 5 //pinout 5
#define L3 3 //pinout 6
#define Y1 9 //pinout 1 & ledLoad 1
#define Y2 10 //pinout 2 & ledLoad 2
#define Y3 11 //pinout 3 & ledLoad 3
#define led1 12 //led indicator 1
#define led2 2 //led indicator 2
#define VbatADC A6 //Battery volatge measurement
#define BrightADC A1 //Brightness measurement
#define Motionsensor A2 //Reading Motion sensor
#define VbatSub_ADC A3 //Sub_battery volatge measurement
// A1, A2: analog input with VR pull_down (50K anf 5K)
// A3, A4, A5: Float connection
// SI1 for White-led
#define SI2 7
#define SI3 4
#define SI4 2
//Config POWER INDEX-------------------------------------------------
/*
Config ::BRmin - Brightness that to turn ON Lights
::BRmax - Brightness that to turn OFF Lights
::L100 - Brightness of Lights in 100%
::L40 - Brightness of Lights in 40%
*/
#define BRmin 0.5
#define BRmax 10
#define L100 85
#define L40 40
#define V37 4.5
#define V32 3
//Config FastLED-----------------------------------------------------
/*
Config :: TIMER_FastLED - Time to turn OFF FastLED after time(min)
:: UVLO_FastLED - Under Voltage Lock Out FastLED (V)
*/
#define TIMER_FastLED 1 //in minutes 120:2h - 180:3h - 240:4h
#define UVLO_FastLED 3.1 //Volt
//Config MODE 2 (AUTO MODE with MOTION SENSOR)------------------------
/*
Config :: TIMER_AUTOMODE - Time to entry Auto Mode, brightness will decrease 50%.
in Auto Mode, system will scan Motion and ready to light at full power.
:: TIMER_LIGHTMOTION - Time of full power lighting after detecting Motion
*/
#define TIMER_AUTOMODE 180 //in minutes
#define TIMER_LIGHTMOTION 1 //in sec
//Config CHARGE CONTROLER (Mix-dual-batteries)------------------------
/*
This function is to control Charge between 2 batteries. When voltage of
Main Battery is greater than PASS_VOLTAGE, switch charge will turn to
Sub-Battery to charge. To make sure that no drop voltage occurred in
Main Battery, system will check main battery`s volatge a gain after
PERIOD_CHECK_VBAT (min) since switch has been closed.
*/
#define PERIOD_CHECK_VBAT 2 //in minute
#define PASS_VOLTAGE 4.1f
#define VbatSub_full 3.9f
/*
* Light = L100, when Vbat > V37
* Light is liner to Vbat, when V32 < Vbat < V37
* Light = 0, when Vbat < V32
*/
float Vbat = 0, Bright = 0, VbatSub = 0;
unsigned int timerun = 0, timer_charge = 0;
unsigned long moment = 0;
float a, b, VbatMain;
int PowerIndex = 0, Pindex = 0, forceindex = 0, i, indexDAY;
#define DAY 0
#define NIGHT 1
#define NORMAL 0
#define AMODE 1
#define UNDETECTED 0
#define DETECTED 1
#define DISABLE 0
#define EN 1
bool P_MODE, MOTION, FORCE_OFF_FastLED;
bool RELAY_CHARGE, UPDATE_VbatMain, RELAY_CHARGE_prev, STOPPED;
int SSTR = 0, SSTP = 0, MODE, MODE_prev;
void setup()
{
pinMode(L1, OUTPUT);
pinMode(L2, OUTPUT);
pinMode(L3, OUTPUT);
pinMode(Y1, OUTPUT);
pinMode(Y2, OUTPUT);
pinMode(Y3, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(SI2, INPUT_PULLUP);
pinMode(SI3, INPUT_PULLUP);
pinMode(SI4, INPUT_PULLUP);
pinMode(13, OUTPUT);
a = (L100 - L40)/(V37 - V32);
b = L100 - (a*V37);
RELAY_CHARGE = DISABLE;
FORCE_OFF_FastLED = EN;
Serial.begin(9600);
}
void loop()
{
timerun = (millis()*0.00001666667) - moment;
CHECK_ADC();
//////DAY/////
if (MODE == DAY)
{
CHECK_SOFTSTOP();
if (SSTP == 1) //NIGHT go to DAY
{
SSTP = 0;
UPDATE_VbatMain = EN;
for (i = Pindex; i > 0; i--)
{
outputLight(i);
delay(50);
}
STOPPED = 1;
}
if (STOPPED == 1) //Really being at DAY
{
DO_AT_DAY();
}
indexDAY = (STOPPED == 1) ? 0 : Pindex;
outputLight(indexDAY);
Pindex = PowerIndex;
}
/////NIGHT/////
if (MODE == NIGHT)
{
CHECK_SOFTSTART();
if (SSTR == 1)
{
SSTR = 0;
Pindex = PowerIndex;
for (i = 0; i < Pindex; i++)
{
outputLight(i);
delay(50);
}
}
RELAY_CHARGE = DISABLE;
outputLight(Pindex);
}
}
/*Do to turn ON/OFF light through Pindex
.Pindex = 0: when DAY
.Pindex = L100: when Vbat > V37 @night
.Pindex = Liner: when Vbat < V37 @night
.Pindex = 0: when Vbat < V32 @night
*/
void outputLight(int Pindex)
{
Serial.print(Pindex);
Serial.print(" ");
Serial.print(PowerIndex);
Serial.println(" ");
if (RELAY_CHARGE == EN)
{
digitalWrite(Y3, HIGH);
}
if (RELAY_CHARGE == DISABLE)
{
digitalWrite(Y3, LOW);
}
if (GetVbatSub() < UVLO_FastLED)
{
moment = (millis()*0.00001666667) - TIMER_FastLED + 1;
}
if ((Pindex != 0)&&(timerun < TIMER_FastLED))
{
digitalWrite(Y1, HIGH);
}
if ((Pindex == 0)||(timerun >= TIMER_FastLED))
{
digitalWrite(Y1, LOW);
}
if ((digitalRead(SI2)==1)&&(digitalRead(SI3)==1)&&(digitalRead(SI4)==1)) //normal mode
{
analogWrite(L1, Pindex*0.5);
analogWrite(L2, Pindex*0.85);
analogWrite(L3, Pindex*2.5);
}
else if ((digitalRead(SI2)==0)&&(digitalRead(SI3)==1)&&(digitalRead(SI4)==1)) //force full power
{
forceindex = (Pindex == 0) ? 0 : 100;
analogWrite(L1, forceindex*2.55);
analogWrite(L2, forceindex*2.55);
analogWrite(L3, forceindex*2.55);
}
else if ((digitalRead(SI2)==1)&&(digitalRead(SI3)==0)&&(digitalRead(SI4)==1)) //low power
{
P_MODE = (timerun < TIMER_AUTOMODE) ? NORMAL : AMODE;
Serial.println();
Serial.println("---P_MODE:");
Serial.println(P_MODE);
if (P_MODE == NORMAL)
{
analogWrite(L1, Pindex*0.5);
analogWrite(L2, Pindex*0.85);
analogWrite(L3, Pindex*2.5);
}
if ((P_MODE == AMODE)&&(MOTION == DETECTED))
{
Serial.println("---MOTION:");
Serial.println(MOTION);
for (int i = Pindex*0.5; i < 255; i++) //inscr
{
analogWrite(L1, i);
analogWrite(L2, i);
analogWrite(L3, i);
delay(5);
}
analogWrite(L1, 255);
analogWrite(L2, 255);
analogWrite(L3, 255);
delay(1000*TIMER_LIGHTMOTION);
for (int i = 255; i > Pindex*0.5; i--) //descr
{
analogWrite(L1, i);
analogWrite(L2, i);
analogWrite(L3, i);
delay(5);
}
}
if ((P_MODE == AMODE)&&(MOTION == UNDETECTED))
{
analogWrite(L1, Pindex*0.4);
analogWrite(L2, Pindex*0.4);
analogWrite(L3, Pindex*0.4);
Serial.println("---MOTION:");
Serial.println(MOTION);
}
}
else if ((digitalRead(SI2)==1)&&(digitalRead(SI3)==1)&&(digitalRead(SI4)==0)) //force off
{
forceindex = 0;
analogWrite(L1, 0);
analogWrite(L2, 0);
analogWrite(L3, 0);
}
else if ((digitalRead(SI2)==0)&&(digitalRead(SI3)==0)&&(digitalRead(SI4)==0)) //test mode
{
Mode_test();
}
}
void CHECK_ADC()
{
Bright = 0.097752*analogRead(BrightADC);
Serial.print(Bright);
Serial.print(" ");
MOTION = (analogRead(Motionsensor) > 800) ? DETECTED : UNDETECTED;
if (Bright < BRmin)
{
MODE = NIGHT;
STOPPED = 0;
//PUT MOTION HERE()
Vbat = GetVbat();
Serial.print(Vbat);
Serial.print(" ");
if (Vbat > V37)
{PowerIndex = L100;}
if ((Vbat <= V37)&&(Vbat > V32))
{PowerIndex = (a*Vbat) + b;}
if (Vbat <= V32)
{PowerIndex = 0;
digitalWrite(L1, HIGH);
}
Pindex = (PowerIndex < Pindex) ? PowerIndex : Pindex;
VbatSub = GetVbatSub();
FORCE_OFF_FastLED = (VbatSub < UVLO_FastLED) ? EN : DISABLE;
}
if (Bright > BRmax)
{
MODE = DAY;
}
}
void CHECK_SOFTSTART()
{
if ((MODE_prev == DAY)&&(MODE == NIGHT))
{
MODE_prev = NIGHT;
SSTR = 1;
moment = (millis()*0.00001666667);
}
}
void DO_AT_DAY()
{
float Vbat_timer = GetVbat();
float VbatSub_timer = GetVbatSub();
if (((millis()*0.00001666667) - timer_charge) >= PERIOD_CHECK_VBAT)
{
timer_charge = millis()*0.00001666667;
if ((Vbat_timer <= PASS_VOLTAGE) || (VbatSub_timer >= VbatSub_full))
{
RELAY_CHARGE = DISABLE;
}
else if ((Vbat_timer > PASS_VOLTAGE)&&(VbatSub_timer < VbatSub_full))
{
RELAY_CHARGE = EN;
}
}
Serial.println("---------\\--------- ");
Serial.print(" TimerDAY: ");
Serial.println((millis()*0.00001666667) - timer_charge);
Serial.print(" Vbat main: ");
Serial.println(Vbat_timer);
Serial.print(" Vbat sub: ");
Serial.println(VbatSub_timer);
if (RELAY_CHARGE == DISABLE)
{
Serial.println(" CHARGING FOR MAIN BATTERY");
}
if (RELAY_CHARGE == EN)
{
Serial.println(" CHARGING FOR SUB BATTERY ");
}
Serial.println("---------\\--------- ");
}
void CHECK_SOFTSTOP()
{
if ((MODE_prev == NIGHT)&&(MODE == DAY))
{
delay(5000);
Bright = 0.097752*analogRead(BrightADC);
if (Bright > BRmax)
{
MODE_prev = DAY;
SSTP = 1;
}
}
}
float GetVbat()
{
unsigned int VbatSumADC = 0;
for (i = 1; i <= 10; i++)
{
VbatSumADC += analogRead(VbatADC);
delay(40);
}
return(0.000456*VbatSumADC);
}
float GetVbatSub()
{
unsigned int VbatsubSumADC = 0;
for (i = 1; i <= 10; i++)
{
VbatsubSumADC += analogRead(VbatSub_ADC);
delay(40);
}
return(0.000456*VbatsubSumADC);
}
void Mode_test()
{
for(int i = 0; i < 255; i++)
{
analogWrite(L1, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L1, 255-i);
analogWrite(L2, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L2, 255-i);
analogWrite(L3, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L3, 255-i);
analogWrite(L1, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L1, 255-i);
delay(6);
}
analogWrite(L1, 0);
analogWrite(L2, 0);
analogWrite(L3, 0);
for(int i = 0; i < 255; i++)
{
analogWrite(L1, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L2, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L3, i);
delay(6);
}
for(int i = 0; i < 255; i++)
{
analogWrite(L1, 255-i);
analogWrite(L2, 255-i);
analogWrite(L3, 255-i);
delay(6);
}
delay(500);
digitalWrite(Y1, HIGH);
delay(500);
digitalWrite(Y2, HIGH);
delay(500);
digitalWrite(Y3, HIGH);
delay(500);
digitalWrite(Y1, LOW);
digitalWrite(Y2, LOW);
digitalWrite(Y3, LOW);
}