PART1: Main code
#include <Beomote.h>
#include <Ethernet.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include "RGBdriver.h"
//Clocked In RGB LED Strip interface --
#define LED_CLK 24 //Led strip driver
#define LED_DIO 26 //Led strip driver
//Beoremote IR Code table -------------
#include "BeoRemote_Lookup_Table.h"
//Declare the RGB LED Driver
RGBdriver LEDDriver(LED_CLK,LED_DIO);
// assign a MAC address for the Ethernet controller.---
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
// assign an IP address for the controller: ---
IPAddress ip(192, 168, 123, 101);
// Initialize the Ethernet server library
// with the IP address and port
// (port 80 is default for HTTP):
EthernetServer server(80);
Adafruit_BMP280 bmp; //BMP280 I2C connection
//For I2C Temperature sensor, I2C line are pin 20:SDA and pin 21:SCL
//pin definition
static const int IRBOPin = 22; //IR Detector Bang&Olufsen
//static const int IRSTDPin = 4;
static const int audioPin = 28; //Relay command output for audio power on/off
static const int blowerPin = 30; //Relay command output for blower power on/off
static const int PIRPin = 6; //PIR movment detector pin
//status
boolean audioStatus = false;
boolean blowerStatus = false;
int currentLedStripColor = 0;
boolean lightChannelSelect = false;
int PIRCalibrationTime = 30; //time needed for PIR to calibrate and stabilize
//the time when the PIR sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the PIR sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
boolean BTGO = false; //This is used to toggle a wait for next key for selection of relay to toggle
boolean DOOR = false; //This is used on remote to wait for a four digit code to toggle alarm ON/OFF
String ALARMCODE = ""; //This variable is used to hold the code ticked in by remotecontrol
static const int RELAY_ON = 0;
static const int RELAY_OFF = 1;
static const int ON = 1;
static const int OFF = 0;
static const int YellowColor = 1;
static const int RedColor = 2;
static const int BlueColor = 3;
static const int GreenColor = 4;
static const int WhiteColor = 5;
float temperature = 0;
float humidity = 0;
float pressure = 0;
String URLCommandString = String(100); //string for fetching data from address //fetch the header part of the URL
String WorkMode; //Isolate the GET command to see if we are in ALARM mode
boolean getAlarm = false; //false: normal mode true: alarm mode activated
boolean intrusionDetection = false; //false:no intrusion detected, true: intrusion detected transmitted to central unit
boolean setAlarm = false; //if set to true, command is send to Central Unit to switch house in alarm mode
void setup() {
pinMode(IRBOPin,INPUT);
pinMode(PIRPin,INPUT);
// pinMode(IRSTDPin,INPUT);
pinMode(audioPin,OUTPUT);
pinMode(blowerPin,OUTPUT);
getAlarm = false;
setAlarm = false;
intrusionDetection = false;
BTGO=false;
DOOR=false;
LEDDriver.begin();
LEDDriver.SetColor(0,0,0);
LEDDriver.end();
//at power up, audio relay and blower relay are also shutdown
digitalWrite(audioPin,RELAY_OFF);
digitalWrite(blowerPin,RELAY_OFF);
Serial.begin(9600);
lightChannelSelect = false;
currentLedStripColor = 0;
Serial.println(F("BMP280 test"));
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
//Initialize B&O IR eye
Beo.initialize(IRBOPin);
//Start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
// give the IR sensor and Ethernet shield time to set up:
//delay(1000);
//give all the interfaces some time to calibrate
Serial.print("calibrating sensor & ethernet ");
for(int i = 0; i < PIRCalibrationTime; i++){
Serial.print(".");
delay(300);
}
Serial.println(" done");
Serial.println("SENSOR & ETHERNET ACTIVE");
delay(50);
}
void loop() {
checkIREye();
//checkBMP280(); //only for serial monitoring purpose...
checkEthernet();
checkPIRSensor();
}
void checkPIRSensor() {
if (getAlarm == true) {
if(digitalRead(PIRPin) == HIGH){
if(lockLow){
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
intrusionDetection = true;
}
takeLowTime = true;
}
if(digitalRead(PIRPin) == LOW){
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
}
}
}
}
void checkBMP280() {
Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature()-5);
Serial.println(" *C");
Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure()/100);
Serial.println(" hPa");
Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1021.60)); // this should be adjusted to your local forcase
Serial.println(" m");
Serial.println();
//delay(2000);
}
void checkIREye() {
BeoCommand cmd;
if (Beo.receive(cmd)) {
//Serial.print(cmd.link, HEX);
//Serial.print(":");
//Serial.print(cmd.address, HEX);
//Serial.print("!");
//Serial.println(cmd.command, HEX);
checkRemoteCmd(cmd);
}
}
void checkEthernet() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (URLCommandString.length() < 100) {
//store characters to string
URLCommandString = URLCommandString += c;
}
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// output the value of each analog input pin
client.print("temperature ");
client.print(bmp.readTemperature()-5);
client.print("</br>");
client.print("pression ");
client.print(bmp.readPressure()/100);
client.print("</br>");
client.print("CURRENT UNIT ALARM MODE: ");
if (getAlarm == true) {
client.print("ACTIVE");
} else {
client.print("INACTIVE");
}
client.print("</br>");
client.print("CURRENT HOUSE ALARM MODE: ");
if (setAlarm == true) {
client.print("ACTIVE");
} else {
client.print("INACTIVE");
}
client.print("</br>");
client.print("INTRUSION DETECTION: ");
if (intrusionDetection == true) {
client.print("INTRUSION DETECTED!");
} else {
client.print("NO INTRUSION...");
}
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
//Serial.write(c);
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
//Check if we are in ALARM mode...
WorkMode = URLCommandString.substring(3,10);
if(WorkMode.indexOf("/alarm") > 0) {
getAlarm = true;
} else {
getAlarm = false;
}
//Check if we are in ALARM RESET mode...
WorkMode = URLCommandString.substring(3,10);
if(WorkMode.indexOf("/reset") > 0) {
intrusionDetection = false;
}
// close the connection:
client.stop();
Serial.println("client disconnected");
URLCommandString="";
}
}
void toggleLedStripColor(int color) {
if (currentLedStripColor == color) {
setLedStripColor(OFF);
currentLedStripColor = 0;
} else {
currentLedStripColor = color;
setLedStripColor(color);
}
}
void setLedStripColor(int color) {
switch(color) {
case OFF: LEDDriver.begin();
LEDDriver.SetColor(0,0,0);
LEDDriver.end();
break;
case WhiteColor: LEDDriver.begin();
LEDDriver.SetColor(255,255,255);
LEDDriver.end();
break;
case YellowColor: LEDDriver.begin();
LEDDriver.SetColor(255,100,20);
LEDDriver.end();
break;
case RedColor: LEDDriver.begin();
LEDDriver.SetColor(255,0,0);
LEDDriver.end();
break;
case GreenColor: LEDDriver.begin();
LEDDriver.SetColor(0,255,0);
LEDDriver.end();
break;
case BlueColor: LEDDriver.begin();
LEDDriver.SetColor(0,0,255);
LEDDriver.end();
break;
default: LEDDriver.begin();
LEDDriver.SetColor(0,0,0);
LEDDriver.end();
break;
}
}
void composeCode(String code) {
ALARMCODE = ALARMCODE + code;
if (ALARMCODE.length() == 4) {
if (ALARMCODE == "3521") {
setAlarm = !setAlarm;
if(setAlarm == true) {
delay(300);
setLedStripColor(RedColor);
delay(300);
setLedStripColor(OFF);
delay(300);
setLedStripColor(RedColor);
delay(300);
setLedStripColor(OFF);
delay(300);
} else {
delay(300);
setLedStripColor(GreenColor);
delay(300);
setLedStripColor(OFF);
delay(300);
setLedStripColor(GreenColor);
delay(300);
setLedStripColor(OFF);
delay(300);
}
setLedStripColor(currentLedStripColor);
}
ALARMCODE="";
DOOR=false;
}
}
void checkRemoteCmd(BeoCommand cmd ) {
switch (cmd.command) {
case SPEC_RED: Serial.print("Red LED");
if (lightChannelSelect) {
toggleLedStripColor(RedColor);
}
break;
case SPEC_GREEN: Serial.print("Green LED");
if (lightChannelSelect) {
toggleLedStripColor(GreenColor);
}
break;
case SPEC_BLUE: Serial.print("Blue LED");
if (lightChannelSelect) {
toggleLedStripColor(BlueColor);
}
break;
case SPEC_YELLOW: Serial.print("Orange LED");
if (lightChannelSelect) {
toggleLedStripColor(YellowColor);
}
break;
case BEO1_PAD_GO: Serial.print("Pad GO");
BTGO = true;
break;
case BEO4_PAD_GO: Serial.print("Pad GO");
BTGO = true;
break;
case NUM_0: Serial.print("0");
if (BTGO) {
digitalWrite(audioPin,RELAY_OFF);
digitalWrite(blowerPin,RELAY_OFF);
audioStatus=false;
blowerStatus=false;
BTGO=false;
}
if(DOOR) {
composeCode("0");
}
break;
case NUM_1: Serial.print("1");
if (BTGO) {
if(audioStatus) {
digitalWrite(audioPin,RELAY_OFF);
audioStatus=false;
BTGO=false;
break;
}else {
digitalWrite(audioPin,RELAY_ON);
audioStatus=true;
BTGO=false;
break;
}
}
if(DOOR) {
composeCode("1");
}
break;
case NUM_2: Serial.print("2");
if (BTGO) {
if(blowerStatus) {
digitalWrite(blowerPin,RELAY_OFF);
blowerStatus=false;
BTGO=false;
break;
}else {
digitalWrite(blowerPin,RELAY_ON);
blowerStatus=true;
BTGO=false;
break;
}
}
if(DOOR) {
composeCode("2");
}
break;
case NUM_3: if(DOOR) {
composeCode("3");
}
break;
case NUM_4: if(DOOR) {
composeCode("4");
}
break;
case NUM_5: if(DOOR) {
composeCode("5");
}
break;
case NUM_6: if(DOOR) {
composeCode("6");
}
break;
case NUM_7: if(DOOR) {
composeCode("7");
}
break;
case NUM_8: if(DOOR) {
composeCode("8");
}
break;
case NUM_9: if(DOOR) {
composeCode("9");
}
break;
case CMD_LIGHT: Serial.print("LIGHTCHANNELSELECT TOGGLE:");
lightChannelSelect = true;
if (currentLedStripColor == 0) {
setLedStripColor(WhiteColor);
currentLedStripColor = WhiteColor;
} else {
toggleLedStripColor(currentLedStripColor);
}
break;
case ACT_MENU: DOOR=!DOOR; //just toggle the DOOR boolean on /off
ALARMCODE="";
Serial.print("DOOR: " + DOOR);
break;
case CMD_TV: lightChannelSelect = false;
break;
case CMD_RADIO: lightChannelSelect = false;
break;
case CMD_CD: lightChannelSelect = false;
break;
case CMD_DVD: lightChannelSelect = false;
break;
case CMD_SAT: lightChannelSelect = false;
break;
case CMD_VTAPE: lightChannelSelect = false;
break;
case CMD_MYVIDEO: lightChannelSelect = false;
break;
case CMD_MYPC: lightChannelSelect = false;
break;
case CMD_MYMUSIC: lightChannelSelect = false;
break;
case CMD_TEXT: lightChannelSelect = false;
break;
case CMD_AUX: lightChannelSelect = false;
break;
case CMD_NETRADIO: lightChannelSelect = false;
break;
case CMD_NMUSIC: lightChannelSelect = false;
break;
case CMD_CINEMA: lightChannelSelect = false;
break;
}
}