Sorry I changed a few of the states to work with my ESP
Compiles Error free,
for both ESP and Nano, though I don't have a nano to actually test.
Have a read thru and see if it confuses you more.!
But it should give another view.
You can also Smooth the bumps in the readings by keeping a running total,
then either add or subtract half the current reading depending on direction.
I did some crazy stuff trying to smooth a tilt sensor many(MANY) moons ago.
I wrote a little VB to demonstrate different methods and the reaction times.
I guess I should read your original post to see what you were actually asking :o
#define LIGHTSON LOW
#define LIGHTSOFF HIGH
#define READINTERVAL 5
const int numReadings = 50;
#ifdef ESP8266
#define HEADER F("ESP-")
#define IGNITIONACTIVE LOW
const int ignPin = 0; //0v LOW when ignition is ON
const int lightSensePin = A0; //LDR in Dashboard
const int lightRelayPin = 16; //Relay to control lights pull LOW is ON
const int OnThreshold = 50;
const int OffThreshold = 600;
#else
#define HEADER F("OTHER-")
#define IGNITIONACTIVE HIGH
const int ignPin = 2; //5v HIGH when ignition is ON
const int lightSensePin = A1; //LDR in Dashboard
const int lightRelayPin = 12; //Relay to control lights pull LOW is ON
const int OnThreshold = 240;
const int OffThreshold = 600;
#endif
int readings[numReadings];
int readIndex = 0;
int total = 0;
int average = 0;
//int CalcRead = map(A1,0,1023,0,100);
int ignState = 0;
unsigned long ignLastOnTime = 0;
unsigned long lightsOnTime = 0;
unsigned long lastread = 0;
const long lightDelay = 30000;
unsigned long lastdaylighttime = 0;
int runningaverage = 0;
int smoothed = 0;
int difference = 0;
bool needlights = false;
bool lightsareon = false;
bool AlwaysUseLights = false;
//=====================================
String pad(String x2,byte p);
void TurnLightsOn(void);
void TurnLightsOff(void);
bool IsIgnitionOn(void);
bool isitDark(void);
bool isitLight(void);
int CalcRead(int r);
//=====================================
void TurnLightsOn(void){digitalWrite(lightRelayPin, LIGHTSON); lightsareon=true;}
void TurnLightsOff(void){digitalWrite(lightRelayPin, LIGHTSOFF); lightsareon=false;}
bool IsIgnitionOn(void){return (digitalRead(ignPin) == IGNITIONACTIVE);}
bool isitDark(void){return (smoothed < OnThreshold);}
bool isitLight(void){return (average > OffThreshold);}
int CalcRead(int r){return map(r,0,1023,0,100);}
String pad(String x2,byte p){
for (int i = x2.length(); i < p; i++) {x2 = String(0) + x2;}
return x2;
}
//=====================================
void setup() {
Serial.begin(115200);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {readings[thisReading] = 0;}
pinMode(lightSensePin, INPUT);
pinMode(lightRelayPin,OUTPUT);
pinMode(ignPin, INPUT);
readIndex = 0;
total = analogRead(lightSensePin);
lightsOnTime = millis();
ignLastOnTime = millis();
TurnLightsOff();
}
void loop() {
//Serial.print('.'); // uncomment to see how many dots fill a screen !
if ((millis() - lastread) < READINTERVAL){return;} // too much reading is bad for the mind.!
lastread = millis();
total = total - readings[readIndex];
readings[readIndex] = analogRead(lightSensePin);
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex < numReadings) {return;}
// So you have done 35 readings, whats to do?
readIndex = 0;
ignState = IsIgnitionOn(); // Test Ignition
average = total / numReadings;
runningaverage = (runningaverage + average);
runningaverage = runningaverage/2;
if(smoothed > runningaverage) {smoothed = smoothed - ((smoothed - runningaverage)/2);}
else if(smoothed < runningaverage){smoothed = smoothed + ((runningaverage - smoothed) /2);}
if(IsIgnitionOn()){
if (AlwaysUseLights) {lightsOnTime = millis(); needlights = true;}
if (isitDark()) {
if ((millis() - lastdaylighttime) > 750){
lightsOnTime = millis();
needlights = true;
}
} else {
lastdaylighttime = millis();
if ((millis() - lightsOnTime) > 3000){needlights = false;}
}
ignLastOnTime = millis();
} else {
//if you want to keep the delay for the full time and not turn off if it gets light.
// remove next line
if (!isitDark()) {needlights = false;}
if((millis() - ignLastOnTime) > lightDelay){needlights = false;}
}
Serial.print((String) HEADER + F("Time:") + String(millis(),DEC) + F(", "));
Serial.print((String) F("Ign:") + String(IsIgnitionOn()) + F(", "));
Serial.print((String) F("Dark:") + String(isitDark()) + F(", "));
Serial.print((String) F("Need:") + String(needlights) + F(", "));
Serial.print((String) F("Lamp:") + String(lightsareon) + F(", "));
Serial.print((String) F("Total:") + pad(String(total,DEC),6) + F(", "));
Serial.print((String) F("Average:") + pad(String(average,DEC),3) + F(", "));
Serial.print((String) F("Smoothed:") + pad(String(smoothed,DEC),3) + F(", "));
Serial.print((String) F("Avg2:") + pad(String(runningaverage,DEC),3) + F(", "));
Serial.print((String) F("Avg3:") + pad(String(((runningaverage+average)/2),DEC),3) + F(", "));
// Finally Turn the lights On or Off depending on current state and required state.
if(lightsareon){
Serial.print((String) F("Burn:") + pad(String((millis() - ignLastOnTime)/100L,DEC),3) + F(", "));
if (!needlights){TurnLightsOff();}
} else {
if (needlights) {TurnLightsOn();}
}
Serial.println();
}