commit df14c5c690492f0be17d7533e56d9392664900cb Author: Rachel Fae Fox (foxiepaws) Date: Fri Jul 19 01:49:28 2019 -0400 initial commit diff --git a/Code/lightingTimer.ino b/Code/lightingTimer.ino new file mode 100644 index 0000000..bb0b40d --- /dev/null +++ b/Code/lightingTimer.ino @@ -0,0 +1,195 @@ +/* + * Filename: main.cpp + * + * Description: device to turn out lights in the bathroom based on a + * PIR sensor. + * + * Version: + * Created: Sat Jan 12 22:54:52 2019 + * Revision: None + * Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws + * + */ + +#include + +enum states { inactive = 0, active, waiting }; + +const int led = 11; +const int pir = 6; +const int power = 5; +const int servo = 9 ; + +#define MOTION_HEURUSTIC 5 +#define MILLIS 1000 +#define POWER_TIME (6 * MILLIS) +#define CHECK_POWER_TIME (3 * MILLIS) + +int motion = 0; + +elapsedMillis motionTimer; // motion Timeout +elapsedMillis powerTimer; // Power Timeout +elapsedMillis cPowerTimer; // checkPower timeout + +Servo lightSwitch; +#define SERVO_RESTING_POSITION 90 +#define SERVO_SWITCH_PLATE_MOTION 20 +#define SERVO_SLEW_TIME 120 +#define SERVO_SLEW_DEG 60 +#define SERVO_SLEW_RATE (SERVO_SLEW_TIME/SERVO_SLEW_DEG) +#define SERVO_MIN 0 +#define SERVO_MAX 180 + +enum states state = inactive; +int powerState = 0; +int wantedPowerState = 0; +int servoPosition = 0; +int servoDir = 1; +// Saturation of servo position. +int servoSat ( int pos ) { + if (pos >= SERVO_MAX) { + return SERVO_MAX; + } else if (pos <= SERVO_MIN) { + return SERVO_MIN; + } else { + return pos; + } +} + +// function to solve a delay for a move, given a slew rate +// this is to avoid running into a bad move where a new command +// is sent before the servo has had time to make its move. +void servoDelay(int oldpos, int newpos) { + int delayTime = abs(oldpos - newpos) * SERVO_SLEW_RATE; + delay(delayTime); +} + +void servoMove ( int pos ) { + int oldPos = servoPosition; + servoPosition = servoSat(pos); + lightSwitch.write(servoPosition); + servoDelay(oldPos, servoPosition); +} + +void servoAdd ( int amount ) { + servoMove(servoPosition + amount ); +} + +void setup() { + pinMode(led, OUTPUT); + pinMode(pir, INPUT); + pinMode(power, INPUT); + lightSwitch.attach(servo); + servoMove(SERVO_RESTING_POSITION); +} + + +void evalPowerState() { + int actualPowerState = digitalRead(power); + + switch (powerState) { + case 0: // power off + if (actualPowerState == 1) { + powerState = 1; + break; + } + break; + case 1: // power on + if (actualPowerState == 0) { + powerState = 0; + break; + } + if (wantedPowerState == 0) { + servoDir = -1; + servoMove(SERVO_RESTING_POSITION + SERVO_SWITCH_PLATE_MOTION); + servoMove(SERVO_RESTING_POSITION); + cPowerTimer = 0; + powerState = 2; + break; + } + break; + case 2: // transitional; + if (wantedPowerState == 0 and actualPowerState == 0) { + powerState = 0; + break; + } + if (wantedPowerState == 0 and actualPowerState == 1 and cPowerTimer >= CHECK_POWER_TIME) { + servoMove(SERVO_RESTING_POSITION + (servoDir * SERVO_SWITCH_PLATE_MOTION)); + servoMove(SERVO_RESTING_POSITION); + servoDir *= -1; + cPowerTimer = 0; + break; + } + if (wantedPowerState == 1 and actualPowerState == 1) { + powerState = 1; + break; + } + break; + default: + break; + } +} + +void evalMainState() { + switch (state) { + case inactive: + // return to inactive state if the light gets turned off. + if (powerState == 1) { + state = active; + break; + } + break; + case active: + digitalWrite(led,HIGH); + // return to inactive state if the light gets turned off. + if (powerState == 0) { + state = inactive; + break; + } + if (powerState == 2) { + wantedPowerState = 1; + } + if (digitalRead(pir)) { + motionTimer = 0; + } + // if the pir has not detected motion for 5 seconds change state + if (!digitalRead(pir) and motionTimer >= MILLIS *5) { + state = waiting; + // reset the power timer to start counting + powerTimer = 0; + break; + } + break; + case waiting: + // return to inactive state if the light gets turned off. + // blinky while timer is active, doubling up the motion timer use. + if(motionTimer >= 1000) + digitalWrite(led,HIGH); + if(motionTimer > 2000) { + digitalWrite(led,LOW); + motionTimer = 0; + } + if (powerState == 0) { + state = inactive; + break; + } + if (digitalRead(pir)) { + state = active; + break; + } + if (powerTimer >= POWER_TIME ) { + wantedPowerState = 0; + state = inactive; + break; + } + break; + default: + + break; + } +} + +void loop () { + evalMainState(); + evalPowerState(); +} diff --git a/README.org b/README.org new file mode 100644 index 0000000..95c4861 --- /dev/null +++ b/README.org @@ -0,0 +1,11 @@ +#+TITLE: AutoSwitcher + +This project is separated into two parts + +* Schematic + All schematic stuff will probably be done in kicad, it has not yet been made. +* Code + Code is written using Arduino currently. + +* License + Code is licensed under BSD2. Design files are licensed under CC-BY diff --git a/Schematic/.keep b/Schematic/.keep new file mode 100644 index 0000000..e69de29