About Smart Desk Clock with RGB Lamp:
Smart Wi-Fi connected Desk Clock which includes a RGB panel and a IR Blaster is a multipurpose IoT device built using ESP8266 interfaced with the Infineon’s DPS310 which is a miniaturized digital barometric pressure sensor that offers high accuracy, low current consumption, and Infineon's BGT24LTR11N16 24GHz Radar with smart motion tracking, direction, proximity and speed detection capability. As the name says the device shows time and date on a 1.3" OLED display interfaced with it, the device includes a 4x4 WS2812B RGB LED panel and an IR LED interfaced with the ESP8266 which helps us control devices which can be controlled using an IR remote control. The prototype connects to internet via Wi-Fi to receive and send commands using MQTT protocol through Internet to communicate with the Mobile App and other IoT devices like Wi-Fi AC Appliance Switches.
Architecture:
The device works on different modes of operation as per the code specified for the selected mode, collectively based on the sensor data processed by the device and various algorithms. Whereas, the base architecture of the device remains the same as shown in the picture below:
Android App:
In the android app, whenever you press the buttons to select the mode, it will publish the command in the HacksterProjectRx topic to set the selected mode on the device and when it receives the acknowledgement in the HacksterProjectTx topic from the device it will alert saying that the mode has been set. Similarly, when it receives the Intrusion alert message in the HacksterProjectTx topic from the device it will give a push notification.
As you can see in the above video android app helps us set the device at different modes of operation for different use cases of the device based on where you want to use it, which are discussed below.
1. Office Cabin Mode
2. Living Mode
3. Surveillance Mode
4. RGB Mode
5. Night Mode
Each of this mode is explained in detail below with separate videos for better understanding.
1. Office Cabin Mode
Office cabin and home office rooms generally have an air conditioner and lighting systems. Some even have a lavatory that can be accessed from the main cabin. It has become a human tendency nowadays that we hardly take time to switch off these AC appliances while leaving the cabin/room.
The desk clock helps us in doing this by triggering the IR based AC wall switches, Air Conditioner through IR Signals and Internet connected switches over MQTT.
Based on Open and Close Events of Main Door / Lavatory Door of the Cabin detected by the Infineon’s DPS310 pressure sensor and smart motion detection by Infineon's BGT24LTR11N16 24GHz Radar helps us to write an algorithm on the ESP8266 for turning on and turning off the light, fan and air conditioner of the room when the room is occupied and unoccupied respectively to save power usage.
Below image shows the items on the room which are being sensed and triggered
You can have a look at the demo of the Office Cabin Mode in the video below:
2. Living Mode
With living room, bedroom, kitchen, water closet and so on in a typical household, the living room is the most commonly used space until we go to bed. Say we usually spend our family time together in the evening from 6-10, and it's obvious that we tend to move to a room or the other to grab something when required. We generally tend to keep the doors open and again, even in this case we ignore to switch off the lights while moving out of the room.
Using the Infineon's BGT24LTR11N16 24GHz Radar we can detect the motion of someone approaching towards the Radar continuously for a particular period of time and also with the amplitude of the signal the lights are turned on. Likewise the lights are turned off when the the person is departing away from the room.
Note: When a PIR sensor is used to control the lights automatically based on motion detection, we get false detection when someone moved across the door and didn't enter the room, you can note this in the video of Living Mode that, we don't get any such false detection when we use the Sense2GoL Board. The approaching and departing motion of the person moving towards and away from the radar is detected correctly to turn on and turn off the light.
Have a look at the video below to see a demo of the Living Mode.
3. Surveillance Mode
A mode of operation which can be used when you are not at house and would like to receive alerts on your phone when someone breaks into your house.
The surveillance mode is similar to the cabin mode, whereas it sends a push notification to your mobile phone giving intruder alert instead of switching on/off the lights when the open/closed door event is detected.
Have a look at the video below to see a demo of the Surveillance Mode.
4. RGB and Proximity Switch Mode
In this mode the RGB Panel of the device can be controlled from the phone to set different colors picked from the phone to give mood lighting inside the room. The video also shows how the analog values from Sense2GoL board is used sense it as a proximity switch to turn on and turn off the main light of the room, you can see this feature at the start and end of the video.
Have a look at the video below to see a demo of the RGB Mode.
5. Night Mode
This mode of operation is similar to the Living Mode. Whereas in this case instead of turning on the main light we will be switching on the RGB panel with white LIGHT, that gives a dimmed lighting when you wake up in the middle of night to drink water or use the WC or do something else. Basically, to move around in the dark without disturbing someone else who is sleeping in the room.
Have a look at the video below to see a demo of the Night Mode.
You note that the device is powered using a normal USB charger / power supply.
Steps to build the prototype are as follows:
If you are a pro in using arduino and electronics, you may directly have a look at the full schematic and the code available in the code and schematics section of the project and go ahead. If you are beginner you may follow the steps given below for better understanding:
Step 1: Setting up the NodeMCU
Since you will be using NodeMCU as the main main MCU in this project, to program the NodeMCU/ESP8266 using Arduino IDE you need to follow certain steps, a lot of guides are available online. For your reference, one of the hackster project link which shows how you can get started with NodeMCU in Arduino IDE is given below for your reference
https://www.hackster.io/Aritro/getting-started-with-esp-nodemcu-using-arduinoide-aa7267
Once you have successfully added the NodeMCU board to your arduino you can get started with next steps of interfacing the sensors with NodeMCU using the schematic of this project which is given below and upload the final code to test the project as well.
To make it easy to understand and tinker more on the project. Interfacing of each sensor has been explained in detail separately below:
Interfacing Sense2GoL Board:
Setup your Sense2GoL board using the tutorial available in the link given below
Once you successfully finished the flashing process using DAVE IDE of the supplied demo code which you received with the Sense2GoL board as per the video link given above, you should be able to see three different color LEDs lighting on on the Sense2GoL board
RED meaning Approaching
ORANGE meaning Departing
BLUE meaning No motion
The output pins from the XMC1302 which lights up the RED LED and ORANGE LED are available as pinouts OUT1 and OUT2 on the Sense2GoL breakout board which are shown in the picture below:
The Logic Level of these pins are as follows:
OUT1 is HIGH and OUT2 is HIGH ====> No Motion Detected
OUT1 is LOW and OUT2 is HIGH ====> Approaching Motion Detected
OUT1 is HIGH and OUT2 is LOW ====> Departing Motion Detected
so using this HIGH and LOW levels of the OUT1 and OUT2 pins. Connecting them to NodeMCU's input pins we can sense the detection and direction of movement to write code on NodeMCU using Arduino IDE to perform different operations.
Similarly you may connect the IF_I_HG pin to any analog pin of the MCU to read the analog values to use the sensor as a proximity switch which I have done in this project.
Note: You may also use the analog values to calculate the speed at which someone is approaching or departing towards the radar using FFT algorithm. I will not be discussing this in this project as the processing of FFT needs a faster processor like the Arduino Due or Zero or MKR1000. So, I will be posting that as a separate project using the MKR1000 which I have already tested and compared with speed shown by the Micrium GUI when we use the test code uploaded on the XMC1302.
Code to test the Sense2GoL Demo Board with NodeMCU for detecting Approaching and Departing motion:
int App = 14; //OUT1
int Dep = 13; //OUT2
String MStat = "";
void setup()
{
Serial.begin(9600);
pinMode(App, INPUT);
pinMode(Dep, INPUT);
}
void loop()
{
int Aps = digitalRead(App);
int Dps = digitalRead(Dep);
if (Aps == HIGH && Dps == HIGH) {
MStat = "No motion";
Serial.println(MStat);
}
else if (Aps == HIGH && Dps == LOW) {
MStat = "Departing";
Serial.println(MStat);
}
else if (Aps == LOW && Dps == HIGH) {
MStat = "Approaching";
Serial.println(MStat);
}
}
Sense2GoL Test Video
Code to test the Sense2Gol board with NodeMCU to act as proximity Switch:
int IF = 0;
int ProxS = 0;
int CatProx = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
IF = analogRead(A0);
if (IF > 980) {
CatProx = CatProx + 1;
if (CatProx == 5) {
Serial.println("ProximitySwitch");
delay(3000);
}
}
else {
CatProx = 0;
}
}
Test Video:
Interfacing DPS310 with ESP8266/NodeMCU:
DPS310 Sensor Hub Nano Board Pinout Reference is shown in the picture below:
There is a arduino library available for DPS310 which is available at https://github.com/Infineon/DPS310-Pressure-Sensor provided by Infineon.
But this existing library doesn't work with ESP8266. So I have modified this library to make it work with ESP8266 using Software I2C using Slow Soft I2C Library.
The modified library works with ESP8266 and Arduino MKR1000 as far as I have tested it for interfacing the DPS310 via I2C.
You will have to download the Slow Soft Wire and Master Libraries also to use the modified library, because the modified library is using these two libraries for getting data from the sensor via I2C.
You can get these libraries from the following URLs
Once you have successfully installed the libraries you may open the DPS310 sensor example that is available and connect the sensor to the ESP8266 and upload the example code to test the sensor values
Upload the code and open serial plotter to see the pressure change values when you open and close the door
Code to Test DPS310 Pressure Sensor Values
#include <ifx_dps310.h>
SlowSoftWire Wire = SlowSoftWire(4, 5); //GPIO 4 to SDA and GPIO 5 to SCL
void setup()
{
Serial.begin(9600);
Wire.begin();
ifxDps310.begin(Wire, 0x76);
// IMPORTANT NOTE
//If you face the issue that the DPS310 indicates a temperature around 60 °C although it should be around 20 °C (room temperature), you might have got an IC with a fuse bit problem
//Call the following function directly after begin() to resolve this issue (needs only be called once after startup)
//ifxDps310.correctTemp();
Serial.println("Init complete!");
}
void loop()
{
int32_t temperature;
int32_t pressure;
int oversampling = 7;
int ret;
//lets the Dps310 perform a Single temperature measurement with the last (or standard) configuration
//The result will be written to the paramerter temperature
ret = ifxDps310.measureTempOnce(temperature);
//the commented line below does exactly the same as the one above, but you can also config the precision
//oversampling can be a value from 0 to 7
//the Dps 310 will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision
//measurements with higher precision take more time, consult datasheet for more information
//ret = ifxDps310.measureTempOnce(temperature, oversampling);
/*if (ret != 0)
{
//Something went wrong.
//Look at the library code for more information about return codes
Serial.print("FAIL! ret = ");
Serial.println(ret);
}
else
{
//Serial.print("Temperature: ");
//Serial.print(temperature);
//Serial.println(" degrees of Celsius");
}*/
//Pressure measurement behaves like temperature measurement
ret = ifxDps310.measurePressureOnce(pressure);
//ret = ifxDps310.measurePressureOnce(pressure, oversampling);
if (ret != 0)
{
//Something went wrong.
//Look at the library code for more information about return codes
Serial.print("FAIL! ret = ");
Serial.println(ret);
}
else
{
//Serial.print("Pressure: ");
Serial.println(pressure);
//Serial.println(" Pascal");
}
//Wait some time
delay(10);
}
In my case the events detected has been shown below:
Interfacing 1.3" OLED SSD1305 with ESP8266:
SSD1305 Pinout Reference is shown in the picture below:
Required Libraries:
Code to test OLED Display with Time and Date obtained via NTP:
#include <ESP8266WiFi.h>
const char* ssid = "********";
const char* password = "*********";
///////////////////////////////////////////////
#include <TimeLib.h>
#include <WiFiUdp.h>
static const char ntpServerName[] = "us.pool.ntp.org";
const int timeZone = +5;
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
time_t getNtpTime();
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);
time_t prevDisplay = 0;
/////////////////////////////////////////////////////////////////////////////////
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, 5,4);
/////////////////////////////////////////////////////////////////////////////////
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
setup_wifi();
///////////////////////////////////////////////
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(300);
///////////////////////////////////////////////
u8g2.begin();
}
void loop() {
if (timeStatus() != timeNotSet) {
if (now() != prevDisplay) { //update the display only if time has changed
prevDisplay = now();
digitalClockDisplay();
}
}
}
void digitalClockDisplay()
{
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(".");
Serial.print(month());
Serial.print(".");
Serial.print(year());
Serial.println();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_profont22_mn);
String K = "";
char charBuf[20];
K += day();
K += "-";
K += month();
K += "-";
K += year();;
K.toCharArray(charBuf, 20);
u8g2.drawStr(12,20,charBuf);
K = "";
K += hour();
K += ":";
K += minute();
K += ":";
K += second();
K.toCharArray(charBuf, 20);
u8g2.drawStr(20,52,charBuf);
} while ( u8g2.nextPage() );
}
void printDigits(int digits)
{
// utility for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
Serial.print(ntpServerName);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return (secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR)+1800;
}
}
Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
Output Test Video:
Interfacing IR Led with ESP8266:
Interfacing IR blaster with ESP8266 is very simple, a lot of resources are available online for reference.
I would recommend the links given below for you to understand how you can decode and code your Arduino or ESP8266 to make it act as an IR blaster
https://learn.sparkfun.com/tutorials/ir-communication
https://learn.adafruit.com/ir-sensor/ir-remote-signals
https://www.hackster.io/BuddyC/wifi-ir-blaster-af6bca
After understanding the content given in the links above, you will be able to decode the signals of any IR remote as NEC or RAW or any other format using the IR Library mentioned in the links given below, in this project as we are using the ESP8266 we will be using the IR Library for ESP8266 which is available at
https://github.com/markszabo/IRremoteESP8266
In my case I got NEC codes to control my IR based AC Switches I used them to control the Light and Fan in the demo videos shown, you may modify the code as per your decoded signals to test it.
Base Code to test IR Blaster:
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRsend.h>
IRsend irsend(0); // An IR LED is controlled by GPIO pin 0
void setup()
{
irsend.begin();
setup_wifi();
}
void loop(){
//////////////////////////////////////Send signals as per your decoded signals
irsend.sendNEC(0x8F7C13E, 32); //1
delay(2000);
irsend.sendNEC(0x8F7C13E, 32); //1
delay(2000);
}
Interfacing RGB Panel with ESP8266
The RGB Panel used in this project contains WS2812B which is same as the neopixel explained very well by Adafruit Community.
I would recommend the link given below for you to understand more about neopixel and how you can interface the RGB LEDs with your Arduino or ESP8266
https://learn.adafruit.com/adafruit-neopixel-uberguide/overview
Code to test NeoPixels (Adafruit NeoPixel Library Example)
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 12
#define NUM_LEDS 16
#define BRIGHTNESS 50
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
byte neopix_gamma[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
strip.setBrightness(BRIGHTNESS);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
colorWipe(strip.Color(0, 0, 0, 255), 50); // White
whiteOverRainbow(20,75,5);
pulseWhite(5);
// fullWhite();
// delay(2000);
rainbowFade2White(3,3,1);
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void pulseWhite(uint8_t wait) {
for(int j = 0; j < 256 ; j++){
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0,0,0, neopix_gamma[j] ) );
}
delay(wait);
strip.show();
}
for(int j = 255; j >= 0 ; j--){
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0,0,0, neopix_gamma[j] ) );
}
delay(wait);
strip.show();
}
}
void rainbowFade2White(uint8_t wait, int rainbowLoops, int whiteLoops) {
float fadeMax = 100.0;
int fadeVal = 0;
uint32_t wheelVal;
int redVal, greenVal, blueVal;
for(int k = 0 ; k < rainbowLoops ; k ++){
for(int j=0; j<256; j++) { // 5 cycles of all colors on wheel
for(int i=0; i< strip.numPixels(); i++) {
wheelVal = Wheel(((i * 256 / strip.numPixels()) + j) & 255);
redVal = red(wheelVal) * float(fadeVal/fadeMax);
greenVal = green(wheelVal) * float(fadeVal/fadeMax);
blueVal = blue(wheelVal) * float(fadeVal/fadeMax);
strip.setPixelColor( i, strip.Color( redVal, greenVal, blueVal ) );
}
//First loop, fade in!
if(k == 0 && fadeVal < fadeMax-1) {
fadeVal++;
}
//Last loop, fade out!
else if(k == rainbowLoops - 1 && j > 255 - fadeMax ){
fadeVal--;
}
strip.show();
delay(wait);
}
}
delay(500);
for(int k = 0 ; k < whiteLoops ; k ++){
for(int j = 0; j < 256 ; j++){
for(uint16_t i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0,0,0, neopix_gamma[j] ) );
}
strip.show();
}
delay(2000);
for(int j = 255; j >= 0 ; j--){
for(uint16_t i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0,0,0, neopix_gamma[j] ) );
}
strip.show();
}
}
delay(500);
}
void whiteOverRainbow(uint8_t wait, uint8_t whiteSpeed, uint8_t whiteLength ) {
if(whiteLength >= strip.numPixels()) whiteLength = strip.numPixels() - 1;
int head = whiteLength - 1;
int tail = 0;
int loops = 3;
int loopNum = 0;
static unsigned long lastTime = 0;
while(true){
for(int j=0; j<256; j++) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
if((i >= tail && i <= head) || (tail > head && i >= tail) || (tail > head && i <= head) ){
strip.setPixelColor(i, strip.Color(0,0,0, 255 ) );
}
else{
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
}
if(millis() - lastTime > whiteSpeed) {
head++;
tail++;
if(head == strip.numPixels()){
loopNum++;
}
lastTime = millis();
}
if(loopNum == loops) return;
head%=strip.numPixels();
tail%=strip.numPixels();
strip.show();
delay(wait);
}
}
}
void fullWhite() {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0,0,0, 255 ) );
}
strip.show();
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256 * 5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3,0);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3,0);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0,0);
}
uint8_t red(uint32_t c) {
return (c >> 16);
}
uint8_t green(uint32_t c) {
return (c >> 8);
}
uint8_t blue(uint32_t c) {
return (c);
}
Output Test Video:
Breadboard prototype:
Picture below shows the bread board prototype of this project. Note that the OLED display is not shown the picture below as it was added at the end of the project directly on the PCB board to make the device a much useful one to be kept on the desk.
PCB Board:
Pictures below show the General purpose PCB board on which I have mounted the components and soldered them
Note: I have used a BC547 transistor to increase the IR Blaster range on this PCB. It is optional element which you may use if you wish. This is explained in the IR Interface section in the links that I have provided.
Laser Cut Parts:
Image below: Shows the laser cut parts which I used to make the enclosure for the PCB
PCB Mounted Inside Assembled Enclosure:
Cordova Project Code:
You can download the Cordova App Zip File and edit the index.js file to replace the MQTT server that you use in the place shown in the image below to make the app work with your device which connects to your mqtt server
You have to use the same mqtt server which you use in the App, on the device also to make them communicate with each other.
Basic Arduino Code Break Down for Understanding:
Since I have explained almost all the features of the sensors and IR Blaster separately, you can see that the final code is a mixture off all that examples with MQTT connection, so I will be explaining about how I am using MQTT Library library for ESP8266 which is used to listen at send commands over particular MQTT topic mentioned in the code to listen to commands from the Android App and to Send back acknowledgements and to send intrusion alert as well as switch on AC switches which can be controlled over MQTT.
The Android App publishes on topic HacksterProjectRx to send commands to device and subscribes to topic HacksterProjectTx to receive messages from the device via the MQTT to server.
Similarly the Tx and Rx is vice versa on the device. The Device subscribes to HacksterProjectRx and publishes on HacksterProjectTx
Note: How to setup a Wi-Fi Switch is not explained in Detail in this project because it would be a separate project all together, just for reference, you may consider it as a MQTT based ESP8266 AC Switch, there a lots of projects available online. One such project's link is https://www.hackster.io/Armtronix/arduino-nodemcu-esp8266-wifi-4-relay-switch-board-2e8d7c . So consider it as publishing a command at a particular topic will turn on the light and turn off the light, which is being done from the device based on sensed data and door open and close events
The smart desk clock hardware can work in a lot of other ways based on how you code the ESP8266 to use the detected sensor values. Play around with it build much more cooler use case scenarios for building future smart homes.
I guess I have shared all the information needed to replicate this project. Just in case if you face any issues, you can type in on the comments section below, I will be ready to help.
Comments