Change IRremoteESP8266 library updated to v2.7.4

This commit is contained in:
Hadinger 2020-02-29 13:51:16 +01:00
parent be1b0e7c86
commit 4008b9ed3e
242 changed files with 2623 additions and 941 deletions

View File

@ -9,8 +9,8 @@
This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an
[ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc.
## v2.7.3 Now Available
Version 2.7.3 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
## v2.7.4 Now Available
Version 2.7.4 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
#### Upgrading from pre-v2.0
Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.

View File

@ -9,8 +9,8 @@
Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole
[ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc.
## v2.7.3 disponible
Version 2.7.3 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
## v2.7.4 disponible
Version 2.7.4 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
#### mise à jour depuis pre-v2.0
L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.

View File

@ -1,5 +1,25 @@
# Release Notes
## _v2.7.4 (20200226)_
**[Bug Fixes]**
- IRMQTTServer: Fix bug when receiving an IR A/C message and not re-transmitting it. (#1035, #1038)
- Coolix: `setRaw()` doesn't update power state. (#1040, #1041)
**[Features]**
- Electra: Add improved feature support. (#1033, #1051)
- Add support for Epson protocol. (#1034, #1050)
- Add options to `decode()` to aid detection. Improve NEC detection. (#1042, #1046)
- SamsungAc: Add support for Light & Ion (VirusDoctor). (#1045, #1048, #1049)
- Add Italian (it-IT) locale/language support. (#1047) (kudos @egueli)
- gc_decode: Add repeat support for pronto codes. (#1034, #1043)
**[Misc]**
- Update supported SamsungAc devices (#1045)
- Coolix: Subtle protocol timing adjustments (#1036, #1037)
- Add supported Electra device model info (#1033)
## _v2.7.3 (20200130)_
**[Features]**

View File

@ -1,6 +1,6 @@
<!--- WARNING: Do NOT edit this file directly.
It is generated by './tools/scrape_supported_devices.py'.
Last generated: Thu Jan 30 20:05:33 2020 --->
Last generated: Wed Feb 26 16:31:08 2020 --->
# IR Protocols supported by this library
| Protocol | Brand | Model | A/C Model | Detailed A/C Support |
@ -16,6 +16,8 @@
| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - |
| [Dish](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Dish.cpp) | **DISH NETWORK** | echostar 301 | | - |
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AUX](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | KFR-35GW/BpNFW=3 A/C<BR>YKR-T/011 remote | | Yes |
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | Classic INV 17 / AXW12DCS A/C<BR>YKR-M/003E remote | | Yes |
| [Epson](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Epson.cpp) | **Unknown** | | | - |
| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AGTV14LAC A/C<BR>AR-DB1 remote<BR>AR-DL10 remote<BR>AR-RAC1E remote<BR>AR-RAE1E remote<BR>AR-RAH2E remote<BR>AR-REB1E remote<BR>AR-RY4 remote<BR>AST9RSGCW A/C<BR>ASTB09LBC A/C<BR>ASU30C1 A/C<BR>ASYG30LFCA A/C<BR>ASYG7LMCA A/C | ARDB1<BR>ARJW2<BR>ARRAH2E<BR>ARREB1E<BR>ARRY4 | Yes |
| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu General](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AR-JW2 remote | ARDB1<BR>ARJW2<BR>ARRAH2E<BR>ARREB1E<BR>ARRY4 | Yes |
| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **Unknown** | | | - |
@ -54,7 +56,7 @@
| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Unknown** | | | - |
| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Unknown** | | | - |
| [RCMM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RCMM.cpp) | **Microsoft** | XBOX 360 | | - |
| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR12HSSDBWKNEU A/C<BR>AR12KSFPEWQNET A/C<BR>IEC-R03 remote<BR>UA55H6300 TV | | Yes |
| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR09FSSDAWKNFA A/C<BR>AR12HSSDBWKNEU A/C<BR>AR12KSFPEWQNET A/C<BR>DB63-03556X003 remote<BR>IEC-R03 remote<BR>UA55H6300 TV | | Yes |
| [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Unknown** | | | - |
| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AY-ZP40KR A/C<BR>LC-52D62U TV | | Yes |
| [Sherwood](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sherwood.cpp) | **Sherwood** | RC-138 remote<BR>RD6505(B) Receiver | | - |
@ -94,6 +96,7 @@
- DENON
- DISH
- ELECTRA_AC
- EPSON
- FUJITSU_AC
- GICABLE
- GOODWEATHER

View File

@ -239,7 +239,7 @@ const uint16_t kJsonAcStateMaxSize = 1024; // Bytes
// ----------------- End of User Configuration Section -------------------------
// Constants
#define _MY_VERSION_ "v1.4.5"
#define _MY_VERSION_ "v1.4.6"
const uint8_t kRebootTime = 15; // Seconds
const uint8_t kQuickDisplayTime = 2; // Seconds

View File

@ -2679,7 +2679,7 @@ uint64_t getUInt64fromHex(char const *str) {
// code: Numeric payload of the IR message. Most protocols use this.
// code_str: The unparsed code to be sent. Used by complex protocol encodings.
// bits: Nr. of bits in the protocol. 0 means use the protocol's default.
// repeat: Nr. of times the message is to be repeated. (Not all protcols.)
// repeat: Nr. of times the message is to be repeated. (Not all protocols.)
// Returns:
// bool: Successfully sent or not.
bool sendIRCode(IRsend *irsend, decode_type_t const ir_type,
@ -3071,6 +3071,10 @@ bool sendClimate(const String topic_prefix, const bool retain,
lastClimateIr.reset();
irClimateCounter++;
}
// Mark the "next" value as old/previous.
if (ac != NULL) {
ac->markAsSent();
}
return success;
}
@ -3098,20 +3102,20 @@ bool decodeCommonAc(const decode_results *decode) {
}
#if IGNORE_DECODED_AC_PROTOCOL
if (climate[0]->next.protocol != decode_type_t::UNKNOWN) {
// Use the previous protcol/model if set.
// Use the previous protocol/model if set.
state.protocol = climate[0]->next.protocol;
state.model = climate[0]->next.model;
}
#endif // IGNORE_DECODED_AC_PROTOCOL
// Continue to use the previously prefered temperature units.
// i.e. Keep using Celsius or Fahrenheit.
if (climate[0]->next.celsius != state.celsius) {
// We've got a mismatch, so we need to convert.
state.degrees = climate[0]->next.celsius ? fahrenheitToCelsius(state.degrees)
: celsiusToFahrenheit(state.degrees);
state.celsius = climate[0]->next.celsius;
}
climate[0]->next = state; // Copy over the new climate state.
// Continue to use the previously prefered temperature units.
// i.e. Keep using Celsius or Fahrenheit.
if (climate[0]->next.celsius != state.celsius) {
// We've got a mismatch, so we need to convert.
state.degrees = climate[0]->next.celsius ?
fahrenheitToCelsius(state.degrees) : celsiusToFahrenheit(state.degrees);
state.celsius = climate[0]->next.celsius;
}
climate[0]->next = state; // Copy over the new climate state.
#if MQTT_ENABLE
sendClimate(genStatTopic(0), true, false, REPLAY_DECODED_AC_MESSAGE,
REPLAY_DECODED_AC_MESSAGE, climate[0]);

View File

@ -17,7 +17,7 @@
* Version 0.4 July, 2018
* - Minor improvements and more A/C unit support.
* Version 0.3 November, 2017
* - Support for A/C decoding for some protcols.
* - Support for A/C decoding for some protocols.
* Version 0.2 April, 2017
* - Decode from a copy of the data so we can start capturing faster thus
* reduce the likelihood of miscaptures.

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -133,6 +133,7 @@ convertSwingV KEYWORD2
coolix KEYWORD2
copyIrParams KEYWORD2
countBits KEYWORD2
crudeNoiseFilter KEYWORD2
daikin KEYWORD2
daikin128 KEYWORD2
daikin152 KEYWORD2
@ -156,6 +157,7 @@ decodeDaikin2 KEYWORD2
decodeDaikin216 KEYWORD2
decodeDenon KEYWORD2
decodeElectraAC KEYWORD2
decodeEpson KEYWORD2
decodeFujitsuAC KEYWORD2
decodeGICable KEYWORD2
decodeGoodweather KEYWORD2
@ -252,6 +254,7 @@ getCorrectedRawLength KEYWORD2
getCurrTime KEYWORD2
getCurrentDay KEYWORD2
getCurrentTime KEYWORD2
getDisplay KEYWORD2
getEcono KEYWORD2
getEye KEYWORD2
getEyeAuto KEYWORD2
@ -355,6 +358,7 @@ ledOff KEYWORD2
ledOn KEYWORD2
lg KEYWORD2
mark KEYWORD2
markAsSent KEYWORD2
match KEYWORD2
matchAtLeast KEYWORD2
matchBytes KEYWORD2
@ -406,6 +410,7 @@ sendDaikin216 KEYWORD2
sendData KEYWORD2
sendDenon KEYWORD2
sendElectraAC KEYWORD2
sendEpson KEYWORD2
sendExtended KEYWORD2
sendFujitsuAC KEYWORD2
sendGC KEYWORD2
@ -484,6 +489,7 @@ setCommand KEYWORD2
setCurrTime KEYWORD2
setCurrentDay KEYWORD2
setCurrentTime KEYWORD2
setDisplay KEYWORD2
setEcono KEYWORD2
setEye KEYWORD2
setEyeAuto KEYWORD2
@ -666,6 +672,7 @@ DECODE_DAIKIN216 LITERAL1
DECODE_DENON LITERAL1
DECODE_DISH LITERAL1
DECODE_ELECTRA_AC LITERAL1
DECODE_EPSON LITERAL1
DECODE_FUJITSU_AC LITERAL1
DECODE_GICABLE LITERAL1
DECODE_GLOBALCACHE LITERAL1
@ -728,6 +735,8 @@ DG11J191 LITERAL1
DISH LITERAL1
DISH_BITS LITERAL1
ELECTRA_AC LITERAL1
ENABLE_NOISE_FILTER_OPTION LITERAL1
EPSON LITERAL1
FUJITSU_AC LITERAL1
FUJITSU_AC_BITS LITERAL1
FUJITSU_AC_CMD_STAY_ON LITERAL1
@ -964,6 +973,7 @@ SEND_DAIKIN216 LITERAL1
SEND_DENON LITERAL1
SEND_DISH LITERAL1
SEND_ELECTRA_AC LITERAL1
SEND_EPSON LITERAL1
SEND_FUJITSU_AC LITERAL1
SEND_GICABLE LITERAL1
SEND_GLOBALCACHE LITERAL1
@ -1634,6 +1644,7 @@ kEconoStr LITERAL1
kElectraAcAuto LITERAL1
kElectraAcBitMark LITERAL1
kElectraAcBits LITERAL1
kElectraAcCleanOffset LITERAL1
kElectraAcCool LITERAL1
kElectraAcDry LITERAL1
kElectraAcFan LITERAL1
@ -1646,6 +1657,9 @@ kElectraAcFanSize LITERAL1
kElectraAcHdrMark LITERAL1
kElectraAcHdrSpace LITERAL1
kElectraAcHeat LITERAL1
kElectraAcLightToggleMask LITERAL1
kElectraAcLightToggleOff LITERAL1
kElectraAcLightToggleOn LITERAL1
kElectraAcMaxTemp LITERAL1
kElectraAcMessageGap LITERAL1
kElectraAcMinRepeat LITERAL1
@ -1662,7 +1676,10 @@ kElectraAcSwingVOffset LITERAL1
kElectraAcTempDelta LITERAL1
kElectraAcTempOffset LITERAL1
kElectraAcTempSize LITERAL1
kElectraAcTurboOffset LITERAL1
kElectraAcZeroSpace LITERAL1
kEpsonBits LITERAL1
kEpsonMinRepeat LITERAL1
kEyeAutoStr LITERAL1
kEyeStr LITERAL1
kFalseStr LITERAL1
@ -2763,6 +2780,7 @@ kSamsungAcClean10Offset LITERAL1
kSamsungAcClean11Offset LITERAL1
kSamsungAcCool LITERAL1
kSamsungAcDefaultRepeat LITERAL1
kSamsungAcDisplayOffset LITERAL1
kSamsungAcDry LITERAL1
kSamsungAcExtendedBits LITERAL1
kSamsungAcExtendedStateLength LITERAL1
@ -2778,6 +2796,7 @@ kSamsungAcFanTurbo LITERAL1
kSamsungAcHdrMark LITERAL1
kSamsungAcHdrSpace LITERAL1
kSamsungAcHeat LITERAL1
kSamsungAcIonOffset LITERAL1
kSamsungAcMaxTemp LITERAL1
kSamsungAcMinTemp LITERAL1
kSamsungAcModeOffset LITERAL1

View File

@ -1,6 +1,6 @@
{
"name": "IRremoteESP8266",
"version": "2.7.3",
"version": "2.7.4",
"keywords": "infrared, ir, remote, esp8266, esp32",
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
"repository":

View File

@ -1,7 +1,7 @@
name=IRremoteESP8266
version=2.7.3
version=2.7.4
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
maintainer=Mark Szabo, David Conran, Sebastien Warin, Roi Dayan, Massimiliano Pinto
maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto
sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32)
paragraph=This library enables you to send and receive infra-red signals on an ESP8266 or an ESP32.
category=Device Control

View File

@ -45,7 +45,7 @@ IRac::IRac(const uint16_t pin, const bool inverted, const bool use_modulation) {
_inverted = inverted;
_modulation = use_modulation;
initState(&next);
_prev = next;
this->markAsSent();
}
void IRac::initState(stdAc::state_t *state,
@ -466,7 +466,8 @@ void IRac::electra(IRElectraAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh) {
const stdAc::swingh_t swingh, const bool turbo,
const bool lighttoggle, const bool clean) {
ac->begin();
ac->setPower(on);
ac->setMode(ac->convertMode(mode));
@ -475,11 +476,12 @@ void IRac::electra(IRElectraAc *ac,
ac->setSwingV(swingv != stdAc::swingv_t::kOff);
ac->setSwingH(swingh != stdAc::swingh_t::kOff);
// No Quiet setting available.
// No Turbo setting available.
ac->setTurbo(turbo);
ac->setLightToggle(lighttoggle);
// No Light setting available.
// No Econo setting available.
// No Filter setting available.
// No Clean setting available.
ac->setClean(clean);
// No Beep setting available.
// No Sleep setting available.
// No Clock setting available.
@ -968,7 +970,8 @@ void IRac::samsung(IRSamsungAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool quiet, const bool turbo, const bool clean,
const bool quiet, const bool turbo, const bool light,
const bool filter, const bool clean,
const bool beep, const bool prevpower,
const bool forcepower) {
ac->begin();
@ -981,9 +984,9 @@ void IRac::samsung(IRSamsungAc *ac,
// No Horizontal swing setting available.
ac->setQuiet(quiet);
ac->setPowerful(turbo);
// No Light setting available.
ac->setDisplay(light);
// No Econo setting available.
// No Filter setting available.
ac->setIon(filter);
ac->setClean(clean);
ac->setBeep(beep);
// No Sleep setting available.
@ -1219,6 +1222,9 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
result.power = desired.power ^ prev->power;
result.light = desired.light ^ prev->light;
break;
case decode_type_t::ELECTRA_AC:
result.light = desired.light ^ prev->light;
break;
case decode_type_t::MIDEA:
case decode_type_t::HITACHI_AC424:
if ((desired.swingv == stdAc::swingv_t::kOff) ^
@ -1389,7 +1395,7 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
{
IRElectraAc ac(_pin, _inverted, _modulation);
electra(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
send.swingh);
send.swingh, send.turbo, send.light, send.clean);
break;
}
#endif // SEND_ELECTRA_AC
@ -1557,7 +1563,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
{
IRSamsungAc ac(_pin, _inverted, _modulation);
samsung(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
send.quiet, send.turbo, send.clean, send.beep, prev->power);
send.quiet, send.turbo, send.light, send.filter, send.clean,
send.beep, prev->power);
break;
}
#endif // SEND_SAMSUNG_AC
@ -1628,13 +1635,18 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
return true; // Success.
}
// Update the previous state to the current one.
void IRac::markAsSent(void) {
_prev = next;
}
// Send an A/C message based soley on our internal state.
//
// Returns:
// boolean: True, if accepted/converted/attempted. False, if unsupported.
bool IRac::sendAc(void) {
bool success = this->sendAc(next, &_prev);
_prev = next;
if (success) this->markAsSent();
return success;
}
@ -2232,7 +2244,6 @@ namespace IRAcUtils {
#if DECODE_COOLIX
case decode_type_t::COOLIX: {
IRCoolixAC ac(kGpioUnused);
ac.on();
ac.setRaw(decode->value); // Uses value instead of state.
*result = ac.toCommon(prev);
break;

View File

@ -54,6 +54,7 @@ class IRac {
const bool beep, const int16_t sleep,
const int16_t clock);
static void initState(stdAc::state_t *state);
void markAsSent(void);
bool sendAc(void);
bool sendAc(const stdAc::state_t desired, const stdAc::state_t *prev = NULL);
bool sendAc(const decode_type_t vendor, const int16_t model,
@ -170,7 +171,8 @@ void electra(IRElectraAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh);
const stdAc::swingh_t swingh, const bool turbo,
const bool lighttoggle, const bool clean);
#endif // SEND_ELECTRA_AC
#if SEND_FUJITSU_AC
void fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model,
@ -299,7 +301,8 @@ void electra(IRElectraAc *ac,
void samsung(IRSamsungAc *ac,
const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool quiet, const bool turbo, const bool clean,
const bool quiet, const bool turbo, const bool light,
const bool filter, const bool clean,
const bool beep, const bool prevpower = true,
const bool forcepower = true);
#endif // SEND_SAMSUNG_AC

View File

@ -307,6 +307,37 @@ void IRrecv::setTolerance(const uint8_t percent) {
// Get the base tolerance percentage for matching incoming IR messages.
uint8_t IRrecv::getTolerance(void) { return _tolerance; }
#if ENABLE_NOISE_FILTER_OPTION
// Remove or merge pulses in the capture buffer that are too short.
// Args:
// results: Ptr to the decode_results we are going to filter/modify.
// floor: Only allow values in the buffer large than this. (in micro seconds)
void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) {
if (floor == 0) return; // Nothing to do.
const uint16_t kTickFloor = floor / kRawTick;
const uint16_t kBufSize = getBufSize();
uint16_t offset = kStartOffset;
while (offset < results->rawlen && offset + 2 < kBufSize) {
uint16_t curr = results->rawbuf[offset];
uint16_t next = results->rawbuf[offset + 1];
uint16_t addition = curr + next;
if (curr < kTickFloor) { // Is it too short?
// Shuffle the buffer down. i.e. Remove the mark & space pair.
// Note: `memcpy()` can't be used as rawbuf is `volatile`.
for (uint16_t i = offset + 2; i <= results->rawlen && i < kBufSize; i++)
results->rawbuf[i - 2] = results->rawbuf[i];
if (offset > 1) { // There is a previous pair we can add to.
// Merge this pair into into the previous space.
results->rawbuf[offset - 1] += addition;
}
results->rawlen -= 2; // Adjust the length.
} else {
offset++; // Move along.
}
}
}
#endif // ENABLE_NOISE_FILTER_OPTION
// Decodes the received IR message.
// If the interrupt state is saved, we will immediately resume waiting
// for the next IR message to avoid missing messages.
@ -317,9 +348,41 @@ uint8_t IRrecv::getTolerance(void) { return _tolerance; }
// results: A pointer to where the decoded IR message will be stored.
// save: A pointer to an irparams_t instance in which to save
// the interrupt's memory/state. NULL means don't save it.
// max_skip: Maximum Nr. of pulses at the begining of a capture we can skip
// when attempting to find a protocol we can successfully decode.
// This parameter can dramatically improve detection of protocols
// when there is light IR interference just before an incoming IR
// message, however, it comes at a steep performace price.
// CAUTION: Increasing this value will dramatically (linnearly)
// increase the cpu time & usage to decode protocols.
// e.g. 0 -> 1 will be a 2x increase in cpu usage/time.
// 0 -> 2 will be a 3x increase etc.
// If you are going to do this, consider disabling
// protocol decoding for protocols you are not expecting.
// (Default is 0. No skipping.)
// noise_floor: Pulses below this size (in usecs) will be removed or merged
// prior to any decoding. This is to try to remove noise/poor
// readings & slighly increase the chances of a successful
// decode but at the cost of data fidelity & integrity.
// (Defaults to 0 usecs. i.e. Don't filter; which is safe!)
// DANGER: **Here Be Dragons!**
// If you set the `filter_floor` value too high, it **WILL**
// break decoding of some protocols. You have been warned!
// **Any** non-zero value has the potential to **cook** the
// captured raw data. i.e. The data is going to lie to you.
// It may obscure hardware, circuit, & environment issues thus
// making it impossible to support you accurately or
// confidently.
// Values of <= 50 usecs will probably be safe.
// 51 - 100 usecs **might** be okay.
// 100 - 150 usecs is "Danger, Will Robinson!".
// 150 - 200 usecs expect broken protocols.
// At 200+ usecs, you **have** protocols you can't decode!!
//
// Returns:
// A boolean indicating if an IR message is ready or not.
bool IRrecv::decode(decode_results *results, irparams_t *save) {
bool IRrecv::decode(decode_results *results, irparams_t *save,
uint8_t max_skip, uint16_t noise_floor) {
// Proceed only if an IR message been received.
#ifndef UNIT_TEST
if (irparams.rcvstate != kStopState) return false;
@ -365,320 +428,342 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
results->command = 0;
results->repeat = false;
#if ENABLE_NOISE_FILTER_OPTION
crudeNoiseFilter(results, noise_floor);
#endif // ENABLE_NOISE_FILTER_OPTION
// Keep looking for protocols until we've run out of entries to skip or we
// find a valid protocol message.
for (uint16_t offset = kStartOffset;
offset <= (max_skip * 2) + kStartOffset;
offset += 2) {
#if DECODE_AIWA_RC_T501
DPRINTLN("Attempting Aiwa RC T501 decode");
// Try decodeAiwaRCT501() before decodeSanyoLC7461() & decodeNEC()
// because the protocols are similar. This protocol is more specific than
// those ones, so should got before them.
if (decodeAiwaRCT501(results)) return true;
DPRINTLN("Attempting Aiwa RC T501 decode");
// Try decodeAiwaRCT501() before decodeSanyoLC7461() & decodeNEC()
// because the protocols are similar. This protocol is more specific than
// those ones, so should go before them.
if (decodeAiwaRCT501(results, offset)) return true;
#endif
#if DECODE_SANYO
DPRINTLN("Attempting Sanyo LC7461 decode");
// Try decodeSanyoLC7461() before decodeNEC() because the protocols are
// similar in timings & structure, but the Sanyo one is much longer than the
// NEC protocol (42 vs 32 bits) so this one should be tried first to try to
// reduce false detection as a NEC packet.
if (decodeSanyoLC7461(results)) return true;
DPRINTLN("Attempting Sanyo LC7461 decode");
// Try decodeSanyoLC7461() before decodeNEC() because the protocols are
// similar in timings & structure, but the Sanyo one is much longer than the
// NEC protocol (42 vs 32 bits) so this one should be tried first to try to
// reduce false detection as a NEC packet.
if (decodeSanyoLC7461(results, offset)) return true;
#endif
#if DECODE_CARRIER_AC
DPRINTLN("Attempting Carrier AC decode");
// Try decodeCarrierAC() before decodeNEC() because the protocols are
// similar in timings & structure, but the Carrier one is much longer than the
// NEC protocol (3x32 bits vs 1x32 bits) so this one should be tried first to
// try to reduce false detection as a NEC packet.
if (decodeCarrierAC(results)) return true;
DPRINTLN("Attempting Carrier AC decode");
// Try decodeCarrierAC() before decodeNEC() because the protocols are
// similar in timings & structure, but the Carrier one is much longer than
// the NEC protocol (3x32 bits vs 1x32 bits) so this one should be tried
// first to try to reduce false detection as a NEC packet.
if (decodeCarrierAC(results, offset)) return true;
#endif
#if DECODE_PIONEER
DPRINTLN("Attempting Pioneer decode");
// Try decodePioneer() before decodeNEC() because the protocols are
// similar in timings & structure, but the Pioneer one is much longer than the
// NEC protocol (2x32 bits vs 1x32 bits) so this one should be tried first to
// try to reduce false detection as a NEC packet.
if (decodePioneer(results)) return true;
DPRINTLN("Attempting Pioneer decode");
// Try decodePioneer() before decodeNEC() because the protocols are
// similar in timings & structure, but the Pioneer one is much longer than
// the NEC protocol (2x32 bits vs 1x32 bits) so this one should be tried
// first to try to reduce false detection as a NEC packet.
if (decodePioneer(results, offset)) return true;
#endif
#if DECODE_EPSON
DPRINTLN("Attempting Epson decode");
// Try decodeEpson() before decodeNEC() because the protocols are
// similar in timings & structure, but the Epson one is much longer than the
// NEC protocol (3x32 identical bits vs 1x32 bits) so this one should be tried
// first to try to reduce false detection as a NEC packet.
if (decodeEpson(results, offset)) return true;
#endif
#if DECODE_NEC
DPRINTLN("Attempting NEC decode");
if (decodeNEC(results)) return true;
DPRINTLN("Attempting NEC decode");
if (decodeNEC(results, offset)) return true;
#endif
#if DECODE_SONY
DPRINTLN("Attempting Sony decode");
if (decodeSony(results)) return true;
DPRINTLN("Attempting Sony decode");
if (decodeSony(results, offset)) return true;
#endif
#if DECODE_MITSUBISHI
DPRINTLN("Attempting Mitsubishi decode");
if (decodeMitsubishi(results)) return true;
DPRINTLN("Attempting Mitsubishi decode");
if (decodeMitsubishi(results, offset)) return true;
#endif
#if DECODE_MITSUBISHI_AC
DPRINTLN("Attempting Mitsubishi AC decode");
if (decodeMitsubishiAC(results)) return true;
DPRINTLN("Attempting Mitsubishi AC decode");
if (decodeMitsubishiAC(results, offset)) return true;
#endif
#if DECODE_MITSUBISHI2
DPRINTLN("Attempting Mitsubishi2 decode");
if (decodeMitsubishi2(results)) return true;
DPRINTLN("Attempting Mitsubishi2 decode");
if (decodeMitsubishi2(results, offset)) return true;
#endif
#if DECODE_RC5
DPRINTLN("Attempting RC5 decode");
if (decodeRC5(results)) return true;
DPRINTLN("Attempting RC5 decode");
if (decodeRC5(results, offset)) return true;
#endif
#if DECODE_RC6
DPRINTLN("Attempting RC6 decode");
if (decodeRC6(results)) return true;
DPRINTLN("Attempting RC6 decode");
if (decodeRC6(results, offset)) return true;
#endif
#if DECODE_RCMM
DPRINTLN("Attempting RC-MM decode");
if (decodeRCMM(results)) return true;
DPRINTLN("Attempting RC-MM decode");
if (decodeRCMM(results, offset)) return true;
#endif
#if DECODE_FUJITSU_AC
// Fujitsu A/C needs to precede Panasonic and Denon as it has a short
// message which looks exactly the same as a Panasonic/Denon message.
DPRINTLN("Attempting Fujitsu A/C decode");
if (decodeFujitsuAC(results)) return true;
// Fujitsu A/C needs to precede Panasonic and Denon as it has a short
// message which looks exactly the same as a Panasonic/Denon message.
DPRINTLN("Attempting Fujitsu A/C decode");
if (decodeFujitsuAC(results, offset)) return true;
#endif
#if DECODE_DENON
// Denon needs to precede Panasonic as it is a special case of Panasonic.
DPRINTLN("Attempting Denon decode");
if (decodeDenon(results, kDenon48Bits) || decodeDenon(results, kDenonBits) ||
decodeDenon(results, kDenonLegacyBits))
return true;
// Denon needs to precede Panasonic as it is a special case of Panasonic.
DPRINTLN("Attempting Denon decode");
if (decodeDenon(results, offset, kDenon48Bits) ||
decodeDenon(results, offset, kDenonBits) ||
decodeDenon(results, offset, kDenonLegacyBits))
return true;
#endif
#if DECODE_PANASONIC
DPRINTLN("Attempting Panasonic decode");
if (decodePanasonic(results)) return true;
DPRINTLN("Attempting Panasonic decode");
if (decodePanasonic(results, offset)) return true;
#endif
#if DECODE_LG
DPRINTLN("Attempting LG (28-bit) decode");
if (decodeLG(results, kLgBits, true)) return true;
DPRINTLN("Attempting LG (32-bit) decode");
// LG32 should be tried before Samsung
if (decodeLG(results, kLg32Bits, true)) return true;
DPRINTLN("Attempting LG (28-bit) decode");
if (decodeLG(results, offset, kLgBits, true)) return true;
DPRINTLN("Attempting LG (32-bit) decode");
// LG32 should be tried before Samsung
if (decodeLG(results, offset, kLg32Bits, true)) return true;
#endif
#if DECODE_GICABLE
// Note: Needs to happen before JVC decode, because it looks similar except
// with a required NEC-like repeat code.
DPRINTLN("Attempting GICable decode");
if (decodeGICable(results)) return true;
// Note: Needs to happen before JVC decode, because it looks similar except
// with a required NEC-like repeat code.
DPRINTLN("Attempting GICable decode");
if (decodeGICable(results, offset)) return true;
#endif
#if DECODE_JVC
DPRINTLN("Attempting JVC decode");
if (decodeJVC(results)) return true;
DPRINTLN("Attempting JVC decode");
if (decodeJVC(results, offset)) return true;
#endif
#if DECODE_SAMSUNG
DPRINTLN("Attempting SAMSUNG decode");
if (decodeSAMSUNG(results)) return true;
DPRINTLN("Attempting SAMSUNG decode");
if (decodeSAMSUNG(results, offset)) return true;
#endif
#if DECODE_SAMSUNG36
DPRINTLN("Attempting Samsung36 decode");
if (decodeSamsung36(results)) return true;
DPRINTLN("Attempting Samsung36 decode");
if (decodeSamsung36(results, offset)) return true;
#endif
#if DECODE_WHYNTER
DPRINTLN("Attempting Whynter decode");
if (decodeWhynter(results)) return true;
DPRINTLN("Attempting Whynter decode");
if (decodeWhynter(results, offset)) return true;
#endif
#if DECODE_DISH
DPRINTLN("Attempting DISH decode");
if (decodeDISH(results)) return true;
DPRINTLN("Attempting DISH decode");
if (decodeDISH(results, offset)) return true;
#endif
#if DECODE_SHARP
DPRINTLN("Attempting Sharp decode");
if (decodeSharp(results)) return true;
DPRINTLN("Attempting Sharp decode");
if (decodeSharp(results, offset)) return true;
#endif
#if DECODE_COOLIX
DPRINTLN("Attempting Coolix decode");
if (decodeCOOLIX(results)) return true;
DPRINTLN("Attempting Coolix decode");
if (decodeCOOLIX(results, offset)) return true;
#endif
#if DECODE_NIKAI
DPRINTLN("Attempting Nikai decode");
if (decodeNikai(results)) return true;
DPRINTLN("Attempting Nikai decode");
if (decodeNikai(results, offset)) return true;
#endif
#if DECODE_KELVINATOR
// Kelvinator based-devices use a similar code to Gree ones, to avoid false
// matches this needs to happen before decodeGree().
DPRINTLN("Attempting Kelvinator decode");
if (decodeKelvinator(results)) return true;
// Kelvinator based-devices use a similar code to Gree ones, to avoid false
// matches this needs to happen before decodeGree().
DPRINTLN("Attempting Kelvinator decode");
if (decodeKelvinator(results, offset)) return true;
#endif
#if DECODE_DAIKIN
DPRINTLN("Attempting Daikin decode");
if (decodeDaikin(results)) return true;
DPRINTLN("Attempting Daikin decode");
if (decodeDaikin(results, offset)) return true;
#endif
#if DECODE_DAIKIN2
DPRINTLN("Attempting Daikin2 decode");
if (decodeDaikin2(results)) return true;
DPRINTLN("Attempting Daikin2 decode");
if (decodeDaikin2(results, offset)) return true;
#endif
#if DECODE_DAIKIN216
DPRINTLN("Attempting Daikin216 decode");
if (decodeDaikin216(results)) return true;
DPRINTLN("Attempting Daikin216 decode");
if (decodeDaikin216(results, offset)) return true;
#endif
#if DECODE_TOSHIBA_AC
DPRINTLN("Attempting Toshiba AC decode");
if (decodeToshibaAC(results)) return true;
DPRINTLN("Attempting Toshiba AC decode");
if (decodeToshibaAC(results, offset)) return true;
#endif
#if DECODE_MIDEA
DPRINTLN("Attempting Midea decode");
if (decodeMidea(results)) return true;
DPRINTLN("Attempting Midea decode");
if (decodeMidea(results, offset)) return true;
#endif
#if DECODE_MAGIQUEST
DPRINTLN("Attempting Magiquest decode");
if (decodeMagiQuest(results)) return true;
DPRINTLN("Attempting Magiquest decode");
if (decodeMagiQuest(results, offset)) return true;
#endif
/* NOTE: Disabled due to poor quality.
/* NOTE: Disabled due to poor quality.
#if DECODE_SANYO
// The Sanyo S866500B decoder is very poor quality & depricated.
// *IF* you are going to enable it, do it near last to avoid false positive
// matches.
DPRINTLN("Attempting Sanyo SA8650B decode");
if (decodeSanyo(results))
return true;
// The Sanyo S866500B decoder is very poor quality & depricated.
// *IF* you are going to enable it, do it near last to avoid false positive
// matches.
DPRINTLN("Attempting Sanyo SA8650B decode");
if (decodeSanyo(results, offset))
return true;
#endif
*/
*/
#if DECODE_NEC
// Some devices send NEC-like codes that don't follow the true NEC spec.
// This should detect those. e.g. Apple TV remote etc.
// This needs to be done after all other codes that use strict and some
// other protocols that are NEC-like as well, as turning off strict may
// cause this to match other valid protocols.
DPRINTLN("Attempting NEC (non-strict) decode");
if (decodeNEC(results, kNECBits, false)) {
results->decode_type = NEC_LIKE;
return true;
}
// Some devices send NEC-like codes that don't follow the true NEC spec.
// This should detect those. e.g. Apple TV remote etc.
// This needs to be done after all other codes that use strict and some
// other protocols that are NEC-like as well, as turning off strict may
// cause this to match other valid protocols.
DPRINTLN("Attempting NEC (non-strict) decode");
if (decodeNEC(results, offset, kNECBits, false)) {
results->decode_type = NEC_LIKE;
return true;
}
#endif
#if DECODE_LASERTAG
DPRINTLN("Attempting Lasertag decode");
if (decodeLasertag(results)) return true;
DPRINTLN("Attempting Lasertag decode");
if (decodeLasertag(results, offset)) return true;
#endif
#if DECODE_GREE
// Gree based-devices use a similar code to Kelvinator ones, to avoid false
// matches this needs to happen after decodeKelvinator().
DPRINTLN("Attempting Gree decode");
if (decodeGree(results)) return true;
// Gree based-devices use a similar code to Kelvinator ones, to avoid false
// matches this needs to happen after decodeKelvinator().
DPRINTLN("Attempting Gree decode");
if (decodeGree(results, offset)) return true;
#endif
#if DECODE_HAIER_AC
DPRINTLN("Attempting Haier AC decode");
if (decodeHaierAC(results)) return true;
DPRINTLN("Attempting Haier AC decode");
if (decodeHaierAC(results, offset)) return true;
#endif
#if DECODE_HAIER_AC_YRW02
DPRINTLN("Attempting Haier AC YR-W02 decode");
if (decodeHaierACYRW02(results)) return true;
DPRINTLN("Attempting Haier AC YR-W02 decode");
if (decodeHaierACYRW02(results, offset)) return true;
#endif
#if DECODE_HITACHI_AC424
// HitachiAc424 should be checked before HitachiAC & HitachiAC2
DPRINTLN("Attempting Hitachi AC 424 decode");
if (decodeHitachiAc424(results, kHitachiAc424Bits)) return true;
// HitachiAc424 should be checked before HitachiAC & HitachiAC2
DPRINTLN("Attempting Hitachi AC 424 decode");
if (decodeHitachiAc424(results, offset, kHitachiAc424Bits)) return true;
#endif // DECODE_HITACHI_AC2
#if DECODE_HITACHI_AC2
// HitachiAC2 should be checked before HitachiAC
DPRINTLN("Attempting Hitachi AC2 decode");
if (decodeHitachiAC(results, kHitachiAc2Bits)) return true;
// HitachiAC2 should be checked before HitachiAC
DPRINTLN("Attempting Hitachi AC2 decode");
if (decodeHitachiAC(results, offset, kHitachiAc2Bits)) return true;
#endif // DECODE_HITACHI_AC2
#if DECODE_HITACHI_AC
DPRINTLN("Attempting Hitachi AC decode");
if (decodeHitachiAC(results, kHitachiAcBits)) return true;
DPRINTLN("Attempting Hitachi AC decode");
if (decodeHitachiAC(results, offset, kHitachiAcBits)) return true;
#endif
#if DECODE_HITACHI_AC1
DPRINTLN("Attempting Hitachi AC1 decode");
if (decodeHitachiAC(results, kHitachiAc1Bits)) return true;
DPRINTLN("Attempting Hitachi AC1 decode");
if (decodeHitachiAC(results, offset, kHitachiAc1Bits)) return true;
#endif
#if DECODE_WHIRLPOOL_AC
DPRINTLN("Attempting Whirlpool AC decode");
if (decodeWhirlpoolAC(results)) return true;
DPRINTLN("Attempting Whirlpool AC decode");
if (decodeWhirlpoolAC(results, offset)) return true;
#endif
#if DECODE_SAMSUNG_AC
DPRINTLN("Attempting Samsung AC (extended) decode");
// Check the extended size first, as it should fail fast due to longer length.
if (decodeSamsungAC(results, kSamsungAcExtendedBits, false)) return true;
// Now check for the more common length.
DPRINTLN("Attempting Samsung AC decode");
if (decodeSamsungAC(results, kSamsungAcBits)) return true;
DPRINTLN("Attempting Samsung AC (extended) decode");
// Check the extended size first, as it should fail fast due to longer
// length.
if (decodeSamsungAC(results, offset, kSamsungAcExtendedBits, false))
return true;
// Now check for the more common length.
DPRINTLN("Attempting Samsung AC decode");
if (decodeSamsungAC(results, offset, kSamsungAcBits)) return true;
#endif
#if DECODE_ELECTRA_AC
DPRINTLN("Attempting Electra AC decode");
if (decodeElectraAC(results)) return true;
DPRINTLN("Attempting Electra AC decode");
if (decodeElectraAC(results, offset)) return true;
#endif
#if DECODE_PANASONIC_AC
DPRINTLN("Attempting Panasonic AC decode");
if (decodePanasonicAC(results)) return true;
DPRINTLN("Attempting Panasonic AC short decode");
if (decodePanasonicAC(results, kPanasonicAcShortBits)) return true;
DPRINTLN("Attempting Panasonic AC decode");
if (decodePanasonicAC(results, offset)) return true;
DPRINTLN("Attempting Panasonic AC short decode");
if (decodePanasonicAC(results, offset, kPanasonicAcShortBits)) return true;
#endif
#if DECODE_LUTRON
DPRINTLN("Attempting Lutron decode");
if (decodeLutron(results)) return true;
DPRINTLN("Attempting Lutron decode");
if (decodeLutron(results, offset)) return true;
#endif
#if DECODE_MWM
DPRINTLN("Attempting MWM decode");
if (decodeMWM(results)) return true;
DPRINTLN("Attempting MWM decode");
if (decodeMWM(results, offset)) return true;
#endif
#if DECODE_VESTEL_AC
DPRINTLN("Attempting Vestel AC decode");
if (decodeVestelAc(results)) return true;
DPRINTLN("Attempting Vestel AC decode");
if (decodeVestelAc(results, offset)) return true;
#endif
#if DECODE_MITSUBISHI112 || DECODE_TCL112AC
// Mitsubish112 and Tcl112 share the same decoder.
DPRINTLN("Attempting Mitsubishi112/TCL112AC decode");
if (decodeMitsubishi112(results)) return true;
// Mitsubish112 and Tcl112 share the same decoder.
DPRINTLN("Attempting Mitsubishi112/TCL112AC decode");
if (decodeMitsubishi112(results, offset)) return true;
#endif // DECODE_MITSUBISHI112 || DECODE_TCL112AC
#if DECODE_TECO
DPRINTLN("Attempting Teco decode");
if (decodeTeco(results)) return true;
DPRINTLN("Attempting Teco decode");
if (decodeTeco(results, offset)) return true;
#endif
#if DECODE_LEGOPF
DPRINTLN("Attempting LEGOPF decode");
if (decodeLegoPf(results)) return true;
DPRINTLN("Attempting LEGOPF decode");
if (decodeLegoPf(results, offset)) return true;
#endif
#if DECODE_MITSUBISHIHEAVY
DPRINTLN("Attempting MITSUBISHIHEAVY (152 bit) decode");
if (decodeMitsubishiHeavy(results, kMitsubishiHeavy152Bits)) return true;
DPRINTLN("Attempting MITSUBISHIHEAVY (88 bit) decode");
if (decodeMitsubishiHeavy(results, kMitsubishiHeavy88Bits)) return true;
DPRINTLN("Attempting MITSUBISHIHEAVY (152 bit) decode");
if (decodeMitsubishiHeavy(results, offset, kMitsubishiHeavy152Bits))
return true;
DPRINTLN("Attempting MITSUBISHIHEAVY (88 bit) decode");
if (decodeMitsubishiHeavy(results, offset, kMitsubishiHeavy88Bits))
return true;
#endif
#if DECODE_ARGO
DPRINTLN("Attempting Argo decode");
if (decodeArgo(results)) return true;
DPRINTLN("Attempting Argo decode");
if (decodeArgo(results, offset)) return true;
#endif // DECODE_ARGO
#if DECODE_SHARP_AC
DPRINTLN("Attempting SHARP_AC decode");
if (decodeSharpAc(results)) return true;
DPRINTLN("Attempting SHARP_AC decode");
if (decodeSharpAc(results, offset)) return true;
#endif
#if DECODE_GOODWEATHER
DPRINTLN("Attempting GOODWEATHER decode");
if (decodeGoodweather(results)) return true;
DPRINTLN("Attempting GOODWEATHER decode");
if (decodeGoodweather(results, offset)) return true;
#endif // DECODE_GOODWEATHER
#if DECODE_INAX
DPRINTLN("Attempting Inax decode");
if (decodeInax(results)) return true;
DPRINTLN("Attempting Inax decode");
if (decodeInax(results, offset)) return true;
#endif // DECODE_INAX
#if DECODE_TROTEC
DPRINTLN("Attempting Trotec decode");
if (decodeTrotec(results)) return true;
DPRINTLN("Attempting Trotec decode");
if (decodeTrotec(results, offset)) return true;
#endif // DECODE_TROTEC
#if DECODE_DAIKIN160
DPRINTLN("Attempting Daikin160 decode");
if (decodeDaikin160(results)) return true;
DPRINTLN("Attempting Daikin160 decode");
if (decodeDaikin160(results, offset)) return true;
#endif // DECODE_DAIKIN160
#if DECODE_NEOCLIMA
DPRINTLN("Attempting Neoclima decode");
if (decodeNeoclima(results)) return true;
DPRINTLN("Attempting Neoclima decode");
if (decodeNeoclima(results, offset)) return true;
#endif // DECODE_NEOCLIMA
#if DECODE_DAIKIN176
DPRINTLN("Attempting Daikin176 decode");
if (decodeDaikin176(results)) return true;
DPRINTLN("Attempting Daikin176 decode");
if (decodeDaikin176(results, offset)) return true;
#endif // DECODE_DAIKIN176
#if DECODE_DAIKIN128
DPRINTLN("Attempting Daikin128 decode");
if (decodeDaikin128(results)) return true;
DPRINTLN("Attempting Daikin128 decode");
if (decodeDaikin128(results, offset)) return true;
#endif // DECODE_DAIKIN128
#if DECODE_AMCOR
DPRINTLN("Attempting Amcor decode");
if (decodeAmcor(results)) return true;
DPRINTLN("Attempting Amcor decode");
if (decodeAmcor(results, offset)) return true;
#endif // DECODE_AMCOR
#if DECODE_DAIKIN152
DPRINTLN("Attempting Daikin152 decode");
if (decodeDaikin152(results)) return true;
DPRINTLN("Attempting Daikin152 decode");
if (decodeDaikin152(results, offset)) return true;
#endif // DECODE_DAIKIN152
#if DECODE_MITSUBISHI136
DPRINTLN("Attempting Mitsubishi136 decode");
if (decodeMitsubishi136(results)) return true;
DPRINTLN("Attempting Mitsubishi136 decode");
if (decodeMitsubishi136(results, offset)) return true;
#endif // DECODE_MITSUBISHI136
}
// Typically new protocols are added above this line.
#if DECODE_HASH
// decodeHash returns a hash on any input.

View File

@ -125,7 +125,8 @@ class IRrecv {
~IRrecv(void); // Destructor
void setTolerance(const uint8_t percent = kTolerance);
uint8_t getTolerance(void);
bool decode(decode_results *results, irparams_t *save = NULL);
bool decode(decode_results *results, irparams_t *save = NULL,
uint8_t max_skip = 0, uint16_t noise_floor = 0);
void enableIRIn(const bool pullup = false);
void disableIRIn(void);
void resume(void);
@ -220,52 +221,64 @@ class IRrecv {
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true);
void crudeNoiseFilter(decode_results *results, const uint16_t floor = 0);
bool decodeHash(decode_results *results);
#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || SEND_SANYO)
bool decodeNEC(decode_results *results, uint16_t nbits = kNECBits,
bool strict = true);
bool decodeNEC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kNECBits, const bool strict = true);
#endif
#if DECODE_ARGO
bool decodeArgo(decode_results *results, const uint16_t nbits = kArgoBits,
const bool strict = true);
bool decodeArgo(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kArgoBits, const bool strict = true);
#endif // DECODE_ARGO
#if DECODE_SONY
bool decodeSony(decode_results *results, uint16_t nbits = kSonyMinBits,
bool strict = false);
bool decodeSony(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSonyMinBits,
const bool strict = false);
#endif
#if DECODE_SANYO
// DISABLED due to poor quality.
// bool decodeSanyo(decode_results *results,
// bool decodeSanyo(decode_results *results, uint16_t offset = kStartOffset,
// uint16_t nbits = kSanyoSA8650BBits,
// bool strict = false);
bool decodeSanyoLC7461(decode_results *results,
uint16_t nbits = kSanyoLC7461Bits, bool strict = true);
uint16_t offset = kStartOffset,
const uint16_t nbits = kSanyoLC7461Bits,
bool strict = true);
#endif
#if DECODE_MITSUBISHI
bool decodeMitsubishi(decode_results *results,
uint16_t nbits = kMitsubishiBits, bool strict = true);
bool decodeMitsubishi(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
const bool strict = true);
#endif
#if DECODE_MITSUBISHI2
bool decodeMitsubishi2(decode_results *results,
uint16_t nbits = kMitsubishiBits, bool strict = true);
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
const bool strict = true);
#endif
#if DECODE_MITSUBISHI_AC
bool decodeMitsubishiAC(decode_results *results,
uint16_t nbits = kMitsubishiACBits,
bool strict = false);
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiACBits,
const bool strict = false);
#endif
#if DECODE_MITSUBISHI136
bool decodeMitsubishi136(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishi136Bits,
const bool strict = true);
#endif
#if DECODE_MITSUBISHI112
bool decodeMitsubishi112(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishi112Bits,
const bool strict = true);
#endif
#if DECODE_MITSUBISHIHEAVY
bool decodeMitsubishiHeavy(decode_results *results, const uint16_t nbits,
bool decodeMitsubishiHeavy(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiHeavy152Bits,
const bool strict = true);
#endif
#if (DECODE_RC5 || DECODE_R6 || DECODE_LASERTAG || DECODE_MWM)
@ -275,236 +288,276 @@ class IRrecv {
uint8_t maxwidth = 3);
#endif
#if DECODE_RC5
bool decodeRC5(decode_results *results, uint16_t nbits = kRC5XBits,
bool strict = true);
bool decodeRC5(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kRC5XBits,
const bool strict = true);
#endif
#if DECODE_RC6
bool decodeRC6(decode_results *results, uint16_t nbits = kRC6Mode0Bits,
bool strict = false);
bool decodeRC6(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kRC6Mode0Bits,
const bool strict = false);
#endif
#if DECODE_RCMM
bool decodeRCMM(decode_results *results, uint16_t nbits = kRCMMBits,
bool strict = false);
bool decodeRCMM(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kRCMMBits,
const bool strict = false);
#endif
#if (DECODE_PANASONIC || DECODE_DENON)
bool decodePanasonic(decode_results *results,
bool decodePanasonic(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kPanasonicBits,
const bool strict = false,
const uint32_t manufacturer = kPanasonicManufacturer);
#endif
#if DECODE_LG
bool decodeLG(decode_results *results, uint16_t nbits = kLgBits,
bool strict = false);
bool decodeLG(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kLgBits,
const bool strict = false);
#endif
#if DECODE_INAX
bool decodeInax(decode_results *results, const uint16_t nbits = kInaxBits,
bool decodeInax(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kInaxBits,
const bool strict = true);
#endif // DECODE_INAX
#if DECODE_JVC
bool decodeJVC(decode_results *results, uint16_t nbits = kJvcBits,
bool strict = true);
bool decodeJVC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kJvcBits,
const bool strict = true);
#endif
#if DECODE_SAMSUNG
bool decodeSAMSUNG(decode_results *results,
bool decodeSAMSUNG(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsungBits,
const bool strict = true);
#endif
#if DECODE_SAMSUNG
bool decodeSamsung36(decode_results *results,
bool decodeSamsung36(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsung36Bits,
const bool strict = true);
#endif
#if DECODE_SAMSUNG_AC
bool decodeSamsungAC(decode_results *results,
bool decodeSamsungAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsungAcBits,
const bool strict = true);
#endif
#if DECODE_WHYNTER
bool decodeWhynter(decode_results *results, uint16_t nbits = kWhynterBits,
bool strict = true);
bool decodeWhynter(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kWhynterBits,
const bool strict = true);
#endif
#if DECODE_COOLIX
bool decodeCOOLIX(decode_results *results, uint16_t nbits = kCoolixBits,
bool strict = true);
bool decodeCOOLIX(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kCoolixBits,
const bool strict = true);
#endif
#if DECODE_DENON
bool decodeDenon(decode_results *results, uint16_t nbits = kDenonBits,
bool strict = true);
bool decodeDenon(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDenonBits,
const bool strict = true);
#endif
#if DECODE_DISH
bool decodeDISH(decode_results *results, uint16_t nbits = kDishBits,
bool strict = true);
bool decodeDISH(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDishBits,
const bool strict = true);
#endif
#if (DECODE_SHARP || DECODE_DENON)
bool decodeSharp(decode_results *results, const uint16_t nbits = kSharpBits,
bool decodeSharp(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSharpBits,
const bool strict = true, const bool expansion = true);
#endif
#if DECODE_SHARP_AC
bool decodeSharpAc(decode_results *results,
bool decodeSharpAc(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSharpAcBits,
const bool strict = true);
#endif
#if DECODE_AIWA_RC_T501
bool decodeAiwaRCT501(decode_results *results,
uint16_t nbits = kAiwaRcT501Bits, bool strict = true);
bool decodeAiwaRCT501(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kAiwaRcT501Bits,
const bool strict = true);
#endif
#if DECODE_NIKAI
bool decodeNikai(decode_results *results, uint16_t nbits = kNikaiBits,
bool strict = true);
bool decodeNikai(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kNikaiBits,
const bool strict = true);
#endif
#if DECODE_MAGIQUEST
bool decodeMagiQuest(decode_results *results, uint16_t nbits = kMagiquestBits,
bool strict = true);
bool decodeMagiQuest(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kMagiquestBits,
const bool strict = true);
#endif
#if DECODE_KELVINATOR
bool decodeKelvinator(decode_results *results,
uint16_t nbits = kKelvinatorBits, bool strict = true);
bool decodeKelvinator(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kKelvinatorBits,
const bool strict = true);
#endif
#if DECODE_DAIKIN
bool decodeDaikin(decode_results *results, const uint16_t nbits = kDaikinBits,
bool decodeDaikin(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikinBits,
const bool strict = true);
#endif
#if DECODE_DAIKIN128
bool decodeDaikin128(decode_results *results,
bool decodeDaikin128(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin128Bits,
const bool strict = true);
#endif // DECODE_DAIKIN128
#if DECODE_DAIKIN152
bool decodeDaikin152(decode_results *results,
bool decodeDaikin152(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin152Bits,
const bool strict = true);
#endif // DECODE_DAIKIN152
#if DECODE_DAIKIN160
bool decodeDaikin160(decode_results *results,
bool decodeDaikin160(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin160Bits,
const bool strict = true);
#endif // DECODE_DAIKIN160
#if DECODE_DAIKIN176
bool decodeDaikin176(decode_results *results,
bool decodeDaikin176(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin176Bits,
const bool strict = true);
#endif // DECODE_DAIKIN176
#if DECODE_DAIKIN2
bool decodeDaikin2(decode_results *results, uint16_t nbits = kDaikin2Bits,
bool strict = true);
bool decodeDaikin2(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin2Bits,
const bool strict = true);
#endif
#if DECODE_DAIKIN216
bool decodeDaikin216(decode_results *results,
bool decodeDaikin216(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin216Bits,
const bool strict = true);
#endif
#if DECODE_TOSHIBA_AC
bool decodeToshibaAC(decode_results *results,
bool decodeToshibaAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbytes = kToshibaACBits,
const bool strict = true);
#endif
#if DECODE_TROTEC
bool decodeTrotec(decode_results *results, const uint16_t nbits = kTrotecBits,
bool decodeTrotec(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kTrotecBits,
const bool strict = true);
#endif // DECODE_TROTEC
#if DECODE_MIDEA
bool decodeMidea(decode_results *results, uint16_t nbits = kMideaBits,
bool strict = true);
bool decodeMidea(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kMideaBits,
const bool strict = true);
#endif
#if DECODE_FUJITSU_AC
bool decodeFujitsuAC(decode_results *results, uint16_t nbits = kFujitsuAcBits,
bool strict = false);
bool decodeFujitsuAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kFujitsuAcBits,
const bool strict = false);
#endif
#if DECODE_LASERTAG
bool decodeLasertag(decode_results *results, uint16_t nbits = kLasertagBits,
bool strict = true);
bool decodeLasertag(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kLasertagBits,
const bool strict = true);
#endif
#if DECODE_CARRIER_AC
bool decodeCarrierAC(decode_results *results, uint16_t nbits = kCarrierAcBits,
bool strict = true);
bool decodeCarrierAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAcBits,
const bool strict = true);
#endif
#if DECODE_GOODWEATHER
bool decodeGoodweather(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGoodweatherBits,
const bool strict = true);
#endif // DECODE_GOODWEATHER
#if DECODE_GREE
bool decodeGree(decode_results *results, uint16_t nbits = kGreeBits,
bool strict = true);
bool decodeGree(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kGreeBits,
const bool strict = true);
#endif
#if (DECODE_HAIER_AC | DECODE_HAIER_AC_YRW02)
bool decodeHaierAC(decode_results *results, uint16_t nbits = kHaierACBits,
bool strict = true);
bool decodeHaierAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierACBits,
const bool strict = true);
#endif
#if DECODE_HAIER_AC_YRW02
bool decodeHaierACYRW02(decode_results *results,
uint16_t nbits = kHaierACYRW02Bits,
bool strict = true);
uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierACYRW02Bits,
const bool strict = true);
#endif
#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2)
bool decodeHitachiAC(decode_results *results,
bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAcBits,
const bool strict = true);
#endif
#if DECODE_HITACHI_AC1
bool decodeHitachiAC1(decode_results *results,
bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc1Bits,
const bool strict = true);
#endif
#if DECODE_HITACHI_AC424
bool decodeHitachiAc424(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc424Bits,
const bool strict = true);
#endif // DECODE_HITACHI_AC424
#if DECODE_GICABLE
bool decodeGICable(decode_results *results, uint16_t nbits = kGicableBits,
bool strict = true);
bool decodeGICable(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kGicableBits,
const bool strict = true);
#endif
#if DECODE_WHIRLPOOL_AC
bool decodeWhirlpoolAC(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kWhirlpoolAcBits,
const bool strict = true);
#endif
#if DECODE_LUTRON
bool decodeLutron(decode_results *results, uint16_t nbits = kLutronBits,
bool strict = true);
bool decodeLutron(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kLutronBits,
const bool strict = true);
#endif
#if DECODE_ELECTRA_AC
bool decodeElectraAC(decode_results *results, uint16_t nbits = kElectraAcBits,
bool strict = true);
bool decodeElectraAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kElectraAcBits,
const bool strict = true);
#endif
#if DECODE_PANASONIC_AC
bool decodePanasonicAC(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPanasonicAcBits,
const bool strict = true);
#endif
#if DECODE_PIONEER
bool decodePioneer(decode_results *results,
bool decodePioneer(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kPioneerBits,
const bool strict = true);
#endif
#if DECODE_MWM
bool decodeMWM(decode_results *results, uint16_t nbits = 24,
bool strict = true);
bool decodeMWM(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = 24,
const bool strict = true);
#endif
#if DECODE_VESTEL_AC
bool decodeVestelAc(decode_results *results,
bool decodeVestelAc(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kVestelAcBits,
const bool strict = true);
#endif
#if DECODE_TECO
bool decodeTeco(decode_results *results, const uint16_t nbits = kTecoBits,
bool decodeTeco(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kTecoBits,
const bool strict = false);
#endif
#if DECODE_LEGOPF
bool decodeLegoPf(decode_results *results, const uint16_t nbits = kLegoPfBits,
bool decodeLegoPf(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kLegoPfBits,
const bool strict = true);
#endif
#if DECODE_NEOCLIMA
bool decodeNeoclima(decode_results *results,
const uint16_t nbits = kNeoclimaBits,
const bool strict = true);
bool decodeNeoclima(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kNeoclimaBits,
const bool strict = true);
#endif // DECODE_NEOCLIMA
#if DECODE_AMCOR
bool decodeAmcor(decode_results *results,
const uint16_t nbits = kAmcorBits,
const bool strict = true);
bool decodeAmcor(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kAmcorBits,
const bool strict = true);
#endif // DECODE_AMCOR
#if DECODE_EPSON
bool decodeEpson(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kEpsonBits,
const bool strict = true);
#endif // DECODE_EPSON
};
#endif // IRRECV_H_

View File

@ -52,7 +52,7 @@
#endif // UNIT_TEST
// Library Version
#define _IRREMOTEESP8266_VERSION_ "2.7.3"
#define _IRREMOTEESP8266_VERSION_ "2.7.4"
// Set the language & locale for the library. See the `locale` dir for options.
#ifndef _IR_LOCALE_
@ -565,6 +565,13 @@
#define SEND_HITACHI_AC424 _IR_ENABLE_DEFAULT_
#endif // SEND_HITACHI_AC424
#ifndef DECODE_EPSON
#define DECODE_EPSON _IR_ENABLE_DEFAULT_
#endif // DECODE_EPSON
#ifndef SEND_EPSON
#define SEND_EPSON _IR_ENABLE_DEFAULT_
#endif // SEND_EPSON
#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
@ -589,6 +596,22 @@
#define ALLOW_DELAY_CALLS true
#endif // ALLOW_DELAY_CALLS
// Enable a run-time settable high-pass filter on captured data **before**
// trying any protocol decoding.
// i.e. Try to remove/merge any really short pulses detected in the raw data.
// Note: Even when this option is enabled, it is _off_ by default, and requires
// a user who knows what they are doing to enable it.
// The option to disable this feature is here if your project is _really_
// tight on resources. i.e. Saves a small handful of bytes and cpu time.
// WARNING: If you use this feature at runtime, you can no longer trust the
// **raw** data captured. It will now have been slightly **cooked**!
// DANGER: If you set the `noise_floor` value too high, it **WILL** break
// decoding of some protocols. You have been warned. Here Be Dragons!
//
// See: `irrecv::decode()` in IRrecv.cpp for more info.
#ifndef ENABLE_NOISE_FILTER_OPTION
#define ENABLE_NOISE_FILTER_OPTION true
#endif // ENABLE_NOISE_FILTER_OPTION
/*
* Always add to the end of the list and should never remove entries
* or change order. Projects may save the type number for later usage
@ -671,8 +694,9 @@ enum decode_type_t {
MITSUBISHI112,
HITACHI_AC424,
SONY_38K,
EPSON, // 75
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = SONY_38K,
kLastDecodeType = EPSON,
};
// Message lengths & required repeat values
@ -720,6 +744,8 @@ const uint16_t kDenon48Bits = 48;
const uint16_t kDenonLegacyBits = 14;
const uint16_t kDishBits = 16;
const uint16_t kDishMinRepeat = 3;
const uint16_t kEpsonBits = 32;
const uint16_t kEpsonMinRepeat = 2;
const uint16_t kElectraAcStateLength = 13;
const uint16_t kElectraAcBits = kElectraAcStateLength * 8;
const uint16_t kElectraAcMinRepeat = kNoRepeat;

View File

@ -477,7 +477,8 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace,
//
// Ref:
// examples/IRrecvDumpV2/IRrecvDumpV2.ino
void IRsend::sendRaw(uint16_t buf[], uint16_t len, uint16_t hz) {
void IRsend::sendRaw(const uint16_t buf[], const uint16_t len,
const uint16_t hz) {
// Set IR carrier frequency
enableIROut(hz);
for (uint16_t i = 0; i < len; i++) {
@ -517,6 +518,8 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) {
return kSonyMinRepeat;
case SONY_38K:
return kSonyMinRepeat + 1;
case EPSON:
return kEpsonMinRepeat;
default:
return kNoRepeat;
}
@ -558,6 +561,7 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
case LG2:
return 28;
case CARRIER_AC:
case EPSON:
case NEC:
case NEC_LIKE:
case SAMSUNG:
@ -687,6 +691,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
sendDISH(data, nbits, min_repeat);
break;
#endif
#if SEND_EPSON
case EPSON:
sendEpson(data, nbits, min_repeat);
break;
#endif
#if SEND_GICABLE
case GICABLE:
sendGICable(data, nbits, min_repeat);

View File

@ -158,7 +158,7 @@ class IRsend {
VIRTUAL uint16_t mark(uint16_t usec);
VIRTUAL void space(uint32_t usec);
int8_t calibrate(uint16_t hz = 38000U);
void sendRaw(uint16_t buf[], uint16_t len, uint16_t hz);
void sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz);
void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark,
uint32_t zerospace, uint64_t data, uint16_t nbits,
bool MSBfirst = true);
@ -535,7 +535,10 @@ class IRsend {
const uint16_t nbytes = kAmcorStateLength,
const uint16_t repeat = kAmcorDefaultRepeat);
#endif // SEND_AMCOR
#if SEND_EPSON
void sendEpson(uint64_t data, uint16_t nbits = kEpsonBits,
uint16_t repeat = kEpsonMinRepeat);
#endif
protected:
#ifdef UNIT_TEST

View File

@ -125,6 +125,8 @@ decode_type_t strToDecodeType(const char * const str) {
return decode_type_t::DISH;
else if (!strcasecmp(str, "ELECTRA_AC"))
return decode_type_t::ELECTRA_AC;
else if (!strcasecmp(str, "EPSON"))
return decode_type_t::EPSON;
else if (!strcasecmp(str, "FUJITSU_AC"))
return decode_type_t::FUJITSU_AC;
else if (!strcasecmp(str, "GICABLE"))
@ -310,6 +312,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case ELECTRA_AC:
result = F("ELECTRA_AC");
break;
case EPSON:
result = F("EPSON");
break;
case FUJITSU_AC:
result = F("FUJITSU_AC");
break;

View File

@ -53,6 +53,8 @@ void IRsend::sendAiwaRCT501(uint64_t data, uint16_t nbits, uint16_t repeat) {
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: The number of data bits to expect. Typically kAiwaRcT501Bits.
// strict: Flag indicating if we should perform strict matching.
// Returns:
@ -69,8 +71,8 @@ void IRsend::sendAiwaRCT501(uint64_t data, uint16_t nbits, uint16_t repeat) {
//
// Ref:
// http://www.sbprojects.com/knowledge/ir/nec.php
bool IRrecv::decodeAiwaRCT501(decode_results *results, uint16_t nbits,
bool strict) {
bool IRrecv::decodeAiwaRCT501(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// Compliance
if (strict && nbits != kAiwaRcT501Bits)
return false; // Doesn't match our protocol defn.
@ -82,7 +84,7 @@ bool IRrecv::decodeAiwaRCT501(decode_results *results, uint16_t nbits,
return false; // We can't possibly match something that big.
// Decode it as a much bigger (non-standard) NEC message, so we have to turn
// off strict mode checking for NEC.
if (!decodeNEC(results, expected_nbits, false))
if (!decodeNEC(results, offset, expected_nbits, false))
return false; // The NEC decode had a problem, so we should too.
uint16_t actual_bits = results->bits;
new_data = results->value;

View File

@ -56,6 +56,8 @@ void IRsend::sendAmcor(const unsigned char data[], const uint16_t nbytes,
// Decode the supplied Amcor HVAC message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion.
// Typically kAmcorBits.
// strict: Flag to indicate if we strictly adhere to the specification.
@ -64,15 +66,13 @@ void IRsend::sendAmcor(const unsigned char data[], const uint16_t nbytes,
//
// Status: STABLE / Reported as working.
//
bool IRrecv::decodeAmcor(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * nbits + kHeader - 1)
bool IRrecv::decodeAmcor(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen <= 2 * nbits + kHeader - 1 + offset)
return false; // Can't possibly be a valid Amcor message.
if (strict && nbits != kAmcorBits)
return false; // We expect Amcor to be 64 bits of message.
uint16_t offset = kStartOffset;
uint16_t used;
// Header + Data Block (64 bits) + Footer
used = matchGeneric(results->rawbuf + offset, results->state,

View File

@ -378,6 +378,8 @@ String IRArgoAC::toString(void) {
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: The number of data bits to expect. Typically kArgoBits.
// strict: Flag indicating if we should perform strict matching.
// Returns:
@ -388,12 +390,11 @@ String IRArgoAC::toString(void) {
// Note:
// This decoder is based soley off sendArgo(). We have no actual captures
// to test this against. If you have one of these units, please let us know.
bool IRrecv::decodeArgo(decode_results *results, const uint16_t nbits,
bool IRrecv::decodeArgo(decode_results *results, uint16_t offset,
const uint16_t nbits,
const bool strict) {
if (strict && nbits != kArgoBits) return false;
uint16_t offset = kStartOffset;
// Match Header + Data
if (!matchGeneric(results->rawbuf + offset, results->state,
results->rawlen - offset, nbits,

View File

@ -53,6 +53,8 @@ void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) {
// i.e. normal + inverted + normal
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion.
// Typically kCarrierAcBits.
// strict: Flag to indicate if we strictly adhere to the specification.
@ -61,16 +63,15 @@ void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) {
//
// Status: ALPHA / Untested.
//
bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1)
bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset)
return false; // Can't possibly be a valid Carrier message.
if (strict && nbits != kCarrierAcBits)
return false; // We expect Carrier to be 32 bits of message.
uint64_t data = 0;
uint64_t prev_data = 0;
uint16_t offset = kStartOffset;
for (uint8_t i = 0; i < 3; i++) {
prev_data = data;

View File

@ -130,6 +130,7 @@ void IRCoolixAC::send(const uint16_t repeat) {
uint32_t IRCoolixAC::getRaw() { return remote_state; }
void IRCoolixAC::setRaw(const uint32_t new_code) {
powerFlag = true; // Everything that is not the special power off mesg is On.
if (!handleSpecialState(new_code)) {
// it isn`t special so might affect Temp|mode|Fan
if (new_code == kCoolixCmdFan) {
@ -578,17 +579,19 @@ String IRCoolixAC::toString(void) {
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: The number of data bits to expect. Typically kCoolixBits.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA / Probably working.
bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t nbits,
bool strict) {
bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// The protocol sends the data normal + inverted, alternating on
// each byte. Hence twice the number of expected data bits.
if (results->rawlen < 2 * 2 * nbits + kHeader + kFooter - 1)
if (results->rawlen <= 2 * 2 * nbits + kHeader + kFooter - 1 + offset)
return false; // Can't possibly be a valid COOLIX message.
if (strict && nbits != kCoolixBits)
return false; // Not strictly a COOLIX message.
@ -597,7 +600,6 @@ bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t nbits,
uint64_t data = 0;
uint64_t inverted = 0;
uint16_t offset = kStartOffset;
if (nbits > sizeof(data) * 8)
return false; // We can't possibly capture a Coolix packet that big.

View File

@ -513,6 +513,8 @@ String IRDaikinESP::toString(void) {
// Decode the supplied Daikin A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikinBits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -522,17 +524,17 @@ String IRDaikinESP::toString(void) {
//
// Ref:
// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
bool IRrecv::decodeDaikin(decode_results *results, const uint16_t nbits,
const bool strict) {
bool IRrecv::decodeDaikin(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// Is there enough data to match successfully?
if (results->rawlen < (2 * (nbits + kDaikinHeaderLength) +
kDaikinSections * (kHeader + kFooter) + kFooter - 1))
kDaikinSections * (kHeader + kFooter) + kFooter - 1) +
offset)
return false;
// Compliance
if (strict && nbits != kDaikinBits) return false;
uint16_t offset = kStartOffset;
match_result_t data_result;
// Header #1 - Doesn't count as data.
@ -1206,6 +1208,8 @@ String IRDaikin2::toString(void) {
// Decode the supplied Daikin2 A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikin2Bits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -1219,15 +1223,14 @@ String IRDaikin2::toString(void) {
//
// Ref:
// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
bool IRrecv::decodeDaikin2(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) + kHeader - 1)
bool IRrecv::decodeDaikin2(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) + kHeader - 1 + offset)
return false;
// Compliance
if (strict && nbits != kDaikin2Bits) return false;
uint16_t offset = kStartOffset;
const uint8_t ksectionSize[kDaikin2Sections] = {kDaikin2Section1Length,
kDaikin2Section2Length};
@ -1552,6 +1555,8 @@ String IRDaikin216::toString(void) {
// Decode the supplied Daikin 216 bit A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikin216Bits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -1565,15 +1570,14 @@ String IRDaikin216::toString(void) {
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/689
// https://github.com/danny-source/Arduino_DY_IRDaikin
bool IRrecv::decodeDaikin216(decode_results *results, const uint16_t nbits,
const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1)
bool IRrecv::decodeDaikin216(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset)
return false;
// Compliance
if (strict && nbits != kDaikin216Bits) return false;
uint16_t offset = kStartOffset;
const uint8_t ksectionSize[kDaikin216Sections] = {kDaikin216Section1Length,
kDaikin216Section2Length};
// Sections
@ -1905,6 +1909,8 @@ String IRDaikin160::toString(void) {
// Decode the supplied Daikin 160 bit A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikin160Bits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -1917,15 +1923,14 @@ String IRDaikin160::toString(void) {
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/731
bool IRrecv::decodeDaikin160(decode_results *results, const uint16_t nbits,
const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1)
bool IRrecv::decodeDaikin160(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset)
return false;
// Compliance
if (strict && nbits != kDaikin160Bits) return false;
uint16_t offset = kStartOffset;
const uint8_t ksectionSize[kDaikin160Sections] = {kDaikin160Section1Length,
kDaikin160Section2Length};
@ -2268,6 +2273,8 @@ String IRDaikin176::toString(void) {
// Decode the supplied Daikin 176 bit A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikin176Bits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -2279,15 +2286,15 @@ String IRDaikin176::toString(void) {
// Status: BETA / Probably works.
//
bool IRrecv::decodeDaikin176(decode_results *results, const uint16_t nbits,
bool IRrecv::decodeDaikin176(decode_results *results, uint16_t offset,
const uint16_t nbits,
const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1)
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset)
return false;
// Compliance
if (strict && nbits != kDaikin176Bits) return false;
uint16_t offset = kStartOffset;
const uint8_t ksectionSize[kDaikin176Sections] = {kDaikin176Section1Length,
kDaikin176Section2Length};
@ -2762,6 +2769,8 @@ stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) {
// Decode the supplied Daikin 128 bit A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikin128Bits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -2773,17 +2782,15 @@ stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) {
// Status: STABLE / Known Working.
//
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827
bool IRrecv::decodeDaikin128(decode_results *results, const uint16_t nbits,
const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader) + kFooter - 1)
bool IRrecv::decodeDaikin128(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader) + kFooter - 1 + offset)
return false;
if (nbits / 8 <= kDaikin128SectionLength) return false;
// Compliance
if (strict && nbits != kDaikin128Bits) return false;
uint16_t offset = kStartOffset;
// Leader
for (uint8_t i = 0; i < 2; i++) {
if (!matchMark(results->rawbuf[offset++], kDaikin128LeaderMark,
@ -2862,6 +2869,8 @@ void IRsend::sendDaikin152(const unsigned char data[], const uint16_t nbytes,
// Decode the supplied Daikin 152 bit A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Nr. of bits to expect in the data portion. (kDaikin152Bits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
@ -2873,16 +2882,15 @@ void IRsend::sendDaikin152(const unsigned char data[], const uint16_t nbytes,
// Status: STABLE / Known working.
//
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873
bool IRrecv::decodeDaikin152(decode_results *results, const uint16_t nbits,
const bool strict) {
if (results->rawlen < 2 * (5 + nbits + kFooter) + kHeader - 1)
bool IRrecv::decodeDaikin152(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (results->rawlen < 2 * (5 + nbits + kFooter) + kHeader - 1 + offset)
return false;
if (nbits / 8 < kDaikin152StateLength) return false;
// Compliance
if (strict && nbits != kDaikin152Bits) return false;
uint16_t offset = kStartOffset;
uint16_t used;
// Leader

View File

@ -64,7 +64,10 @@ void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) {
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// offset: The starting index to use when attempting to decode the raw data.
// Typically/Defaults to kStartOffset.
// nbits: Expected nr. of data bits. (Typically kDenonBits)
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
@ -72,7 +75,8 @@ void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) {
//
// Ref:
// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
bool IRrecv::decodeDenon(decode_results *results, uint16_t nbits, bool strict) {
bool IRrecv::decodeDenon(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// Compliance
if (strict) {
switch (nbits) {
@ -92,15 +96,14 @@ bool IRrecv::decodeDenon(decode_results *results, uint16_t nbits, bool strict) {
// Ditto for Panasonic, it's the same except for a different
// manufacturer code.
if (!decodeSharp(results, nbits, true, false) &&
!decodePanasonic(results, nbits, true, kDenonManufacturer)) {
if (!decodeSharp(results, offset, nbits, true, false) &&
!decodePanasonic(results, offset, nbits, true, kDenonManufacturer)) {
// We couldn't decode it as expected, so try the old legacy method.
// NOTE: I don't think this following protocol actually exists.
// Looks like a partial version of the Sharp protocol.
if (strict && nbits != kDenonLegacyBits) return false;
uint64_t data = 0;
uint16_t offset = kStartOffset;
// Match Header + Data + Footer
if (!matchGeneric(results->rawbuf + offset, &data,

Some files were not shown because too many files have changed in this diff Show More