/*
* Project Smart Room Controller
* Description: Detects "danger zone" for climate to curb the growth of b* black mold utilizing sensors and smart lights/outlets.
*
*Author: Kevin Flores
* Date: July 2022
*/
#include <Ethernet.h>
#include <mac.h>
#include <hue.h>
#include <wemo.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BME280.h>
#include <OneButton.h>
#include <colors.h> //adding installed library
#include <Adafruit_NeoPixel.h> //adding installed library
#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"
const int SCREEN_WIDTH = 128;
const int SCREEN_HEIGHT = 64;
const int OLED_RESET = -1;
const int SCREEN_ADDRESS = 0x3C;
const int LOGO_HEIGHT = 64;
const int LOGO_WIDTH = 128;
const int PIXELPIN = 17; //declare pixel pin as 17
const int PIXELCOUNT = 12; //declare 12 pixels
const int BUTTONPIN = 4;
const int ETHERIN = 12;
const int ETHEROUT = 11;
const int RESET = 9;
const int CHIPSET = 10;
// 'THOR Logo Inverse', 128x64px
const unsigned char myBitmap [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x80, 0x07, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00,
0x03, 0xc1, 0x07, 0x1f, 0xc0, 0x00, 0x00, 0x01, 0xc0, 0xc0, 0x00, 0x1f, 0xf4, 0x80, 0x00, 0x00,
0x07, 0xff, 0xff, 0x9f, 0xc0, 0xff, 0x80, 0x3f, 0xf0, 0x3f, 0xff, 0x80, 0x72, 0x60, 0x00, 0x00,
0x07, 0xff, 0xff, 0x9f, 0xc0, 0xff, 0x80, 0xff, 0xfc, 0x3f, 0xff, 0xe0, 0x71, 0x30, 0x00, 0x00,
0x07, 0xff, 0xff, 0x9f, 0xc0, 0xff, 0xc1, 0x7f, 0xfe, 0x1f, 0xff, 0xf0, 0x79, 0x08, 0x00, 0x00,
0x03, 0xff, 0xff, 0x9f, 0xc0, 0x7f, 0xc7, 0xff, 0xff, 0x0f, 0xff, 0xf8, 0x38, 0xc4, 0x00, 0x00,
0x07, 0xff, 0xff, 0x9f, 0xc0, 0x7f, 0xc7, 0xf8, 0xff, 0x1f, 0xff, 0xfc, 0x38, 0x38, 0x00, 0x00,
0x03, 0x00, 0x70, 0x1f, 0xc0, 0x7f, 0xcf, 0xf0, 0x3f, 0x9f, 0xe1, 0xfc, 0x5c, 0x00, 0x00, 0x00,
0x07, 0xf7, 0xf0, 0x1f, 0xc0, 0x7f, 0xcf, 0xe0, 0x3f, 0x9f, 0xe1, 0xfe, 0x5c, 0x00, 0x00, 0x00,
0x0c, 0x1f, 0xf0, 0x1f, 0xc0, 0x7f, 0x0f, 0xe0, 0x1f, 0xcf, 0xe0, 0xfc, 0x5c, 0x00, 0x00, 0x00,
0x01, 0x1f, 0xf0, 0x1f, 0xff, 0xff, 0x0f, 0xe0, 0x1f, 0xcf, 0xe0, 0xfe, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x1f, 0xf0, 0x1f, 0xff, 0xff, 0x8f, 0xe0, 0x1f, 0xcf, 0xe1, 0xfc, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x07, 0xf0, 0x1f, 0x7f, 0xff, 0x9f, 0xe0, 0x1f, 0xcf, 0xff, 0xf8, 0x0e, 0x00, 0x00, 0x00,
0x18, 0x07, 0xf0, 0x1f, 0x7f, 0xff, 0x9f, 0xc0, 0x1f, 0xcf, 0xff, 0xf0, 0x0e, 0x00, 0x00, 0x00,
0x0e, 0x07, 0xf0, 0x1d, 0x7f, 0xff, 0x9f, 0xc0, 0x1f, 0xdf, 0xff, 0x20, 0x0e, 0x00, 0x00, 0x00,
0x0c, 0x0f, 0xf0, 0x9f, 0xe0, 0x3f, 0x9f, 0xc0, 0x1f, 0xdf, 0xff, 0x20, 0x4e, 0x00, 0x00, 0x00,
0x00, 0x07, 0xf0, 0x1f, 0xc0, 0x3f, 0x9f, 0xc0, 0x1f, 0xdf, 0xff, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x07, 0xf0, 0x3f, 0x80, 0x3f, 0x8f, 0xc0, 0x1f, 0xdf, 0xe3, 0x20, 0x07, 0x00, 0x00, 0x00,
0x00, 0x05, 0xf0, 0x3f, 0x80, 0x3f, 0x8f, 0xc0, 0x1f, 0xdf, 0xe1, 0x30, 0x07, 0x00, 0x00, 0x00,
0x00, 0x04, 0x70, 0x3b, 0x84, 0x79, 0x8f, 0xe0, 0x3f, 0x8f, 0xe1, 0x70, 0x05, 0x83, 0xc0, 0x00,
0x00, 0x04, 0xf0, 0x37, 0x86, 0x70, 0x8f, 0xf0, 0xff, 0x8f, 0xe0, 0xfc, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x05, 0xf0, 0x3f, 0x80, 0x67, 0x87, 0xff, 0xff, 0x8f, 0xe0, 0xfe, 0x04, 0x7f, 0xf8, 0x00,
0x00, 0x0f, 0xf0, 0x3f, 0x80, 0x64, 0x87, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xf8, 0x2f, 0xf8, 0x00,
0x00, 0x0f, 0xf0, 0x1f, 0x80, 0x7c, 0x80, 0xff, 0xfe, 0x1f, 0xe0, 0x7f, 0xf8, 0x87, 0xf8, 0x00,
0x00, 0x0f, 0xf0, 0x1f, 0x80, 0x32, 0x80, 0x7f, 0xf8, 0x1f, 0xe0, 0x3f, 0xe3, 0x40, 0xa8, 0x00,
0x00, 0x0f, 0xf0, 0x2e, 0x00, 0x7f, 0x80, 0x1f, 0xe0, 0x1f, 0xe0, 0x3f, 0xf6, 0xe1, 0xfc, 0x00,
0x10, 0x00, 0x03, 0xe2, 0x00, 0x3f, 0x80, 0x00, 0x07, 0xf1, 0xe0, 0x1f, 0xff, 0xc1, 0xc4, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x1f, 0xff, 0xe0, 0x14, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0xa0, 0x00,
0x00, 0x1a, 0xd0, 0x14, 0xf5, 0x96, 0x9a, 0xa8, 0x48, 0x55, 0x0a, 0x0f, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x08, 0xd0, 0x40, 0x54, 0x91, 0x06, 0x78, 0x1a, 0x02, 0x02, 0x03, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x1a, 0x52, 0x10, 0xd3, 0x84, 0x06, 0xbc, 0x79, 0x07, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int i; //declaring an variable for my 'for' loop
int timer2; //declaring a variable for timer
int inputValue;
int myWemo[] = {0,1,2,3,4};
float tempC, pressPA, humidRH, tempF, inHG, currentTempF, lastTemp, lastHG;
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
bool status, enableMusicPlayer, buttonState, buttonState2, onoff, blinker;
byte thisbyte;
Adafruit_NeoPixel pixel(12, 17, NEO_GRB + NEO_KHZ800); //declaring my object
OneButton button1(23, false, INPUT); //object defined as pin 23, circuit is Input pull down, and button is considered an input
OneButton button2(4, false, INPUT); //object defined as pin 23, circuit is pull down with 10KOhm resistor, and button is considered an input
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_BME280 bme;
void setup() {
button1.attachClick(click1); //initializing the object
button1.setClickTicks(500); //setting timer on clicks off
button1.setPressTicks(1500); //setting timer on click ticks on
buttonState = false; //the button state is set to off initialilly
button2.attachClick(click2); //initializing the object
button2.attachLongPressStart(longPressStart1);
button2.setClickTicks(500);
button2.setPressTicks(2000);
buttonState2 = false;
pixel.begin(); //pixel begin
pinMode(PIXELPIN, OUTPUT); //use PIXELPIN as an output
pixel.setBrightness(200); //set brightness to just below max (255)
pixel.show(); //initializing all as of
Serial1.begin(9600);
Serial.begin(9600);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
Ethernet.begin(mac);
delay(2000); //ensure Serial Monitor is up and running
//printIP();
Serial.printf("LinkStatus: %i \n",Ethernet.linkStatus());
display.begin(SCREEN_ADDRESS);
//while(!Serial); //leaving in for test option
status = bme.begin(0x76);
if (status == false) {
Serial.printf("BME280 at address 0x%02X failed to start \n", 0x76);
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.printf("SSD1306 allocation failed");
for(;;); // Don't proceed, loop forever
}
Serial.printf("");
Serial.printf("DFRobot DFPlayer Mini Demo");
Serial.printf("Initializing DFPlayer ... (May take 3~5 seconds)");
for (int i = 0; i < 5; i++) {
enableMusicPlayer = myDFPlayer.begin(Serial1);
delay(200);
if (enableMusicPlayer) {
break;
}
}
delay(2000);
Serial.printf("DFPlayer Mini online.");
myDFPlayer.volume(10); //Set volume value. From 0 to 30
myDFPlayer.play(1); //Play the first mp3
}
void loop() {
if (millis() - timer2 > 5000) {
testdrawbitmap();
}
if (millis() - timer2 > 5000) {
touchSensorBegin();
}
checkWemo();
static unsigned long timer;
if (millis() - timer > 10000) {
timer = millis();
}
if (myDFPlayer.available()) {
printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
if (millis() - timer2 > 20000) {
checkBMEHue ();
testdrawstyles();
timer2 = millis();
}
}
void touchSensorBegin (void){
button1.tick();
if (buttonState == true){
for (i = 0; i < 12; i = i + 1) { //telling LED use 0 -12 when incrementing lights
//pixel.clear();
pixel.setPixelColor(i+1, maize); //setting pixel color as maize and blue is equal to the remainder of the div
pixel.setPixelColor(i+2, blue);
pixel.setPixelColor(i+3, maize);
pixel.show();
delay(10);
Serial.printf("Button single click /n");
}
for (i = 12; i > 0; i = i - 1) {
pixel.clear();
pixel.setPixelColor(i+1, blue); //setting pixel color
pixel.setPixelColor(i+2, maize);
pixel.show();
delay(10);
Serial.printf("Button single click false /n");
}
}
}
void printDetail(uint8_t type, int value){
switch (type) {
case TimeOut:
Serial.println(F("Time Out!"));
break;
case WrongStack:
Serial.println(F("Stack Wrong!"));
break;
case DFPlayerCardInserted:
Serial.println(F("Card Inserted!"));
break;
case DFPlayerCardRemoved:
Serial.println(F("Card Removed!"));
break;
case DFPlayerCardOnline:
Serial.println(F("Card Online!"));
break;
case DFPlayerUSBInserted:
Serial.println("USB Inserted!");
break;
case DFPlayerUSBRemoved:
Serial.println("USB Removed!");
break;
case DFPlayerPlayFinished:
Serial.print(F("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
break;
case DFPlayerError:
Serial.print(F("DFPlayerError:"));
switch (value) {
case Busy:
Serial.println(F("Card not found"));
break;
case Sleeping:
Serial.println(F("Sleeping"));
break;
case SerialWrongStack:
Serial.println(F("Get Wrong Stack"));
break;
case CheckSumNotMatch:
Serial.println(F("Check Sum Not Match"));
break;
case FileIndexOut:
Serial.println(F("File Index Out of Bound"));
break;
case FileMismatch:
Serial.println(F("Cannot Find File"));
break;
case Advertise:
Serial.println(F("In Advertise"));
break;
default:
break;
}
break;
default:
break;
}
}
void checkWemo (void) {
int myButton;
button2.tick(); //check the state of the button
inputValue = digitalRead(myButton);
Serial.printf("%i \n", inputValue);
}
void click1() { //function that is going to tell Serial printf to log clicks on and off
buttonState = !buttonState; //toggling buttonState
}
void click2() { //function that is going to tell Serial printf to log clicks on and off
buttonState2 = !buttonState2;
if (buttonState2 == true) {
switchON(myWemo[2]);
Serial.printf("Hello Wemo %i /n", myWemo);
}
else {
switchOFF(myWemo[2]);
Serial.printf("Bye Wemo %i /n", myWemo);
}
}
void longPressStart1() {
buttonState2 = !buttonState2;
if (buttonState2 == true) {
switchON(myWemo[3]);
Serial.printf("Hello Wemo %i /n", myWemo);
}
else {
switchOFF(myWemo[3]);
Serial.printf("Bye Wemo %i /n", myWemo);
}
Serial.printf("Button double click /n");
}
void checkBMEHue (void) {
setHue(3,true,HueBlue,255,255);
Serial.printf("Get Hue Data: ");
getHue(3);
setHue(3,false,0,0,0);
tempC = bme.readTemperature();
pressPA = bme.readPressure();
humidRH = bme.readHumidity();
tempF = tempC*9/5+32;
inHG = pressPA/3386;
Serial.printf("%f, %f, %f \n", tempF, inHG, humidRH);
if (tempF > 80.00) {
setHue(1,true,HueBlue,255,255);
setHue(2,true,HueBlue,255,255);
setHue(3,true,HueBlue,255,255);
Serial.printf("Get Hue Data: ");
display.display();
Serial.printf("%f, %f \n", tempF, lastTemp);
lastTemp = tempF;
}
else {
setHue(1, false, 0, 0, 0);
setHue(2, false, 0, 0, 0);
setHue(3, false, 0, 0, 0);
}
if (inHG != lastHG) {
setHue(4,true,HueGreen,255,255);
setHue(5,true,HueGreen,255,255);
setHue(6,true,HueViolet,255,255);
Serial.printf("Get Hue Data: ");
Serial.printf("%f, %f \n", inHG, lastHG);
lastHG = inHG;
}
else {
setHue(4, false, 0, 0, 0);
setHue(5, false, 0, 0, 0);
setHue(6, false, 0, 0, 0);
}
if (inHG > 60.00) {
setHue(6,true,HueViolet,255,255);
Serial.printf("Get Hue Data: ");
Serial.printf("%f, %f \n", inHG, lastHG);
lastHG = inHG;
}
else {
setHue(6, false, 0, 0, 0);
}
}
void testdrawstyles(void) {
display.clearDisplay();
display.setTextSize(1); //Draw 5x-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 0);
display.printf("Temperature:", tempF);
display.display();
display.setTextSize(1); //Draw 5x-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 10);
display.printf("%f", tempF);
display.display();
display.setTextSize(.5); //Draw 5x-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
display.printf("Humidity:");
display.display();
display.setTextSize(1); //Draw 5x-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 30);
display.printf("%f", humidRH);
display.display();
display.setTextSize(.5); //Draw 5x-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 40);
display.printf("Barometric Pressure:");
display.display();
display.setTextSize(.5); //Draw 5x-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 50);
display.printf("%f", humidRH);
display.display();
}
void testdrawbitmap(void) {
display.clearDisplay();
display.drawBitmap(
(display.width() - LOGO_WIDTH )/2,
(display.height() - LOGO_HEIGHT)/2,
myBitmap, LOGO_WIDTH, LOGO_HEIGHT, 1);
display.display();
}
void printIP() {
Serial.printf("My IP address: ");
for (byte thisByte = 0; thisByte < 3; thisByte++) {
Serial.printf("%i.",Ethernet.localIP()[thisByte]);
}
Serial.printf("%i\n",Ethernet.localIP()[3]);
}
Comments