/* * ESP8266 + FastLED + IR Remote + MSGEQ7: https://github.com/jasoncoon/esp8266-fastled-webserver * Copyright (C) 2015 Jason Coon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ enum class InputCommand { None, Up, Down, Left, Right, Select, Brightness, PlayMode, Palette, Power, BrightnessUp, BrightnessDown, Pattern1, Pattern2, Pattern3, Pattern4, Pattern5, Pattern6, Pattern7, Pattern8, Pattern9, Pattern10, Pattern11, Pattern12, RedUp, RedDown, GreenUp, GreenDown, BlueUp, BlueDown, Red, RedOrange, Orange, YellowOrange, Yellow, Green, Lime, Aqua, Teal, Navy, Blue, RoyalBlue, Purple, Indigo, Magenta, White, Pink, LightPink, BabyBlue, LightBlue, }; // IR Raw Key Codes for SparkFun remote #define IRCODE_SPARKFUN_POWER 0x10EFD827 // 284153895 #define IRCODE_SPARKFUN_A 0x10EFF807 // #define IRCODE_SPARKFUN_B 0x10EF7887 #define IRCODE_SPARKFUN_C 0x10EF58A7 #define IRCODE_SPARKFUN_UP 0x10EFA05F // 284139615 #define IRCODE_SPARKFUN_LEFT 0x10EF10EF #define IRCODE_SPARKFUN_SELECT 0x10EF20DF #define IRCODE_SPARKFUN_RIGHT 0x10EF807F #define IRCODE_SPARKFUN_DOWN 0x10EF00FF #define IRCODE_SPARKFUN_HELD 0xFFFFFFFF // IR Raw Key Codes for Adafruit remote #define IRCODE_ADAFRUIT_HELD 0x7FFFFFFF // 4294967295 #define IRCODE_ADAFRUIT_VOLUME_UP 0x00FD40BF // 16597183 #define IRCODE_ADAFRUIT_PLAY_PAUSE 0x00FD807F // 16613503 #define IRCODE_ADAFRUIT_VOLUME_DOWN 0x00FD00FF // 16580863 #define IRCODE_ADAFRUIT_SETUP 0x00FD20DF // 16589023 #define IRCODE_ADAFRUIT_UP 0x00FDA05F // 16621663 #define IRCODE_ADAFRUIT_STOP_MODE 0x00FD609F // 16605343 #define IRCODE_ADAFRUIT_LEFT 0x00FD10EF // 16584943 #define IRCODE_ADAFRUIT_ENTER_SAVE 0x00FD906F // 16617583 #define IRCODE_ADAFRUIT_RIGHT 0x00FD50AF // 16601263 #define IRCODE_ADAFRUIT_0_10_PLUS 0x00FD30CF // 16593103 #define IRCODE_ADAFRUIT_DOWN 0x00FDB04F // 16625743 #define IRCODE_ADAFRUIT_BACK 0x00FD708F // 16609423 #define IRCODE_ADAFRUIT_1 0x00FD08F7 // 16582903 #define IRCODE_ADAFRUIT_2 0x00FD8877 // 16615543 #define IRCODE_ADAFRUIT_3 0x00FD48B7 // 16599223 #define IRCODE_ADAFRUIT_4 0x00FD28D7 // 16591063 #define IRCODE_ADAFRUIT_5 0x00FDA857 // 16623703 #define IRCODE_ADAFRUIT_6 0x00FD6897 // 16607383 #define IRCODE_ADAFRUIT_7 0x00FD18E7 // 16586983 #define IRCODE_ADAFRUIT_8 0x00FD9867 // 16619623 #define IRCODE_ADAFRUIT_9 0x00FD58A7 // 16603303 // IR Raw Key Codes for eTopxizu 44Key IR Remote Controller for 5050 3528 RGB LED Light Strip #define IRCODE_ETOPXIZU_HELD 0x7FFFFFFF // 4294967295 #define IRCODE_ETOPXIZU_POWER 16712445 #define IRCODE_ETOPXIZU_PLAY_PAUSE 16745085 #define IRCODE_ETOPXIZU_BRIGHTNESS_UP 16726725 #define IRCODE_ETOPXIZU_BRIGHTNESS_DOWN 16759365 #define IRCODE_ETOPXIZU_DIY1 16724175 #define IRCODE_ETOPXIZU_DIY2 16756815 #define IRCODE_ETOPXIZU_DIY3 16740495 #define IRCODE_ETOPXIZU_DIY4 16716015 #define IRCODE_ETOPXIZU_DIY5 16748655 #define IRCODE_ETOPXIZU_DIY6 16732335 #define IRCODE_ETOPXIZU_JUMP3 16720095 #define IRCODE_ETOPXIZU_JUMP7 16752735 #define IRCODE_ETOPXIZU_FADE3 16736415 #define IRCODE_ETOPXIZU_FADE7 16769055 #define IRCODE_ETOPXIZU_FLASH 16764975 #define IRCODE_ETOPXIZU_AUTO 16773135 #define IRCODE_ETOPXIZU_QUICK 16771095 #define IRCODE_ETOPXIZU_SLOW 16762935 #define IRCODE_ETOPXIZU_RED_UP 16722135 #define IRCODE_ETOPXIZU_RED_DOWN 16713975 #define IRCODE_ETOPXIZU_GREEN_UP 16754775 #define IRCODE_ETOPXIZU_GREEN_DOWN 16746615 #define IRCODE_ETOPXIZU_BLUE_UP 16738455 #define IRCODE_ETOPXIZU_BLUE_DOWN 16730295 #define IRCODE_ETOPXIZU_RED 16718565 #define IRCODE_ETOPXIZU_RED_ORANGE 16722645 #define IRCODE_ETOPXIZU_ORANGE 16714485 #define IRCODE_ETOPXIZU_YELLOW_ORANGE 16726215 #define IRCODE_ETOPXIZU_YELLOW 16718055 #define IRCODE_ETOPXIZU_GREEN 16751205 #define IRCODE_ETOPXIZU_LIME 16755285 #define IRCODE_ETOPXIZU_AQUA 16747125 #define IRCODE_ETOPXIZU_TEAL 16758855 #define IRCODE_ETOPXIZU_NAVY 16750695 #define IRCODE_ETOPXIZU_BLUE 16753245 #define IRCODE_ETOPXIZU_ROYAL_BLUE 16749165 #define IRCODE_ETOPXIZU_PURPLE 16757325 #define IRCODE_ETOPXIZU_INDIGO 16742535 #define IRCODE_ETOPXIZU_MAGENTA 16734375 #define IRCODE_ETOPXIZU_WHITE 16720605 #define IRCODE_ETOPXIZU_PINK 16716525 #define IRCODE_ETOPXIZU_LIGHT_PINK 16724685 #define IRCODE_ETOPXIZU_BABY_BLUE 16775175 #define IRCODE_ETOPXIZU_LIGHT_BLUE 16767015 bool sparkfunRemoteEnabled = true; bool adafruitRemoteEnabled = true; bool etopxizuRemoteEnabled = true; // Low level IR code reading function // Function will return 0 if no IR code available unsigned long decodeIRCode() { decode_results results; results.value = 0; // Attempt to read an IR code ? if (irReceiver.decode(&results)) { delay(20); if (results.value != 0) Serial.println(results.value); // Prepare to receive the next IR code irReceiver.resume(); } return results.value; } // Read an IR code // Function will return 0 if no IR code available unsigned long readIRCode() { // Is there an IR code to read ? unsigned long code = decodeIRCode(); if (code == 0) { // No code so return 0 return 0; } // Keep reading until code changes while (decodeIRCode() == code) { ; } // Serial.println(code); return code; } unsigned long lastIrCode = 0; unsigned int holdStartTime = 0; unsigned int defaultHoldDelay = 500; bool isHolding = false; unsigned int zeroStartTime = 0; unsigned int zeroDelay = 120; unsigned long readIRCode(unsigned int holdDelay) { // read the raw code from the sensor unsigned long irCode = readIRCode(); //Serial.print(millis()); //Serial.print("\t"); //Serial.println(irCode); // don't return a short click until we know it's not a long hold // we'll have to wait for holdDelay ms to pass before returning a non-zero IR code // then, after that delay, as long as the button is held, we can keep returning the code // every time until it's released // the ir remote only sends codes every 107 ms or so (avg 106.875, max 111, min 102), // so the ir sensor will return 0 even if a button is held // so we have to wait longer than that before returning a non-zero code // in order to detect that a button has been released and is no longer held // only reset after we've gotten 0 back for more than the ir remote send interval unsigned int zeroTime = 0; if (irCode == 0) { zeroTime = millis() - zeroStartTime; if (zeroTime >= zeroDelay && lastIrCode != 0) { //Serial.println(F("zero delay has elapsed, returning last ir code")); // the button has been released for longer than the zero delay // start over delays over and return the last code irCode = lastIrCode; lastIrCode = 0; return irCode; } return 0; } // reset the zero timer every time a non-zero code is read zeroStartTime = millis(); unsigned int heldTime = 0; if (irCode == IRCODE_SPARKFUN_HELD || irCode == IRCODE_ADAFRUIT_HELD) { // has the hold delay passed? heldTime = millis() - holdStartTime; if (heldTime >= holdDelay) { isHolding = true; //Serial.println(F("hold delay has elapsed, returning last ir code")); return lastIrCode; } else if (holdStartTime == 0) { isHolding = false; holdStartTime = millis(); } } else { // not zero, not IRCODE_SPARKFUN_HELD // store it for use later, until the hold and zero delays have elapsed holdStartTime = millis(); isHolding = false; lastIrCode = irCode; return 0; } return 0; } void heldButtonHasBeenHandled() { lastIrCode = 0; isHolding = false; holdStartTime = 0; } unsigned long waitForIRCode() { unsigned long irCode = readIRCode(); while ((irCode == 0) || (irCode == 0xFFFFFFFF)) { delay(200); irCode = readIRCode(); } return irCode; } InputCommand getCommand(unsigned long input) { if (adafruitRemoteEnabled) { switch (input) { case IRCODE_ADAFRUIT_UP: return InputCommand::Up; case IRCODE_ADAFRUIT_DOWN: return InputCommand::Down; case IRCODE_ADAFRUIT_LEFT: return InputCommand::Left; case IRCODE_ADAFRUIT_RIGHT: return InputCommand::Right; case IRCODE_ADAFRUIT_ENTER_SAVE: return InputCommand::Select; case IRCODE_ADAFRUIT_STOP_MODE: case IRCODE_ADAFRUIT_1: return InputCommand::PlayMode; case IRCODE_ADAFRUIT_2: return InputCommand::Palette; case IRCODE_ADAFRUIT_PLAY_PAUSE: return InputCommand::Power; case IRCODE_ADAFRUIT_VOLUME_UP: return InputCommand::BrightnessUp; case IRCODE_ADAFRUIT_VOLUME_DOWN: return InputCommand::BrightnessDown; } } if (sparkfunRemoteEnabled) { switch (input) { case IRCODE_SPARKFUN_UP: return InputCommand::Up; case IRCODE_SPARKFUN_DOWN: return InputCommand::Down; case IRCODE_SPARKFUN_LEFT: return InputCommand::Left; case IRCODE_SPARKFUN_RIGHT: return InputCommand::Right; case IRCODE_SPARKFUN_SELECT: return InputCommand::Select; case IRCODE_SPARKFUN_POWER: return InputCommand::Brightness; case IRCODE_SPARKFUN_A: return InputCommand::PlayMode; case IRCODE_SPARKFUN_B: return InputCommand::Palette; } } if (etopxizuRemoteEnabled) { switch (input) { case IRCODE_ETOPXIZU_QUICK: return InputCommand::Up; case IRCODE_ETOPXIZU_SLOW: return InputCommand::Down; case IRCODE_ETOPXIZU_PLAY_PAUSE: return InputCommand::PlayMode; case IRCODE_ETOPXIZU_POWER: return InputCommand::Power; case IRCODE_ETOPXIZU_BRIGHTNESS_UP: return InputCommand::BrightnessUp; case IRCODE_ETOPXIZU_BRIGHTNESS_DOWN: return InputCommand::BrightnessDown; case IRCODE_ETOPXIZU_DIY1: return InputCommand::Pattern1; case IRCODE_ETOPXIZU_DIY2: return InputCommand::Pattern2; case IRCODE_ETOPXIZU_DIY3: return InputCommand::Pattern3; case IRCODE_ETOPXIZU_DIY4: return InputCommand::Pattern4; case IRCODE_ETOPXIZU_DIY5: return InputCommand::Pattern5; case IRCODE_ETOPXIZU_DIY6: return InputCommand::Pattern6; case IRCODE_ETOPXIZU_JUMP3: return InputCommand::Pattern7; case IRCODE_ETOPXIZU_JUMP7: return InputCommand::Pattern8; case IRCODE_ETOPXIZU_FADE3: return InputCommand::Pattern9; case IRCODE_ETOPXIZU_FADE7: return InputCommand::Pattern10; case IRCODE_ETOPXIZU_FLASH: return InputCommand::Pattern11; case IRCODE_ETOPXIZU_AUTO: return InputCommand::Pattern12; case IRCODE_ETOPXIZU_RED_UP: return InputCommand::RedUp; case IRCODE_ETOPXIZU_RED_DOWN: return InputCommand::RedDown; case IRCODE_ETOPXIZU_GREEN_UP: return InputCommand::GreenUp; case IRCODE_ETOPXIZU_GREEN_DOWN: return InputCommand::GreenDown; case IRCODE_ETOPXIZU_BLUE_UP: return InputCommand::BlueUp; case IRCODE_ETOPXIZU_BLUE_DOWN: return InputCommand::BlueDown; case IRCODE_ETOPXIZU_RED: return InputCommand::Red; case IRCODE_ETOPXIZU_RED_ORANGE: return InputCommand::RedOrange; case IRCODE_ETOPXIZU_ORANGE: return InputCommand::Orange; case IRCODE_ETOPXIZU_YELLOW_ORANGE: return InputCommand::YellowOrange; case IRCODE_ETOPXIZU_YELLOW: return InputCommand::Yellow; case IRCODE_ETOPXIZU_GREEN: return InputCommand::Green; case IRCODE_ETOPXIZU_LIME: return InputCommand::Lime; case IRCODE_ETOPXIZU_AQUA: return InputCommand::Aqua; case IRCODE_ETOPXIZU_TEAL: return InputCommand::Teal; case IRCODE_ETOPXIZU_NAVY: return InputCommand::Navy; case IRCODE_ETOPXIZU_BLUE: return InputCommand::Blue; case IRCODE_ETOPXIZU_ROYAL_BLUE: return InputCommand::RoyalBlue; case IRCODE_ETOPXIZU_PURPLE: return InputCommand::Purple; case IRCODE_ETOPXIZU_INDIGO: return InputCommand::Indigo; case IRCODE_ETOPXIZU_MAGENTA: return InputCommand::Magenta; case IRCODE_ETOPXIZU_WHITE: return InputCommand::White; case IRCODE_ETOPXIZU_PINK: return InputCommand::Pink; case IRCODE_ETOPXIZU_LIGHT_PINK: return InputCommand::LightPink; case IRCODE_ETOPXIZU_BABY_BLUE: return InputCommand::BabyBlue; case IRCODE_ETOPXIZU_LIGHT_BLUE: return InputCommand::LightBlue; } } return InputCommand::None; } InputCommand readCommand() { return getCommand(readIRCode()); } InputCommand readCommand(unsigned int holdDelay) { return getCommand(readIRCode(holdDelay)); }