├── Crypto_Ticker ├── Wemos SSD1306.rar ├── Wemos SSD1306 Wiring.fzz ├── Wemos SSD1306 Wiring_bb.jpg ├── SSD1306UiDemo-One-Currency │ ├── images.h │ └── SSD1306UiDemo-One-Currency.ino └── README.md ├── Chromecast_Gesture_Control ├── Schematic │ ├── Wiring Schematic.png │ ├── ADPS9960-Wemos-Breakout.rar │ └── Wemos-ADPS9960-Breakout.fzz ├── Modified Libraries │ ├── ArduCastControl-main.zip │ └── APDS-9960_Gesture_Sensor_esp8266_Library-master.zip ├── Arduino_IDE_Code │ └── ESP8266_Chromecast_Control │ │ └── ESP8266_Chromecast_Control.ino └── README.md ├── Google_Home_RF_Control ├── Wemos RF Trasnmitter and Receiver_bb.jpg └── Google_Home_RF_Control.ino ├── Neopixel_Blynk.ino ├── Dotstar_Blynk.ino ├── Wemosiotswitch.ino ├── Google-Home-NodeMCU.ino ├── AmazonEcho_Home_Automation_NodeMCU.ino ├── Alexa_and_Google_Assistant_White_LED_Strip.ino └── AmazonEcho_RGB_STRP_NodeMCU.ino /Crypto_Ticker/Wemos SSD1306.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Crypto_Ticker/Wemos SSD1306.rar -------------------------------------------------------------------------------- /Crypto_Ticker/Wemos SSD1306 Wiring.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Crypto_Ticker/Wemos SSD1306 Wiring.fzz -------------------------------------------------------------------------------- /Crypto_Ticker/Wemos SSD1306 Wiring_bb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Crypto_Ticker/Wemos SSD1306 Wiring_bb.jpg -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/Schematic/Wiring Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Chromecast_Gesture_Control/Schematic/Wiring Schematic.png -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/Schematic/ADPS9960-Wemos-Breakout.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Chromecast_Gesture_Control/Schematic/ADPS9960-Wemos-Breakout.rar -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/Schematic/Wemos-ADPS9960-Breakout.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Chromecast_Gesture_Control/Schematic/Wemos-ADPS9960-Breakout.fzz -------------------------------------------------------------------------------- /Google_Home_RF_Control/Wemos RF Trasnmitter and Receiver_bb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Google_Home_RF_Control/Wemos RF Trasnmitter and Receiver_bb.jpg -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/Modified Libraries/ArduCastControl-main.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Chromecast_Gesture_Control/Modified Libraries/ArduCastControl-main.zip -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/Modified Libraries/APDS-9960_Gesture_Sensor_esp8266_Library-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/iotwemos/HEAD/Chromecast_Gesture_Control/Modified Libraries/APDS-9960_Gesture_Sensor_esp8266_Library-master.zip -------------------------------------------------------------------------------- /Neopixel_Blynk.ino: -------------------------------------------------------------------------------- 1 | 2 | //*************************************************************************************** 3 | // Code for Controlling Neopixel LEDs using Blynk App 4 | // Written by Sid for Sid's E Classroom 5 | // https://www.youtube.com/c/SidsEClassroom 6 | // All text above must be included in any redistribution. 7 | // If you find this useful and want to make a donation -> https://paypal.me/sidsclass 8 | // *************************************************************************************** 9 | #define BLYNK_PRINT Serial 10 | #include 11 | #include 12 | #include 13 | 14 | // You should get Auth Token in the Blynk App. 15 | // Go to the Project Settings (nut icon). 16 | char auth[] = "ENETR YOUR BLYNK KEY HERE"; 17 | 18 | // Your WiFi credentials. 19 | // Set password to "" for open networks. 20 | char ssid[] = "ENTER YOUR WIFI SSID HERE"; 21 | char pass[] = "ENTER YOUR WIFI PASSWORD HERE"; 22 | 23 | //Pin and Strip declaration 24 | #define PIN D8 25 | #define NUMPIXELS 30 26 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); 27 | 28 | //Initialize all the colours to 0 29 | int color_r = 0, color_g = 0, color_b = 0; 30 | uint32_t color = 0xFF0000; 31 | 32 | //Create three sliders or use the Horse RGB Widget and connect to Virtual Pin 1, 2 and 3 for Red, Blue and Green respectively 33 | BLYNK_WRITE(1) { 34 | color_r = param.asInt(); 35 | } 36 | BLYNK_WRITE(2) { 37 | color_g = param.asInt(); 38 | } 39 | BLYNK_WRITE(3) { 40 | color_b = param.asInt(); 41 | } 42 | 43 | void setup() 44 | { 45 | // Debug console 46 | Serial.begin(9600); 47 | 48 | Blynk.begin(auth, ssid, pass); 49 | // You can also specify server: 50 | //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80); 51 | //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080); 52 | 53 | strip.begin(); 54 | strip.show(); 55 | } 56 | 57 | void loop() { 58 | Blynk.run(); //Start Blynk 59 | //Set pixels to a colour 60 | for (int i = 0; i < NUMPIXELS; i++) { 61 | strip.setPixelColor(i, color); 62 | } 63 | strip.show(); 64 | color <<= 8; 65 | color |= color_r; 66 | color <<= 8; 67 | color |= color_g; 68 | color <<= 8; 69 | color |= color_b; 70 | } 71 | -------------------------------------------------------------------------------- /Dotstar_Blynk.ino: -------------------------------------------------------------------------------- 1 | 2 | //*************************************************************************************** 3 | // Code for Controlling Dotstar LEDs using Blynk App 4 | // Written by Sid for Sid's E Classroom 5 | // https://www.youtube.com/c/SidsEClassroom 6 | // All text above must be included in any redistribution. 7 | // If you find this useful and want to make a donation -> https://paypal.me/sidsclass 8 | // *************************************************************************************** 9 | #define BLYNK_PRINT Serial 10 | #include 11 | #include 12 | #include 13 | 14 | // You should get Auth Token in the Blynk App. 15 | // Go to the Project Settings (nut icon). 16 | char auth[] = "ENETR YOUR BLYNK KEY HERE"; 17 | 18 | // Your WiFi credentials. 19 | // Set password to "" for open networks. 20 | char ssid[] = "ENTER YOUR WIFI SSID HERE"; 21 | char pass[] = "ENTER YOUR WIFI PASSWORD HERE"; 22 | 23 | //Pin and Strip declaration 24 | #define NUMPIXELS 30 25 | #define DATAPIN D7 26 | #define CLOCKPIN D5 27 | Adafruit_DotStar strip(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_GRB); 28 | 29 | //Initialize all the colours to 0 30 | int color_r = 0, color_g = 0, color_b = 0; 31 | uint32_t color = 0xFF0000; 32 | 33 | //Create three sliders or use the Horse RGB Widget and connect to Virtual Pin 1, 2 and 3 for Red, Blue and Green respectively 34 | BLYNK_WRITE(1) { 35 | color_r = param.asInt(); 36 | } 37 | BLYNK_WRITE(2) { 38 | color_g = param.asInt(); 39 | } 40 | BLYNK_WRITE(3) { 41 | color_b = param.asInt(); 42 | } 43 | 44 | void setup() 45 | { 46 | // Debug console 47 | Serial.begin(9600); 48 | 49 | Blynk.begin(auth, ssid, pass); 50 | // You can also specify server: 51 | //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80); 52 | //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080); 53 | 54 | strip.begin(); 55 | strip.show(); 56 | } 57 | 58 | void loop() { 59 | Blynk.run(); //Start Blynk 60 | //Set pixels to a colour 61 | for (int i = 0; i < NUMPIXELS; i++) { 62 | strip.setPixelColor(i, color); 63 | } 64 | strip.show(); 65 | //Get value from the color wheel 66 | color <<= 8; 67 | color |= color_r; 68 | color <<= 8; 69 | color |= color_g; 70 | color <<= 8; 71 | color |= color_b; 72 | } 73 | -------------------------------------------------------------------------------- /Wemosiotswitch.ino: -------------------------------------------------------------------------------- 1 | //https://www.youtube.com/c/SidsEClassroom 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | const char* ssid = "******"; //Set your wifi network name(ssid) 8 | const char* password = "*******"; //Set your router password 9 | 10 | int RelayPin = D1; //Relay Shield is controlled by pin D1 11 | WiFiServer server(80); 12 | 13 | void setup() { 14 | Serial.begin(115200); //change according to your com port baud rate 15 | delay(10); 16 | 17 | 18 | pinMode(RelayPin, OUTPUT); 19 | digitalWrite(RelayPin, LOW); 20 | 21 | // Connect to WiFi network 22 | Serial.println(); 23 | Serial.println(); 24 | Serial.print("Connecting to "); 25 | Serial.println(ssid); 26 | 27 | WiFi.mode(WIFI_STA); 28 | WiFi.begin(ssid, password); 29 | 30 | while (WiFi.status() != WL_CONNECTED) { 31 | delay(500); 32 | Serial.print("."); 33 | } 34 | Serial.println(""); 35 | Serial.println("WiFi connected"); 36 | 37 | // Start the server 38 | server.begin(); 39 | Serial.println("Server started"); 40 | 41 | // Print the IP address 42 | Serial.print("Use this URL : "); 43 | Serial.print("http://"); 44 | Serial.print(WiFi.localIP()); 45 | Serial.println("/"); 46 | } 47 | 48 | 49 | void loop() { 50 | 51 | 52 | // Check for an active client 53 | WiFiClient client = server.available(); 54 | if (!client) { 55 | return; 56 | } 57 | 58 | // Wait until client responds 59 | Serial.println("new client"); 60 | while(!client.available()){ 61 | delay(1); 62 | } 63 | 64 | // Read client request 65 | String request = client.readStringUntil('\r'); 66 | Serial.println(request); 67 | client.flush(); 68 | 69 | // Match the request 70 | 71 | int value = LOW; 72 | if (request.indexOf("/Relay=ON") != -1) { 73 | digitalWrite(RelayPin, HIGH); 74 | value = HIGH; 75 | } 76 | if (request.indexOf("/Relay=OFF") != -1){ 77 | digitalWrite(RelayPin, LOW); 78 | value = LOW; 79 | } 80 | 81 | 82 | 83 | // Return the client response 84 | client.println("HTTP/1.1 200 OK"); 85 | client.println("Content-Type: text/html"); 86 | client.println(""); // do not forget this one 87 | client.println(""); 88 | client.println(""); 89 | 90 | client.print("Relay pin is now: "); 91 | 92 | if(value == HIGH) { 93 | client.print("On"); 94 | } else { 95 | client.print("Off"); 96 | } 97 | client.println("

"); 98 | client.println("Click here to turn the Relay ON
"); 99 | client.println("Click here to turn the Relay OFF
"); 100 | client.println(""); 101 | 102 | delay(1); 103 | Serial.println("Client disconnected"); 104 | Serial.println(""); 105 | 106 | } 107 | -------------------------------------------------------------------------------- /Google-Home-NodeMCU.ino: -------------------------------------------------------------------------------- 1 | //https://www.youtube.com/c/SidsEClassroom 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | const char* ssid = "*********"; //Set your wifi network name(ssid) 8 | const char* password = "************"; //Set your router password 9 | 10 | int Device1 = D1; 11 | int Device2 = D2; 12 | int Device3 = D3; 13 | WiFiServer server(80); 14 | 15 | void setup() { 16 | Serial.begin(115200); //change according to your com port baud rate 17 | delay(10); 18 | 19 | //Declare device pins 20 | pinMode(Device1, OUTPUT); 21 | digitalWrite(Device1, LOW); 22 | pinMode(Device2, OUTPUT); 23 | digitalWrite(Device2, LOW); 24 | pinMode(Device3, OUTPUT); 25 | digitalWrite(Device3, LOW); 26 | 27 | 28 | // Connect to WiFi network 29 | Serial.println(); 30 | Serial.println(); 31 | Serial.print("Connecting to "); 32 | Serial.println(ssid); 33 | 34 | WiFi.mode(WIFI_STA); 35 | WiFi.begin(ssid, password); 36 | 37 | while (WiFi.status() != WL_CONNECTED) { 38 | delay(500); 39 | Serial.print("."); 40 | } 41 | Serial.println(""); 42 | Serial.println("WiFi connected"); 43 | 44 | // Start the server 45 | server.begin(); 46 | Serial.println("Server started"); 47 | 48 | // Print the IP address 49 | Serial.print("Use this URL : "); 50 | Serial.print("http://"); 51 | Serial.print(WiFi.localIP()); 52 | Serial.println("/"); 53 | } 54 | 55 | 56 | void loop() { 57 | 58 | 59 | // Check for an active client 60 | WiFiClient client = server.available(); 61 | if (!client) { 62 | return; 63 | } 64 | 65 | // Wait until client responds 66 | Serial.println("new client"); 67 | while (!client.available()) { 68 | delay(1); 69 | } 70 | 71 | // Read client request 72 | String request = client.readStringUntil('\r'); 73 | Serial.println(request); 74 | client.flush(); 75 | 76 | // Check device request 77 | if (request.indexOf("/Device1=ON") != -1) { 78 | digitalWrite(Device1, HIGH); 79 | } 80 | if (request.indexOf("/Device1=OFF") != -1) { 81 | digitalWrite(Device1, LOW); 82 | } 83 | if (request.indexOf("/Device2=ON") != -1) { 84 | digitalWrite(Device2, HIGH); 85 | } 86 | if (request.indexOf("/Device2=OFF") != -1) { 87 | digitalWrite(Device2, LOW); 88 | } 89 | if (request.indexOf("/Device3=ON") != -1) { 90 | digitalWrite(Device3, HIGH); 91 | } 92 | if (request.indexOf("/Device3=OFF") != -1) { 93 | digitalWrite(Device3, LOW); 94 | } 95 | 96 | // Return the client response 97 | client.println("HTTP/1.1 200 OK"); 98 | client.println("Content-Type: text/html"); 99 | client.println(""); // do not forget this one 100 | client.println(""); 101 | client.println(""); 102 | 103 | //HTML code for controling devices from browser 104 | client.println("

"); 105 | client.println("Device 1: ON and OFF
"); 106 | client.println("
"); 107 | client.println("Device 2: ON and OFF
"); 108 | client.println("
"); 109 | client.println("Device 3: ON and OFF
"); 110 | client.println("
"); 111 | client.println(""); 112 | client.println(""); 113 | 114 | delay(1); 115 | Serial.println("Client disconnected"); 116 | Serial.println(""); 117 | 118 | } 119 | -------------------------------------------------------------------------------- /AmazonEcho_Home_Automation_NodeMCU.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************************** 2 | * Code for controlling multiple devices connected to one NodeMCU using Amazon Echo 3 | * 4 | * Written by Sid for Sid's E Classroom 5 | * 6 | * https://www.youtube.com/c/SidsEClassroom 7 | *********************************************************************************/ 8 | #include 9 | #include 10 | #include "fauxmoESP.h" 11 | 12 | #define WIFI_SSID "**********"//change your Wifi name 13 | #define WIFI_PASS "*********"//Change your Wifi Password 14 | #define SERIAL_BAUDRATE 115200 15 | 16 | fauxmoESP fauxmo; 17 | //declare switching pins 18 | //Change pins according to your NodeMCU pinouts 19 | #define Kitchen D1 20 | #define Bedroom D2 21 | #define Living D3 22 | 23 | // ----------------------------------------------------------------------------- 24 | // Wifi Setup 25 | // ----------------------------------------------------------------------------- 26 | 27 | void wifiSetup() { 28 | 29 | // Set WIFI module to STA mode 30 | WiFi.mode(WIFI_STA); 31 | 32 | // Connect 33 | Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID); 34 | WiFi.begin(WIFI_SSID, WIFI_PASS); 35 | 36 | // Wait 37 | while (WiFi.status() != WL_CONNECTED) { 38 | Serial.print("."); 39 | delay(100); 40 | } 41 | Serial.println(); 42 | 43 | // Connected! 44 | Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str()); 45 | } 46 | 47 | void setup() { 48 | //Initialize pins to Low on device start 49 | pinMode(Kitchen, OUTPUT); 50 | digitalWrite(Kitchen, LOW); 51 | pinMode(Bedroom, OUTPUT); 52 | digitalWrite(Bedroom, LOW); 53 | pinMode(Living, OUTPUT); 54 | digitalWrite(Living, LOW); 55 | 56 | // Init serial port and clean garbage 57 | Serial.begin(SERIAL_BAUDRATE); 58 | Serial.println("FauxMo demo sketch"); 59 | Serial.println("After connection, ask Alexa/Echo to 'turn on' or 'off'"); 60 | 61 | // Wifi 62 | wifiSetup(); 63 | 64 | // By default, fauxmoESP creates it's own webserver on the defined port 65 | // The TCP port must be 80 for gen3 devices (default is 1901) 66 | // This has to be done before the call to enable() 67 | fauxmo.createServer(true); // not needed, this is the default value 68 | fauxmo.setPort(80); // This is required for gen3 devices 69 | 70 | // You have to call enable(true) once you have a WiFi connection 71 | // You can enable or disable the library at any moment 72 | // Disabling it will prevent the devices from being discovered and switched 73 | fauxmo.enable(true); 74 | 75 | // Device Names for Simulated Wemo switches 76 | fauxmo.addDevice("Living Room Lights"); 77 | fauxmo.addDevice("Kitchen Lights"); 78 | fauxmo.addDevice("Bedroom Lights"); 79 | 80 | 81 | // ----------------------------------------------------------------------------- 82 | // Device Callback 83 | // ----------------------------------------------------------------------------- 84 | 85 | fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) { 86 | 87 | // Callback when a command from Alexa is received. 88 | // You can use device_id or device_name to choose the element to perform an action onto (relay, LED,...) 89 | // State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say "set kitchen light to 50%" you will receive a 128 here). 90 | // Just remember not to delay too much here, this is a callback, exit as soon as possible. 91 | // If you have to do something more involved here set a flag and process it in your main loop. 92 | 93 | Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value); 94 | 95 | // Checking for device_id is simpler if you are certain about the order they are loaded and it does not change. 96 | // Otherwise comparing the device_name is safer. 97 | 98 | if (strcmp(device_name, "Living Room Lights")==0) { 99 | digitalWrite(Living, state ? HIGH : LOW); 100 | } else if (strcmp(device_name, "Kitchen Lights")==0) { 101 | digitalWrite(Kitchen, state ? HIGH : LOW); 102 | } else if (strcmp(device_name, "Bedroom Lights")==0) { 103 | digitalWrite(Bedroom, state ? HIGH : LOW); 104 | } 105 | }); 106 | } 107 | 108 | void loop() { 109 | fauxmo.handle(); 110 | static unsigned long last = millis(); 111 | if (millis() - last > 5000) { 112 | last = millis(); 113 | Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap()); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Crypto_Ticker/SSD1306UiDemo-One-Currency/images.h: -------------------------------------------------------------------------------- 1 | #define Currency_Logo_width 60 2 | #define Currency_Logo_height 60 3 | const uint8_t Currency_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 5 | 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x03, 0x00, 0x00, 6 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 7 | 0xFF, 0x3F, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 8 | 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 9 | 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0xFF, 0xFF, 0x1F, 0x00, 0xC0, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0x3F, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0xFF, 0x1F, 13 | 0xC7, 0xFF, 0x7F, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0xC7, 0xFF, 0xFF, 0x00, 14 | 0xF0, 0xFF, 0x1F, 0x0F, 0xC3, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0x1F, 0x88, 15 | 0xC3, 0xFF, 0xFF, 0x01, 0xF8, 0xFF, 0x1F, 0x00, 0xE3, 0xFF, 0xFF, 0x01, 16 | 0xFC, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0xFF, 0x03, 0xFC, 0xFF, 0xFF, 0x00, 17 | 0x80, 0xFF, 0xFF, 0x03, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x07, 18 | 0xFE, 0xFF, 0xFF, 0xC0, 0x00, 0xFC, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0xC0, 19 | 0x07, 0xF8, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0xC0, 0x0F, 0xF8, 0xFF, 0x07, 20 | 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xF8, 0xFF, 0x07, 0xFF, 0xFF, 0x7F, 0xE0, 21 | 0x1F, 0xF0, 0xFF, 0x0F, 0xFF, 0xFF, 0x7F, 0xE0, 0x1F, 0xF8, 0xFF, 0x0F, 22 | 0xFF, 0xFF, 0x7F, 0xE0, 0x0F, 0xF8, 0xFF, 0x0F, 0xFF, 0xFF, 0x3F, 0x00, 23 | 0x02, 0xF8, 0xFF, 0x0F, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 24 | 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x0F, 0xFF, 0xFF, 0x3F, 0x70, 25 | 0x00, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0x3F, 0xF0, 0x03, 0xFE, 0xFF, 0x0F, 26 | 0xFF, 0xFF, 0x1F, 0xF8, 0x07, 0xFC, 0xFF, 0x0F, 0xFF, 0xFF, 0x1F, 0xF8, 27 | 0x0F, 0xF8, 0xFF, 0x0F, 0xFE, 0xFF, 0x1F, 0xF8, 0x0F, 0xF8, 0xFF, 0x07, 28 | 0xFE, 0xFF, 0x01, 0xFC, 0x0F, 0xF8, 0xFF, 0x07, 0xFE, 0xFF, 0x00, 0xFC, 29 | 0x0F, 0xF8, 0xFF, 0x07, 0xFE, 0xFF, 0x00, 0xF0, 0x07, 0xFC, 0xFF, 0x07, 30 | 0xFE, 0x7F, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x03, 0xFC, 0xFF, 0x0F, 0x00, 31 | 0x00, 0xFC, 0xFF, 0x03, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x03, 32 | 0xF8, 0xFF, 0x3F, 0x06, 0x00, 0xFF, 0xFF, 0x01, 0xF8, 0xFF, 0x1F, 0x86, 33 | 0xE1, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0x1F, 0x87, 0xFF, 0xFF, 0xFF, 0x00, 34 | 0xF0, 0xFF, 0x1F, 0xC7, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0x1F, 0xC7, 35 | 0xFF, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x3F, 0x00, 36 | 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 37 | 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 38 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 39 | 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 40 | 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 41 | 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 42 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 43 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x07, 0x00, 0x00, 0x00, 44 | }; 45 | 46 | const uint8_t activeSymbol[] PROGMEM = { 47 | B00000000, 48 | B00000000, 49 | B00011000, 50 | B00100100, 51 | B01000010, 52 | B01000010, 53 | B00100100, 54 | B00011000 55 | }; 56 | 57 | const uint8_t inactiveSymbol[] PROGMEM = { 58 | B00000000, 59 | B00000000, 60 | B00000000, 61 | B00000000, 62 | B00011000, 63 | B00011000, 64 | B00000000, 65 | B00000000 66 | }; 67 | 68 | #define Arrow_Logo_width 30 69 | #define Arrow_Logo_height 30 70 | 71 | const uint8_t Down_Arrow_bits[] PROGMEM = { 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x01, 0xF0, 0x00, 0x80, 0x03, 74 | 0xF0, 0x01, 0xE0, 0x03, 0xE0, 0x01, 0xF0, 0x01, 0xC0, 0x03, 0xF0, 0x00, 75 | 0x80, 0x0F, 0x7C, 0x00, 0x00, 0x1F, 0x3E, 0x00, 0x00, 0x3E, 0x1F, 0x00, 76 | 0x00, 0xBC, 0x0F, 0x00, 0x20, 0xF8, 0x07, 0x01, 0xF0, 0xF0, 0xC3, 0x03, 77 | 0xF0, 0xE0, 0xC1, 0x03, 0xE0, 0x43, 0xE0, 0x01, 0xC0, 0x03, 0xF8, 0x00, 78 | 0x80, 0x0F, 0x78, 0x00, 0x00, 0x1F, 0x3E, 0x00, 0x00, 0x1E, 0x1F, 0x00, 79 | 0x00, 0x7C, 0x0F, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0xF0, 0x03, 0x00, 80 | 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | }; 83 | 84 | const uint8_t Up_Arrow_bits[] PROGMEM = { 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 87 | 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x3C, 0x0F, 0x00, 88 | 0x00, 0x3E, 0x1F, 0x00, 0x00, 0x1F, 0x3C, 0x00, 0x80, 0x0F, 0x7C, 0x00, 89 | 0xC0, 0x03, 0xF0, 0x00, 0xE0, 0x83, 0xF0, 0x01, 0xF0, 0xE1, 0xC1, 0x03, 90 | 0x70, 0xF0, 0x83, 0x03, 0x20, 0xF8, 0x07, 0x01, 0x00, 0x7C, 0x0F, 0x00, 91 | 0x00, 0x3E, 0x1F, 0x00, 0x00, 0x1F, 0x3E, 0x00, 0x80, 0x0F, 0x7C, 0x00, 92 | 0xC0, 0x07, 0xF8, 0x00, 0xE0, 0x01, 0xE0, 0x01, 0xF0, 0x01, 0xE0, 0x03, 93 | 0x70, 0x00, 0xC0, 0x03, 0x60, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | }; 96 | -------------------------------------------------------------------------------- /Google_Home_RF_Control/Google_Home_RF_Control.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | Adafruit MQTT Library ESP8266 Example 3 | 4 | Must use ESP8266 Arduino from: 5 | https://github.com/esp8266/Arduino 6 | 7 | Works great with Adafruit's Huzzah ESP board & Feather 8 | ----> https://www.adafruit.com/product/2471 9 | ----> https://www.adafruit.com/products/2821 10 | 11 | Adafruit invests time and resources providing this open source code, 12 | please support Adafruit and open-source hardware by purchasing 13 | products from Adafruit! 14 | 15 | Written by Tony DiCola for Adafruit Industries. 16 | MIT license, all text above must be included in any redistribution 17 | ****************************************************/ 18 | 19 | /******************************************************************** 20 | Modified by Sid for Sid's E Classroom 21 | https://www.youtube.com/c/SidsEClassroom 22 | ********************************************************************/ 23 | 24 | #include 25 | #include "Adafruit_MQTT.h" 26 | #include "Adafruit_MQTT_Client.h" 27 | #include 28 | 29 | 30 | //Change the pins according to the choice of your board 31 | //Get the pin maps from this link https://escapequotes.net/esp8266-wemos-d1-mini-pins-and-diagram/ for Wemos 32 | #define RCPIN 0 //Corresponds to D3 on Wemos D1 33 | 34 | 35 | /************************* WiFi Access Point *********************************/ 36 | 37 | #define WLAN_SSID "**********" //Change accordingly 38 | #define WLAN_PASS "**********" //Change accordingly 39 | 40 | /************************* Adafruit.io Setup *********************************/ 41 | 42 | #define AIO_SERVER "io.adafruit.com" 43 | #define AIO_SERVERPORT 1883 // use 8883 for SSL 44 | //Add your Adafruit.IO username and key. It can be found under settings tab 45 | #define AIO_USERNAME "********************" 46 | #define AIO_KEY "********************" 47 | 48 | 49 | /************ Global State (you don't need to change this!) ******************/ 50 | 51 | // Create an ESP8266 WiFiClient class to connect to the MQTT server. 52 | WiFiClient client; 53 | // or... use WiFiFlientSecure for SSL 54 | //WiFiClientSecure client; 55 | 56 | // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. 57 | Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); 58 | 59 | /****************************** Feeds ***************************************/ 60 | 61 | // Notice MQTT paths for AIO follow the form: /feeds/ 62 | // Setup a feed for subscribing to changes. 63 | //Change "/feeds/AlexaAndHome" to "/feeds/YOUR_FEED_NAME" 64 | Adafruit_MQTT_Subscribe FEEDNAME = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/AlexaAndHome"); 65 | 66 | /****************************** RC Switch ***************************************/ 67 | RCSwitch mySwitch = RCSwitch(); 68 | /*************************** Sketch Code ************************************/ 69 | 70 | // Bug workaround for Arduino 1.6.6, it seems to need a function declaration 71 | // for some reason (only affects ESP8266, likely an arduino-builder bug). 72 | void MQTT_connect(); 73 | 74 | void setup() { 75 | Serial.begin(115200); 76 | delay(10); 77 | 78 | mySwitch.enableTransmit(RCPIN); 79 | // Optional set pulse length. 80 | // mySwitch.setPulseLength(320); 81 | 82 | // Optional set protocol (default is 1, will work for most outlets) 83 | // mySwitch.setProtocol(2); 84 | 85 | // Optional set number of transmission repetitions. 86 | // mySwitch.setRepeatTransmit(15); 87 | 88 | 89 | Serial.println(F("Adafruit MQTT demo")); 90 | 91 | // Connect to WiFi access point. 92 | Serial.println(); Serial.println(); 93 | Serial.print("Connecting to "); 94 | Serial.println(WLAN_SSID); 95 | 96 | WiFi.begin(WLAN_SSID, WLAN_PASS); 97 | while (WiFi.status() != WL_CONNECTED) { 98 | delay(500); 99 | Serial.print("."); 100 | } 101 | Serial.println(); 102 | 103 | Serial.println("WiFi connected"); 104 | Serial.println("IP address: "); Serial.println(WiFi.localIP()); 105 | 106 | // Setup MQTT subscription for onoff feed. 107 | mqtt.subscribe(&FEEDNAME); 108 | 109 | } 110 | 111 | uint32_t x = 0; 112 | 113 | void loop() { 114 | // Ensure the connection to the MQTT server is alive (this will make the first 115 | // connection and automatically reconnect when disconnected). See the MQTT_connect 116 | // function definition further below. 117 | MQTT_connect(); 118 | 119 | // this is our 'wait for incoming subscription packets' busy subloop 120 | // try to spend your time here 121 | 122 | Adafruit_MQTT_Subscribe *subscription; 123 | while ((subscription = mqtt.readSubscription(5000))) { 124 | 125 | 126 | if (subscription == &FEEDNAME) { 127 | Serial.print(F("Got from your Feed: ")); 128 | 129 | Serial.println((char *)FEEDNAME.lastread); 130 | 131 | if (strcmp((char *)FEEDNAME.lastread, "on monitor") == 0) { 132 | mySwitch.send(13911311, 24); 133 | } 134 | if (strcmp((char *)FEEDNAME.lastread, "off monitor") == 0) { 135 | mySwitch.send(13911310, 24); 136 | } 137 | 138 | } 139 | 140 | } 141 | } 142 | // ping the server to keep the mqtt connection alive 143 | // NOT required if you are publishing once every KEEPALIVE seconds 144 | /* 145 | if(! mqtt.ping()) { 146 | mqtt.disconnect(); 147 | } 148 | */ 149 | 150 | // Function to connect and reconnect as necessary to the MQTT server. 151 | // Should be called in the loop function and it will take care if connecting. 152 | void MQTT_connect() { 153 | int8_t ret; 154 | 155 | // Stop if already connected. 156 | if (mqtt.connected()) { 157 | return; 158 | } 159 | 160 | Serial.print("Connecting to MQTT... "); 161 | 162 | uint8_t retries = 3; 163 | while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected 164 | Serial.println(mqtt.connectErrorString(ret)); 165 | Serial.println("Retrying MQTT connection in 5 seconds..."); 166 | mqtt.disconnect(); 167 | delay(5000); // wait 5 seconds 168 | retries--; 169 | if (retries == 0) { 170 | // basically die and wait for WDT to reset me 171 | while (1); 172 | } 173 | } 174 | Serial.println("MQTT Connected!"); 175 | } 176 | -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/Arduino_IDE_Code/ESP8266_Chromecast_Control/ESP8266_Chromecast_Control.ino: -------------------------------------------------------------------------------- 1 | //**********************Putogether by Sid for Sid's E Classroom**************************** 2 | //**********************https://www.youtube.com/c/SidsEClassroom*************************** 3 | //*************************https://github.com/shivasiddharth******************************* 4 | //*************************Do not modify or remove this part******************************* 5 | //************If you are modifying or re-using the code, credit the the author************* 6 | 7 | //***************************************************************************************** 8 | // *********************************Libraries Used***************************************** 9 | // ArduinoJson : version=6.18.5 10 | // Arduino_JSON : version=0.1.0 11 | // Modified Sparkfun APDS9960 : Zip file in Git 12 | // Modified ArduCastControl : Zip file in Git 13 | // SnappyProto : version=0.1.2 14 | //***************************************************************************************** 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "ArduCastControl.h" 24 | 25 | // Pins on wemos D1 mini 26 | #define APDS9960_SDA 4 //GPIO4 (D2) 27 | #define APDS9960_SCL 5 //GPIO5 (D1) 28 | // Constants 29 | const byte APDS9960_INT = 12; //GPIO12 (D6) 30 | #define STATUS_LED 13 //GPIO13 (D7) 31 | 32 | // Global Variables 33 | SparkFun_APDS9960 apds = SparkFun_APDS9960(); 34 | volatile bool isr_flag = 0; 35 | 36 | //Interrupt callback function in IRAM 37 | void ICACHE_RAM_ATTR interruptRoutine (); 38 | 39 | #define CHROMECASTIP "ENTER YOUR CHROMECAST's IP HERE" 40 | 41 | const char* ssid = "WiFI SSID"; 42 | const char* password = "WIFi Password"; 43 | 44 | ArduCastControl cc = ArduCastControl(); 45 | 46 | void setup() { 47 | 48 | //Start I2C with pins defined above 49 | Wire.begin(APDS9960_SDA, APDS9960_SCL); 50 | 51 | // Set interrupt pin as input 52 | pinMode(digitalPinToInterrupt(APDS9960_INT), INPUT); 53 | pinMode(STATUS_LED, OUTPUT); 54 | 55 | // Initialize Serial port 56 | Serial.begin(115200); 57 | WiFi.mode(WIFI_STA); 58 | WiFi.disconnect(); 59 | delay(10); 60 | WiFi.begin(ssid, password); 61 | Serial.print("Connecting to WiFi..."); 62 | while (WiFi.status() != WL_CONNECTED) { 63 | delay(500); 64 | Serial.print("."); 65 | } 66 | delay(1000); 67 | Serial.print("\nConnected to: "); 68 | Serial.println(ssid); 69 | Serial.print("IP address: "); 70 | Serial.println(WiFi.localIP()); 71 | Serial.println(""); 72 | 73 | ArduinoOTA.setHostname ("chromecastremote"); 74 | ArduinoOTA.begin(); 75 | Serial.println(); 76 | Serial.println(F("--------------------------------")); 77 | Serial.println(F("Chromecast----Gesture Controller")); 78 | Serial.println(F("--------------------------------")); 79 | 80 | // Initialize interrupt service routine 81 | attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING); 82 | 83 | // Initialize APDS-9960 (configure I2C and initial values) 84 | if ( apds.init() ) { 85 | Serial.println(F("APDS-9960 initialization complete")); 86 | } else { 87 | Serial.println(F("Something went wrong during APDS-9960 init!")); 88 | } 89 | 90 | // Start running the APDS-9960 gesture sensor engine 91 | if ( apds.enableGestureSensor(true) ) { 92 | Serial.println(F("Gesture sensor is now running")); 93 | } else { 94 | Serial.println(F("Something went wrong during gesture sensor init!")); 95 | } 96 | } 97 | 98 | uint32_t lastUpdated = 0; 99 | uint32_t updatePeriod = 5000; 100 | 101 | uint32_t bLastUpdated = 0; 102 | uint32_t bUpdatePeriod = 25; 103 | 104 | void loop() { 105 | if (WiFi.status() != WL_CONNECTED) { 106 | Serial.println(F("WiFI disconnected.....")); 107 | digitalWrite(STATUS_LED, !digitalRead(STATUS_LED)); 108 | delay(1000); 109 | 110 | } 111 | else if (WiFi.status() == WL_CONNECTED) { 112 | ArduinoOTA.handle(); 113 | //wait for 5s to boot - this is useful in case of a bootloop to keep OTA running 114 | if ( millis() < 10000 ) 115 | return; 116 | 117 | if ( millis() - lastUpdated > updatePeriod ) { 118 | if ( cc.getConnection() != WAIT_FOR_RESPONSE ) { 119 | cc.dumpStatus(); 120 | } 121 | int st; 122 | 123 | if ( cc.getConnection() == DISCONNECTED ) { 124 | Serial.print("Connecting..."); 125 | st = cc.connect(CHROMECASTIP); 126 | Serial.println(st); 127 | } else { 128 | //at this point, cc.volume and cc.isMuted should be valid 129 | connection_t c = cc.loop(); 130 | if ( c == WAIT_FOR_RESPONSE || c == CONNECT_TO_APPLICATION ) { 131 | updatePeriod = 50; 132 | } else if ( c == APPLICATION_RUNNING ) { 133 | updatePeriod = 500; 134 | //at this point, all public fields describing the casting 135 | //(e.g. cc.artist, cc.title) should be valid 136 | } else { 137 | updatePeriod = 5000; 138 | } 139 | } 140 | lastUpdated = millis(); 141 | digitalWrite(STATUS_LED, !digitalRead(STATUS_LED)); 142 | } 143 | if ( millis() - bLastUpdated > bUpdatePeriod && cc.getConnection() == APPLICATION_RUNNING ) { 144 | if ( isr_flag == 1 ) { 145 | detachInterrupt(digitalPinToInterrupt(APDS9960_INT)); 146 | handleGesture(); 147 | isr_flag = 0; 148 | attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING); 149 | } 150 | digitalWrite(STATUS_LED, !digitalRead(STATUS_LED)); 151 | bLastUpdated = millis(); 152 | } 153 | } 154 | } 155 | 156 | void interruptRoutine() { 157 | isr_flag = 1; 158 | } 159 | 160 | void handleGesture() { 161 | if ( apds.isGestureAvailable() ) { 162 | switch ( apds.readGesture() ) { 163 | case DIR_UP: 164 | Serial.println("UP"); 165 | cc.setVolume(true, 0.1); 166 | break; 167 | case DIR_DOWN: 168 | Serial.println("DOWN"); 169 | cc.setVolume(true, -0.1); 170 | break; 171 | case DIR_LEFT: 172 | Serial.println("LEFT"); 173 | cc.seek(true, -10); 174 | break; 175 | case DIR_RIGHT: 176 | Serial.println("RIGHT"); 177 | cc.seek(true, 10); 178 | break; 179 | case DIR_NEAR: 180 | Serial.println("NEAR"); 181 | cc.setMute(true, true); 182 | break; 183 | case DIR_FAR: 184 | Serial.println("FAR"); 185 | cc.pause(true); 186 | break; 187 | default: 188 | Serial.println("NONE"); 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /Alexa_and_Google_Assistant_White_LED_Strip.ino: -------------------------------------------------------------------------------- 1 | //************************Written by Sid for Sid's E Classroom***************************** 2 | //**********************https://www.youtube.com/c/SidsEClassroom*************************** 3 | //*************************https://github.com/shivasiddharth******************************* 4 | //*************************Do not modify or remove this part******************************* 5 | //************If you are modifying or re-using the code, credit the the author************* 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "fauxmoESP.h" 16 | #include 17 | 18 | 19 | 20 | fauxmoESP fauxmo; 21 | 22 | // On a Trinket or Gemma we suggest changing this to 1: 23 | //Pin is set for Wemos. If using any other board, change it accordingly. 24 | #define LED_PIN D6 25 | 26 | // How many NeoPixels are attached to the Arduino? 27 | #define LED_COUNT 12 28 | 29 | // Declare NeoPixel strip object: 30 | Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); 31 | // Argument 1 = Number of pixels in NeoPixel strip 32 | // Argument 2 = Arduino pin number (most are valid) 33 | // Argument 3 = Pixel type flags, add together as needed: 34 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 35 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 36 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 37 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 38 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 39 | 40 | //EEPROM address definition 41 | #define Start_Address 0 42 | #define Bri_Address Start_Address + sizeof(int) 43 | 44 | //Firebase Database URL and KEY 45 | #define FIREBASE_DATABASE_URL "ENTER YOUR DATABASE URL HERE" 46 | #define FIREBASE_KEY "ENTER YOUR FIREBASE KEY HERE" 47 | 48 | //Set the ID to the device id used in the index.json file 49 | static const String STRMDEVID = "2"; 50 | 51 | //Variables for brightness and state 52 | bool onstate; 53 | int bri; 54 | bool alexachange; 55 | 56 | //Set the light name to your desired value 57 | #define LIGHTNAME "Corridor Light" 58 | 59 | void setup() { 60 | 61 | Serial.begin(115200); 62 | EEPROM.begin(256); 63 | EEPROM.get(Bri_Address, bri); 64 | strip.begin(); 65 | strip.fill(0xFFFFFF); 66 | strip.setBrightness(bri); 67 | strip.show(); 68 | Serial.println("Current value: " + String(bri)); 69 | 70 | //WiFi Manager 71 | WiFiManager wifiManager; 72 | wifiManager.autoConnect(); 73 | Serial.println("Connected.."); 74 | // By default, fauxmoESP creates it's own webserver on the defined port 75 | // The TCP port must be 80 for gen3 devices (default is 1901) 76 | // This has to be done before the call to enable() 77 | fauxmo.createServer(true); // not needed, this is the default value 78 | fauxmo.setPort(80); // This is required for gen3 devices 79 | 80 | // You have to call enable(true) once you have a WiFi connection 81 | // You can enable or disable the library at any moment 82 | // Disabling it will prevent the devices from being discovered and switched 83 | fauxmo.enable(true); 84 | 85 | //Replace the following light name with a desired name of yours 86 | fauxmo.addDevice("Simulated Light"); 87 | 88 | //Firebase Declaration 89 | Firebase.begin(FIREBASE_DATABASE_URL, FIREBASE_KEY); 90 | Firebase.stream(STRMDEVID); 91 | 92 | fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) { 93 | 94 | // Callback when a command from Alexa is received. 95 | // You can use device_id or device_name to choose the element to perform an action onto (relay, LED,...) 96 | // State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say "set kitchen light to 50%" you will receive a 128 here). 97 | // Just remember not to delay too much here, this is a callback, exit as soon as possible. 98 | // If you have to do something more involved here set a flag and process it in your main loop. 99 | // Checking for device_id is simpler if you are certain about the order they are loaded and it does not change. 100 | // Otherwise comparing the device_name is safer. 101 | 102 | if (strcmp(device_name, LIGHTNAME) == 0) { 103 | if (state == 0) { 104 | onstate = false; 105 | alexachange = true; 106 | } else if (state == 1) { 107 | onstate = true; 108 | alexachange = true; 109 | bri = round((value * 100.0) / 255); 110 | } 111 | Serial.println(state); 112 | Serial.println(value); 113 | Serial.println(bri); 114 | } 115 | }); 116 | } 117 | 118 | 119 | void loop() { 120 | 121 | if (alexachange == true) { 122 | Firebase.setInt("/" + STRMDEVID + "/Brightness/brightness", bri); 123 | Firebase.setBool("/" + STRMDEVID + "/OnOff/on", onstate); 124 | alexachange = false; 125 | delay(1000); 126 | } 127 | 128 | //Check Firebase connection 129 | if (Firebase.failed()) { 130 | Serial.println("Streaming Error"); 131 | Serial.println(Firebase.error()); 132 | } 133 | 134 | if (Firebase.available()) { 135 | FirebaseObject event = Firebase.readEvent(); 136 | String eventType = event.getString("type"); 137 | eventType.toLowerCase(); 138 | Serial.println(eventType); 139 | String path = event.getString("path"); 140 | Serial.println(path); 141 | 142 | if (eventType == "patch" || eventType == "put" || eventType == "type") { 143 | if (path == "/Brightness" || path == "/Brightness/brightness") { 144 | int bright = Firebase.getInt("/" + STRMDEVID + "/Brightness/brightness"); 145 | strip.setBrightness(bright); 146 | strip.show(); 147 | bri = bright; 148 | EEPROM.put(Bri_Address, bri); 149 | EEPROM.commit(); 150 | EEPROM.end(); 151 | Serial.println(bri); 152 | } 153 | else if (path == "/OnOff" || path == "/OnOff/on") { 154 | bool lightstatus = Firebase.getBool("/" + STRMDEVID + "/OnOff/on"); 155 | if (lightstatus == 0) { 156 | strip.fill(); 157 | strip.show(); 158 | } else if (lightstatus == 1) { 159 | EEPROM.get(Bri_Address, bri); 160 | strip.fill(0xFFFFFF); 161 | strip.setBrightness(bri); 162 | strip.show(); 163 | } 164 | Serial.println(lightstatus); 165 | } 166 | } 167 | } 168 | fauxmo.handle(); 169 | static unsigned long last = millis(); 170 | if (millis() - last > 5000) { 171 | last = millis(); 172 | Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap()); 173 | } 174 | } 175 | 176 | 177 | -------------------------------------------------------------------------------- /Crypto_Ticker/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | ![github-small](https://content.instructables.com/ORIG/FR7/OVXJ/KY9E5966/FR7OVXJKY9E5966.png?auto=webp&width=1600&height=900&fit=bounds&md=193a71943e042312d45a5e0692ee3034) 4 | 5 |

When you are trading Cryptos it is always itching to constantly look at the prevailing rate. I wanted a gadget that could display the live Crypto rate without constantly refreshing the browser.

I have incorporated a slideshow effect for better appeal. The first slide will be an image of the Crypto logo, the second slide will be the live Crypto trading rate and the last slide will be the rate of change, that is it shows whether the price of Crypto has decreased or increased and by how much.

My first thought was to 3D print a case for this project and then when I saw a plastic box on my table, decided to recycle the old plastic instead of adding to the global plastic woes by 3D printing a new one.

I have got all the files in the git project page. You can get access to all the related files by clicking here.

6 | 7 | 8 | ## Supplies 9 | 10 |

Hardware:

  1. Wemos D1 Mini (any other NodeMCU will do as well).
  2. SSD1306 Monochrome OLED display.

Tools:

  1. Box cutter.
  2. Electrical tape.
  3. A plastic box (optional)
11 | 12 | 13 | ## Getting The Enclosure Ready 14 | 15 | ![github-small](https://content.instructables.com/ORIG/FW2/10RY/KY9E595K/FW210RYKY9E595K.png?auto=webp&width=1600&height=900&fit=bounds&md=954d0c953259a519a7d804d4787b6629) 16 | ![github-small](https://content.instructables.com/ORIG/F7X/UC8S/KY9E595S/F7XUC8SKY9E595S.png?auto=webp&width=1600&height=900&fit=bounds&md=a6e99f3b8485c87252205aa839139cdf) 17 | ![github-small](https://content.instructables.com/ORIG/FS8/VQ9C/KY9E595T/FS8VQ9CKY9E595T.png?auto=webp&width=1600&height=900&fit=bounds&md=c18c5871853fcf6c8c5200ef30f240b9) 18 | ![github-small](https://content.instructables.com/ORIG/FOX/KQF5/KY9E595V/FOXKQF5KY9E595V.png?auto=webp&width=1600&height=900&fit=bounds&md=089d788bd3f7f8a1233aca26bc1118e6) 19 | 20 |

My first idea was to add a Micro USB female connector to the enclosure and then connect the Wemos to it. But on second thought, decided to partially expose the Wemos's USB connector and RESET button outside the enclosure. This way, I need not take out the Wemos out of the enclosure for updating the code or re-purposing the setup for some other display based project. This will also allow me to RESET the Wemos when desired.

  1. First I inspected the plastic enclosure for any defects. While inspecting the enclosure, I saw that the plastic was partially translucent.
  2. The partial translucency in fact helped my cause. I placed the Wemos inside in the desired position and I could see it's outline from outside.
  3. With the Wemos's outline as reference, I used a piece of electrical tape to mark the dimensions of the cutout.
  4. In the last image, you can actually see the tape's border matching the Wemos's height.
21 | 22 | 23 | ## Cutting Through 24 | 25 | ![github-small](https://content.instructables.com/ORIG/FM9/ZPZB/KY9E595W/FM9ZPZBKY9E595W.png?auto=webp&width=1600&height=900&fit=bounds&md=933b29a95cdb575978960530253b9ae9) 26 | ![github-small](https://content.instructables.com/ORIG/FO3/JF1Z/KY9E595Z/FO3JF1ZKY9E595Z.png?auto=webp&width=1600&height=900&fit=bounds&md=dc535488637ba38ee1e0fcbec2ffc0d4) 27 | 28 |
  1. Using a box cutter, I cutout the plastic to make room for the Wemos.
  2. Similarly, made a cutout for the OLED display on the plastic enclosure's cover.
29 | 30 | 31 | ## Fixing The Wemos Tight 32 | 33 | ![github-small](https://content.instructables.com/ORIG/FTZ/0JAN/KY9E595Y/FTZ0JANKY9E595Y.png?auto=webp&width=1600&height=900&fit=bounds&md=0965fbcf8202b8aa7e14eb97df3752d3) 34 | 35 |

I slid the Wemos through the cutout on the side just enough to partially expose the USB connector and the RESET button of the Wemos.

To hold the Wemos tight in its place, used a fair bit of hot glue to affix the Wemos to its plastic enclosure.

Now it is ready to be tossed around.

36 | 37 | 38 | ## Putting It All Together 39 | 40 | ![github-small](https://content.instructables.com/ORIG/F8B/2XMK/KY9E5962/F8B2XMKKY9E5962.png?auto=webp&width=1600&height=900&fit=bounds&md=a96d457b86d5ee1486ae368527bb916a) 41 | ![github-small](https://content.instructables.com/ORIG/FY8/CI57/KY9E596D/FY8CI57KY9E596D.jpg?auto=webp&width=1600&height=900&fit=bounds&md=d75676925b69e50516f12e0aeb6f87ab) 42 | ![github-small](https://content.instructables.com/ORIG/FG0/S73T/KY9E595J/FG0S73TKY9E595J.jpg?auto=webp&width=1600&height=900&fit=bounds&md=f32e69d80022e9458f730b26200da535) 43 | 44 |

For the OLED display, I used strips of electrical tape to hold it against the cutout on the plastic lid.

The OLED display uses I2C protocol for communicating with the Wemos. So its just four wires, VCC, GND, SDA and SCL. You can use attached wiring diagram as a reference for the connection.

Alternately, you can prepare your own OLED shield for Wemos and get rid of the wires. I have designed a simple board and have generated the Gerber file. You can download the Gerber from here. You can get your PCB printed using JLCPCB's PCB printing service. With their online Gerber viewer, you can verify the PCB design before ordering. Use this link https://jlcpcb.com/IAT for great discounts and minimal PCB fabrication costs.

45 | 46 | 47 | ## Brining The Ticker To Life 48 | 49 | ![github-small](https://content.instructables.com/ORIG/F1Q/NX1N/KY9E598X/F1QNX1NKY9E598X.jpg?auto=webp&width=1600&height=900&fit=bounds&md=cc5f2408336db684b6b7d441cb10471b) 50 | ![github-small](https://content.instructables.com/ORIG/F8K/5QS9/KY9E595E/F8K5QS9KY9E595E.jpg?auto=webp&width=1600&height=900&fit=bounds&md=52976d68f6d0e94120f17185567cd740) 51 | ![github-small](https://content.instructables.com/ORIG/FIL/X8HO/KY9E595F/FILX8HOKY9E595F.jpg?auto=webp&width=1600&height=900&fit=bounds&md=67b99f46a57d1682e81419a1a936c748) 52 | ![github-small](https://content.instructables.com/ORIG/FRJ/ODOP/KY9E595H/FRJODOPKY9E595H.jpg?auto=webp&width=1600&height=900&fit=bounds&md=a7fef0a372d0a8c6275773e1c5b30d5f) 53 | ![github-small](https://content.instructables.com/ORIG/FNI/PVIT/KY9E595G/FNIPVITKY9E595G.jpg?auto=webp&width=1600&height=900&fit=bounds&md=1c38d442d8d2782414e63dbedf29f137) 54 | ![github-small](https://content.instructables.com/ORIG/F54/T8NH/KY9E5965/F54T8NHKY9E5965.png?auto=webp&width=1600&height=900&fit=bounds&md=89f7be7706f72d25cda4607bc8c852e2) 55 | 56 |
This project uses Coindesk's API for getting the crypto rates. Its a free API, so I urge the users to use that with caution and fairly. Please do not bombard the server with multiple requests constantly. We may end up loosing the only free API we have.

With the disclaimer done, lets continue with the instructions.

Preparing the Image

Coindesk also has great images to go with their data. Replace the ISO name of the Crypto in this link https://downloads.coindesk.com/arc-hosted-images/eth.png with your desired Crypto's ISO value.

Couple of ISOs for popular Cryptos:

  1. btc for Bitcoin
  2. sol for Solana
  3. luna for Terra
  4. bch for Bitcoin Cash

Get more ISOs info here.

Once you have got the desired image, open that using Microsoft's Paint and resize it to 60x60 pixels. Save that as PNG itself. Please do not change the format.

Next you need a service to change the PNG to values that the microcontroller can decipher. Use this online PNG to XBM converter. The conversion will result in the creation of a XBM file that you need to download to your computer.

Time to download the Arduino code. Get your Arduino code from here. Mind the images.h file it is required as well.

Customize the Code

By default, the script or code or sketch is for displaying Bitcoin values. If you wish to replace that to some other currency, Press Ctrl + F on your keyboard and replace BTC with the desired ISO of your currency. For example, if you need Ethereum, replace BTC with ETH.

Mind the lettering case. For the PNG images it was lower case, but it is upper case here.

If you don't change the Boot logo in the images.h file, irrespective of the Crypto changed in the code, Bitcoin logo will be displayed by default.

Remember the XBM file that you just created using the first step ? Now Open the XBM file with Notepad or Notepad++ in Windows. Copy the values within the first curly "{}" brackets and replace the existing values in the images.h with that.

Set your Wifi SSID and Password in the place provided in the code.

By default, I have set the sketch to get the Crypto values every 2 minutes. This is to honor the Coindesk's free API. If you scroll through the code you should be able to figure the variable declaration. But please do not touch that, we may loose the only free and reliable API.

Now compile the sketch and upload it to the Wemos.

57 | 58 | 59 | ## All Done 60 | 61 | ![github-small](https://content.instructables.com/ORIG/F6V/3X1V/KY9E5967/F6V3X1VKY9E5967.png?auto=webp&width=1600&height=900&fit=bounds&md=b23abbde1b348cee2b899385967e12d4) 62 | ![github-small](https://content.instructables.com/ORIG/FCZ/H27T/KY9E5ANG/FCZH27TKY9E5ANG.png?auto=webp&width=1600&height=900&fit=bounds&md=677bbc384b42f9381fddbeb7de838f5b) 63 | 64 |

Wow !! After the initial wait period of 2 minutes, we should have the Crypto values show up.

65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /AmazonEcho_RGB_STRP_NodeMCU.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************************** 2 | Code for controlling RGB Strip using Amazon Echo and NodeMCU 3 | 4 | Written by Sid for Sid's E Classroom 5 | 6 | https://www.youtube.com/c/SidsEClassroom 7 | *********************************************************************************/ 8 | #include 9 | #include 10 | #include "fauxmoESP.h" 11 | #include 12 | 13 | #define WIFI_SSID "abcd"//Set your Wifi name 14 | #define WIFI_PASS "efgh"//Set your Wifi Password 15 | #define SERIAL_BAUDRATE 115200 16 | 17 | fauxmoESP fauxmo; 18 | //declare switching pins 19 | #define RGBCTL D1 //Change pins according to your NodeMCU/ESP pinouts 20 | 21 | int numPixels = 12; 22 | int i; 23 | //----------------------------------------------------------------------------------------------- 24 | //Pixel initialization for Google's Colours 25 | //Divide the total number of pixels in the stip by 4 and set pixel increments starting from zero 26 | //If num of Pixels is not perfectly divisible by 4, consider the nearest multiple of 4 27 | //eg: 28 in case of 29,30 and 31 pixels, 32 in case of 33,34 and 35 pixels. 28 | //----------------------------------------------------------------------------------------------- 29 | int start1 = 0; 30 | int start2 = 3; 31 | int start3 = 6; 32 | int start4 = 9; 33 | 34 | // Parameter 1 = number of pixels in strip 35 | // Parameter 2 = Arduino pin number (most are valid) 36 | // Parameter 3 = pixel type flags, add together as needed: 37 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 38 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 39 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 40 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 41 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 42 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixels, RGBCTL, NEO_GRB + NEO_KHZ800); 43 | // ----------------------------------------------------------------------------- 44 | // Wifi Setup 45 | // ----------------------------------------------------------------------------- 46 | 47 | void wifiSetup() { 48 | 49 | // Set WIFI module to STA mode 50 | WiFi.mode(WIFI_STA); 51 | 52 | // Connect 53 | Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID); 54 | WiFi.begin(WIFI_SSID, WIFI_PASS); 55 | 56 | // Wait 57 | while (WiFi.status() != WL_CONNECTED) { 58 | Serial.print("."); 59 | delay(100); 60 | } 61 | Serial.println(); 62 | 63 | // Connected! 64 | Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str()); 65 | } 66 | // ----------------------------------------------------------------------------- 67 | // Device callback and printing response in serial monitor 68 | // ----------------------------------------------------------------------------- 69 | void callback(uint8_t device_id, const char * device_name, bool state) { 70 | Serial.print("Device "); Serial.print(device_name); 71 | Serial.print(" state: "); 72 | if (state) { 73 | Serial.println("ON"); 74 | } else { 75 | Serial.println("OFF"); 76 | } 77 | //------------------------------------------------------------------------------ 78 | //Switching action on detection of device name 79 | //------------------------------------------------------------------------------ 80 | 81 | //Turns strip RED 82 | if ( (strcmp(device_name, "RED LIGHTS") == 0) ) { 83 | if (state) { 84 | i = 1; 85 | } 86 | else { 87 | allOff(); 88 | i = 0; 89 | } 90 | } 91 | //Turns strip GREEN 92 | if ( (strcmp(device_name, "GREEN LIGHTS") == 0) ) { 93 | if (state) { 94 | i = 2; 95 | } 96 | else { 97 | allOff(); 98 | i = 0; 99 | } 100 | } 101 | //Turns strip BLUE 102 | if ( (strcmp(device_name, "BLUE LIGHTS") == 0) ) { 103 | if (state) { 104 | i = 3; 105 | } 106 | else { 107 | allOff(); 108 | i = 0; 109 | } 110 | } 111 | //RAINBOW pattern on the strip 112 | if ( (strcmp(device_name, "RAINBOW LIGHTS") == 0) ) { 113 | if (state) { 114 | i = 8; 115 | } 116 | else { 117 | allOff(); 118 | i = 0; 119 | } 120 | } 121 | //Turns strip WHITE 122 | if ( (strcmp(device_name, "LIGHTS") == 0) ) { 123 | if (state) { 124 | i = 4; 125 | } 126 | else { 127 | allOff(); 128 | i = 0; 129 | } 130 | } 131 | //Turns strip into Google's colours 132 | if ( (strcmp(device_name, "GOOGLE LIGHTS") == 0) ) { 133 | if (state) { 134 | i = 9; 135 | } 136 | else { 137 | allOff(); 138 | i = 0; 139 | } 140 | } 141 | } 142 | 143 | void setup() { 144 | //Initialize pins to Low on device start 145 | pinMode(RGBCTL, OUTPUT); 146 | digitalWrite(RGBCTL, LOW); 147 | 148 | // Init serial port and clean garbage 149 | Serial.begin(SERIAL_BAUDRATE); 150 | Serial.println("FauxMo demo sketch"); 151 | Serial.println("After connection, ask Alexa/Echo to 'turn on' or 'off'"); 152 | 153 | // Wifi 154 | wifiSetup(); 155 | 156 | // Device Names for RGB Patterns 157 | fauxmo.addDevice("GREEN LIGHTS"); 158 | fauxmo.addDevice("RED LIGHTS"); 159 | fauxmo.addDevice("BLUE LIGHTS"); 160 | fauxmo.addDevice("RAINBOW LIGHTS"); 161 | fauxmo.addDevice("LIGHTS"); 162 | fauxmo.addDevice("GOOGLE LIGHTS"); 163 | fauxmo.onMessage(callback); 164 | 165 | strip.begin(); 166 | strip.show(); 167 | strip.setBrightness(5); 168 | 169 | i = 0; 170 | 171 | } 172 | 173 | void loop() { 174 | fauxmo.handle(); 175 | startShow(i); 176 | } 177 | 178 | //Case for strip patterns. Add a new case or pattern if you wish 179 | void startShow(int i) { 180 | switch (i) { 181 | case 0: colorWipe(strip.Color(0, 0, 0), 50); // Black/Off 182 | break; 183 | case 1: colorWipe(strip.Color(255, 0, 0), 50); // Red 184 | break; 185 | case 2: colorWipe(strip.Color(0, 255, 0), 50); // Green 186 | break; 187 | case 3: colorWipe(strip.Color(0, 0, 255), 50); // Blue 188 | break; 189 | case 4: colorWipe(strip.Color(255, 255, 255), 50); // White 190 | break; 191 | case 5: theaterChase(strip.Color(127, 127, 127), 50); // White Chase 192 | break; 193 | case 6: theaterChase(strip.Color(127, 0, 0), 50); // Red Chase 194 | break; 195 | case 7: theaterChase(strip.Color( 0, 0, 127), 50); // Blue Chase 196 | break; 197 | case 8: rainbow(20); 198 | break; 199 | case 9: google(); 200 | break; 201 | case 10: theaterChaseRainbow(50); 202 | break; 203 | } 204 | } 205 | 206 | // Fill the dots one after the other with a color 207 | void colorWipe(uint32_t c, uint8_t wait) { 208 | for (uint16_t i = 0; i < strip.numPixels(); i++) { 209 | strip.setPixelColor(i, c); 210 | strip.show(); 211 | delay(wait); 212 | } 213 | } 214 | //Rainbow pattern 215 | void rainbow(uint8_t wait) { 216 | uint16_t i, j; 217 | 218 | for (j = 0; j < 256; j++) { 219 | for (i = 0; i < strip.numPixels(); i++) { 220 | strip.setPixelColor(i, Wheel((i + j) & 255)); 221 | } 222 | strip.show(); 223 | delay(wait); 224 | } 225 | } 226 | //Rainbow equally distributed throughout 227 | void rainbowCycle(uint8_t wait) { 228 | uint16_t i, j; 229 | 230 | for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel 231 | for (i = 0; i < strip.numPixels(); i++) { 232 | strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); 233 | } 234 | strip.show(); 235 | delay(wait); 236 | } 237 | } 238 | //Theatre-style crawling lights 239 | void theaterChase(uint32_t c, uint8_t wait) { 240 | for (int j = 0; j < 10; j++) { //do 10 cycles of chasing 241 | for (int q = 0; q < 3; q++) { 242 | for (int i = 0; i < strip.numPixels(); i = i + 3) { 243 | strip.setPixelColor(i + q, c); //turn every third pixel on 244 | } 245 | strip.show(); 246 | 247 | delay(wait); 248 | 249 | for (int i = 0; i < strip.numPixels(); i = i + 3) { 250 | strip.setPixelColor(i + q, 0); //turn every third pixel off 251 | } 252 | } 253 | } 254 | } 255 | //Theatre-style crawling lights with rainbow effect 256 | void theaterChaseRainbow(uint8_t wait) { 257 | for (int j = 0; j < 256; j++) { // cycle all 256 colors in the wheel 258 | for (int q = 0; q < 3; q++) { 259 | for (int i = 0; i < strip.numPixels(); i = i + 3) { 260 | strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on 261 | } 262 | strip.show(); 263 | 264 | delay(wait); 265 | 266 | for (int i = 0; i < strip.numPixels(); i = i + 3) { 267 | strip.setPixelColor(i + q, 0); //turn every third pixel off 268 | } 269 | } 270 | } 271 | } 272 | //Fill strip with Google's Colour 273 | void google() { 274 | //Set initial couple of pixels to match Google Blue 275 | for ( int i = start1; i < start1 + 3; i++ ) { 276 | strip.setPixelColor(i, 23, 107, 239 ); 277 | } 278 | //Set initial couple of pixels to match Google Red 279 | // next 3 pixels = color set #2 280 | for ( int i = start2; i < start2 + 3 ; i++ ) { 281 | strip.setPixelColor(i, 255, 62, 48 ); 282 | } 283 | //Set initial couple of pixels to match Google Orange 284 | // next 3 pixels = color set #3 285 | for ( int i = start3; i < start3 + 3; i++ ) { 286 | strip.setPixelColor(i, 247, 181, 41 ); 287 | } 288 | //Set initial couple of pixels to match Google Green 289 | // last 3 pixels = color set #3 290 | for ( int i = start4; i < start4 + 3; i++ ) { 291 | strip.setPixelColor(i, 23, 156, 82 ); 292 | } 293 | 294 | strip.show(); 295 | } 296 | //Turns all pixels OFF 297 | void allOff() { 298 | for ( int i = 0; i < numPixels; i++ ) { 299 | strip.setPixelColor(i, 0, 0, 0 ); 300 | } 301 | strip.show(); 302 | } 303 | 304 | // Input a value 0 to 255 to get a color value. 305 | // The colours are a transition r - g - b - back to r. 306 | uint32_t Wheel(byte WheelPos) { 307 | WheelPos = 255 - WheelPos; 308 | if (WheelPos < 85) { 309 | return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); 310 | } 311 | if (WheelPos < 170) { 312 | WheelPos -= 85; 313 | return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 314 | } 315 | WheelPos -= 170; 316 | return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 317 | } 318 | -------------------------------------------------------------------------------- /Crypto_Ticker/SSD1306UiDemo-One-Currency/SSD1306UiDemo-One-Currency.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | Copyright (c) 2018 by Fabrice Weinberg 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | ThingPulse invests considerable time and money to develop these open source libraries. 26 | Please support us by buying our products (and not the clones) from 27 | https://thingpulse.com 28 | 29 | */ 30 | 31 | // Include the correct display library 32 | // For a connection via I2C using Wire include 33 | #include // Only needed for Arduino 1.6.5 and earlier 34 | // #include "SH1106Wire.h" 35 | #include "SSD1306.h" 36 | 37 | // For a connection via SPI include 38 | // #include // Only needed for Arduino 1.6.5 and earlier 39 | // #include "SSD1306Spi.h" 40 | // #include "SH1106SPi.h" 41 | 42 | // Include the UI lib 43 | #include "OLEDDisplayUi.h" 44 | 45 | // Include custom images 46 | 47 | #include "images.h" 48 | 49 | #define ARDUINOJSON_USE_DOUBLE 1 50 | #define ARDUINOJSON_USE_LONG_LONG 1 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #define SCREEN_WIDTH 128 58 | #define SCREEN_HEIGHT 64 59 | 60 | 61 | // Use the corresponding display class: 62 | 63 | // Initialize the OLED display using SPI 64 | // D5 -> CLK 65 | // D7 -> MOSI (DOUT) 66 | // D0 -> RES 67 | // D2 -> DC 68 | // D8 -> CS 69 | // SSD1306Spi display(D0, D2, D8); 70 | // or 71 | // SH1106Spi display(D0, D2); 72 | 73 | // Initialize the OLED display using i2c 74 | // D2 -> SDA 75 | // D1 -> SCL 76 | // Initialize the OLED display using Wire library 77 | SSD1306 display(0x3c, D2, D1); 78 | 79 | OLEDDisplayUi ui ( &display ); 80 | 81 | const char *host = "production.api.coindesk.com"; 82 | const int httpsPort = 443; //HTTPS= 443 and HTTP = 80 83 | String Link = "/v2/tb/price/ticker?assets=BTC"; 84 | 85 | //SHA1 finger print of certificate use web browser to view and copy 86 | const char fingerprint[] PROGMEM = "94 19 A7 32 1E 0A E6 2E 0A 2B 8D 74 0D 94 99 4B 43 B9 89 6A"; 87 | 88 | unsigned long lastTime = 0; 89 | unsigned long timerDelay = 120000; 90 | StaticJsonDocument<512> cryptoReadings; 91 | //char sample_json[] = "{\"statusCode\": 200,\"message\": \"OK\",\"data\": {\"BTC\": {\"iso\": \"BTC\",\"name\":\"Bitcoin\",\"slug\": \"bitcoin\",\"change\":{\"percent\": 0.8120221253967227,\"value\": 378.210186},\"ohlc\":{\"o\": 46576.34,\"h\": 47535.7,\"l\": 45599.775339,\"c\": 46954.550186},\"circulatingSupply\": 18905243.7915621,\"marketCap\": 887687218389.4675,\"ts\": 1640052959000,\"src\": \"tb\"}}"; 92 | 93 | // Enter the WiFi credentials 94 | char wifissid[] = "ENTER YOUR WIFI SSID HERE"; 95 | char wifipass[] = "ENTER YOUR WIFI PASSWORD HERE"; 96 | 97 | String crypto_currency_growth_rate = ""; 98 | String crypto_currency_value = ""; 99 | String crypto_currency_iso = ""; 100 | String crypto_currency_rate_direction = ""; 101 | 102 | void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 103 | // draw an xbm image. 104 | // Please note that everything that should be transitioned 105 | // needs to be drawn relative to x and y 106 | 107 | display->drawXbm(x + (SCREEN_WIDTH - Currency_Logo_width) / 2, y + (SCREEN_HEIGHT - Currency_Logo_height) / 2, Currency_Logo_width, Currency_Logo_height, Currency_Logo_bits); 108 | } 109 | 110 | void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 111 | display->setTextAlignment(TEXT_ALIGN_CENTER); 112 | display->setFont(ArialMT_Plain_24); 113 | display->drawString(x + (SCREEN_WIDTH) / 2, y + 5, crypto_currency_iso); 114 | if (crypto_currency_value != "") { 115 | display->setTextAlignment(TEXT_ALIGN_CENTER); 116 | display->setFont(ArialMT_Plain_16); 117 | display->drawString(x + SCREEN_WIDTH / 2, y + 8 + SCREEN_HEIGHT / 2, crypto_currency_value); 118 | } 119 | else if (crypto_currency_value == "") { 120 | display->setTextAlignment(TEXT_ALIGN_CENTER); 121 | display->setFont(ArialMT_Plain_10); 122 | display->drawString(x + SCREEN_WIDTH / 2, y + 8 + SCREEN_HEIGHT / 2, "Waiting for Values"); 123 | } 124 | } 125 | 126 | void drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 127 | 128 | if (crypto_currency_rate_direction == "UP") { 129 | // Upward Trend 130 | display->setTextAlignment(TEXT_ALIGN_CENTER); 131 | display->setFont(ArialMT_Plain_24); 132 | display->drawString(x + SCREEN_WIDTH / 2, y + 5 + Arrow_Logo_width, crypto_currency_growth_rate); 133 | display->drawXbm(x + (SCREEN_WIDTH / 2) - (Arrow_Logo_width / 2) - Arrow_Logo_width, y + 5, Arrow_Logo_width, Arrow_Logo_height, Up_Arrow_bits); 134 | display->drawXbm(x + (SCREEN_WIDTH / 2) - (Arrow_Logo_width / 2), y + 5, Arrow_Logo_width, Arrow_Logo_height, Up_Arrow_bits); 135 | display->drawXbm(x + (SCREEN_WIDTH / 2) - (Arrow_Logo_width / 2) + Arrow_Logo_width, y + 5, Arrow_Logo_width, Arrow_Logo_height, Up_Arrow_bits); 136 | } 137 | else if (crypto_currency_rate_direction == "DOWN") { 138 | // Downward Trend 139 | display->setTextAlignment(TEXT_ALIGN_CENTER); 140 | display->setFont(ArialMT_Plain_24); 141 | display->drawString(x + SCREEN_WIDTH / 2, y + 5, crypto_currency_growth_rate); 142 | display->drawXbm(x + (SCREEN_WIDTH / 2) - (Arrow_Logo_width / 2) - Arrow_Logo_width, y + 5 + Arrow_Logo_width, Arrow_Logo_width, Arrow_Logo_height, Down_Arrow_bits); 143 | display->drawXbm(x + (SCREEN_WIDTH / 2) - (Arrow_Logo_width / 2), y + 5 + Arrow_Logo_width, Arrow_Logo_width, Arrow_Logo_height, Down_Arrow_bits); 144 | display->drawXbm(x + (SCREEN_WIDTH / 2) - (Arrow_Logo_width / 2) + Arrow_Logo_width, y + 5 + Arrow_Logo_width, Arrow_Logo_width, Arrow_Logo_height, Down_Arrow_bits); 145 | } 146 | else if (crypto_currency_rate_direction == "") { 147 | display->setTextAlignment(TEXT_ALIGN_CENTER); 148 | display->setFont(ArialMT_Plain_10); 149 | display->drawString(x + SCREEN_WIDTH / 2, y + 8 + SCREEN_HEIGHT / 2, "Waiting for Values"); 150 | } 151 | 152 | } 153 | 154 | // This array keeps function pointers to all frames 155 | // frames are the single views that slide in 156 | FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3 }; 157 | 158 | // Number of frames 159 | int frameCount = 3; 160 | 161 | void setup() { 162 | 163 | Serial.begin(115200); 164 | Serial.println(); 165 | Serial.println(); 166 | 167 | // The ESP is capable of rendering 60fps in 80Mhz mode 168 | // but that won't give you much time for anything else 169 | // run it in 160Mhz mode or just set it to 30 fps 170 | ui.setTargetFPS(60); 171 | 172 | // Customize the active and inactive symbol 173 | ui.setActiveSymbol(activeSymbol); 174 | ui.setInactiveSymbol(inactiveSymbol); 175 | 176 | // You can change this to 177 | // TOP, LEFT, BOTTOM, RIGHT 178 | ui.setIndicatorPosition(LEFT); 179 | 180 | // Defines where the first frame is located in the bar. 181 | ui.setIndicatorDirection(LEFT_RIGHT); 182 | 183 | // You can change the transition that is used 184 | // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN 185 | ui.setFrameAnimation(SLIDE_DOWN); 186 | 187 | // Add frames 188 | ui.setFrames(frames, frameCount); 189 | 190 | // Initialising the UI will init the display too. 191 | ui.init(); 192 | 193 | //display.flipScreenVertically(); 194 | 195 | // Set WiFi to Station Mode 196 | WiFi.mode(WIFI_STA); 197 | WiFi.disconnect(); 198 | delay(10); 199 | 200 | // Connect to WiFi 201 | WiFi.begin(wifissid, wifipass); 202 | Serial.print("Connecting to WiFi..."); 203 | display.clear(); 204 | display.setTextAlignment(TEXT_ALIGN_CENTER); 205 | display.setFont(ArialMT_Plain_10); 206 | display.drawString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, "Connecting to WiFi..."); 207 | display.display(); 208 | // Check if connected to WiFi 209 | while (WiFi.status() != WL_CONNECTED) { 210 | delay(500); 211 | Serial.print("."); 212 | } 213 | // Print connection information 214 | display.clear(); 215 | display.setTextAlignment(TEXT_ALIGN_CENTER); 216 | display.setFont(ArialMT_Plain_10); 217 | display.drawString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, "Connected to " + String(wifissid)); 218 | display.display(); 219 | delay(3000); 220 | Serial.print("\nConnected to: "); 221 | Serial.println(wifissid); 222 | Serial.print("IP address: "); 223 | Serial.println(WiFi.localIP()); 224 | Serial.println(""); 225 | } 226 | 227 | 228 | void loop() { 229 | 230 | if (WiFi.status() != WL_CONNECTED) { 231 | display.clear(); 232 | display.setTextAlignment(TEXT_ALIGN_CENTER); 233 | display.setFont(ArialMT_Plain_10); 234 | display.drawString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, "Connection lost"); 235 | display.display(); 236 | delay(1000); 237 | } 238 | else if (WiFi.status() == WL_CONNECTED) { 239 | int remainingTimeBudget = ui.update(); 240 | if (remainingTimeBudget > 0) { 241 | // You can do some work here 242 | // Don't do stuff if you are below your 243 | // time budget. 244 | delay(remainingTimeBudget); 245 | } 246 | if ((millis() - lastTime) > timerDelay) { 247 | WiFiClientSecure httpsClient; 248 | httpsClient.setFingerprint(fingerprint); 249 | httpsClient.setTimeout(15000); 250 | delay(1000); 251 | int r = 0; //retry counter 252 | while ((!httpsClient.connect(host, httpsPort)) && (r < 30)) { 253 | delay(100); 254 | Serial.print("."); 255 | r++; 256 | } 257 | if (r == 30) { 258 | Serial.println("Connection failed"); 259 | } 260 | else { 261 | Serial.println("Connected to CoinDesk"); 262 | } 263 | httpsClient.print(String("GET ") + Link + " HTTP/1.1\r\n" + 264 | "Host: " + host + "\r\n" + 265 | "Connection: close\r\n\r\n"); 266 | Serial.println("Requesting Crypto Values..........."); 267 | while (httpsClient.connected()) { 268 | String line = httpsClient.readStringUntil('\n'); 269 | if (line == "\r") { 270 | Serial.println("Crypto Values Received:"); 271 | break; 272 | } 273 | } 274 | 275 | DeserializationError error = deserializeJson(cryptoReadings, httpsClient); 276 | if (error) { 277 | Serial.print(F("deserializeJson() failed: ")); 278 | Serial.println(error.f_str()); 279 | return; 280 | } 281 | 282 | JsonObject data_BTC = cryptoReadings["data"]["BTC"]; 283 | 284 | const char* data_BTC_iso = data_BTC["iso"]; // "BTC" 285 | const char* data_BTC_name = data_BTC["name"]; // "Bitcoin" 286 | const char* data_BTC_slug = data_BTC["slug"]; // "bitcoin" 287 | 288 | double data_BTC_change_percent = data_BTC["change"]["percent"]; // 0.8120221253967227 289 | double data_BTC_change_value = data_BTC["change"]["value"]; // 378.210186 290 | 291 | JsonObject data_BTC_ohlc = data_BTC["ohlc"]; 292 | float data_BTC_ohlc_o = data_BTC_ohlc["o"]; // 46576.34 293 | float data_BTC_ohlc_h = data_BTC_ohlc["h"]; // 47535.7 294 | double data_BTC_ohlc_l = data_BTC_ohlc["l"]; // 45599.775339 295 | double data_BTC_ohlc_c = data_BTC_ohlc["c"]; // 46954.550186 296 | 297 | double data_BTC_circulatingSupply = data_BTC["circulatingSupply"]; // 18905243.7915621 298 | double data_BTC_marketCap = data_BTC["marketCap"]; // 887687218389.4675 299 | long long data_BTC_ts = data_BTC["ts"]; // 1640052959000 300 | const char* data_BTC_src = data_BTC["src"]; // "tb" 301 | 302 | 303 | Serial.print("\n"); 304 | Serial.print(data_BTC_iso); 305 | crypto_currency_iso = String(data_BTC_iso); 306 | Serial.print("\n"); 307 | Serial.print(data_BTC_change_percent); 308 | crypto_currency_growth_rate = String(data_BTC_change_percent) + "%"; 309 | if (String(data_BTC_change_percent).indexOf("-") != -1) { 310 | crypto_currency_rate_direction = "DOWN"; 311 | } 312 | else if (String(data_BTC_change_percent).indexOf("-") == -1) { 313 | crypto_currency_rate_direction = "UP"; 314 | } 315 | Serial.print("\n"); 316 | Serial.print(data_BTC_ohlc_c); 317 | crypto_currency_value = "$" + String(data_BTC_ohlc_c); 318 | Serial.print("\n"); 319 | lastTime = millis(); 320 | } 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /Chromecast_Gesture_Control/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | ![github-small](https://content.instructables.com/ORIG/FKE/BFJ3/KZ6ZPQTP/FKEBFJ3KZ6ZPQTP.jpg?auto=webp&width=1600&height=900&fit=bounds&md=88b1e10ed9e10ee04de462521dc22d67) 4 | 5 |

Ages back, when Google's Chromecast was without the Android TV, I came up an idea to control the Chromecast with a Raspberry Pi. This was for those who wanted a tactile experience and who did not mind tossing their device to their children. But there was an issue with that. Raspberry Pi had an OS running and had to be booted which naturally took time and can't be shutdown abruptly which would corrupt the OS installation.

So here is Version 2 of the project and its a Covid-19 special. Non-contact based remote control for your Chromecast. That is, you can control your Chromecast with hand gestures. No more shouting "Hey, Goooogle" or getting distracted with your phone forgetting to pause your Chromecast. This overcomes the disadvantages of the Pi based remote control that I just mentioned above. This will serve as a good activity time project for the tiny tots in your home and they will surely have fun interacting with the device.

6 | 7 | 8 | ## Supplies 9 | 10 |

Hardware:

  1. Wemos D1 Mini (any other NodeMCU will do as well).
  2. APDS9960 Sensor.
  3. Jumper wires.
  4. 3mm LED (any color).
  5. 220 Ohm 1/4 W resistor.

Tools (if you are going to enclose the hardware in a case):

  1. Box cutter.
  2. Electrical tape.
  3. A plastic box.
  4. Electric hand drill.
  5. A piece of MDF/Wood.
  6. General purpose PCB (4cm x 2.5cm).
  7. M2.5 screws.
11 | 12 | 13 | ## Hurdle No1 - Wemos And APDS9960 Sensor Integration 14 | 15 | ![github-small](https://content.instructables.com/ORIG/FZD/UTQA/KZ6ZPQU4/FZDUTQAKZ6ZPQU4.png?auto=webp&width=1600&height=900&fit=bounds&md=a9a496a0f29b5d8c934c33f5fce510b3) 16 | ![github-small](https://content.instructables.com/ORIG/F50/Q7VJ/KZ6ZR6I7/F50Q7VJKZ6ZR6I7.jpg?auto=webp&width=1600&height=900&fit=bounds&md=f5ed2b0d5e31ba4a7102298f46e08312) 17 | ![github-small](https://content.instructables.com/ORIG/F2P/LU9P/KZ6ZR6I6/F2PLU9PKZ6ZR6I6.jpg?auto=webp&width=1600&height=900&fit=bounds&md=b68dabd503932d30a21197eafb58b6ec) 18 | ![github-small](https://content.instructables.com/ORIG/FB4/XSF6/KZ6ZRFUK/FB4XSF6KZ6ZRFUK.png?auto=webp&width=1600&height=900&fit=bounds&md=c6b7fb9e49d2da6a3cc0bab8444d2aad) 19 | ![github-small](https://content.instructables.com/ORIG/FWS/A0BV/KZ6ZRGL3/FWSA0BVKZ6ZRGL3.png?auto=webp&width=1600&height=900&fit=bounds&md=3e279383f1a090b976d87e88d25cf241) 20 | 21 |

There were hardly any working references available for using Wemos D1 Mini/NodeMCU with ADPS9960 sensor in the internet. So I knew that I was venturing into the unknown territory.

  1. So to start with, I first connected the APDS9960 sensor to the Wemos as per the attached wiring diagram to check if the Wemos detected the sensor at all. I used the I2Cdetect library and check for the APDS9960 Sensor's address. I could see that the sensor was at 0x39 I2C address. That was a positive start.
  2. Next step was to check the if the Wemos read the gestures. So I downloaded the Sparkfun's APDS9960 sensor library and use the built-in example. It was a bummer. The code would not even compile. Going through various forums, the issue was likely IRAM related. None of the suggested solutions worked. That was when I came across a fork of the Sparkfun's official library. That was tailored to work with Wemos and when I tested it out it did work, but had to do some minor changes. You can download the copy of the modified library from here.
  3. I gave the Wemos a test run with the modified library and it did work. I was able see the gestures getting detected in the serial monitor.

That was one huge hurdle that was crossed.

22 | 23 | 24 | ## Preparing The Project Enclosure - The Cutting 25 | 26 | ![github-small](https://content.instructables.com/ORIG/FC7/C8ER/KZ6ZPQTQ/FC7C8ERKZ6ZPQTQ.png?auto=webp&width=1600&height=900&fit=bounds&md=38227a2724a3051dcdbe9080f9fff5c8) 27 | ![github-small](https://content.instructables.com/ORIG/FEK/VUE0/KZ6ZPQTR/FEKVUE0KZ6ZPQTR.png?auto=webp&width=1600&height=900&fit=bounds&md=30ac18dcb4985413187c67bdd1597a50) 28 | ![github-small](https://content.instructables.com/ORIG/FK4/FN0N/KZ6ZPQTU/FK4FN0NKZ6ZPQTU.png?auto=webp&width=1600&height=900&fit=bounds&md=261d656ae20432fcf71e22b1abd69512) 29 | ![github-small](https://content.instructables.com/ORIG/FR2/BI69/KZ6ZPQTX/FR2BI69KZ6ZPQTX.png?auto=webp&width=1600&height=900&fit=bounds&md=6d01e9ef6cd40dc3ace8d2bbbebd9c06) 30 | ![github-small](https://content.instructables.com/ORIG/FZW/5M61/KZ6ZPQTY/FZW5M61KZ6ZPQTY.png?auto=webp&width=1600&height=900&fit=bounds&md=ffe221a73452d2a2abeb1cdc73aee440) 31 | ![github-small](https://content.instructables.com/ORIG/F6H/4P6G/KZ6ZPQTZ/F6H4P6GKZ6ZPQTZ.png?auto=webp&width=1600&height=900&fit=bounds&md=c6d3f6ccd040dd4c0415051220f242dd) 32 | ![github-small](https://content.instructables.com/ORIG/FRA/4DDJ/KZ6ZPQU3/FRA4DDJKZ6ZPQU3.png?auto=webp&width=1600&height=900&fit=bounds&md=4057c07c15899ad0592fc2be880f42bd) 33 | ![github-small](https://content.instructables.com/ORIG/FU7/J4VR/KZ6ZPQU5/FU7J4VRKZ6ZPQU5.png?auto=webp&width=1600&height=900&fit=bounds&md=69cfebd856242e28b41f6addfe0af4a7) 34 | ![github-small](https://content.instructables.com/ORIG/FYM/53AY/KZ6ZPQU6/FYM53AYKZ6ZPQU6.png?auto=webp&width=1600&height=900&fit=bounds&md=3bc0e956ca0307bec7e5c0b1c925504c) 35 | 36 |

I did not want to add new and more plastic waste in this world by 3D printing something. Instead I decided to recycle a sweatbox that I had in plenty with me. This was the same box that I used in my previous Crypto Ticker project.

I decided to partially expose the Wemos's USB connector and RESET button outside the enclosure. This way, I need not take out the Wemos out of the enclosure for updating the code or re-purposing the setup for some other display based project. This will also allow me to RESET the Wemos when desired.

  1. First I inspected the plastic enclosure for any defects. While inspecting the enclosure, I saw that the plastic was partially translucent.
  2. The partial translucency in fact helped my cause. I placed the Wemos inside in the desired position and I could see it's outline from outside.
  3. With the Wemos's outline as reference, I used a piece of electrical tape to mark the dimensions of the cutout.
  4. In the fourth image, you can actually see the tape's border matching the Wemos's height.
  5. Using a box cutter, I cutout the plastic to make room for the Wemos.
  6. Similarly, made a cutout on the lid for the gesture sensor.
  7. I hot-glued the Wemos in its place and stuck some paper tape on the exposed Wemos to temporarily protect it from dust and other elements
  8. On the back of the lid, I stuck a piece of small wood and held it in place with some electrical tape. On a hindsight, I could have used a duct tape here, my bad.



37 | 38 | 39 | ## Preparing The Project Enclosure - The Drilling 40 | 41 | ![github-small](https://content.instructables.com/ORIG/FGE/4O6J/KZ6ZPQUK/FGE4O6JKZ6ZPQUK.png?auto=webp&width=1600&height=900&fit=bounds&md=d3490bb845ebf056d71e72b14356ac10) 42 | ![github-small](https://content.instructables.com/ORIG/F4M/WDJ9/KZ6ZPQUR/F4MWDJ9KZ6ZPQUR.png?auto=webp&width=1600&height=900&fit=bounds&md=ada2952f624da1f1c318627d48f5fd00) 43 | ![github-small](https://content.instructables.com/ORIG/FXK/JSNH/KZ6ZPQUU/FXKJSNHKZ6ZPQUU.png?auto=webp&width=1600&height=900&fit=bounds&md=7dacdd3321ca0623c2579bb045085b23) 44 | ![github-small](https://content.instructables.com/ORIG/F3D/46IV/KZ6ZPQUV/F3D46IVKZ6ZPQUV.png?auto=webp&width=1600&height=900&fit=bounds&md=b3bec6d1674972808fe7c37a00b5d046) 45 | ![github-small](https://content.instructables.com/ORIG/FO6/4PNL/KZ6ZPQV2/FO64PNLKZ6ZPQV2.png?auto=webp&width=1600&height=900&fit=bounds&md=64a33e9b585300f64c62c4fabf56fc62) 46 | ![github-small](https://content.instructables.com/ORIG/FIN/OD96/KZ6ZPQV4/FINOD96KZ6ZPQV4.png?auto=webp&width=1600&height=900&fit=bounds&md=21e311abeb75b1471ee3af7e71c6ac8e) 47 | ![github-small](https://content.instructables.com/ORIG/FZR/ECNC/KZ6ZPQV9/FZRECNCKZ6ZPQV9.png?auto=webp&width=1600&height=900&fit=bounds&md=6ecdf4e45cfad635ef9109d21bfc0307) 48 | 49 |
This part involves the use of power tools. Always take the necessary precautions and wear the required safety gear while operating the electric power tools. Also, pay full attention and do not get distracted.

Drilled the following holes.

  1. 2 holes on the lid for two M2.5 Screws to hold the backplate in place.
  2. 1 hole of approximately 5mm diameter for the sensor.
  3. 1 hole of approximately 3mm diameter for the 3mm indicator LED.

After drilling the front two holes, secured the backplate with two M2.5 screws and then removed the temporary electrical tape that was holding it in place.

50 | 51 | 52 | ## Preparing The Project Enclosure - The Paint Job 53 | 54 | ![github-small](https://content.instructables.com/ORIG/FMG/7TKF/KZ6ZPQU8/FMG7TKFKZ6ZPQU8.png?auto=webp&width=1600&height=900&fit=bounds&md=be1bc45be2122df923f2223bde4c4d73) 55 | ![github-small](https://content.instructables.com/ORIG/F76/ZHIV/KZ6ZPQUG/F76ZHIVKZ6ZPQUG.png?auto=webp&width=1600&height=900&fit=bounds&md=60c7ff5b3e163876a98db646f566cd51) 56 | ![github-small](https://content.instructables.com/ORIG/F76/ZHIV/KZ6ZPQUG/F76ZHIVKZ6ZPQUG.png?auto=webp&width=1600&height=900&fit=bounds&md=60c7ff5b3e163876a98db646f566cd51) 57 | ![github-small](https://content.instructables.com/ORIG/FT4/S6Q2/KZ6ZPQUJ/FT4S6Q2KZ6ZPQUJ.png?auto=webp&width=1600&height=900&fit=bounds&md=b5da4519b7b8b97fd7f72b2127392bb0) 58 | ![github-small](https://content.instructables.com/ORIG/F19/XINT/KZ6ZPQVA/F19XINTKZ6ZPQVA.png?auto=webp&width=1600&height=900&fit=bounds&md=c8a9e3602130d7843ac3aac949a8c047) 59 | 60 |

First, I buffed up the plastic surface with some sand paper to make the surface rough. This was to make sure that the enclosure would hold the paint well.

Then, I masked the parts of Wemos that was protruding with some paper tape.

After roughing up the enclosure surfaces, gave it a good dose of black spay paint and left it to dry for 48 hours. The paint could have dried earlier, but did not want to check just in case.


61 | 62 | 63 | ## Hurdle No 2 - My Mistake 64 | 65 | ![github-small](https://content.instructables.com/ORIG/F5L/HPE0/KZ7C5546/F5LHPE0KZ7C5546.png?auto=webp&width=1600&height=900&fit=bounds&md=75c7d3f39048c532379740a286c2e9cf) 66 | ![github-small](https://content.instructables.com/ORIG/FJ2/XK2M/KZ6ZPQVC/FJ2XK2MKZ6ZPQVC.png?auto=webp&width=1600&height=900&fit=bounds&md=506b4e0eb5ff6b6dbf72a9f8cf04df60) 67 | ![github-small](https://content.instructables.com/ORIG/FF2/N9X0/KZ6ZPQVE/FF2N9X0KZ6ZPQVE.png?auto=webp&width=1600&height=900&fit=bounds&md=97d0664364c6eae44f5f43f5a460d01d) 68 | ![github-small](https://content.instructables.com/ORIG/FUY/WFSE/KZ7C59RI/FUYWFSEKZ7C59RI.png?auto=webp&width=1600&height=900&fit=bounds&md=cc872073d4d6e4343084eedb5c57e833) 69 | 70 |

After putting altogether as per the attached schematic, tried to see if the device could pickup any gestures with sample code previously used. The sensor was working, as you could clearly see the infrared light from the sensor. But there was nothing on the Serial Monitor.

Tried to see if I could figure out anything from the datasheet and it was a dead end. At this point, I had two probable causes:

  1. The indicator light was interfering with the detector, or
  2. The hole was not large enough for the detection cone of the sensor

Just to check on both, took out the LED and the sensor out of the enclosure and while holding the LED just above the sensor, tried some gestures and it was working. So the culprit was the hole.

So i decided to fully expose the sensor just to not run into similar issues again.

71 | 72 | 73 | ## Putting It Together The Second Time And Properly 74 | 75 | ![github-small](https://content.instructables.com/ORIG/FDC/Y360/KZ6ZPQVF/FDCY360KZ6ZPQVF.png?auto=webp&width=1600&height=900&fit=bounds&md=df0fff8d4f157813c1bc22c9768dc5ec) 76 | ![github-small](https://content.instructables.com/ORIG/F7N/UH3J/KZ7C5F8G/F7NUH3JKZ7C5F8G.jpg?auto=webp&width=1600&height=900&fit=bounds&md=e6e7e14c9885f203c10da38dc5c40136) 77 | ![github-small](https://content.instructables.com/ORIG/FJW/7YDE/KZ7C5FDB/FJW7YDEKZ7C5FDB.png?auto=webp&width=1600&height=900&fit=bounds&md=b0eb7093c12292f7ab2ecc45d78c5ad1) 78 | ![github-small](https://content.instructables.com/ORIG/FKJ/L4W1/KZ7C5FDF/FKJL4W1KZ7C5FDF.png?auto=webp&width=1600&height=900&fit=bounds&md=d6dd0fd8d7e4a2ee68c7ab2340bde546) 79 | ![github-small](https://content.instructables.com/ORIG/FLJ/TYGL/KZ7C5FDG/FLJTYGLKZ7C5FDG.png?auto=webp&width=1600&height=900&fit=bounds&md=1996a906da932b97fc5343b614fac0ec) 80 | 81 |

I measured the seize of the wooden backplate that was previously used and replaced it with a double sided PCB. Drilled the matching holes on the PCB and held them in place securely using two M2.5 screws. The LED and the connections to the sensor were bonded to the backplate with some hot glue.

The connections were made using just the jumper wires. Not clean, but I did not mind as they going to be unseen inside the enclosure. Instead if you want something neat, I have prepared a gesture sensor shield for the Wemos. You can find the Gerber files here. For PCB fabrication, you can use JLCPCB's service. With their online Gerber viewer, you can verify the PCB design before ordering and they have different PCB colors to choose from. Use this link https://jlcpcb.com/IAT for great discounts and minimal PCB fabrication costs. If you want to create your own design, you can modify the board design with the Fritzing file I have provided here.

I modified the sample code from the ArduCastControl library and combined it with the modified gesture sensor code. You can find the modified libraries here and the sample code here.

There something else you need to mind. The code is dependent on other libraries as well.

  • ArduinoJson version=6.18.5
  • Arduino_JSON version=0.1.0
  • SnappyProto version=0.1.2

For your own use, make sure to declare the IP address of your Chromecast and also your WiFi SSID and WiFi password in the code/script. The locations for these declarations have marked clearly.

After compiling and verification, I decided to power the setup with a power bank. I could place this easily on the sofa armrest and control the Chromecast.

82 | 83 | 84 | ## Purpose Of The Indicator LED 85 | 86 | [![LED Working](https://i.imgur.com/t0xGlhg.jpg)](https://www.youtube.com/watch?v=996fY4w48jY "Remote Control Chromecast with Gestures Using ESP8266 NodeMCU LED Status Indication") 87 | 88 |

I have assigned specific behavioral patterns to the indicator LED.

  • If the LED blinks every 1 second, it means that the WiFi connection has got disconnected.
  • If the LED blinks in long intervals, it means that it is unable to shake hands with the Chromecast.
  • If the LED pulses constantly, it means that its constantly communicating with the Chromecast.
  • If the LED momentarily blinks while pulsing, it means that it has picked up a gesture.
89 | 90 | 91 | ## Demo: And The Controls 92 | 93 | [![LED Working](https://i.imgur.com/bBZJQ8A.jpg)](https://www.youtube.com/watch?v=0buSCjYbQNg "Remote Control Chromecast with Gestures Using ESP8266 NodeMCU Gestures Working Demo") 94 | 95 |

The gesture sensor can inherently detect 4 gestures:

  • Right swipe.
  • Left swipe.
  • Top swipe and
  • Bottom swipe.

Thanks to Sparkfun, we have two additional gestures:

  • Far swipe and
  • Near swipe.

For Far swipe, you need to start close to the sensor and take your hand away and for Near swipe, its the opposite, you need to start Far away and bring your hand close to the sensor.

I have integrated these 6 gestures with 6 different Chromecast controls.

  1. Right swipe will Seek or move the video forward by 10 seconds.
  2. Left swipe will Seek or move the video backward by 10 seconds.
  3. Top swipe will increase the volume by 1 unit.
  4. Bottom swipe will reduce the volume by 1 unit
  5. Far swipe will Pause/Unpause the video.
  6. Near swipe will Mute/Unmute the video.

I have shown the working of the gadget in the attached video. Hope you do create your own device and have fun.

96 | 97 | 98 | 99 | --------------------------------------------------------------------------------