initial commit
commit
df14c5c690
|
@ -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 <Servo.h>
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue