485 lines
14 KiB
C
485 lines
14 KiB
C
|
/*
|
||
|
* 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 <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
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));
|
||
|
}
|