Sure.
#define BLYNK_PRINT Serial
#include <Adafruit_NeoPixel.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <SPI.h>
#include <SimpleTimer.h>
#include <WiFiUdp.h>
// LED Stuff
#define PIN D5
#define NUM_LEDS 37
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ400);
void showStrip();
void clearStrip();
void setPixel(int, int, int, int);
void fadeToBlack(int, byte);
void ZeRGBa();
void colorWipe(int, int, int, int);
void CylonBounce(int, int, int, int, int, int);
void meteorRain(int, int, int, int, int, boolean, int);
void Strobe(int, int, int, int, int, int);
// normal Void Declaration
void WIFI_check();
void TIME_check();
void PIR_time_check();
void PIR_check();
void ALARM_time_check();
void ALARM_check();
void WDAY_and_NOW();
// WiFi Stuff
char auth[] = "******************";
char ssid[] = "******************";
char pass[] = "******************";
char serv[] = "******************";
// Variables
int interval = 1000;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
int red = 1;
int green = 0;
int blue = 2;
int connectionSuccess = 0;
// Motion Sensor Variables
int PIR_pin = D3;
int PIR_val;
int PIR_start = 79200;
int PIR_stop = 21600;
int PIR_timer = 10 * 1000;
int PIR_running;
int PIR_effect = 1;
char PIR_days_start[] = "1,2,3,4,5,6,7";
bool PIR_days[] = {true, true, true, true, true, true, true};
bool PIR_status = false;
bool PIR_active = false;
unsigned long PIR_start_millis = 0;
int now;
int finish;
int weekday;
// Alarm Variables
int ALARM_start = 21600;
int ALARM_timer = 60 * 1000;
int ALARM_running;
int ALARM_effect = 4;
char ALARM_days_start[] = "1,2,3,4,5";
bool ALARM_days[] = {true, true, true, true, true, false, false};
bool ALARM_status = false;
unsigned long ALARM_start_millis = 0;
const long utcOffsetInSeconds = 2 * 60 * 60;
unsigned long delayStart = 0;
bool delayRunning = false;
bool debug = false; // debug Serial.print messages
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "10.0.4.1", utcOffsetInSeconds);
unsigned long TIME_sync_millis = 0;
int TIME_sync_timer = 60;
SimpleTimer timer;
void setup()
{
Serial.begin(115200);
unsigned long started = millis();
Serial.println();
WiFi.begin(ssid, pass); //Blynk.begin(auth, ssid, pass, serv, 8080);
Serial.println(String("Connecting to ") + ssid + " ...");
while (WiFi.status() != WL_CONNECTED) {
if (millis() - started < 20 * 1000) {
yield();
}
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Wifi works, now try Blynk connection");
delay(2 * 1000);
Blynk.config(auth, serv, 8080);
Blynk.connect(30 * 1000);
if (Blynk.connected() == true) {
delay(2000);
Blynk.run();
Serial.println("Blynk is online");
}
}
timeClient.begin();
timer.setInterval(60 * 1000L, WIFI_check);
timer.setInterval(60 * 1000L, TIME_check);
ALARM_running = timer.setInterval(1 * 1000L, ALARM_check);
PIR_running = timer.setInterval(1 * 1000L, PIR_check);
pinMode(PIR_pin, INPUT);
timeClient.begin();
pixels.begin();
pixels.clear();
delayStart = millis();
delayRunning = false;
Blynk.virtualWrite(V0, red);
Blynk.virtualWrite(V1, green);
Blynk.virtualWrite(V2, blue);
Blynk.virtualWrite(V5, "First Start");
Blynk.virtualWrite(V8, ALARM_timer / 1000);
Blynk.virtualWrite(V9, PIR_timer / 1000);
Blynk.virtualWrite(V11, ALARM_start, 0, 0, ALARM_days_start);
Blynk.virtualWrite(V12, PIR_start, PIR_stop, 0, PIR_days_start);
Blynk.virtualWrite(V13, PIR_effect);
Blynk.virtualWrite(V14, ALARM_effect);
Blynk.virtualWrite(V20, TIME_sync_timer);
if (debug) {
Blynk.virtualWrite(V21, 1);
}
else {
Blynk.virtualWrite(V21, 2);
}
timeClient.update();
timer.disable(ALARM_running);
timer.disable(PIR_running);
if (debug) {
if (timer.isEnabled(ALARM_running)) {
Blynk.virtualWrite(V22, "ALARM is running");
}
else {
Blynk.virtualWrite(V22, "ALARM is stoped");
}
if (timer.isEnabled(PIR_running)) {
Blynk.virtualWrite(V23, "PIR is running");
}
else {
Blynk.virtualWrite(V23, "PIR is stoped");
}
}
}
void loop()
{
timer.run();
Blynk.run();
currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval) {
previousMillis = currentMillis;
}
}
void WIFI_check()
{
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, pass);
Serial.println("Lost WiFi Connection, trying to reconnect... ");
connectionSuccess = 1;
}
else if (WiFi.status() == WL_CONNECTED && connectionSuccess == 1) {
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Wifi works, now try Blynk connection");
delay(2 * 1000);
Blynk.config(auth, serv, 8080);
Blynk.connect(30 * 1000);
if (Blynk.connected() == true) {
delay(2000);
Blynk.run();
Serial.println("Blynk is online");
}
connectionSuccess = 0;
}
}
void TIME_check()
{
if ((unsigned long)(currentMillis - TIME_sync_millis) >= TIME_sync_timer * 60 * 1000) {
if (debug) {
Serial.println("Syncing NTP time");
}
TIME_sync_millis = currentMillis;
timeClient.update();
}
WDAY_and_NOW();
ALARM_time_check();
PIR_time_check();
if (debug) {
if (timer.isEnabled(ALARM_running)) {
Blynk.virtualWrite(V22, "ALARM running again");
}
else {
Blynk.virtualWrite(V22, "ALARM is stoped");
}
if (timer.isEnabled(PIR_running)) {
Blynk.virtualWrite(V23, "PIR running again");
}
else {
Blynk.virtualWrite(V23, "PIR is stoped");
}
}
}
void WDAY_and_NOW()
{
weekday = timeClient.getDay();
if (debug) {
Serial.println(String("Zeit: ") + timeClient.getHours() + ":" + timeClient.getMinutes());
}
if (timeClient.getDay() == 0) {
weekday = 7;
}
now = timeClient.getHours() * 60 * 60 + timeClient.getMinutes() * 60;
}
void ALARM_time_check()
{
/*****************************************************
ALARM Time Check START
*****************************************************/
if (now == ALARM_start && ALARM_days[weekday] && ALARM_start >= 0) {
clearStrip(); // Strip turned off if other PIR_effects are running while Alarm is triggered
ALARM_status = true;
ALARM_start_millis = currentMillis;
timer.enable(ALARM_running);
if (debug) {
Serial.println(String("ALARM Effect started at: ") + timeClient.getHours() + ":" + timeClient.getMinutes());
}
}
/*****************************************************
ALARM Time Check END
*****************************************************/
}
void PIR_time_check()
{
/*****************************************************
PIR Time Check START
*****************************************************/
if (PIR_days[weekday] && PIR_start >= 0 && PIR_stop >= 0) {
// Time between 5:00 and 6:00 f.e.
if (PIR_start < PIR_stop) {
finish = PIR_stop;
}
// Time between 6:00 and 5:00 f.e.
else if (PIR_start > PIR_stop) {
finish = PIR_stop + 24 * 60 * 60;
// Now is at time on the next day after Start
// Start = 20:00 | Stop = 4:00 | Now = 2:00
if (now < PIR_start) {
now = now + 24 * 60 * 60;
}
}
}
// Check if Now is between Start and Stop
if (now >= PIR_start && now < finish && !ALARM_status) {
//PIR_status = true;
timer.enable(PIR_running);
if (debug) {
Serial.println("PIR Detection IS Active");
}
}
else {
//PIR_status = false;
timer.disable(PIR_running);
if (debug) {
Serial.println("PIR Detection NOT Active");
}
}
/*****************************************************
PIR Time Check END
*****************************************************/
}
void ALARM_check()
{
if (debug) {
Serial.println(String("ALARM was running at: ") + timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds());
}
if (ALARM_status) {
if ((unsigned long)(currentMillis - ALARM_start_millis) >= ALARM_timer) {
ALARM_status = false;
clearStrip();
timer.disable(ALARM_running);
if (debug) {
Serial.println(String("ALARM Effect ended at: ") + timeClient.getHours() + ":" + timeClient.getMinutes());
}
}
else {
if (ALARM_effect == 1) {
ZeRGBa();
}
else if (ALARM_effect == 2) {
colorWipe(10, 45, 50, 50);
colorWipe(0, 0, 0, 50);
}
else if (ALARM_effect == 3) {
CylonBounce(255, 0, 0, 4, 20, 60);
}
else if (ALARM_effect == 4) {
meteorRain(255, 127, 127, 10, 64, true, 30);
}
else if (ALARM_effect == 5) {
// Slower:
// Strobe(0xff, 0x77, 0x00, 10, 100, 1000);
Strobe(255, 0, 255, 10, 50, 1000);
}
}
}
}
void PIR_check()
{
if (debug) {
Serial.println(String("PIR was running at: ") + timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds());
}
//if (PIR_status) {
PIR_val = digitalRead(PIR_pin);
if (PIR_val == HIGH) {
Blynk.virtualWrite(V5, "Motion detected");
PIR_active = true;
PIR_start_millis = currentMillis;
if (debug) {
Serial.println(String("PIR Effect started at: ") + timeClient.getHours() + ":" + timeClient.getMinutes());
}
}
else {
Blynk.virtualWrite(V5, "no Motion");
}
if (PIR_active) {
if ((unsigned long)(currentMillis - PIR_start_millis) >= PIR_timer) {
PIR_active = false;
clearStrip();
timer.disable(PIR_running);
//timer.deleteTimer(PIR_running);
//PIR_running = timer.setInterval(10 * 1000L, PIR_check);
if (debug) {
Serial.println(String("PIR Effect ended at: ") + timeClient.getHours() + ":" + timeClient.getMinutes());
}
}
else {
if (PIR_effect == 1) {
ZeRGBa();
}
else if (PIR_effect == 2) {
colorWipe(50, 10, 45, 25);
colorWipe(0, 0, 0, 25);
}
else if (PIR_effect == 3) {
CylonBounce(255, 0, 0, 4, 20, 60);
}
else if (PIR_effect == 4) {
meteorRain(255, 127, 127, 10, 64, true, 30);
}
else if (PIR_effect == 5) {
// Slower:
// Strobe(0xff, 0x77, 0x00, 10, 100, 1000);
Strobe(255, 0, 255, 10, 50, 1000);
}
}
}
//}
}
void showStrip() {
pixels.show();
}
void clearStrip() {
pixels.fill(0, 0, NUM_LEDS);
showStrip();
}
void setPixel(int Pixel, int red, int green, int blue) {
pixels.setPixelColor(Pixel, pixels.Color(red, blue, green));
}
/********************* LED PIR_effectS *********************/
void ZeRGBa() {
for (int i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
}
}
void colorWipe(int red, int green, int blue, int SpeedDelay) {
for (uint16_t i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}
void CylonBounce(int red, int green, int blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for (int i = 0; i < NUM_LEDS - EyeSize - 2; i++) {
//setAll(0, 0, 0);
clearStrip();
setPixel(i, red / 10, green / 10, blue / 10);
for (int j = 1; j <= EyeSize; j++) {
setPixel(i + j, red, green, blue);
}
setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
for (int i = NUM_LEDS - EyeSize - 2; i > 0; i--) {
//setAll(0,0,0);
clearStrip();
setPixel(i, red / 10, green / 10, blue / 10);
for (int j = 1; j <= EyeSize; j++) {
setPixel(i + j, red, green, blue);
}
setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}
void meteorRain(int red, int green, int blue, int meteorSize, int meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
//setAll(0,0,0);
clearStrip();
for (int i = 0; i < NUM_LEDS + NUM_LEDS; i++) {
// fade brightness all LEDs one step
for (int j = 0; j < NUM_LEDS; j++) {
if ( (!meteorRandomDecay) || (random(10) > 5) ) {
fadeToBlack(j, meteorTrailDecay);
}
}
// draw meteor
for (int j = 0; j < meteorSize; j++) {
if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
setPixel(i - j, red, green, blue);
}
}
showStrip();
delay(SpeedDelay);
}
}
void fadeToBlack(int ledNo, byte fadeValue) {
uint32_t oldColor;
uint8_t r, g, b;
oldColor = pixels.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);
r = (r <= 10) ? 0 : (int) r - (r * fadeValue / 256);
g = (g <= 10) ? 0 : (int) g - (g * fadeValue / 256);
b = (b <= 10) ? 0 : (int) b - (b * fadeValue / 256);
pixels.setPixelColor(ledNo, r, g, b);
}
void Strobe(int red, int green, int blue, int StrobeCount, int FlashDelay, int EndPause) {
for(int j = 0; j < StrobeCount; j++) {
for (int i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
}
showStrip();
delay(FlashDelay);
clearStrip();
delay(FlashDelay);
}
delay(EndPause);
}
/********************* LED PIR_effectS *********************/
BLYNK_WRITE(V0)
{
red = param.asInt();
}
BLYNK_WRITE(V1)
{
green = param.asInt();
}
BLYNK_WRITE(V2)
{
blue = param.asInt();
}
BLYNK_WRITE(V8)
{
ALARM_timer = param.asInt() * 1000;
}
BLYNK_WRITE(V9)
{
PIR_timer = param.asInt() * 1000;
}
BLYNK_WRITE(V11)
{
TimeInputParam t(param);
if (t.hasStartTime()) {
ALARM_start = t.getStartHour() * 60 * 60 + t.getStartMinute() * 60 + t.getStartSecond();
}
else {
ALARM_start = -1;
}
for (int i = 1; i <= 7; i++) {
ALARM_days[i] = t.isWeekdaySelected(i);
}
}
BLYNK_WRITE(V12)
{
TimeInputParam t(param);
if (t.hasStartTime()) {
PIR_start = t.getStartHour() * 60 * 60 + t.getStartMinute() * 60 + t.getStartSecond();
}
else {
PIR_start = -1;
}
if (t.hasStopTime()) {
PIR_stop = t.getStopHour() * 60 * 60 + t.getStopMinute() * 60 + t.getStopSecond();
}
else {
PIR_stop = -1;
}
for (int i = 1; i <= 7; i++) {
PIR_days[i] = t.isWeekdaySelected(i);
}
WDAY_and_NOW();
PIR_time_check();
}
BLYNK_WRITE(V13)
{
switch (param.asInt()) {
case 1: {
//ZeRGBa
PIR_effect = 1;
break;
}
case 2: {
//colorWipe
PIR_effect = 2;
break;
}
case 3: {
//Cylon
PIR_effect = 3;
break;
}
case 4: {
//Meteor
PIR_effect = 4;
break;
}
case 5: {
//Strobe
PIR_effect = 5;
break;
}
}
}
BLYNK_WRITE(V14)
{
switch (param.asInt()) {
case 1: {
//ZeRGBa
ALARM_effect = 1;
break;
}
case 2: {
//colorWipe
ALARM_effect = 2;
break;
}
case 3: {
//Cylon
ALARM_effect = 3;
break;
}
case 4: {
//Meteor
ALARM_effect = 4;
break;
}
case 5: {
//Strobe
ALARM_effect = 5;
break;
}
}
}
BLYNK_WRITE(V20)
{
TIME_sync_timer = param.asInt();
if (debug) {
Serial.println(String("Time Synchronisation every: ") + TIME_sync_timer + "Minutes");
}
}
BLYNK_WRITE(V21)
{
int debug_switch = param.asInt();
if (debug_switch == 1) {
debug = true;
}
else {
debug = false;
}
}