Skip to content

Instantly share code, notes, and snippets.

@jscrane
Created January 30, 2012 14:10
Show Gist options
  • Save jscrane/1704568 to your computer and use it in GitHub Desktop.
Save jscrane/1704568 to your computer and use it in GitHub Desktop.
Arduino sketch for Twilight gadget, version 2
#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