Created
January 30, 2012 14:10
-
-
Save jscrane/1704568 to your computer and use it in GitHub Desktop.
Arduino sketch for Twilight gadget, version 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <EEPROM.h> | |
#define MOTION 1 | |
#define SWITCH 0 | |
#define LIGHT 2 | |
#define LDR 3 | |
#define HZ 4 | |
#define SAMPLES (15*HZ) | |
#define ON_DELAY (15*60*HZ) | |
#define OFF_DELAY (15*HZ) | |
#define THRESHOLD 0 | |
boolean off = true; | |
int onCount = 0, offCount = 0; | |
int samples[SAMPLES], pos, smoothed; | |
long total, press_time; | |
boolean depressed; | |
int threshold; | |
inline int readLight() { | |
return analogRead(LDR); | |
} | |
int sampleLight() { | |
int curr = readLight(); | |
total += curr - samples[pos]; | |
samples[pos++] = curr; | |
if (pos == SAMPLES) pos = 0; | |
smoothed = (int)(total / SAMPLES); | |
return smoothed; | |
} | |
#define SLOW 250 | |
#define FAST 125 | |
void blink(int d) { | |
int n = 500 / d; | |
for (int i = 0; i < n; i++) { | |
digitalWrite(LIGHT, HIGH); | |
delay(d); | |
digitalWrite(LIGHT, LOW); | |
delay(d); | |
} | |
} | |
void setup() { | |
pinMode(MOTION, INPUT); | |
pinMode(SWITCH, INPUT); | |
digitalWrite(SWITCH, HIGH); // activate pull-up | |
pinMode(LIGHT, OUTPUT); | |
smoothed = readLight(); | |
for (int i = 0; i < SAMPLES; i++) { | |
samples[i] = smoothed; | |
total += smoothed; | |
} | |
int t = EEPROM.read(THRESHOLD); | |
if (t == 0xff) | |
blink(FAST); | |
else { | |
blink(SLOW); | |
threshold = 4 * t; | |
} | |
} | |
inline long manual() { | |
boolean d = (digitalRead(SWITCH) == LOW); | |
if (depressed && !d) { | |
depressed = false; | |
return millis() - press_time; | |
} | |
if (!depressed && d) { | |
depressed = true; | |
press_time = millis(); | |
} | |
return 0; | |
} | |
inline boolean isDark() { | |
return smoothed >= threshold; | |
} | |
void turnOn() { | |
if (off) { | |
digitalWrite(LIGHT, HIGH); | |
off = false; | |
} | |
} | |
void turnOff() { | |
if (!off) { | |
digitalWrite(LIGHT, LOW); | |
off = true; | |
} | |
} | |
inline boolean movement() { | |
return digitalRead(MOTION) == HIGH; | |
} | |
void loop() { | |
int s = sampleLight(); | |
long d = manual(); | |
if (d > 0) { | |
if (d > 1000) { | |
threshold = s; | |
EEPROM.write(THRESHOLD, (uint8_t)(s / 4)); | |
blink(SLOW); | |
} | |
if (off) { | |
turnOn(); | |
onCount = ON_DELAY; | |
} else { | |
turnOff(); | |
offCount = OFF_DELAY; | |
} | |
} else if (movement()) { | |
onCount = ON_DELAY; | |
if (offCount == 0 && isDark()) | |
turnOn(); | |
} else if (onCount == 0) | |
turnOff(); | |
delay(1000 / HZ); | |
if (offCount > 0) offCount--; | |
if (onCount > 0) onCount--; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment