Merge branch 'development' into development

This commit is contained in:
Dees7 2018-12-11 15:22:16 +05:00 committed by GitHub
commit 9980707a0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
344 changed files with 39447 additions and 13276 deletions

View File

@ -5,6 +5,7 @@ Alternative firmware for _ESP8266 based devices_ like [iTead](https://www.itead.
[![GitHub version](https://img.shields.io/github/release/arendst/Sonoff-Tasmota.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
[![GitHub download](https://img.shields.io/github/downloads/arendst/Sonoff-Tasmota/total.svg)](https://github.com/arendst/Sonoff-Tasmota/releases/latest)
[![License](https://img.shields.io/github/license/arendst/Sonoff-Tasmota.svg)](https://github.com/arendst/Sonoff-Tasmota/blob/development/LICENSE.txt)
[![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4)
If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
@ -137,6 +138,7 @@ Libraries used with Sonoff-Tasmota are:
- [OneWire](https://github.com/PaulStoffregen/OneWire)
- [PubSubClient](https://github.com/knolleary/pubsubclient)
- [rc-switch](https://github.com/sui77/rc-switch)
- [NewPing](https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home)
#### People inspiring me
People helping to keep the show on the road:

17
REFERENCE.md Normal file
View File

@ -0,0 +1,17 @@
## Tasmota Reference
Tasmota backgound information.
## Supported Smart Switch with Energy Monitoring GPIO usage
Module | GPIO00 | GPIO01 | GPIO02 | GPIO03 | GPIO04 | GPIO05 | GPIO12 | GPIO13 | GPIO14 | GPIO15
-------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------
Sonoff Pow | KEY1 | - | - | - | - | NRG_SEL | REL1 | NRG_CF1 | HLW_CF | LED1
Sonoff Pow R2 | KEY1 | RXD | - | TXD | - | - | REL1 | LED1_INV | - | -
Shelly 2 | - | RXD | - | TXD | REL1 | REL2 | SWT1 | - | SWT2 | -
Huafan SS | LED1_INV | - | - | LED2_INV | KEY1 | REL1_INV | NRG_CF1 | NRG_SEL | HLW_CF | -
KMC 70011 | KEY1 | - | - | - | HLW_CF | NRG_CF1 | NRG_SEL | LED1_INV | REL1 | -
Teckin | - | KEY1 | - | LED2_INV | HJL_CF | NRG_CF1 | NRG_SEL_INV | LED1_INV | REL1 | -
AplicWDP303075 | - | - | - | KEY1 | HLW_CF | NRG_CF1 | NRG_SEL_INV | LED1_INV | REL1 | -
Gosund SP1 v23 | - | LED1_INV | - | KEY1 | HJL_CF | NRG_CF1 | NRG_SEL_INV | LED2_INV | REL1 | -
SK03 Outdoor | KEY1 | - | - | - | HLW_CF | NRG_CF1 | NRG_SEL_INV | LED2_INV | LED1_INV | REL1
BlitzWolf SHP | LED2_INV | - | LED1_INV | - | - | HJL_CF | NRG_SEL_INV | KEY1 | NRG_CF1 | REL1
Teckin US | LED2_INV | - | LED1_INV | - | REL1 | HJL_CF | NRG_SEL_INV | KEY1 | NRG_CF1 | -

View File

@ -66,7 +66,7 @@ Module | Description
42 Zengge WF017 | Zengge WF017 Wifi RGB(W) Led Controller
43 Sonoff Pow R2 | Sonoff Pow R2 Wifi Smart Switch with Energy Monitoring
44 Sonoff iFan02 | Sonoff iFan02 Wifi Smart Ceiling Fan with Light
45 BlitzWolf SHP2 | BlitzWolf BW-SHP2, BW-SHP6, HomeCube SP1, Gosund SP111, Teckin SP22 Wifi Smart Switch with Energy Monitoring
45 BlitzWolf SHP | BlitzWolf BW-SHP2, BW-SHP6, HomeCube SP1, Gosund SP111, Teckin SP22 Wifi Smart Switch with Energy Monitoring
46 Shelly 1 | Shelly 1 Open Source Wifi Relay Module
47 Shelly 2 | Shelly 2 Wifi 2-gang Relay Module with Energy Monitoring
48 Xiaomi Philips | Xiaomi Philips Wifi WW Led Bulb
@ -76,7 +76,11 @@ Module | Description
52 Teckin | Teckin SP20 Wifi Smart Switch with Energy Monitoring
53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring
54 Tuya Dimmer | MIUO (and other Tuya based) Wifi Dimmer for Incandescent Lights and Led
55 Gosund SP1_v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring
55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring
56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led
57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring
58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led
59 Teckin US | Teckin US and ZooZee SA102 Wifi Smart Switch with Energy Monitoring
## Provided Binary Downloads
The following binary downloads have been compiled with ESP8266/Arduino library version **2.3.0**

View File

@ -1,74 +0,0 @@
# IRremote ESP8266 Library
[![Build Status](https://travis-ci.org/markszabo/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/markszabo/IRremoteESP8266)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/markszabo/IRremoteESP8266.svg)](http://isitmaintained.com/project/markszabo/IRremoteESP8266 "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/markszabo/IRremoteESP8266.svg)](http://isitmaintained.com/project/markszabo/IRremoteESP8266 "Percentage of issues still open")
[![GitLicense](https://gitlicense.com/badge/markszabo/IRremoteESP8266)](https://gitlicense.com/license/markszabo/IRremoteESP8266)
This library enables you to **send and receive** infra-red signals on an ESP8266 using Arduino framework (https://github.com/esp8266/Arduino)
## v2.2 Now Available
Version 2.2 of the library is now available. This is a significant internal change to existing versions.
## Upgrading from versions prior to v2.0
You will need to change your pre-v2.0 code slightly to work with post-v2.0 versions of the library. You can read more about the changes on our [wiki](https://github.com/markszabo/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
Please [report an issue](https://github.com/markszabo/IRremoteESP8266/issues/new) if you find any problems with the documentation or the library itself.
## Troubleshooting
Before reporting an issue or asking for help, please try to follow our [Troubleshooting Guide](https://github.com/markszabo/IRremoteESP8266/wiki/Troubleshooting-Guide) first.
## Frequently Asked Questions
Some common answers to common questions and problems can be found on our [F.A.Q. wiki page](https://github.com/markszabo/IRremoteESP8266/wiki/Frequently-Asked-Questions).
## History
This library was originally based on Ken Shirriff's work (https://github.com/shirriff/Arduino-IRremote/)
[Mark Szabo](https://github.com/markszabo/IRremoteESP8266) has updated the IRsend class to work on ESP8266 and [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) the receiving & decoding part (IRrecv class).
## Installation
1. Click "Download ZIP"
2. Extract the downloaded zip file
3. Rename the extracted folder to "IRremoteESP8266"
4. Move this folder to your libraries directory (under windows: C:\Users\YOURNAME\Documents\Arduino\libraries\)
5. Restart your Arduino ide
6. Check out the examples
###### Using Git to install library ( Linux )
```
cd ~/Arduino/libraries
git clone https://github.com/markszabo/IRremoteESP8266.git
```
###### To Update to the latest version of the library
`
cd ~/Arduino/libraries/IRremoteESP8266 && git pull
`
## Unit Tests
The [Unit Tests](https://en.wikipedia.org/wiki/Unit_testing) under the test/ directory are for a Unix machine, **not** the micro-controller (ESP8266).
This allows execution under Travis and on the developer's machine.
We can do this from v2.0 of the library onwards, as everything now uses c98-style type definitions.
e.g. uint16_t etc.
Any Arduino/ESP8266 specific code needs to be disabled using something similar to the following lines:
```
#ifndef UNIT_TEST
<Arduino specific code ...>
#endif
```
This is not a perfect situation as we can not obviously emulate hardware specific features and differences. e.g. Interrupts, GPIOs, CPU instruction timing etc, etc.
If you want to run all the tests yourself, try the following:
```
$ cd test
$ make run
```
## Contributing
If you want to [contribute](.github/CONTRIBUTING.md#how-can-i-contribute) to this project, consider:
- [Report](.github/CONTRIBUTING.md#reporting-bugs) bugs and errors
- Ask for enhancements
- [Create issues](.github/CONTRIBUTING.md#reporting-bugs) and [pull requests](.github/CONTRIBUTING.md#pull-requests)
- Tell other people about this library
## Contributors
Available [here](.github/Contributors.md)

View File

@ -1,112 +0,0 @@
# Release Notes
## _v2.2.1 (20171025)_
**[Features]**
- Support for sending and decoding Nikai TV messages. (#311, #313)
- gc_decode: External utility to decode Global Cache codes. (#308, #312)
- IRMQTTServer: Example code to send IR messages via HTTP & MQTT. (#316, #323)
- Improve converting 64bit values to hexidecimal. (#318)
**[Misc]**
- IRrecvDump.ino code is now deprecated. Use IRrecvDumpV2.ino instead. (#314)
## _v2.2.0 (20170922)_
**[Bug Fixes]**
- Add printing output of RC-MM and RC-5X protocols in example code. (#284)
- LG timing improvements based on observations (#291)
**[Features]**
- Automatic capture timing calibration for some protocols. (#268)
- Support for creating & sending Trotec AC codes. (#279)
- Support for creating & sending Argo Ulisse 13 DCI codes. (#280 #300)
- Move to 2 microsecond timing resolution for capture of codes. (#287)
- Capture buffer changes:
- Size at runtime. (#276)
- Message timeout at runtime. (#294)
- Simplify creating & using a second buffer (#303)
- New example code:
- Trotec A/C (#279)
- LG A/C units (#289)
- Argo Ulisse 13 DCI codes. (#300)
## _v2.1.1 (20170711)_
**[Bug Fixes]**
- GlobalCache incorrectly using hardware offset for period calc. (#267)
**[Features]**
- Support reporting of 'NEC'-like 32-bit protocols. e.g. Apple TV remote (#265)
- Add an example of sendRaw() to IRsendDemo.ino (#270)
## _v2.1.0 (20170704)_
**[Features]**
- Support for sending Pronto IR codes. (#248)
- Support for sending Fujitsu A/C codes. (#88)
- Minor improvements to examples.
## _v2.0.3 (20170618)_
**[Bug fixes]**
- Capture buffer could become corrupt after large message, breaking subsequent decodes. (#253)
## _v2.0.2 (20170615)_
**[Bug fixes]**
- Correct decode issue introduced in v2.0.1 affecting multiple protocol decoders (#243)
- Correct post-message gap for the Panasonic protocol(s) (#245)
- Incorrect display of the decoded uint64_t value in the example code. (#245)
## _v2.0.1 (20170614)_
**[Bug fixes]**
- Decoding protocols when it doesn't detect a post-command gap, and there is no more data. (#243)
- Incorrect minimum size calculation when there is no post-command gap. (#243)
## _v2.0.0 - 64 bit support and major improvements (20170612)_
**[Misc]**
- This is almost a complete re-write of the library.
**[Features]**
- All suitable protocols now handle 64-bit data messages and are repeatable via an optional argument.
- Unit tests for all protocols.
- Far better and stricter decoding for most protocols.
- Address & command decoding for protocols where that information is available.
- Much more precise timing for generation of signals sent.
- Lower duty-cycles for some protocols.
- Several new protocols added, and some new sending and decoding routines for existing ones.
- Ability to optionally chose which protocols are included, enabling faster decoding and smaller code footprints if desired.
- Support for far larger capture buffers. (e.g. RAWLEN > 256)
**[Bug fixes]**
- Numerous bug fixes.
## _v1.2.0 (20170429)_
**[Features]**
- Add ability to copy IR capture buffer, and continue capturing. Means faster and better IR command decoding.
- Reduce IRAM usage by 28 bytes.
- Improve capture of RC-MM & Panasonic protocols.
- Upgrade IRrecvDumpV2 to new IR capture buffer. Much fewer corrupted/truncated IR messages.
## _v1.1.1 (20170413)_
**[Bug fixes]**
- Fix a reported problem when sending the LG protocol. Preemptive fix for possible similar cases.
- Fix minor issues in examples.
**[Features]**
- Add documentation to some examples to aid new people.
- Add ALPHA support for RC-MM protocol. (Known to be currently not 100% working.)

View File

@ -1,199 +0,0 @@
/*
* IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Example circuit diagram:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-receiving
* Changes:
* Version 0.2 April, 2017
* - Decode from a copy of the data so we can start capturing faster thus
* reduce the likelihood of miscaptures.
* Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, Copyright 2009 Ken Shirriff, http://arcfn.com
*/
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
// An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU
// board).
uint16_t RECV_PIN = 14;
// As this program is a special purpose capture/decoder, let us use a larger
// than normal buffer so we can handle Air Conditioner remote codes.
uint16_t CAPTURE_BUFFER_SIZE = 1024;
// Nr. of milli-Seconds of no-more-data before we consider a message ended.
// NOTE: Don't exceed MAX_TIMEOUT_MS. Typically 130ms.
#define TIMEOUT 15U // Suits most messages, while not swallowing repeats.
// #define TIMEOUT 90U // Suits messages with big gaps like XMP-1 & some aircon
// units, but can accidently swallow repeated messages
// in the rawData[] output.
// Use turn on the save buffer feature for more complete capture coverage.
IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT, true);
decode_results results; // Somewhere to store the results
void setup() {
// Status message will be sent to the PC at 115200 baud
Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
delay(500); // Wait a bit for the serial connection to be establised.
irrecv.enableIRIn(); // Start the receiver
}
// Display encoding type
//
void encoding(decode_results *results) {
switch (results->decode_type) {
default:
case UNKNOWN: Serial.print("UNKNOWN"); break;
case NEC: Serial.print("NEC"); break;
case NEC_LIKE: Serial.print("NEC (non-strict)"); break;
case SONY: Serial.print("SONY"); break;
case RC5: Serial.print("RC5"); break;
case RC5X: Serial.print("RC5X"); break;
case RC6: Serial.print("RC6"); break;
case RCMM: Serial.print("RCMM"); break;
case DISH: Serial.print("DISH"); break;
case SHARP: Serial.print("SHARP"); break;
case JVC: Serial.print("JVC"); break;
case SANYO: Serial.print("SANYO"); break;
case SANYO_LC7461: Serial.print("SANYO_LC7461"); break;
case MITSUBISHI: Serial.print("MITSUBISHI"); break;
case SAMSUNG: Serial.print("SAMSUNG"); break;
case LG: Serial.print("LG"); break;
case WHYNTER: Serial.print("WHYNTER"); break;
case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break;
case PANASONIC: Serial.print("PANASONIC"); break;
case DENON: Serial.print("DENON"); break;
case COOLIX: Serial.print("COOLIX"); break;
case NIKAI: Serial.print("NIKAI"); break;
}
if (results->repeat) Serial.print(" (Repeat)");
}
// Dump out the decode_results structure.
//
void dumpInfo(decode_results *results) {
if (results->overflow)
Serial.printf("WARNING: IR code too big for buffer (>= %d). "
"These results shouldn't be trusted until this is resolved. "
"Edit & increase CAPTURE_BUFFER_SIZE.\n",
CAPTURE_BUFFER_SIZE);
// Show Encoding standard
Serial.print("Encoding : ");
encoding(results);
Serial.println("");
// Show Code & length
Serial.print("Code : ");
serialPrintUint64(results->value, 16);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
uint16_t getCookedLength(decode_results *results) {
uint16_t length = results->rawlen - 1;
for (uint16_t i = 0; i < results->rawlen - 1; i++) {
uint32_t usecs = results->rawbuf[i] * RAWTICK;
// Add two extra entries for multiple larger than UINT16_MAX it is.
length += (usecs / UINT16_MAX) * 2;
}
return length;
}
// Dump out the decode_results structure.
//
void dumpRaw(decode_results *results) {
// Print Raw data
Serial.print("Timing[");
Serial.print(results->rawlen - 1, DEC);
Serial.println("]: ");
for (uint16_t i = 1; i < results->rawlen; i++) {
if (i % 100 == 0)
yield(); // Preemptive yield every 100th entry to feed the WDT.
if (i % 2 == 0) { // even
Serial.print("-");
} else { // odd
Serial.print(" +");
}
Serial.printf("%6d", results->rawbuf[i] * RAWTICK);
if (i < results->rawlen - 1)
Serial.print(", "); // ',' not needed for last one
if (!(i % 8)) Serial.println("");
}
Serial.println(""); // Newline
}
// Dump out the decode_results structure.
//
void dumpCode(decode_results *results) {
// Start declaration
Serial.print("uint16_t "); // variable type
Serial.print("rawData["); // array name
Serial.print(getCookedLength(results), DEC); // array size
Serial.print("] = {"); // Start declaration
// Dump data
for (uint16_t i = 1; i < results->rawlen; i++) {
uint32_t usecs;
for (usecs = results->rawbuf[i] * RAWTICK;
usecs > UINT16_MAX;
usecs -= UINT16_MAX)
Serial.printf("%d, 0", UINT16_MAX);
Serial.print(usecs, DEC);
if (i < results->rawlen - 1)
Serial.print(", "); // ',' not needed on last one
if (i % 2 == 0) Serial.print(" "); // Extra if it was even.
}
// End declaration
Serial.print("};"); //
// Comment
Serial.print(" // ");
encoding(results);
Serial.print(" ");
serialPrintUint64(results->value, HEX);
// Newline
Serial.println("");
// Now dump "known" codes
if (results->decode_type != UNKNOWN) {
// Some protocols have an address &/or command.
// NOTE: It will ignore the atypical case when a message has been decoded
// but the address & the command are both 0.
if (results->address > 0 || results->command > 0) {
Serial.print("uint32_t address = 0x");
Serial.print(results->address, HEX);
Serial.println(";");
Serial.print("uint32_t command = 0x");
Serial.print(results->command, HEX);
Serial.println(";");
}
// All protocols have data
Serial.print("uint64_t data = 0x");
serialPrintUint64(results->value, 16);
Serial.println(";");
}
}
// The repeating section of the code
//
void loop() {
// Check if the IR code has been received.
if (irrecv.decode(&results)) {
dumpInfo(&results); // Output the results
dumpRaw(&results); // Output the results in RAW format
dumpCode(&results); // Output the results as source code
Serial.println(""); // Blank line between entries
}
}

View File

@ -1,44 +0,0 @@
// Copyright 2017 Jonny Graham
#include <IRsend.h>
#include <ir_Fujitsu.h>
IRFujitsuAC fujitsu(5); // IR led controlled by Pin D1.
void printState() {
// Display the settings.
Serial.println("Fujitsu A/C remote is in the following state:");
Serial.printf(" Command:%d, Mode: %d, Temp: %dC, Fan Speed: %d," \
" Swing Mode: %d\n",
fujitsu.getCmd(), fujitsu.getMode(), fujitsu.getTemp(),
fujitsu.getFanSpeed(), fujitsu.getSwing());
// Display the encoded IR sequence.
unsigned char* ir_code = fujitsu.getRaw();
Serial.print("IR Code: 0x");
for (uint8_t i = 0; i < FUJITSU_AC_STATE_LENGTH; i++)
Serial.printf("%02X", ir_code[i]);
Serial.println();
}
void setup() {
fujitsu.begin();
Serial.begin(115200);
delay(200);
// Set up what we want to send. See ir_Mitsubishi.cpp for all the options.
Serial.println("Default state of the remote.");
printState();
Serial.println("Setting desired state for A/C.");
fujitsu.setCmd(FUJITSU_AC_CMD_TURN_ON);
fujitsu.setSwing(FUJITSU_AC_SWING_BOTH);
fujitsu.setMode(FUJITSU_AC_MODE_COOL);
fujitsu.setFanSpeed(FUJITSU_AC_FAN_HIGH);
fujitsu.setTemp(24);
}
void loop() {
// Now send the IR signal.
Serial.println("Sending IR command to A/C ...");
fujitsu.send();
printState();
delay(5000);
}

View File

@ -1,128 +0,0 @@
#########################################
# Syntax Coloring Map For IRremoteESP8266
#########################################
#######################################################
# The Arduino IDE requires the use of a tab separator
# between the name and identifier. Without this tab the
# keyword is not highlighted.
#
# Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords
#######################################################
#######################################
# Datatypes (KEYWORD1)
#######################################
decode_results KEYWORD1
IRrecv KEYWORD1
IRsend KEYWORD1
IRtimer KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
decode KEYWORD2
enableIRIn KEYWORD2
disableIRIn KEYWORD2
resume KEYWORD2
begin KEYWORD2
send KEYWORD2
enableIROut KEYWORD2
sendNEC KEYWORD2
encodeNEC KEYWORD2
sendLG KEYWORD2
encodeLG KEYWORD2
sendSony KEYWORD2
encodeSony KEYWORD2
sendSanyo KEYWORD2
sendSanyoLC7461 KEYWORD2
encodeSanyoLC7461 KEYWORD2
sendMitsubishi KEYWORD2
sendRaw KEYWORD2
sendGC KEYWORD2
sendRC5 KEYWORD2
sendRC6 KEYWORD2
sendRCMM KEYWORD2
sendDISH KEYWORD2
sendSharp KEYWORD2
sendSharpRaw KEYWORD2
encodeSharp KEYWORD2
sendPanasonic KEYWORD2
sendPanasonic64 KEYWORD2
encodePanasonic KEYWORD2
sendJVC KEYWORD2
encodeJVC KEYWORD2
sendWhynter KEYWORD2
sendSAMSUNG KEYWORD2
encodeSAMSUNG KEYWORD2
sendDaikin KEYWORD2
sendCOOLIX KEYWORD2
sendDenon KEYWORD2
sendKelvinator KEYWORD2
sendSherwood KEYWORD2
sendMitsubishiAC KEYWORD2
mark KEYWORD2
space KEYWORD2
reset KEYWORD2
elapsed KEYWORD2
calcLGChecksum KEYWORD2
reverseBits KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
NEC LITERAL1
SONY LITERAL1
SANYO LITERAL1
MITSUBISHI LITERAL1
RC5 LITERAL1
RC5X LITERAL1
RC6 LITERAL1
DISH LITERAL1
SHARP LITERAL1
PANASONIC LITERAL1
JVC LITERAL1
LG LITERAL1
SAMSUNG LITERAL1
WHYNTER LITERAL1
AIWA_RC_T501 LITERAL1
COOLIX LITERAL1
UNKNOWN LITERAL1
REPEAT LITERAL1
DENON LITERAL1
DAIKIN LITERAL1
KELVINATOR LITERAL1
SHERWOOD LITERAL1
MITSUBISHIAC LITERAL1
RCMM LITERAL1
SANYO_LC7461 LITERAL1
NEC_BITS LITERAL1
SHERWOOD_BITS LITERAL1
SONY_MIN_BITS LITERAL1
SONY_12_BITS LITERAL1
SONY_15_BITS LITERAL1
SONY_20_BITS LITERAL1
SANYO_SA8650B_BITS LITERAL1
MITSUBISHI_BITS LITERAL1
PANASONIC_BITS LITERAL1
JVC_BITS LITERAL1
LG_BITS LITERAL1
SAMSUNG_BITS LITERAL1
COOLIX_BITS LITERAL1
DAIKIN_BITS LITERAL1
RC5X_BITS LITERAL1
RC6_36_BITS LITERAL1
RC6_MODE0_BITS LITERAL1
RCMM_BITS LITERAL1
WHYNTER_BITS LITERAL1
SANYO_LC7461_BITS LITERAL1
SHARP_BITS LITERAL1
DISH_BITS LITERAL1
DENON_BITS LITERAL1
SONY_MIN_REPEAT LITERAL1
MITSUBISHI_MIN_REPEAT LITERAL1
DISH_MIN_REPEAT LITERAL1
SHERWOOD_MIN_REPEAT LITERAL1

View File

@ -1,207 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2015 Mark Szabo
// Copyright 2015 Sebastien Warin
// Copyright 2017 David Conran
#ifndef IRRECV_H_
#define IRRECV_H_
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <stddef.h>
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include "IRremoteESP8266.h"
// Constants
#define HEADER 2U // Usual nr. of header entries.
#define FOOTER 2U // Usual nr. of footer (stop bits) entries.
#define OFFSET_START 1U // Usual rawbuf entry to start processing from.
#define MS_TO_USEC(x) (x * 1000U) // Convert milli-Seconds to micro-Seconds.
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
#define MARK_EXCESS 50U
#define RAWBUF 100U // Default length of raw capture buffer
#define REPEAT UINT64_MAX
// receiver states
#define STATE_IDLE 2U
#define STATE_MARK 3U
#define STATE_SPACE 4U
#define STATE_STOP 5U
#define TOLERANCE 25U // default percent tolerance in measurements
#define RAWTICK 2U // Capture tick to uSec factor.
// How long (ms) before we give up wait for more data?
// Don't exceed MAX_TIMEOUT_MS without a good reason.
// That is the capture buffers maximum value size. (UINT16_MAX / RAWTICK)
// Typically messages/protocols tend to repeat around the 100ms timeframe,
// thus we should timeout before that to give us some time to try to decode
// before we need to start capturing a possible new message.
// Typically 15ms suits most applications. However, some protocols demand a
// higher value. e.g. 90ms for XMP-1 and some aircon units.
#define TIMEOUT_MS 15U // In MilliSeconds.
#define MAX_TIMEOUT_MS (RAWTICK * UINT16_MAX / MS_TO_USEC(1))
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619UL
#define FNV_BASIS_32 2166136261UL
// Types
// information for the interrupt handler
typedef struct {
uint8_t recvpin; // pin for IR data from detector
uint8_t rcvstate; // state machine
uint16_t timer; // state timer, counts 50uS ticks.
uint16_t bufsize; // max. nr. of entries in the capture buffer.
uint16_t *rawbuf; // raw data
// uint16_t is used for rawlen as it saves 3 bytes of iram in the interrupt
// handler. Don't ask why, I don't know. It just does.
uint16_t rawlen; // counter of entries in rawbuf.
uint8_t overflow; // Buffer overflow indicator.
uint8_t timeout; // Nr. of milliSeconds before we give up.
} irparams_t;
// results from a data match
typedef struct {
bool success; // Was the match successful?
uint64_t data; // The data found.
uint16_t used; // How many buffer positions were used.
} match_result_t;
// Classes
// Results returned from the decoder
class decode_results {
public:
decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN
uint64_t value; // Decoded value
uint16_t bits; // Number of bits in decoded value
volatile uint16_t *rawbuf; // Raw intervals in .5 us ticks
uint16_t rawlen; // Number of records in rawbuf.
bool overflow;
bool repeat; // Is the result a repeat code?
uint32_t address; // Decoded device address.
uint32_t command; // Decoded command.
};
// main class for receiving IR
class IRrecv {
public:
explicit IRrecv(uint16_t recvpin, uint16_t bufsize = RAWBUF,
uint8_t timeout = TIMEOUT_MS,
bool save_buffer = false); // Constructor
~IRrecv(); // Destructor
bool decode(decode_results *results, irparams_t *save = NULL);
void enableIRIn();
void disableIRIn();
void resume();
uint16_t getBufSize();
#ifndef UNIT_TEST
private:
#endif
irparams_t *irparams_save;
// These are called by decode
void copyIrParams(volatile irparams_t *src, irparams_t *dst);
int16_t compare(uint16_t oldval, uint16_t newval);
uint32_t ticksLow(uint32_t usecs, uint8_t tolerance = TOLERANCE);
uint32_t ticksHigh(uint32_t usecs, uint8_t tolerance = TOLERANCE);
bool match(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE);
bool matchAtLeast(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE);
bool matchMark(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE, int16_t excess = MARK_EXCESS);
bool matchSpace(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE, int16_t excess = MARK_EXCESS);
match_result_t matchData(volatile uint16_t *data_ptr, uint16_t nbits,
uint16_t onemark, uint32_t onespace,
uint16_t zeromark, uint32_t zerospace);
bool decodeHash(decode_results *results);
#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || SEND_SANYO)
bool decodeNEC(decode_results *results, uint16_t nbits = NEC_BITS,
bool strict = true);
#endif
#if DECODE_SONY
bool decodeSony(decode_results *results, uint16_t nbits = SONY_MIN_BITS,
bool strict = false);
#endif
#if DECODE_SANYO
// DISABLED due to poor quality.
// bool decodeSanyo(decode_results *results,
// uint16_t nbits = SANYO_SA8650B_BITS,
// bool strict = false);
bool decodeSanyoLC7461(decode_results *results,
uint16_t nbits = SANYO_LC7461_BITS,
bool strict = true);
#endif
#if DECODE_MITSUBISHI
bool decodeMitsubishi(decode_results *results,
uint16_t nbits = MITSUBISHI_BITS,
bool strict = true);
#endif
#if (DECODE_RC5 || DECODE_R6)
int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used,
uint16_t bitTime);
#endif
#if DECODE_RC5
bool decodeRC5(decode_results *results, uint16_t nbits = RC5X_BITS,
bool strict = true);
#endif
#if DECODE_RC6
bool decodeRC6(decode_results *results, uint16_t nbits = RC6_MODE0_BITS,
bool strict = false);
#endif
#if DECODE_RCMM
bool decodeRCMM(decode_results *results, uint16_t nbits = RCMM_BITS,
bool strict = false);
#endif
#if (DECODE_PANASONIC || DECODE_DENON)
bool decodePanasonic(decode_results *results, uint16_t nbits = PANASONIC_BITS,
bool strict = false,
uint32_t manufacturer = PANASONIC_MANUFACTURER);
#endif
#if DECODE_LG
bool decodeLG(decode_results *results, uint16_t nbits = LG_BITS,
bool strict = false);
#endif
#if DECODE_JVC
bool decodeJVC(decode_results *results, uint16_t nbits = JVC_BITS,
bool strict = true);
#endif
#if DECODE_SAMSUNG
bool decodeSAMSUNG(decode_results *results, uint16_t nbits = SAMSUNG_BITS,
bool strict = true);
#endif
#if DECODE_WHYNTER
bool decodeWhynter(decode_results *results, uint16_t nbits = WHYNTER_BITS,
bool strict = true);
#endif
#if DECODE_COOLIX
bool decodeCOOLIX(decode_results *results, uint16_t nbits = COOLIX_BITS,
bool strict = true);
#endif
#if DECODE_DENON
bool decodeDenon(decode_results *results, uint16_t nbits = DENON_BITS,
bool strict = true);
#endif
#if DECODE_DISH
bool decodeDISH(decode_results *results, uint16_t nbits = DISH_BITS,
bool strict = true);
#endif
#if (DECODE_SHARP || DECODE_DENON)
bool decodeSharp(decode_results *results, uint16_t nbits = SHARP_BITS,
bool strict = true, bool expansion = true);
#endif
#if DECODE_AIWA_RC_T501
bool decodeAiwaRCT501(decode_results *results,
uint16_t nbits = AIWA_RC_T501_BITS, bool strict = true);
#endif
#if DECODE_NIKAI
bool decodeNikai(decode_results *results, uint16_t nbits = NIKAI_BITS,
bool strict = true);
#endif
};
#endif // IRRECV_H_

View File

@ -1,337 +0,0 @@
/***************************************************
* IRremote for ESP8266
*
* Based on the IRremote library for Arduino by Ken Shirriff
* Version 0.11 August, 2009
* Copyright 2009 Ken Shirriff
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
*
* Edited by Mitra to add new controller SANYO
*
* Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
*
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
* LG added by Darryl Smith (based on the JVC protocol)
* Whynter A/C ARC-110WD added by Francesco Meschia
* Coolix A/C / heatpump added by (send) bakrus & (decode) crankyoldgit
* Denon: sendDenon, decodeDenon added by Massimiliano Pinto
(from https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp)
* Kelvinator A/C and Sherwood added by crankyoldgit
* Mitsubishi (TV) sending added by crankyoldgit
* Pronto code sending added by crankyoldgit
* Mitsubishi A/C added by crankyoldgit
* (derived from https://github.com/r45635/HVAC-IR-Control)
* DISH decode by marcosamarinho
* Gree Heatpump sending added by Ville Skyttä (scop)
* (derived from https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp)
* Updated by markszabo (https://github.com/markszabo/IRremoteESP8266) for sending IR code on ESP8266
* Updated by Sebastien Warin (http://sebastien.warin.fr) for receiving IR code on ESP8266
*
* Updated by sillyfrog for Daikin, adopted from
* (https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/)
* Fujitsu A/C code added by jonnygraham
* Trotec AC code by stufisher
* GPL license, all text above must be included in any redistribution
****************************************************/
#ifndef IRREMOTEESP8266_H_
#define IRREMOTEESP8266_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#ifdef UNIT_TEST
#include <iostream>
#endif
// Library Version
#define _IRREMOTEESP8266_VERSION_ "2.2.1"
// Supported IR protocols
// Each protocol you include costs memory and, during decode, costs time
// Disable (set to false) all the protocols you do not need/want!
//
/*
#define DECODE_NEC true
#define SEND_NEC true
#define DECODE_SHERWOOD true // Doesn't exist. Actually is DECODE_NEC
#define SEND_SHERWOOD true
#define DECODE_RC5 true
#define SEND_RC5 true
#define DECODE_RC6 true
#define SEND_RC6 true
#define DECODE_RCMM true
#define SEND_RCMM true
#define DECODE_SONY true
#define SEND_SONY true
#define DECODE_PANASONIC true
#define SEND_PANASONIC true
#define DECODE_JVC true
#define SEND_JVC true
#define DECODE_SAMSUNG true
#define SEND_SAMSUNG true
#define DECODE_WHYNTER true
#define SEND_WHYNTER true
#define DECODE_AIWA_RC_T501 true
#define SEND_AIWA_RC_T501 true
#define DECODE_LG true
#define SEND_LG true
#define DECODE_SANYO true
#define SEND_SANYO true
#define DECODE_MITSUBISHI true
#define SEND_MITSUBISHI true
#define DECODE_DISH true
#define SEND_DISH true
#define DECODE_SHARP true
#define SEND_SHARP true
#define DECODE_DENON true
#define SEND_DENON true
#define DECODE_KELVINATOR false // Not written.
#define SEND_KELVINATOR true
#define DECODE_MITSUBISHI_AC false // Not written.
#define SEND_MITSUBISHI_AC true
#define DECODE_FUJITSU_AC false // Not written.
#define SEND_FUJITSU_AC true
#define DECODE_DAIKIN false // Not finished.
#define SEND_DAIKIN true
#define DECODE_COOLIX true
#define SEND_COOLIX true
#define DECODE_GLOBALCACHE false // Not written.
#define SEND_GLOBALCACHE true
#define DECODE_GREE false // Not written.
#define SEND_GREE true
#define DECODE_PRONTO false // Not written.
#define SEND_PRONTO true
#define DECODE_ARGO false // Not written.
#define SEND_ARGO true
#define DECODE_TROTEC false // Not implemented.
#define SEND_TROTEC true
#define DECODE_NIKAI true
#define SEND_NIKAI true
*/
// Tasmota supported protocols (less protocols is less code size)
#define DECODE_NEC true
#define SEND_NEC true
#define DECODE_SHERWOOD false // Doesn't exist. Actually is DECODE_NEC
#define SEND_SHERWOOD false
#define DECODE_RC5 true
#define SEND_RC5 true
#define DECODE_RC6 true
#define SEND_RC6 true
#define DECODE_RCMM false
#define SEND_RCMM false
#define DECODE_SONY true
#define SEND_SONY true
#define DECODE_PANASONIC true
#define SEND_PANASONIC true
#define DECODE_JVC true
#define SEND_JVC true
#define DECODE_SAMSUNG true
#define SEND_SAMSUNG true
#define DECODE_WHYNTER false
#define SEND_WHYNTER false
#define DECODE_AIWA_RC_T501 false
#define SEND_AIWA_RC_T501 false
#define DECODE_LG false
#define SEND_LG false
#define DECODE_SANYO false
#define SEND_SANYO false
#define DECODE_MITSUBISHI false
#define SEND_MITSUBISHI false
#define DECODE_DISH false
#define SEND_DISH true
#define DECODE_SHARP false
#define SEND_SHARP false
#define DECODE_DENON false
#define SEND_DENON false
#define DECODE_KELVINATOR false // Not written.
#define SEND_KELVINATOR false
#define DECODE_MITSUBISHI_AC false // Not written.
#define SEND_MITSUBISHI_AC true
#define DECODE_FUJITSU_AC false // Not written.
#define SEND_FUJITSU_AC false
#define DECODE_DAIKIN false // Not finished.
#define SEND_DAIKIN false
#define DECODE_COOLIX false
#define SEND_COOLIX false
#define DECODE_GLOBALCACHE false // Not written.
#define SEND_GLOBALCACHE false
#define DECODE_GREE false // Not written.
#define SEND_GREE false
#define DECODE_PRONTO false // Not written.
#define SEND_PRONTO false
#define DECODE_ARGO false // Not written.
#define SEND_ARGO false
#define DECODE_TROTEC false // Not implemented.
#define SEND_TROTEC false
#define DECODE_NIKAI false
#define SEND_NIKAI false
/*
* 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
* so numbering should always stay the same.
*/
enum decode_type_t {
UNKNOWN = -1,
UNUSED = 0,
RC5,
RC6,
NEC,
SONY,
PANASONIC,
JVC,
SAMSUNG,
WHYNTER,
AIWA_RC_T501,
LG,
SANYO,
MITSUBISHI,
DISH,
SHARP,
COOLIX,
DAIKIN,
DENON,
KELVINATOR,
SHERWOOD,
MITSUBISHI_AC,
RCMM,
SANYO_LC7461,
RC5X,
GREE,
PRONTO, // Technically not a protocol, but an encoding.
NEC_LIKE,
ARGO,
TROTEC,
NIKAI,
RAW, // Technically not a protocol, but an encoding.
GLOBALCACHE // Technically not a protocol, but an encoding.
};
// Message lengths & required repeat values
#define AIWA_RC_T501_BITS 15U
#define AIWA_RC_T501_MIN_REPEAT 1U
#define COOLIX_BITS 24U
#define DAIKIN_BITS 99U
#define DAIKIN_COMMAND_LENGTH 27U
#define DENON_BITS SHARP_BITS
#define DENON_48_BITS PANASONIC_BITS
#define DENON_LEGACY_BITS 14U
#define DISH_BITS 16U
#define DISH_MIN_REPEAT 3U
#define GREE_STATE_LENGTH 8U
#define GREE_BITS (GREE_STATE_LENGTH * 8)
#define JVC_BITS 16U
#define KELVINATOR_STATE_LENGTH 16U
#define LG_BITS 28U
#define LG32_BITS 32U
#define MITSUBISHI_BITS 16U
// TODO(anyone): Verify that the Mitsubishi repeat is really needed.
#define MITSUBISHI_MIN_REPEAT 1U // Based on marcosamarinho's code.
#define MITSUBISHI_AC_STATE_LENGTH 18U
#define MITSUBISHI_AC_MIN_REPEAT 1U
#define FUJITSU_AC_MIN_REPEAT 0U
#define NEC_BITS 32U
#define PANASONIC_BITS 48U
#define PANASONIC_MANUFACTURER 0x4004ULL
#define PRONTO_MIN_LENGTH 6U
#define RC5_RAW_BITS 14U
#define RC5_BITS RC5_RAW_BITS - 2U
#define RC5X_BITS RC5_RAW_BITS - 1U
#define RC6_MODE0_BITS 20U // Excludes the 'start' bit.
#define RC6_36_BITS 36U // Excludes the 'start' bit.
#define RCMM_BITS 24U
#define SAMSUNG_BITS 32U
#define SANYO_SA8650B_BITS 12U
#define SANYO_LC7461_ADDRESS_BITS 13U
#define SANYO_LC7461_COMMAND_BITS 8U
#define SANYO_LC7461_BITS ((SANYO_LC7461_ADDRESS_BITS + \
SANYO_LC7461_COMMAND_BITS) * 2)
#define SHARP_ADDRESS_BITS 5U
#define SHARP_COMMAND_BITS 8U
#define SHARP_BITS (SHARP_ADDRESS_BITS + SHARP_COMMAND_BITS + 2) // 15U
#define SHERWOOD_BITS NEC_BITS
#define SHERWOOD_MIN_REPEAT 1U
#define SONY_12_BITS 12U
#define SONY_15_BITS 15U
#define SONY_20_BITS 20U
#define SONY_MIN_BITS SONY_12_BITS
#define SONY_MIN_REPEAT 2U
#define TROTEC_COMMAND_LENGTH 9U
#define WHYNTER_BITS 32U
#define ARGO_COMMAND_LENGTH 12U
#define NIKAI_BITS 24U
// Turn on Debugging information by uncommenting the following line.
// #define DEBUG 1
#ifdef DEBUG
#ifdef UNIT_TEST
#define DPRINT(x) do { std::cout << x; } while (0)
#define DPRINTLN(x) do { std::cout << x << std::endl; } while (0)
#endif // UNIT_TEST
#ifdef ARDUINO
#define DPRINT(x) do { Serial.print(x); } while (0)
#define DPRINTLN(x) do { Serial.println(x); } while (0)
#endif // ARDUINO
#else // DEBUG
#define DPRINT(x)
#define DPRINTLN(x)
#endif // DEBUG
#endif // IRREMOTEESP8266_H_

View File

@ -1,327 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2015 Mark Szabo
// Copyright 2017 David Conran
#include "IRsend.h"
#ifndef UNIT_TEST
#include <Arduino.h>
#else
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#endif
#include <algorithm>
#ifdef UNIT_TEST
#include <cmath>
#endif
#include "IRtimer.h"
// Originally from https://github.com/shirriff/Arduino-IRremote/
// Updated by markszabo (https://github.com/markszabo/IRremoteESP8266) for
// sending IR code on ESP8266
// IRsend ----------------------------------------------------------------------
// Create an IRsend object.
//
// Args:
// IRsendPin: Which GPIO pin to use when sending an IR command.
// inverted: *DANGER* Optional flag to invert the output. (default = false)
// e.g. LED is illuminated when GPIO is LOW rather than HIGH.
// Setting this to something other than the default could
// easily destroy your IR LED if you are overdriving it.
// Unless you *REALLY* know what you are doing, don't change this.
// Returns:
// An IRsend object.
IRsend::IRsend(uint16_t IRsendPin, bool inverted) : IRpin(IRsendPin),
periodOffset(PERIOD_OFFSET) {
if (inverted) {
outputOn = LOW;
outputOff = HIGH;
} else {
outputOn = HIGH;
outputOff = LOW;
}
}
// Enable the pin for output.
void IRsend::begin() {
#ifndef UNIT_TEST
pinMode(IRpin, OUTPUT);
#endif
}
// Turn off the IR LED.
void IRsend::ledOff() {
#ifndef UNIT_TEST
digitalWrite(IRpin, outputOff);
#endif
}
// Calculate the period for a given frequency. (T = 1/f)
//
// Args:
// freq: Frequency in Hz.
// use_offset: Should we use the calculated offset or not?
// Returns:
// nr. of uSeconds.
uint32_t IRsend::calcUSecPeriod(uint32_t hz, bool use_offset) {
if (hz == 0) hz = 1; // Avoid Zero hz. Divide by Zero is nasty.
uint32_t period = (1000000UL + hz/2) / hz; // The equiv of round(1000000/hz).
// Apply the offset and ensure we don't result in a <= 0 value.
if (use_offset)
return std::max((uint32_t) 1, period + periodOffset);
else
return std::max((uint32_t) 1, period);
}
// Set the output frequency modulation and duty cycle.
//
// Args:
// freq: The freq we want to modulate at. Assumes < 1000 means kHz else Hz.
// duty: Percentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off.
//
// Note:
// Integer timing functions & math mean we can't do fractions of
// microseconds timing. Thus minor changes to the freq & duty values may have
// limited effect. You've been warned.
void IRsend::enableIROut(uint32_t freq, uint8_t duty) {
// Can't have more than 100% duty cycle.
duty = std::min(duty, (uint8_t) 100);
if (freq < 1000) // Were we given kHz? Supports the old call usage.
freq *= 1000;
uint32_t period = calcUSecPeriod(freq);
// Nr. of uSeconds the LED will be on per pulse.
onTimePeriod = (period * duty) / 100;
// Nr. of uSeconds the LED will be off per pulse.
offTimePeriod = period - onTimePeriod;
}
// Modulate the IR LED for the given period (usec) and at the duty cycle set.
//
// Args:
// usec: The period of time to modulate the IR LED for, in microseconds.
// Returns:
// Nr. of pulses actually sent.
//
// Note:
// The ESP8266 has no good way to do hardware PWM, so we have to do it all
// in software. There is a horrible kludge/brilliant hack to use the second
// serial TX line to do fairly accurate hardware PWM, but it is only
// available on a single specific GPIO and only available on some modules.
// e.g. It's not available on the ESP-01 module.
// Hence, for greater compatibility & choice, we don't use that method.
// Ref:
// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/
uint16_t IRsend::mark(uint16_t usec) {
uint16_t counter = 0;
IRtimer usecTimer = IRtimer();
// Cache the time taken so far. This saves us calling time, and we can be
// assured that we can't have odd math problems. i.e. unsigned under/overflow.
uint32_t elapsed = usecTimer.elapsed();
while (elapsed < usec) { // Loop until we've met/exceeded our required time.
#ifndef UNIT_TEST
digitalWrite(IRpin, outputOn); // Turn the LED on.
// Calculate how long we should pulse on for.
// e.g. Are we to close to the end of our requested mark time (usec)?
delayMicroseconds(std::min((uint32_t) onTimePeriod, usec - elapsed));
digitalWrite(IRpin, outputOff); // Turn the LED off.
#endif
counter++;
if (elapsed + onTimePeriod >= usec)
return counter; // LED is now off & we've passed our allotted time.
// Wait for the lesser of the rest of the duty cycle, or the time remaining.
#ifndef UNIT_TEST
delayMicroseconds(std::min(usec - elapsed - onTimePeriod,
(uint32_t) offTimePeriod));
#endif
elapsed = usecTimer.elapsed(); // Update & recache the actual elapsed time.
}
return counter;
}
// Turn the pin (LED) off for a given time.
// Sends an IR space for the specified number of microseconds.
// A space is no output, so the PWM output is disabled.
//
// Args:
// time: Time in microseconds (us).
void IRsend::space(uint32_t time) {
ledOff();
if (time == 0) return;
#ifndef UNIT_TEST
// delayMicroseconds is only accurate to 16383us.
// Ref: https://www.arduino.cc/en/Reference/delayMicroseconds
if (time <= 16383) {
delayMicroseconds(time);
} else {
// Invoke a delay(), where possible, to avoid triggering the WDT.
delay(time / 1000UL); // Delay for as many whole milliseconds as we can.
// Delay the remaining sub-millisecond.
delayMicroseconds(static_cast<uint16_t>(time % 1000UL));
}
#endif
}
// Calculate & set any offsets to account for execution times.
//
// Args:
// hz: The frequency to calibrate at >= 1000Hz. Default is 38000Hz.
//
// Status: ALPHA / Untested.
//
// NOTE:
// This will generate an 65535us mark() IR LED signal.
// This only needs to be called once, if at all.
void IRsend::calibrate(uint16_t hz) {
if (hz < 1000) // Were we given kHz? Supports the old call usage.
hz *= 1000;
periodOffset = 0; // Turn off any existing offset while we calibrate.
enableIROut(hz);
IRtimer usecTimer = IRtimer(); // Start a timer *just* before we do the call.
uint16_t pulses = mark(UINT16_MAX); // Generate a PWM of 65,535 us. (Max.)
uint32_t timeTaken = usecTimer.elapsed(); // Record the time it took.
// While it shouldn't be necessary, assume at least 1 pulse, to avoid a
// divide by 0 situation.
pulses = std::max(pulses, (uint16_t) 1U);
uint32_t calcPeriod = calcUSecPeriod(hz); // e.g. @38kHz it should be 26us.
// Assuming 38kHz for the example calculations:
// In a 65535us pulse, we should have 2520.5769 pulses @ 26us periods.
// e.g. 65535.0us / 26us = 2520.5769
// This should have caused approx 2520 loops through the main loop in mark().
// The average over that many interations should give us a reasonable
// approximation at what offset we need to use to account for instruction
// execution times.
//
// Calculate the actual period from the actual time & the actual pulses
// generated.
double_t actualPeriod = (double_t) timeTaken / (double_t) pulses;
// Store the difference between the actual time per period vs. calculated.
periodOffset = (int8_t) ((double_t) calcPeriod - actualPeriod);
}
// Generic method for sending data that is common to most protocols.
// Will send leading or trailing 0's if the nbits is larger than the number
// of bits in data.
//
// Args:
// onemark: Nr. of usecs for the led to be pulsed for a '1' bit.
// onespace: Nr. of usecs for the led to be fully off for a '1' bit.
// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit.
// zerospace: Nr. of usecs for the led to be fully off for a '0' bit.
// data: The data to be transmitted.
// nbits: Nr. of bits of data to be sent.
// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order.
void IRsend::sendData(uint16_t onemark, uint32_t onespace,
uint16_t zeromark, uint32_t zerospace,
uint64_t data, uint16_t nbits, bool MSBfirst) {
if (nbits == 0) // If we are asked to send nothing, just return.
return;
if (MSBfirst) { // Send the MSB first.
// Send 0's until we get down to a bit size we can actually manage.
while (nbits > sizeof(data) * 8) {
mark(zeromark);
space(zerospace);
nbits--;
}
// Send the supplied data.
for (uint64_t mask = 1ULL << (nbits - 1); mask; mask >>= 1)
if (data & mask) { // Send a 1
mark(onemark);
space(onespace);
} else { // Send a 0
mark(zeromark);
space(zerospace);
}
} else { // Send the Least Significant Bit (LSB) first / MSB last.
for (uint16_t bit = 0; bit < nbits; bit++, data >>= 1)
if (data & 1) { // Send a 1
mark(onemark);
space(onespace);
} else { // Send a 0
mark(zeromark);
space(zerospace);
}
}
}
// Send a raw IRremote message.
//
// Args:
// buf: An array of uint16_t's that has microseconds elements.
// len: Nr. of elements in the buf[] array.
// hz: Frequency to send the message at. (kHz < 1000; Hz >= 1000)
//
// Status: STABLE / Known working.
//
// Notes:
// Even elements are Mark times (On), Odd elements are Space times (Off).
//
// Ref:
// examples/IRrecvDumpV2/IRrecvDumpV2.ino
void IRsend::sendRaw(uint16_t buf[], uint16_t len, uint16_t hz) {
// Set IR carrier frequency
enableIROut(hz);
for (uint16_t i = 0; i < len; i++) {
if (i & 1) { // Odd bit.
space(buf[i]);
} else { // Even bit.
mark(buf[i]);
}
}
ledOff(); // We potentially have ended with a mark(), so turn of the LED.
}
#ifndef UNIT_TEST
void IRsend::send(uint16_t type, uint64_t data, uint16_t nbits) {
switch (type) {
#if SEND_NEC
case NEC: sendNEC(data, nbits); break;
#endif
#if SEND_SONY
case SONY: sendSony(data, nbits); break;
#endif
#if SEND_RC5
case RC5: sendRC5(data, nbits); break;
#endif
#if SEND_RC6
case RC6: sendRC6(data, nbits); break;
#endif
#if SEND_DISH
case DISH: sendDISH(data, nbits); break;
#endif
#if SEND_JVC
case JVC: sendJVC(data, nbits); break;
#endif
#if SEND_SAMSUNG
case SAMSUNG: sendSAMSUNG(data, nbits); break;
#endif
#if SEND_LG
case LG: sendLG(data, nbits); break;
#endif
#if SEND_WHYNTER
case WHYNTER: sendWhynter(data, nbits); break;
#endif
#if SEND_COOLIX
case COOLIX: sendCOOLIX(data, nbits); break;
#endif
#if SEND_DENON
case DENON: sendDenon(data, nbits); break;
#endif
#if SEND_SHERWOOD
case SHERWOOD: sendSherwood(data, nbits); break;
#endif
#if SEND_RCMM
case RCMM: sendRCMM(data, nbits); break;
#endif
#if SEND_MITSUBISHI
case MITSUBISHI: sendMitsubishi(data, nbits); break;
#endif
#if SEND_SHARP
case SHARP: sendSharpRaw(data, nbits); break;
#endif
#if SEND_AIWA_RC_T501
case AIWA_RC_T501: sendAiwaRCT501(data, nbits); break;
#endif
}
}
#endif

View File

@ -1,209 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2015 Mark Szabo
// Copyright 2017 David Conran
#ifndef IRSEND_H_
#define IRSEND_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include "IRremoteESP8266.h"
// Originally from https://github.com/shirriff/Arduino-IRremote/
// Updated by markszabo (https://github.com/markszabo/IRremoteESP8266) for
// sending IR code on ESP8266
#if TEST || UNIT_TEST
#define VIRTUAL virtual
#else
#define VIRTUAL
#endif
// Constants
// Offset (in microseconds) to use in Period time calculations to account for
// code excution time in producing the software PWM signal.
// Value determined in https://github.com/markszabo/IRremoteESP8266/issues/62
#define PERIOD_OFFSET -3
#define DUTY_DEFAULT 50
// Classes
class IRsend {
public:
explicit IRsend(uint16_t IRsendPin, bool inverted = false);
void begin();
void enableIROut(uint32_t freq, uint8_t duty = DUTY_DEFAULT);
VIRTUAL uint16_t mark(uint16_t usec);
VIRTUAL void space(uint32_t usec);
void calibrate(uint16_t hz = 38000U);
void sendRaw(uint16_t buf[], uint16_t len, 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);
void send(uint16_t type, uint64_t data, uint16_t nbits);
#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO)
void sendNEC(uint64_t data, uint16_t nbits = NEC_BITS, uint16_t repeat = 0);
uint32_t encodeNEC(uint16_t address, uint16_t command);
#endif
#if SEND_SONY
// sendSony() should typically be called with repeat=2 as Sony devices
// expect the code to be sent at least 3 times. (code + 2 repeats = 3 codes)
// Legacy use of this procedure was to only send a single code so call it with
// repeat=0 for backward compatibility. As of v2.0 it defaults to sending
// a Sony command that will be accepted be a device.
void sendSony(uint64_t data, uint16_t nbits = SONY_20_BITS,
uint16_t repeat = SONY_MIN_REPEAT);
uint32_t encodeSony(uint16_t nbits, uint16_t command, uint16_t address,
uint16_t extended = 0);
#endif
#if SEND_SHERWOOD
void sendSherwood(uint64_t data, uint16_t nbits = SHERWOOD_BITS,
uint16_t repeat = SHERWOOD_MIN_REPEAT);
#endif
#if SEND_SAMSUNG
void sendSAMSUNG(uint64_t data, uint16_t nbits = SAMSUNG_BITS,
uint16_t repeat = 0);
uint32_t encodeSAMSUNG(uint8_t customer, uint8_t command);
#endif
#if SEND_LG
void sendLG(uint64_t data, uint16_t nbits = LG_BITS, uint16_t repeat = 0);
uint32_t encodeLG(uint16_t address, uint16_t command);
#endif
#if (SEND_SHARP || SEND_DENON)
uint32_t encodeSharp(uint16_t address, uint16_t command,
uint16_t expansion = 1, uint16_t check = 0,
bool MSBfirst = false);
void sendSharp(uint16_t address, uint16_t command,
uint16_t nbits = SHARP_BITS, uint16_t repeat = 0);
void sendSharpRaw(uint64_t data, uint16_t nbits = SHARP_BITS,
uint16_t repeat = 0);
#endif
#if SEND_JVC
void sendJVC(uint64_t data, uint16_t nbits = JVC_BITS, uint16_t repeat = 0);
uint16_t encodeJVC(uint8_t address, uint8_t command);
#endif
#if SEND_DENON
void sendDenon(uint64_t data, uint16_t nbits = DENON_BITS,
uint16_t repeat = 0);
#endif
#if SEND_SANYO
uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command);
void sendSanyoLC7461(uint64_t data, uint16_t nbits = SANYO_LC7461_BITS,
uint16_t repeat = 0);
#endif
#if SEND_DISH
// sendDISH() should typically be called with repeat=3 as DISH devices
// expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes)
// Legacy use of this procedure was only to send a single code
// so use repeat=0 for backward compatibility.
void sendDISH(uint64_t data, uint16_t nbits = DISH_BITS,
uint16_t repeat = DISH_MIN_REPEAT);
#endif
#if (SEND_PANASONIC || SEND_DENON)
void sendPanasonic64(uint64_t data, uint16_t nbits = PANASONIC_BITS,
uint16_t repeat = 0);
void sendPanasonic(uint16_t address, uint32_t data,
uint16_t nbits = PANASONIC_BITS, uint16_t repeat = 0);
uint64_t encodePanasonic(uint16_t manufacturer, uint8_t device,
uint8_t subdevice, uint8_t function);
#endif
#if SEND_RC5
void sendRC5(uint64_t data, uint16_t nbits = RC5X_BITS, uint16_t repeat = 0);
uint16_t encodeRC5(uint8_t address, uint8_t command,
bool key_released = false);
uint16_t encodeRC5X(uint8_t address, uint8_t command,
bool key_released = false);
uint64_t toggleRC5(uint64_t data);
#endif
#if SEND_RC6
void sendRC6(uint64_t data, uint16_t nbits = RC6_MODE0_BITS,
uint16_t repeat = 0);
uint64_t encodeRC6(uint32_t address, uint8_t command,
uint16_t mode = RC6_MODE0_BITS);
uint64_t toggleRC6(uint64_t data, uint16_t nbits = RC6_MODE0_BITS);
#endif
#if SEND_RCMM
void sendRCMM(uint64_t data, uint16_t nbits = RCMM_BITS, uint16_t repeat = 0);
#endif
#if SEND_COOLIX
void sendCOOLIX(uint64_t data, uint16_t nbits = COOLIX_BITS,
uint16_t repeat = 0);
#endif
#if SEND_WHYNTER
void sendWhynter(uint64_t data, uint16_t nbits = WHYNTER_BITS,
uint16_t repeat = 0);
#endif
#if SEND_MITSUBISHI
void sendMitsubishi(uint64_t data, uint16_t nbits = MITSUBISHI_BITS,
uint16_t repeat = MITSUBISHI_MIN_REPEAT);
#endif
#if SEND_MITSUBISHI_AC
void sendMitsubishiAC(unsigned char data[],
uint16_t nbytes = MITSUBISHI_AC_STATE_LENGTH,
uint16_t repeat = MITSUBISHI_AC_MIN_REPEAT);
#endif
#if SEND_FUJITSU_AC
void sendFujitsuAC(unsigned char data[],
uint16_t nbytes,
uint16_t repeat = FUJITSU_AC_MIN_REPEAT);
#endif
#if SEND_GLOBALCACHE
void sendGC(uint16_t buf[], uint16_t len);
#endif
#if SEND_KELVINATOR
void sendKelvinator(unsigned char data[],
uint16_t nbytes = KELVINATOR_STATE_LENGTH,
uint16_t repeat = 0);
#endif
#if SEND_DAIKIN
void sendDaikin(unsigned char data[],
uint16_t nbytes = DAIKIN_COMMAND_LENGTH,
uint16_t repeat = 0);
#endif
#if SEND_AIWA_RC_T501
void sendAiwaRCT501(uint64_t data, uint16_t nbits = AIWA_RC_T501_BITS,
uint16_t repeat = AIWA_RC_T501_MIN_REPEAT);
#endif
#if SEND_GREE
void sendGree(uint64_t data, uint16_t nbits = GREE_BITS, uint16_t repeat = 0);
void sendGree(uint8_t data[], uint16_t nbytes = GREE_STATE_LENGTH,
uint16_t repeat = 0);
#endif
#if SEND_PRONTO
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat = 0);
#endif
#if SEND_ARGO
void sendArgo(unsigned char data[],
uint16_t nbytes = ARGO_COMMAND_LENGTH,
uint16_t repeat = 0);
#endif
#if SEND_TROTEC
void sendTrotec(unsigned char data[],
uint16_t nbytes = TROTEC_COMMAND_LENGTH,
uint16_t repeat = 0);
#endif
#if SEND_NIKAI
void sendNikai(uint64_t data, uint16_t nbits = NIKAI_BITS,
uint16_t repeat = 0);
#endif
protected:
#ifdef UNIT_TEST
#ifndef HIGH
#define HIGH 0x1
#endif
#ifndef LOW
#define LOW 0x0
#endif
#endif // UNIT_TEST
uint8_t outputOn;
uint8_t outputOff;
private:
uint16_t onTimePeriod;
uint16_t offTimePeriod;
uint16_t IRpin;
int8_t periodOffset;
void ledOff();
uint32_t calcUSecPeriod(uint32_t hz, bool use_offset = true);
};
#endif // IRSEND_H_

View File

@ -1,82 +0,0 @@
// Copyright 2017 David Conran
#include "IRutils.h"
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <algorithm>
#ifndef ARDUINO
#include <string>
#endif
#include "IRrecv.h"
// Reverse the order of the requested least significant nr. of bits.
// Args:
// input: Bit pattern/integer to reverse.
// nbits: Nr. of bits to reverse.
// Returns:
// The reversed bit pattern.
uint64_t reverseBits(uint64_t input, uint16_t nbits) {
if (nbits <= 1)
return input; // Reversing <= 1 bits makes no change at all.
// Cap the nr. of bits to rotate to the max nr. of bits in the input.
nbits = std::min(nbits, (uint16_t) (sizeof(input) * 8));
uint64_t output = 0;
for (uint16_t i = 0; i < nbits; i++) {
output <<= 1;
output |= (input & 1);
input >>= 1;
}
// Merge any remaining unreversed bits back to the top of the reversed bits.
return (input << nbits) | output;
}
// Convert a uint64_t (unsigned long long) to a string.
// Arduino String/toInt/Serial.print() can't handle printing 64 bit values.
//
// Args:
// input: The value to print
// base: The output base.
// Returns:
// A string representation of the integer.
// Note: Based on Arduino's Print::printNumber()
#ifdef ARDUINO // Arduino's & C++'s string implementations can't co-exist.
String uint64ToString(uint64_t input, uint8_t base) {
String result = "";
#else
std::string uint64ToString(uint64_t input, uint8_t base) {
std::string result = "";
#endif
// prevent issues if called with base <= 1
if (base < 2) base = 10;
// Check we have a base that we can actually print.
// i.e. [0-9A-Z] == 36
if (base > 36) base = 10;
do {
char c = input % base;
input /= base;
if (c < 10)
c +='0';
else
c += 'A' - 10;
result = c + result;
} while (input);
return result;
}
#ifdef ARDUINO
// Print a uint64_t/unsigned long long to the Serial port
// Serial.print() can't handle printing long longs. (uint64_t)
//
// Args:
// input: The value to print
// base: The output base.
void serialPrintUint64(uint64_t input, uint8_t base) {
Serial.print(uint64ToString(input, base));
}
#endif

View File

@ -1,23 +0,0 @@
#ifndef IRUTILS_H_
#define IRUTILS_H_
// Copyright 2017 David Conran
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#ifndef ARDUINO
#include <string>
#endif
uint64_t reverseBits(uint64_t input, uint16_t nbits);
#ifdef ARDUINO // Arduino's & C++'s string implementations can't co-exist.
String uint64ToString(uint64_t input, uint8_t base = 10);
#else
std::string uint64ToString(uint64_t input, uint8_t base = 10);
#endif
void serialPrintUint64(uint64_t input, uint8_t base = 10);
#endif // IRUTILS_H_

View File

@ -1,167 +0,0 @@
// Copyright bakrus
// Copyright 2017 David Conran
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// CCCCC OOOOO OOOOO LL IIIII XX XX
// CC C OO OO OO OO LL III XX XX
// CC OO OO OO OO LL III XXXX
// CC C OO OO OO OO LL III XX XX
// CCCCC OOOO0 OOOO0 LLLLLLL IIIII XX XX
// Coolix A/C / heatpump added by (send) bakrus & (decode) crankyoldgit
// Constants
// Pulse parms are *50-100 for the Mark and *50+100 for the space
// First MARK is the one after the long gap
// pulse parameters in usec
#define COOLIX_TICK 560U // Approximately 21 cycles at 38kHz
#define COOLIX_BIT_MARK_TICKS 1U
#define COOLIX_BIT_MARK (COOLIX_BIT_MARK_TICKS * COOLIX_TICK)
#define COOLIX_ONE_SPACE_TICKS 3U
#define COOLIX_ONE_SPACE (COOLIX_ONE_SPACE_TICKS * COOLIX_TICK)
#define COOLIX_ZERO_SPACE_TICKS 1U
#define COOLIX_ZERO_SPACE (COOLIX_ZERO_SPACE_TICKS * COOLIX_TICK)
#define COOLIX_HDR_MARK_TICKS 8U
#define COOLIX_HDR_MARK (COOLIX_HDR_MARK_TICKS * COOLIX_TICK)
#define COOLIX_HDR_SPACE_TICKS 8U
#define COOLIX_HDR_SPACE (COOLIX_HDR_SPACE_TICKS * COOLIX_TICK)
#define COOLIX_MIN_GAP_TICKS (COOLIX_HDR_MARK_TICKS + \
COOLIX_ZERO_SPACE_TICKS)
#define COOLIX_MIN_GAP (COOLIX_MIN_GAP_TICKS * COOLIX_TICK)
#if SEND_COOLIX
// Send a Coolix message
//
// Args:
// data: Contents of the message to be sent.
// nbits: Nr. of bits of data to be sent. Typically COOLIX_BITS.
// repeat: Nr. of additional times the message is to be sent.
//
// Status: BETA / Probably works.
//
// Ref:
// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp
// TODO(anyone): Verify repeat functionality against a real unit.
void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) {
if (nbits % 8 != 0)
return; // nbits is required to be a multiple of 8.
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; r++) {
// Header
mark(COOLIX_HDR_MARK);
space(COOLIX_HDR_SPACE);
// Data
// Break data into byte segments, starting at the Most Significant
// Byte. Each byte then being sent normal, then followed inverted.
for (uint16_t i = 8; i <= nbits; i += 8) {
// Grab a bytes worth of data.
uint8_t segment = (data >> (nbits - i)) & 0xFF;
// Normal
sendData(COOLIX_BIT_MARK, COOLIX_ONE_SPACE,
COOLIX_BIT_MARK, COOLIX_ZERO_SPACE,
segment, 8, true);
// Inverted.
sendData(COOLIX_BIT_MARK, COOLIX_ONE_SPACE,
COOLIX_BIT_MARK, COOLIX_ZERO_SPACE,
segment ^ 0xFF, 8, true);
}
// Footer
mark(COOLIX_BIT_MARK);
space(COOLIX_MIN_GAP); // Pause before repeating
}
}
#endif
#if DECODE_COOLIX
// Decode the supplied Coolix message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: The number of data bits to expect. Typically COOLIX_BITS.
// 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) {
// 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 + HEADER + FOOTER - 1)
return false; // Can't possibly be a valid COOLIX message.
if (strict && nbits != COOLIX_BITS)
return false; // Not strictly an COOLIX message.
if (nbits % 8 != 0) // nbits has to be a multiple of nr. of bits in a byte.
return false;
uint64_t data = 0;
uint64_t inverted = 0;
uint16_t offset = OFFSET_START;
if (nbits > sizeof(data) * 8)
return false; // We can't possibly capture a Coolix packet that big.
// Header
if (!matchMark(results->rawbuf[offset], COOLIX_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = results->rawbuf[offset++] * RAWTICK / COOLIX_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], COOLIX_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = results->rawbuf[offset++] * RAWTICK /
COOLIX_HDR_SPACE_TICKS;
// Data
// Twice as many bits as there are normal plus inverted bits.
for (uint16_t i = 0; i < nbits * 2; i++, offset++) {
bool flip = (i / 8) % 2;
if (!matchMark(results->rawbuf[offset++], COOLIX_BIT_MARK_TICKS * m_tick))
return false;
if (matchSpace(results->rawbuf[offset], COOLIX_ONE_SPACE_TICKS * s_tick)) {
if (flip)
inverted = (inverted << 1) | 1;
else
data = (data << 1) | 1;
} else if (matchSpace(results->rawbuf[offset],
COOLIX_ZERO_SPACE_TICKS * s_tick)) {
if (flip)
inverted <<= 1;
else
data <<= 1;
} else {
return false;
}
}
// Footer
if (!matchMark(results->rawbuf[offset++], COOLIX_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], COOLIX_MIN_GAP_TICKS * s_tick))
return false;
// Compliance
uint64_t orig = data; // Save a copy of the data.
if (strict) {
for (uint16_t i = 0; i < nbits; i += 8, data >>= 8, inverted >>= 8)
if ((data & 0xFF) != ((inverted & 0xFF) ^ 0xFF))
return false;
}
// Success
results->decode_type = COOLIX;
results->bits = nbits;
results->value = orig;
results->address = 0;
results->command = 0;
return true;
}
#endif

View File

@ -1,347 +0,0 @@
/*
An Arduino sketch to emulate IR Daikin ARC433** remote control unit
Read more at:
http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/
Copyright 2016 sillyfrog
*/
#include "ir_Daikin.h"
#include <algorithm>
#include "IRremoteESP8266.h"
#include "IRutils.h"
// DDDDD AAA IIIII KK KK IIIII NN NN
// DD DD AAAAA III KK KK III NNN NN
// DD DD AA AA III KKKK III NN N NN
// DD DD AAAAAAA III KK KK III NN NNN
// DDDDDD AA AA IIIII KK KK IIIII NN NN
// Constants
// Ref:
// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
#define DAIKIN_HDR_MARK 3650U // DAIKIN_ZERO_MARK * 8
#define DAIKIN_HDR_SPACE 1623U // DAIKIN_ZERO_MARK * 4
#define DAIKIN_ONE_SPACE 1280U
#define DAIKIN_ONE_MARK 428U
#define DAIKIN_ZERO_MARK 428U
#define DAIKIN_ZERO_SPACE 428U
#define DAIKIN_GAP 29000U
#if SEND_DAIKIN
// Send a Daikin A/C message.
//
// Args:
// data: An array of DAIKIN_COMMAND_LENGTH bytes containing the IR command.
//
// Status: STABLE
//
// Ref:
// IRDaikinESP.cpp
// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
void IRsend::sendDaikin(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
if (nbytes < DAIKIN_COMMAND_LENGTH)
return; // Not enough bytes to send a proper message.
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; r++) {
// Header #1
mark(DAIKIN_HDR_MARK);
space(DAIKIN_HDR_SPACE);
// Data #1
for (uint16_t i = 0; i < 8 && i < nbytes; i++)
sendData(DAIKIN_ONE_MARK, DAIKIN_ONE_SPACE, DAIKIN_ZERO_MARK,
DAIKIN_ZERO_SPACE, data[i], 8, false);
// Footer #1
mark(DAIKIN_ONE_MARK);
space(DAIKIN_ZERO_SPACE + DAIKIN_GAP);
// Header #2
mark(DAIKIN_HDR_MARK);
space(DAIKIN_HDR_SPACE);
// Data #2
for (uint16_t i = 8; i < nbytes; i++)
sendData(DAIKIN_ONE_MARK, DAIKIN_ONE_SPACE, DAIKIN_ZERO_MARK,
DAIKIN_ZERO_SPACE, data[i], 8, false);
// Footer #2
mark(DAIKIN_ONE_MARK);
space(DAIKIN_ZERO_SPACE + DAIKIN_GAP);
}
}
IRDaikinESP::IRDaikinESP(uint16_t pin) : _irsend(pin) {
stateReset();
}
void IRDaikinESP::begin() {
_irsend.begin();
}
void IRDaikinESP::send() {
_irsend.sendDaikin(daikin);
}
void IRDaikinESP::checksum() {
uint8_t sum = 0;
uint8_t i;
for (i = 0; i <= 6; i++)
sum += daikin[i];
daikin[7] = sum & 0xFF;
sum = 0;
for (i = 8; i <= 25; i++)
sum += daikin[i];
daikin[26] = sum & 0xFF;
}
void IRDaikinESP::stateReset() {
for (uint8_t i = 4; i < DAIKIN_COMMAND_LENGTH; i++)
daikin[i] = 0x0;
daikin[0] = 0x11;
daikin[1] = 0xDA;
daikin[2] = 0x27;
daikin[3] = 0xF0;
daikin[7] = 0x20;
daikin[8] = 0x11;
daikin[9] = 0xDA;
daikin[10] = 0x27;
daikin[13] = 0x41;
daikin[14] = 0x1E;
daikin[16] = 0xB0;
daikin[23] = 0xC0;
daikin[26] = 0xE3;
checksum();
}
uint8_t* IRDaikinESP::getRaw() {
checksum(); // Ensure correct settings before sending.
return daikin;
}
void IRDaikinESP::on() {
// state = ON;
daikin[13] |= 0x01;
checksum();
}
void IRDaikinESP::off() {
// state = OFF;
daikin[13] &= 0xFE;
checksum();
}
void IRDaikinESP::setPower(bool state) {
if (state)
on();
else
off();
}
uint8_t IRDaikinESP::getPower() {
return daikin[13] & 0x01;
}
// DAIKIN_SILENT or DAIKIN_POWERFUL
void IRDaikinESP::setAux(uint8_t aux) {
daikin[21] = aux;
checksum();
}
uint8_t IRDaikinESP::getAux() {
return daikin[21];
}
void IRDaikinESP::setQuiet(bool state) {
if (state)
setAux(DAIKIN_SILENT);
else
setAux(0x0);
}
bool IRDaikinESP::getQuiet() {
return (getAux() == DAIKIN_SILENT);
}
void IRDaikinESP::setPowerful(bool state) {
if (state)
setAux(DAIKIN_POWERFUL);
else
setAux(0x0);
}
bool IRDaikinESP::getPowerful() {
return (getAux() == DAIKIN_POWERFUL);
}
// Set the temp in deg C
void IRDaikinESP::setTemp(uint8_t temp) {
if (temp < DAIKIN_MIN_TEMP)
temp = DAIKIN_MIN_TEMP;
else if (temp > DAIKIN_MAX_TEMP)
temp = DAIKIN_MAX_TEMP;
daikin[14] = temp * 2;
checksum();
}
uint8_t IRDaikinESP::getTemp() {
return daikin[14] / 2;
}
// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed
void IRDaikinESP::setFan(uint8_t fan) {
// Set the fan speed bits, leave low 4 bits alone
uint8_t fanset;
daikin[16] &= 0x0F;
fan = std::min(fan, DAIKIN_FAN_MAX);
if (fan == DAIKIN_FAN_AUTO)
fanset = 0xA0;
else
fanset = 0x20 + (0x10 * fan);
daikin[16] |= fanset;
checksum();
}
uint8_t IRDaikinESP::getFan() {
uint8_t fan = daikin[16] >> 4;
fan -= 2;
if (fan > DAIKIN_FAN_MAX)
fan = DAIKIN_FAN_AUTO;
return fan;
}
uint8_t IRDaikinESP::getMode() {
/*
DAIKIN_COOL
DAIKIN_HEAT
DAIKIN_FAN
DAIKIN_AUTO
DAIKIN_DRY
*/
return daikin[13] >> 4;
}
void IRDaikinESP::setMode(uint8_t mode) {
switch (mode) {
case DAIKIN_COOL:
case DAIKIN_HEAT:
case DAIKIN_FAN:
case DAIKIN_DRY:
break;
default:
mode = DAIKIN_AUTO;
}
daikin[13] = (mode << 4) | getPower();
checksum();
}
void IRDaikinESP::setSwingVertical(bool state) {
if (state)
daikin[16] |= 0x0F;
else
daikin[16] &= 0xF0;
checksum();
}
bool IRDaikinESP::getSwingVertical() {
return daikin[16] & 0x01;
}
void IRDaikinESP::setSwingHorizontal(bool state) {
if (state)
daikin[17] |= 0x0F;
else
daikin[17] &= 0xF0;
checksum();
}
bool IRDaikinESP::getSwingHorizontal() {
return daikin[17] & 0x01;
}
#endif // SEND_DAIKIN
#if DECODE_DAIKIN
// TODO(crankyoldgit): NOT WORKING. This needs to be finished.
// Decode the supplied Daikin A/C message. (NOT WORKING - DO NOT USE)
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of bits to expect in the data portion. Typically SAMSUNG_BITS.
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: UNFINISHED / Completely not working, not even vaguely.
//
// Ref:
// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
bool IRrecv::decodeDaikin(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * nbits + HEADER + FOOTER)
return false;
// Compliance
if (strict && nbits != DAIKIN_BITS)
return false;
uint32_t data = 0;
uint16_t offset = OFFSET_START;
// Header
if (!matchMark(results->rawbuf[offset++], DAIKIN_HDR_MARK))
return false;
if (!matchSpace(results->rawbuf[offset++], DAIKIN_HDR_SPACE))
return false;
// Data (#1)
for (uint8_t i = 0; i < sizeof(data) * 8; i++, offset++) {
if (!matchMark(results->rawbuf[offset++], DAIKIN_ONE_MARK))
return false;
if (matchSpace(results->rawbuf[offset], DAIKIN_ONE_SPACE))
data = (data << 1) | 1; // 1
else if (matchSpace(results->rawbuf[offset], DAIKIN_ZERO_SPACE))
data <<= 1; // 0
else
return false;
}
uint32_t number = data; // some number...
uint32_t reversed = reverseBits(number, sizeof(number) * 8)
DPRINT("Code ");
DPRINTLN(reversed, HEX);
// Data (#2)
for (uint8_t i = 0; i < sizeof(data) * 8; i++, offset++) {
if (!matchMark(results->rawbuf[offset++], DAIKIN_ONE_MARK))
return false;
if (matchSpace(results->rawbuf[offset], DAIKIN_ONE_SPACE))
data = (data << 1) | 1; // 1
else if (matchSpace(results->rawbuf[offset], DAIKIN_ZERO_SPACE))
data <<= 1; // 0
else
return false;
}
number = data; // some number...
reversed = reverseBits(number, sizeof(number) * 8)
DPRINT("Code2 ");
DPRINTLN(reversed, HEX);
if (!matchSpace(results->rawbuf[offset++], DAIKIN_GAP)) {
DPRINTLN("no gap");
return false;
}
// Success
results->bits = DAIKIN_BITS;
results->value = reversed;
results->decode_type = DAIKIN;
results->address = 0;
results->command = 0;
return true;
}
#endif // DECODE_DAIKIN

View File

@ -1,107 +0,0 @@
/* Copyright 2016 sillyfrog */
#ifndef IR_DAIKIN_H_
#define IR_DAIKIN_H_
#include "IRremoteESP8266.h"
#include "IRsend.h"
// DDDDD AAA IIIII KK KK IIIII NN NN
// DD DD AAAAA III KK KK III NNN NN
// DD DD AA AA III KKKK III NN N NN
// DD DD AAAAAAA III KK KK III NN NNN
// DDDDDD AA AA IIIII KK KK IIIII NN NN
/*
Daikin AC map
byte 7= checksum of the first part (and last byte before a 29ms pause)
byte 13=mode
b7 = 0
b6+b5+b4 = Mode
Modes: b6+b5+b4
011 = Cool
100 = Heat (temp 23)
110 = FAN (temp not shown, but 25)
000 = Fully Automatic (temp 25)
010 = DRY (temp 0xc0 = 96 degrees c)
b3 = 0
b2 = OFF timer set
b1 = ON timer set
b0 = Air Conditioner ON
byte 14=temp*2 (Temp should be between 18 - 32)
byte 16=Fan
FAN control
b7+b6+b5+b4 = Fan speed
Fan: b7+b6+b5+b4
0×30 = 1 bar
0×40 = 2 bar
0×50 = 3 bar
0×60 = 4 bar
0×70 = 5 bar
0xa0 = Auto
0xb0 = Not auto, moon + tree
b3+b2+b1+b0 = Swing control up/down
Swing control up/down:
0000 = Swing up/down off
1111 = Swing up/down on
byte 17
Swing control left/right:
0000 = Swing left/right off
1111 = Swing left/right on
byte 21=Aux -> Powerful (bit 1), Silent (bit 5)
byte 24=Aux2 -> Intelligent eye on (bit 7)
byte 26= checksum of the second part
*/
// Constants
#define DAIKIN_COOL 0b011
#define DAIKIN_HEAT 0b100
#define DAIKIN_FAN 0b110
#define DAIKIN_AUTO 0b000
#define DAIKIN_DRY 0b010
#define DAIKIN_POWERFUL 0b00000010
#define DAIKIN_SILENT 0b00100000
#define DAIKIN_MIN_TEMP 18U // Celsius
#define DAIKIN_MAX_TEMP 32U // Celsius
#define DAIKIN_FAN_AUTO (uint8_t) 0U
#define DAIKIN_FAN_MIN (uint8_t) 1U
#define DAIKIN_FAN_MAX (uint8_t) 5U
#if SEND_DAIKIN
class IRDaikinESP {
public:
explicit IRDaikinESP(uint16_t pin);
void send();
void begin();
void on();
void off();
void setPower(bool state);
uint8_t getPower();
void setAux(uint8_t aux);
uint8_t getAux();
void setTemp(uint8_t temp);
uint8_t getTemp();
void setFan(uint8_t fan);
uint8_t getFan();
uint8_t getMode();
void setMode(uint8_t mode);
void setSwingVertical(bool state);
bool getSwingVertical();
void setSwingHorizontal(bool state);
bool getSwingHorizontal();
bool getQuiet();
void setQuiet(bool state);
bool getPowerful();
void setPowerful(bool state);
uint8_t* getRaw();
private:
// # of bytes per command
uint8_t daikin[DAIKIN_COMMAND_LENGTH];
void stateReset();
void checksum();
IRsend _irsend;
};
#endif
#endif // IR_DAIKIN_H_

View File

@ -1,221 +0,0 @@
// Copyright 2017 Jonny Graham
#include "ir_Fujitsu.h"
#include <algorithm>
#include "IRsend.h"
// Fujitsu A/C support added by Jonny Graham
// Fujitsu A/C
// Ref:
// These values are based on averages of measurements
#define FUJITSU_AC_HDR_MARK 3224U
#define FUJITSU_AC_HDR_SPACE 1574U
#define FUJITSU_AC_BIT_MARK 448U
#define FUJITSU_AC_ONE_SPACE 1182U
#define FUJITSU_AC_ZERO_SPACE 367U
#define FUJITSU_AC_TRL_MARK 448U
#define FUJITSU_AC_TRL_SPACE 8100U
#if SEND_FUJITSU_AC
// Send a Fujitsu A/C message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (typically either
// FUJITSU_AC_STATE_LENGTH or FUJITSU_AC_STATE_LENGTH_SHORT)
// repeat: Nr. of times the message is to be repeated.
// (Default = FUJITSU_AC_MIN_REPEAT).
//
// Status: BETA / Appears to be working.
//
void IRsend::sendFujitsuAC(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; ++r) {
// Header
mark(FUJITSU_AC_HDR_MARK);
space(FUJITSU_AC_HDR_SPACE);
// Data
for (uint16_t i = 0; i < nbytes; i++)
sendData(FUJITSU_AC_BIT_MARK, FUJITSU_AC_ONE_SPACE,
FUJITSU_AC_BIT_MARK, FUJITSU_AC_ZERO_SPACE,
data[i], 8, false);
// Footer
mark(FUJITSU_AC_TRL_MARK);
space(FUJITSU_AC_TRL_SPACE);
}
}
// Code to emulate Fujitsu A/C IR remote control unit.
// Warning: Consider this very alpha code. Seems to work, but not validated.
//
// Equipment it seems compatible with:
// * Fujitsu ASYG30LFCA with remote AR-RAH2E
// * <Add models (A/C & remotes) you've gotten it working with here>
// Initialise the object.
IRFujitsuAC::IRFujitsuAC(uint16_t pin) : _irsend(pin) {
stateReset();
}
// Reset the state of the remote to a known good state/sequence.
void IRFujitsuAC::stateReset() {
_temp = 24;
_fanSpeed = FUJITSU_AC_FAN_HIGH;
_mode = FUJITSU_AC_MODE_COOL;
_swingMode = FUJITSU_AC_SWING_BOTH;
_cmd = FUJITSU_AC_CMD_TURN_ON;
}
// Configure the pin for output.
void IRFujitsuAC::begin() {
_irsend.begin();
}
// Send the current desired state to the IR LED.
void IRFujitsuAC::send() {
getRaw();
uint8_t len = getCommandLength();
_irsend.sendFujitsuAC(remote_state, len);
}
uint8_t IRFujitsuAC::getCommandLength() {
if (remote_state[5] != 0xFE)
return FUJITSU_AC_STATE_LENGTH_SHORT;
else
return FUJITSU_AC_STATE_LENGTH;
}
// Return a pointer to the internal state date of the remote.
uint8_t* IRFujitsuAC::getRaw() {
remote_state[0] = 0x14;
remote_state[1] = 0x63;
remote_state[2] = 0x00;
remote_state[3] = 0x10;
remote_state[4] = 0x10;
bool fullCmd = false;
switch (_cmd) {
case FUJITSU_AC_CMD_TURN_OFF:
remote_state[5] = 0x02;
break;
case FUJITSU_AC_CMD_STEP_HORIZ:
remote_state[5] = 0x79;
break;
case FUJITSU_AC_CMD_STEP_VERT:
remote_state[5] = 0x6C;
break;
default:
remote_state[5] = 0xFE;
fullCmd = true;
break;
}
if (fullCmd) {
remote_state[6] = 0x09;
remote_state[7] = 0x30;
uint8_t tempByte = _temp - FUJITSU_AC_MIN_TEMP;
remote_state[8] = (_cmd == FUJITSU_AC_CMD_TURN_ON) | (tempByte << 4);
remote_state[9] = _mode | 0 << 4; // timer off
remote_state[10] = _fanSpeed | _swingMode << 4;
remote_state[11] = 0; // timerOff values
remote_state[12] = 0; // timerOff/on values
remote_state[13] = 0; // timerOn values
remote_state[14] = 0x20;
// Checksum is the sum of the 8th to 16th bytes (ie remote_state[7]
// thru remote_state[15]).
// The checksum itself is stored in the 16th byte (ie remote_state[15]).
// So we sum bytes 8th-15th...
uint8_t checksum = 0;
for (uint8_t i = 7 ; i < 15; ++i) {
checksum += remote_state[i];
}
// and then do 0 - sum and store it in 16th.
remote_state[15] = 0 - checksum;
} else {
// For the short codes, byte 7 is the inverse of byte 6
remote_state[6] = ~remote_state[5];
for (uint8_t i = 7; i < FUJITSU_AC_STATE_LENGTH; ++i) {
remote_state[i] = 0;
}
}
return remote_state;
}
// Set the requested power state of the A/C to off.
void IRFujitsuAC::off() {
_cmd = FUJITSU_AC_CMD_TURN_OFF;
}
void IRFujitsuAC::stepHoriz() {
_cmd = FUJITSU_AC_CMD_STEP_HORIZ;
}
void IRFujitsuAC::stepVert() {
_cmd = FUJITSU_AC_CMD_STEP_VERT;
}
// Set the requested command of the A/C.
void IRFujitsuAC::setCmd(uint8_t cmd) {
switch (cmd) {
case FUJITSU_AC_CMD_TURN_OFF:
case FUJITSU_AC_CMD_TURN_ON:
case FUJITSU_AC_CMD_STAY_ON:
case FUJITSU_AC_CMD_STEP_HORIZ:
case FUJITSU_AC_CMD_STEP_VERT:
break;
default:
cmd = FUJITSU_AC_CMD_STAY_ON;
break;
}
_cmd = cmd;
}
uint8_t IRFujitsuAC::getCmd() {
return _cmd;
}
// Set the temp. in deg C
void IRFujitsuAC::setTemp(uint8_t temp) {
temp = std::max((uint8_t) FUJITSU_AC_MIN_TEMP, temp);
temp = std::min((uint8_t) FUJITSU_AC_MAX_TEMP, temp);
_temp = temp;
}
uint8_t IRFujitsuAC::getTemp() {
return _temp;
}
// Set the speed of the fan
void IRFujitsuAC::setFanSpeed(uint8_t fanSpeed) {
if (fanSpeed > FUJITSU_AC_FAN_QUIET)
fanSpeed = FUJITSU_AC_FAN_HIGH; // Set the fan to maximum if out of range.
_fanSpeed = fanSpeed;
}
uint8_t IRFujitsuAC::getFanSpeed() {
return _fanSpeed;
}
// Set the requested climate operation mode of the a/c unit.
void IRFujitsuAC::setMode(uint8_t mode) {
if (mode > FUJITSU_AC_MODE_HEAT)
mode = FUJITSU_AC_MODE_HEAT; // Set the mode to maximum if out of range.
_mode = mode;
}
uint8_t IRFujitsuAC::getMode() {
return _mode;
}
// Set the requested swing operation mode of the a/c unit.
void IRFujitsuAC::setSwing(uint8_t swingMode) {
if (swingMode > FUJITSU_AC_SWING_BOTH)
swingMode = FUJITSU_AC_SWING_BOTH; // Set the mode to max if out of range
_swingMode = swingMode;
}
uint8_t IRFujitsuAC::getSwing() {
return _swingMode;
}
#endif

View File

@ -1,80 +0,0 @@
// Copyright 2017 Jonny Graham
#ifndef IR_FUJITSU_H_
#define IR_FUJITSU_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include "IRremoteESP8266.h"
#include "IRsend.h"
// FUJITSU A/C support added by Jonny Graham
// Constants
#define FUJITSU_AC_MODE_AUTO 0x00U
#define FUJITSU_AC_MODE_COOL 0x01U
#define FUJITSU_AC_MODE_DRY 0x02U
#define FUJITSU_AC_MODE_FAN 0x03U
#define FUJITSU_AC_MODE_HEAT 0x04U
#define FUJITSU_AC_CMD_STAY_ON 0x00U
#define FUJITSU_AC_CMD_TURN_ON 0x01U
#define FUJITSU_AC_CMD_TURN_OFF 0x02U
#define FUJITSU_AC_CMD_STEP_HORIZ 0x79U
#define FUJITSU_AC_CMD_STEP_VERT 0x6CU
#define FUJITSU_AC_FAN_AUTO 0x00U
#define FUJITSU_AC_FAN_HIGH 0x01U
#define FUJITSU_AC_FAN_MED 0x02U
#define FUJITSU_AC_FAN_LOW 0x03U
#define FUJITSU_AC_FAN_QUIET 0x04U
#define FUJITSU_AC_MIN_TEMP 16U // 16C
#define FUJITSU_AC_MAX_TEMP 30U // 30C
#define FUJITSU_AC_SWING_OFF 0x00U
#define FUJITSU_AC_SWING_VERT 0x01U
#define FUJITSU_AC_SWING_HORIZ 0x02U
#define FUJITSU_AC_SWING_BOTH 0x03U
#define FUJITSU_AC_STATE_LENGTH 16
#define FUJITSU_AC_STATE_LENGTH_SHORT 7
#if SEND_FUJITSU_AC
class IRFujitsuAC {
public:
explicit IRFujitsuAC(uint16_t pin);
void stateReset();
void send();
void begin();
void off();
void stepHoriz();
void stepVert();
void setCmd(uint8_t cmd);
uint8_t getCmd();
void setTemp(uint8_t temp);
uint8_t getTemp();
void setFanSpeed(uint8_t fan);
uint8_t getFanSpeed();
void setMode(uint8_t mode);
uint8_t getMode();
void setSwing(uint8_t mode);
uint8_t getSwing();
uint8_t* getRaw();
private:
uint8_t remote_state[FUJITSU_AC_STATE_LENGTH];
uint8_t getCommandLength();
IRsend _irsend;
uint8_t _temp;
uint8_t _fanSpeed;
uint8_t _mode;
uint8_t _swingMode;
uint8_t _cmd;
};
#endif
#endif // IR_FUJITSU_H_

View File

@ -1,113 +0,0 @@
// Copyright 2017 Ville Skyttä (scop)
// Copyright 2017 David Conran
//
// Gree protocol compatible heat pump carrying the "Ultimate" brand name.
//
#include "IRremoteESP8266.h"
#include "IRsend.h"
// GGGG RRRRRR EEEEEEE EEEEEEE
// GG GG RR RR EE EE
// GG RRRRRR EEEEE EEEEE
// GG GG RR RR EE EE
// GGGGGG RR RR EEEEEEE EEEEEEE
// Constants
// Ref: https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h
#define GREE_HDR_MARK 9000U
#define GREE_HDR_SPACE 4000U
#define GREE_BIT_MARK 620U
#define GREE_ONE_SPACE 1600U
#define GREE_ZERO_SPACE 540U
#define GREE_MSG_SPACE 19000U
#if SEND_GREE
// Send a Gree Heat Pump message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=GREE_STATE_LENGTH)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
// Status: ALPHA / Untested.
//
// Ref:
// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp
void IRsend::sendGree(unsigned char data[], uint16_t nbytes, uint16_t repeat) {
if (nbytes < GREE_STATE_LENGTH)
return; // Not enough bytes to send a proper message.
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; r++) {
// Header #1
mark(GREE_HDR_MARK);
space(GREE_HDR_SPACE);
// Data #1
uint16_t i;
for (i = 0; i < 4 && i < nbytes; i++)
sendData(GREE_BIT_MARK, GREE_ONE_SPACE, GREE_BIT_MARK, GREE_ZERO_SPACE,
data[i], 8, false);
// Footer #1 (010)
sendData(GREE_BIT_MARK, GREE_ONE_SPACE, GREE_BIT_MARK, GREE_ZERO_SPACE,
0b010, 3);
// Header #2
mark(GREE_BIT_MARK);
space(GREE_MSG_SPACE);
// Data #2
for (; i < nbytes; i++)
sendData(GREE_BIT_MARK, GREE_ONE_SPACE, GREE_BIT_MARK, GREE_ZERO_SPACE,
data[i], 8, false);
// Footer #2
mark(GREE_BIT_MARK);
space(GREE_MSG_SPACE);
}
}
// Send a Gree Heat Pump message.
//
// Args:
// data: The raw message to be sent.
// nbits: Nr. of bits of data in the message. (Default is GREE_BITS)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
// Status: ALPHA / Untested.
//
// Ref:
// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp
void IRsend::sendGree(uint64_t data, uint16_t nbits, uint16_t repeat) {
if (nbits != GREE_BITS)
return; // Wrong nr. of bits to send a proper message.
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; r++) {
// Header
mark(GREE_HDR_MARK);
space(GREE_HDR_SPACE);
// Data
for (int16_t i = 8; i <= nbits; i += 8) {
sendData(GREE_BIT_MARK, GREE_ONE_SPACE, GREE_BIT_MARK, GREE_ZERO_SPACE,
(data >> (nbits - i)) & 0xFF, 8, false);
if (i == nbits / 2) {
// Send the mid-message Footer.
sendData(GREE_BIT_MARK, GREE_ONE_SPACE, GREE_BIT_MARK, GREE_ZERO_SPACE,
0b010, 3);
mark(GREE_BIT_MARK);
space(GREE_MSG_SPACE);
}
}
// Footer
mark(GREE_BIT_MARK);
space(GREE_MSG_SPACE);
}
}
#endif // SEND_GREE

View File

@ -1,329 +0,0 @@
// Copyright 2016 David Conran
//
// Code to emulate IR Kelvinator YALIF remote control unit, which should control
// at least the following Kelvinator A/C units:
// KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC,
// KSV70HRC, KSV80HRC.
//
// Note:
// * Unsupported:
// - All Sleep modes.
// - All Timer modes.
// - "I Feel" button & mode.
// - Energy Saving mode.
// - Low Heat mode.
// - Fahrenheit.
#include "ir_Kelvinator.h"
#include <algorithm>
// KK KK EEEEEEE LL VV VV IIIII NN NN AAA TTTTTTT OOOOO RRRRRR
// KK KK EE LL VV VV III NNN NN AAAAA TTT OO OO RR RR
// KKKK EEEEE LL VV VV III NN N NN AA AA TTT OO OO RRRRRR
// KK KK EE LL VV VV III NN NNN AAAAAAA TTT OO OO RR RR
// KK KK EEEEEEE LLLLLLL VVV IIIII NN NN AA AA TTT OOOO0 RR RR
// Constants
#define KELVINATOR_HDR_MARK 8990U
#define KELVINATOR_HDR_SPACE 4490U
#define KELVINATOR_BIT_MARK 675U
#define KELVINATOR_ONE_SPACE 1560U
#define KELVINATOR_ZERO_SPACE 520U
#define KELVINATOR_GAP_SPACE 19950U
#define KELVINATOR_CMD_FOOTER 2U
#define KELVINATOR_POWER 8U
#define KELVINATOR_MODE_MASK 0xF8U
#define KELVINATOR_FAN_OFFSET 4U
#define KELVINATOR_BASIC_FAN_MASK uint8_t(0xFFU ^ (3U << KELVINATOR_FAN_OFFSET))
#define KELVINATOR_FAN_MASK uint8_t(0xFFU ^ (7U << KELVINATOR_FAN_OFFSET))
#define KELVINATOR_CHECKSUM_START 10U
#define KELVINATOR_VENT_SWING_OFFSET 6U
#define KELVINATOR_VENT_SWING uint8_t(1U << KELVINATOR_VENT_SWING_OFFSET)
#define KELVINATOR_VENT_SWING_V uint8_t(1U)
#define KELVINATOR_VENT_SWING_H uint8_t(1U << 4)
#define KELVINATOR_SLEEP_1_AND_3 uint8_t(1U << 7)
#define KELVINATOR_QUIET_OFFSET 7U
#define KELVINATOR_QUIET uint8_t(1U << KELVINATOR_QUIET_OFFSET)
#define KELVINATOR_ION_FILTER_OFFSET 6U
#define KELVINATOR_ION_FILTER uint8_t(1U << KELVINATOR_ION_FILTER_OFFSET)
#define KELVINATOR_LIGHT_OFFSET 5U
#define KELVINATOR_LIGHT uint8_t(1U << KELVINATOR_LIGHT_OFFSET)
#define KELVINATOR_XFAN_OFFSET 7U
#define KELVINATOR_XFAN uint8_t(1U << KELVINATOR_XFAN_OFFSET)
#define KELVINATOR_TURBO_OFFSET 4U
#define KELVINATOR_TURBO uint8_t(1U << KELVINATOR_TURBO_OFFSET)
#if SEND_KELVINATOR
// Send a Kelvinator A/C message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=KELVINATOR_STATE_LENGTH)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
// Status: STABLE / Known working.
//
void IRsend::sendKelvinator(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
if (nbytes < KELVINATOR_STATE_LENGTH)
return; // Not enough bytes to send a proper message.
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; r++) {
// Header #1
mark(KELVINATOR_HDR_MARK);
space(KELVINATOR_HDR_SPACE);
// Data (command)
// Send the first command data (4 bytes)
uint8_t i;
for (i = 0; i < 4; i++)
sendData(KELVINATOR_BIT_MARK, KELVINATOR_ONE_SPACE, KELVINATOR_BIT_MARK,
KELVINATOR_ZERO_SPACE, data[i], 8, false);
// Send Footer for the command data (3 bits (0b010))
sendData(KELVINATOR_BIT_MARK, KELVINATOR_ONE_SPACE, KELVINATOR_BIT_MARK,
KELVINATOR_ZERO_SPACE, KELVINATOR_CMD_FOOTER, 3, false);
// Send an interdata gap.
mark(KELVINATOR_BIT_MARK);
space(KELVINATOR_GAP_SPACE);
// Data (options)
// Send the 1st option chunk of data (4 bytes).
for (; i < 8; i++)
sendData(KELVINATOR_BIT_MARK, KELVINATOR_ONE_SPACE, KELVINATOR_BIT_MARK,
KELVINATOR_ZERO_SPACE, data[i], 8, false);
// Send a double data gap to signify we are starting a new command sequence.
mark(KELVINATOR_BIT_MARK);
space(KELVINATOR_GAP_SPACE * 2);
// Header #2
mark(KELVINATOR_HDR_MARK);
space(KELVINATOR_HDR_SPACE);
// Data (command)
// Send the 2nd command data (4 bytes).
// Basically an almost identical repeat of the earlier command data.
for (; i < 12; i++)
sendData(KELVINATOR_BIT_MARK, KELVINATOR_ONE_SPACE, KELVINATOR_BIT_MARK,
KELVINATOR_ZERO_SPACE, data[i], 8, false);
// Send Footer for the command data (3 bits (B010))
sendData(KELVINATOR_BIT_MARK, KELVINATOR_ONE_SPACE, KELVINATOR_BIT_MARK,
KELVINATOR_ZERO_SPACE, KELVINATOR_CMD_FOOTER, 3, false);
// Send an interdata gap.
mark(KELVINATOR_BIT_MARK);
space(KELVINATOR_GAP_SPACE);
// Data (options)
// Send the 2nd option chunk of data (4 bytes).
// Unlike the commands, definitely not a repeat of the earlier option data.
for (; i < KELVINATOR_STATE_LENGTH; i++)
sendData(KELVINATOR_BIT_MARK, KELVINATOR_ONE_SPACE, KELVINATOR_BIT_MARK,
KELVINATOR_ZERO_SPACE, data[i], 8, false);
// Footer
mark(KELVINATOR_BIT_MARK);
space(KELVINATOR_GAP_SPACE * 2);
}
}
IRKelvinatorAC::IRKelvinatorAC(uint16_t pin) : _irsend(pin) {
stateReset();
}
void IRKelvinatorAC::stateReset() {
for (uint8_t i = 0; i < KELVINATOR_STATE_LENGTH; i++)
remote_state[i] = 0x0;
remote_state[3] = 0x50;
remote_state[11] = 0x70;
}
void IRKelvinatorAC::begin() {
_irsend.begin();
}
void IRKelvinatorAC::fixup() {
// X-Fan mode is only valid in COOL or DRY modes.
if (getMode() != KELVINATOR_COOL && getMode() != KELVINATOR_DRY)
setXFan(false);
checksum(); // Calculate the checksums
}
void IRKelvinatorAC::send() {
fixup(); // Ensure correct settings before sending.
_irsend.sendKelvinator(remote_state);
}
uint8_t* IRKelvinatorAC::getRaw() {
fixup(); // Ensure correct settings before sending.
return remote_state;
}
// Many Bothans died to bring us this information.
void IRKelvinatorAC::checksum() {
// For each command + options block.
for (uint8_t offset = 0; offset < KELVINATOR_STATE_LENGTH; offset += 8) {
uint8_t sum = KELVINATOR_CHECKSUM_START;
// Sum the lower half of the first 4 bytes of this block.
for (uint8_t i = 0; i < 4; i++)
sum += (remote_state[i + offset] & 0xFU);
// then sum the upper half of the next 3 bytes.
for (uint8_t i = 4; i < 7; i++)
sum += (remote_state[i + offset] >> 4);
// Trim it down to fit into the 4 bits allowed. i.e. Mod 16.
sum &= 0xFU;
// Place it into the IR code in the top half of the 8th & 16th byte.
remote_state[7 + offset] = (sum << 4) | (remote_state[7 + offset] & 0xFU);
}
}
void IRKelvinatorAC::on() {
remote_state[0] |= KELVINATOR_POWER;
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
void IRKelvinatorAC::off() {
remote_state[0] &= ~KELVINATOR_POWER;
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
void IRKelvinatorAC::setPower(bool state) {
if (state)
on();
else
off();
}
bool IRKelvinatorAC::getPower() {
return ((remote_state[0] & KELVINATOR_POWER) != 0);
}
// Set the temp. in deg C
void IRKelvinatorAC::setTemp(uint8_t temp) {
temp = std::max((uint8_t) KELVINATOR_MIN_TEMP, temp);
temp = std::min((uint8_t) KELVINATOR_MAX_TEMP, temp);
remote_state[1] = (remote_state[1] & 0xF0U) | (temp - KELVINATOR_MIN_TEMP);
remote_state[9] = remote_state[1]; // Duplicate to the 2nd command chunk.
}
// Return the set temp. in deg C
uint8_t IRKelvinatorAC::getTemp() {
return ((remote_state[1] & 0xFU) + KELVINATOR_MIN_TEMP);
}
// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed
void IRKelvinatorAC::setFan(uint8_t fan) {
fan = std::min((uint8_t) KELVINATOR_FAN_MAX, fan); // Bounds check
// Only change things if we need to.
if (fan != getFan()) {
// Set the basic fan values.
uint8_t fan_basic = std::min((uint8_t) KELVINATOR_BASIC_FAN_MAX, fan);
remote_state[0] = (remote_state[0] & KELVINATOR_BASIC_FAN_MASK) |
(fan_basic << KELVINATOR_FAN_OFFSET);
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
// Set the advanced(?) fan value.
remote_state[14] = (remote_state[14] & KELVINATOR_FAN_MASK) |
(fan << KELVINATOR_FAN_OFFSET);
setTurbo(false); // Turbo mode is turned off if we change the fan settings.
}
}
uint8_t IRKelvinatorAC::getFan() {
return ((remote_state[14] & ~KELVINATOR_FAN_MASK) >> KELVINATOR_FAN_OFFSET);
}
uint8_t IRKelvinatorAC::getMode() {
return (remote_state[0] & ~KELVINATOR_MODE_MASK);
}
void IRKelvinatorAC::setMode(uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
if (mode > KELVINATOR_HEAT) mode = KELVINATOR_AUTO;
remote_state[0] = (remote_state[0] & KELVINATOR_MODE_MASK) | mode;
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
if (mode == KELVINATOR_AUTO || KELVINATOR_DRY)
// When the remote is set to Auto or Dry, it defaults to 25C and doesn't
// show it.
setTemp(KELVINATOR_AUTO_TEMP);
}
void IRKelvinatorAC::setSwingVertical(bool state) {
if (state) {
remote_state[0] |= KELVINATOR_VENT_SWING;
remote_state[4] |= KELVINATOR_VENT_SWING_V;
} else {
remote_state[4] &= ~KELVINATOR_VENT_SWING_V;
if (!getSwingHorizontal())
remote_state[0] &= ~KELVINATOR_VENT_SWING;
}
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getSwingVertical() {
return ((remote_state[4] & KELVINATOR_VENT_SWING_V) != 0);
}
void IRKelvinatorAC::setSwingHorizontal(bool state) {
if (state) {
remote_state[0] |= KELVINATOR_VENT_SWING;
remote_state[4] |= KELVINATOR_VENT_SWING_H;
} else {
remote_state[4] &= ~KELVINATOR_VENT_SWING_H;
if (!getSwingVertical())
remote_state[0] &= ~KELVINATOR_VENT_SWING;
}
remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getSwingHorizontal() {
return ((remote_state[4] & KELVINATOR_VENT_SWING_H) != 0);
}
void IRKelvinatorAC::setQuiet(bool state) {
remote_state[12] &= ~KELVINATOR_QUIET;
remote_state[12] |= (state << KELVINATOR_QUIET_OFFSET);
}
bool IRKelvinatorAC::getQuiet() {
return ((remote_state[12] & KELVINATOR_QUIET) != 0);
}
void IRKelvinatorAC::setIonFilter(bool state) {
remote_state[2] &= ~KELVINATOR_ION_FILTER;
remote_state[2] |= (state << KELVINATOR_ION_FILTER_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getIonFilter() {
return ((remote_state[2] & KELVINATOR_ION_FILTER) != 0);
}
void IRKelvinatorAC::setLight(bool state) {
remote_state[2] &= ~KELVINATOR_LIGHT;
remote_state[2] |= (state << KELVINATOR_LIGHT_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getLight() {
return ((remote_state[2] & KELVINATOR_LIGHT) != 0);
}
// Note: XFan mode is only valid in Cool or Dry mode.
void IRKelvinatorAC::setXFan(bool state) {
remote_state[2] &= ~KELVINATOR_XFAN;
remote_state[2] |= (state << KELVINATOR_XFAN_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getXFan() {
return ((remote_state[2] & KELVINATOR_XFAN) != 0);
}
// Note: Turbo mode is turned off if the fan speed is changed.
void IRKelvinatorAC::setTurbo(bool state) {
remote_state[2] &= ~KELVINATOR_TURBO;
remote_state[2] |= (state << KELVINATOR_TURBO_OFFSET);
remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk.
}
bool IRKelvinatorAC::getTurbo() {
return ((remote_state[2] & KELVINATOR_TURBO) != 0);
}
#endif

View File

@ -1,233 +0,0 @@
// Copyright 2015 Darryl Smith
// Copyright 2015 cheaplin
// Copyright 2017 David Conran
#include "ir_LG.h"
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// L GGGG
// L G
// L G GG
// L G G
// LLLLL GGG
// LG decode originally added by Darryl Smith (based on the JVC protocol)
// LG send originally added by https://github.com/chaeplin
// Constants
#define LG_TICK 50U
#define LG_HDR_MARK_TICKS 160U
#define LG_HDR_MARK (LG_HDR_MARK_TICKS * LG_TICK)
#define LG_HDR_SPACE_TICKS 80U
#define LG_HDR_SPACE (LG_HDR_SPACE_TICKS * LG_TICK)
#define LG_BIT_MARK_TICKS 11U
#define LG_BIT_MARK (LG_BIT_MARK_TICKS * LG_TICK)
#define LG_ONE_SPACE_TICKS 32U
#define LG_ONE_SPACE (LG_ONE_SPACE_TICKS * LG_TICK)
#define LG_ZERO_SPACE_TICKS 11U
#define LG_ZERO_SPACE (LG_ZERO_SPACE_TICKS * LG_TICK)
#define LG_RPT_SPACE_TICKS 45U
#define LG_RPT_SPACE (LG_RPT_SPACE_TICKS * LG_TICK)
#define LG_MIN_GAP_TICKS 795U
#define LG_MIN_GAP (LG_MIN_GAP_TICKS * LG_TICK)
#define LG_MIN_MESSAGE_LENGTH_TICKS 2161U
#define LG_MIN_MESSAGE_LENGTH (LG_MIN_MESSAGE_LENGTH_TICKS * LG_TICK)
#define LG32_HDR_MARK_TICKS 90U
#define LG32_HDR_MARK (LG32_HDR_MARK_TICKS * LG_TICK)
#define LG32_HDR_SPACE_TICKS 89U
#define LG32_HDR_SPACE (LG32_HDR_SPACE_TICKS * LG_TICK)
#define LG32_RPT_HDR_MARK_TICKS 179U
#define LG32_RPT_HDR_MARK (LG32_RPT_HDR_MARK_TICKS * LG_TICK)
#if (SEND_LG || DECODE_LG)
// Calculate the rolling 4-bit wide checksum over all of the data.
// Args:
// data: The value to be checksum'ed.
// Returns:
// A 4-bit checksum.
uint8_t calcLGChecksum(uint16_t data) {
return(((data >> 12) + ((data >> 8) & 0xF) + ((data >> 4) & 0xF) +
(data & 0xF)) & 0xF);
}
#endif
#if SEND_LG
// Send an LG formatted message.
//
// Args:
// data: The contents of the message you want to send.
// nbits: The bit size of the message being sent.
// Typically LG_BITS or LG32_BITS.
// repeat: The number of times you want the message to be repeated.
//
// Status: Beta / Should be working.
//
// Notes:
// LG has a separate message to indicate a repeat, like NEC does.
void IRsend::sendLG(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Set IR carrier frequency
enableIROut(38);
uint16_t repeatHeaderMark = 0;
IRtimer usecTimer = IRtimer();
if (nbits >= LG32_BITS) {
// LG 32bit protocol is near identical to Samsung except for repeats.
sendSAMSUNG(data, nbits, 0); // Send it as a single Samsung message.
repeatHeaderMark = LG32_RPT_HDR_MARK;
repeat++;
} else {
// LG (28-bit) protocol.
repeatHeaderMark = LG_HDR_MARK;
// Header
usecTimer.reset();
mark(LG_HDR_MARK);
space(LG_HDR_SPACE);
// Data
sendData(LG_BIT_MARK, LG_ONE_SPACE, LG_BIT_MARK, LG_ZERO_SPACE,
data, nbits, true);
// Footer
mark(LG_BIT_MARK);
space(std::max((uint32_t) (LG_MIN_MESSAGE_LENGTH - usecTimer.elapsed()),
(uint32_t) LG_MIN_GAP));
}
// Repeat
// Protocol has a mandatory repeat-specific code sent after every command.
for (uint16_t i = 0; i < repeat; i++) {
usecTimer.reset();
mark(repeatHeaderMark);
space(LG_RPT_SPACE);
mark(LG_BIT_MARK);
space(std::max((uint32_t) LG_MIN_MESSAGE_LENGTH - usecTimer.elapsed(),
(uint32_t) LG_MIN_GAP));
}
}
// Construct a raw 28-bit LG message from the supplied address & command.
//
// Args:
// address: The address code.
// command: The command code.
// Returns:
// A raw 28-bit LG message suitable for sendLG().
//
// Status: BETA / Should work.
//
// Notes:
// e.g. Sequence of bits = address + command + checksum.
uint32_t IRsend::encodeLG(uint16_t address, uint16_t command) {
return ((address << 20) | (command << 4) | calcLGChecksum(command));
}
#endif
#if DECODE_LG
// Decode the supplied LG message.
// LG protocol has a repeat code which is 4 items long.
// Even though the protocol has 28/32 bits of data, only 24/28 bits are
// distinct.
// In transmission order, the 28/32 bits are constructed as follows:
// 8/12 bits of address + 16 bits of command + 4 bits of checksum.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of bits to expect in the data portion.
// Typically LG_BITS or LG32_BITS.
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA / Should work.
//
// Note:
// LG 32bit protocol appears near identical to the Samsung protocol.
// They possibly differ on how they repeat and initial HDR mark.
// Ref:
// https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/
bool IRrecv::decodeLG(decode_results *results, uint16_t nbits, bool strict) {
if (results->rawlen < 2 * nbits + HEADER + FOOTER - 1 && results->rawlen != 4)
return false; // Can't possibly be a valid LG message.
if (strict && nbits != LG_BITS && nbits != LG32_BITS)
return false; // Doesn't comply with expected LG protocol.
uint64_t data = 0;
uint16_t offset = OFFSET_START;
// Header
if (!matchMark(results->rawbuf[offset], LG_HDR_MARK) &&
!matchMark(results->rawbuf[offset], LG32_HDR_MARK)) return false;
uint32_t m_tick;
if (matchMark(results->rawbuf[offset], LG_HDR_MARK))
m_tick = results->rawbuf[offset++] * RAWTICK / LG_HDR_MARK_TICKS;
else
m_tick = results->rawbuf[offset++] * RAWTICK / LG32_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], LG_HDR_SPACE) &&
!matchSpace(results->rawbuf[offset], LG32_HDR_SPACE)) return false;
uint32_t s_tick;
if (matchSpace(results->rawbuf[offset], LG_HDR_SPACE))
s_tick = results->rawbuf[offset++] * RAWTICK / LG_HDR_SPACE_TICKS;
else
s_tick = results->rawbuf[offset++] * RAWTICK / LG32_HDR_SPACE_TICKS;
// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
LG_BIT_MARK_TICKS * m_tick,
LG_ONE_SPACE_TICKS * s_tick,
LG_BIT_MARK_TICKS * m_tick,
LG_ZERO_SPACE_TICKS * s_tick);
if (data_result.success == false) return false;
data = data_result.data;
offset += data_result.used;
// Footer
if (!matchMark(results->rawbuf[offset++], LG_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], LG_MIN_GAP_TICKS * s_tick))
return false;
// Repeat
if (nbits >= LG32_BITS) {
// If we are expecting the LG 32-bit protocol, there is always
// a repeat message. So, check for it.
#ifndef UNIT_TEST
if (!matchSpace(results->rawbuf[offset], LG_MIN_GAP_TICKS * s_tick))
#else
if (!(matchSpace(results->rawbuf[offset],
LG_MIN_MESSAGE_LENGTH_TICKS * s_tick) ||
matchSpace(results->rawbuf[offset], 65500) ||
matchSpace(results->rawbuf[offset], LG_MIN_GAP_TICKS * s_tick)))
#endif // UNIT_TEST
return false;
offset++;
if (!matchMark(results->rawbuf[offset++], LG32_RPT_HDR_MARK_TICKS * m_tick))
return false;
if (!matchSpace(results->rawbuf[offset++], LG_RPT_SPACE_TICKS * s_tick))
return false;
if (!matchMark(results->rawbuf[offset++], LG_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], LG_MIN_GAP_TICKS * s_tick))
return false;
}
// Compliance
uint16_t command = (data >> 4) & 0xFFFF; // The 16 bits before the checksum.
if (strict && (data & 0xF) != calcLGChecksum(command))
return false; // The last 4 bits sent are the expected checksum.
// Success
results->decode_type = LG;
results->bits = nbits;
results->value = data;
results->command = command;
results->address = data >> 20; // The bits before the command.
return true;
}
#endif

View File

@ -1,349 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017 David Conran
#include "ir_Mitsubishi.h"
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII
// M M M I T S U U B B I S H H I
// M M M I T SSS U U BBBB I SSS HHHHH I
// M M I T S U U B B I S H H I
// M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII
// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote
// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran
// Constants
// Mitsubishi TV
// period time is 1/33000Hz = 30.303 uSeconds (T)
// Ref:
// GlobalCache's Control Tower's Mitsubishi TV data.
// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp
#define MITSUBISHI_TICK 30U
#define MITSUBISHI_BIT_MARK_TICKS 10U
#define MITSUBISHI_BIT_MARK (MITSUBISHI_BIT_MARK_TICKS * \
MITSUBISHI_TICK)
#define MITSUBISHI_ONE_SPACE_TICKS 70U
#define MITSUBISHI_ONE_SPACE (MITSUBISHI_ONE_SPACE_TICKS * \
MITSUBISHI_TICK)
#define MITSUBISHI_ZERO_SPACE_TICKS 30U
#define MITSUBISHI_ZERO_SPACE (MITSUBISHI_ZERO_SPACE_TICKS * \
MITSUBISHI_TICK)
#define MITSUBISHI_MIN_COMMAND_LENGTH_TICKS 1786U
#define MITSUBISHI_MIN_COMMAND_LENGTH (MITSUBISHI_MIN_COMMAND_LENGTH_TICKS * \
MITSUBISHI_TICK)
#define MITSUBISHI_MIN_GAP_TICKS 936U
#define MITSUBISHI_MIN_GAP (MITSUBISHI_MIN_GAP_TICKS * \
MITSUBISHI_TICK)
// Mitsubishi A/C
// Ref:
// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84
#define MITSUBISHI_AC_HDR_MARK 3400U
#define MITSUBISHI_AC_HDR_SPACE 1750U
#define MITSUBISHI_AC_BIT_MARK 450U
#define MITSUBISHI_AC_ONE_SPACE 1300U
#define MITSUBISHI_AC_ZERO_SPACE 420U
#define MITSUBISHI_AC_RPT_MARK 440U
#define MITSUBISHI_AC_RPT_SPACE 17100UL
#if SEND_MITSUBISHI
// Send a Mitsubishi message
//
// Args:
// data: Contents of the message to be sent.
// nbits: Nr. of bits of data to be sent. Typically MITSUBISHI_BITS.
// repeat: Nr. of additional times the message is to be sent.
//
// Status: ALPHA / untested.
//
// Notes:
// This protocol appears to have no header.
// Ref:
// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp
// GlobalCache's Control Tower's Mitsubishi TV data.
void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) {
enableIROut(33); // Set IR carrier frequency
IRtimer usecTimer = IRtimer();
for (uint16_t i = 0; i <= repeat; i++) {
usecTimer.reset();
// No header
// Data
sendData(MITSUBISHI_BIT_MARK, MITSUBISHI_ONE_SPACE,
MITSUBISHI_BIT_MARK, MITSUBISHI_ZERO_SPACE,
data, nbits, true);
// Footer
mark(MITSUBISHI_BIT_MARK);
space(std::max(MITSUBISHI_MIN_COMMAND_LENGTH - usecTimer.elapsed(),
MITSUBISHI_MIN_GAP));
}
}
#endif
#if DECODE_MITSUBISHI
// Decode the supplied Mitsubishi message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of data bits to expect.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA / previously working.
//
// Notes:
// This protocol appears to have no header.
//
// Ref:
// GlobalCache's Control Tower's Mitsubishi TV data.
bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * nbits + FOOTER - 1)
return false; // Shorter than shortest possibly expected.
if (strict && nbits != MITSUBISHI_BITS)
return false; // Request is out of spec.
uint16_t offset = OFFSET_START;
uint64_t data = 0;
// No Header
// But try to auto-calibrate off the initial mark signal.
if (!matchMark(results->rawbuf[offset], MITSUBISHI_BIT_MARK, 30))
return false;
// Calculate how long the common tick time is based on the initial mark.
uint32_t tick = results->rawbuf[offset] * RAWTICK / MITSUBISHI_BIT_MARK_TICKS;
// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
MITSUBISHI_BIT_MARK_TICKS * tick,
MITSUBISHI_ONE_SPACE_TICKS * tick,
MITSUBISHI_BIT_MARK_TICKS * tick,
MITSUBISHI_ZERO_SPACE_TICKS * tick);
if (data_result.success == false) return false;
data = data_result.data;
offset += data_result.used;
uint16_t actualBits = data_result.used / 2;
// Footer
if (!matchMark(results->rawbuf[offset++], MITSUBISHI_BIT_MARK_TICKS * tick,
30)) return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], MITSUBISHI_MIN_GAP_TICKS * tick))
return false;
// Compliance
if (actualBits < nbits)
return false;
if (strict && actualBits != nbits)
return false; // Not as we expected.
// Success
results->decode_type = MITSUBISHI;
results->bits = actualBits;
results->value = data;
results->address = 0;
results->command = 0;
return true;
}
#endif
#if SEND_MITSUBISHI_AC
// Send a Mitsubishi A/C message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (>=MITSUBISHI_AC_STATE_LENGTH)
// repeat: Nr. of times the message is to be repeated.
// (Default = MITSUBISHI_AC_MIN_REPEAT).
//
// Status: BETA / Appears to be working.
//
void IRsend::sendMitsubishiAC(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
if (nbytes < MITSUBISHI_AC_STATE_LENGTH)
return; // Not enough bytes to send a proper message.
// Set IR carrier frequency
enableIROut(38);
// Mitsubishi AC remote sends the packet twice.
for (uint16_t r = 0; r <= repeat; r++) {
// Header
mark(MITSUBISHI_AC_HDR_MARK);
space(MITSUBISHI_AC_HDR_SPACE);
// Data
for (uint16_t i = 0; i < nbytes; i++)
sendData(MITSUBISHI_AC_BIT_MARK, MITSUBISHI_AC_ONE_SPACE,
MITSUBISHI_AC_BIT_MARK, MITSUBISHI_AC_ZERO_SPACE,
data[i], 8, false);
// Footer
mark(MITSUBISHI_AC_RPT_MARK);
space(MITSUBISHI_AC_RPT_SPACE);
}
}
// Code to emulate Mitsubishi A/C IR remote control unit.
// Inspired and derived from the work done at:
// https://github.com/r45635/HVAC-IR-Control
//
// Warning: Consider this very alpha code. Seems to work, but not validated.
//
// Equipment it seems compatible with:
// * <Add models (A/C & remotes) you've gotten it working with here>
// Initialise the object.
IRMitsubishiAC::IRMitsubishiAC(uint16_t pin) : _irsend(pin) {
stateReset();
}
// Reset the state of the remote to a known good state/sequence.
void IRMitsubishiAC::stateReset() {
// The state of the IR remote in IR code form.
// Known good state obtained from:
// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L108
// Note: Can't use the following because it requires -std=c++11
// uint8_t known_good_state[MITSUBISHI_AC_STATE_LENGTH] = {
// 0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x06, 0x30, 0x45, 0x67, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F};
remote_state[0] = 0x23;
remote_state[1] = 0xCB;
remote_state[2] = 0x26;
remote_state[3] = 0x01;
remote_state[4] = 0x00;
remote_state[5] = 0x20;
remote_state[6] = 0x08;
remote_state[7] = 0x06;
remote_state[8] = 0x30;
remote_state[9] = 0x45;
remote_state[10] = 0x67;
for (uint8_t i = 11; i < MITSUBISHI_AC_STATE_LENGTH - 1; i++)
remote_state[i] = 0;
remote_state[MITSUBISHI_AC_STATE_LENGTH - 1] = 0x1F;
checksum(); // Calculate the checksum
}
// Configure the pin for output.
void IRMitsubishiAC::begin() {
_irsend.begin();
}
// Send the current desired state to the IR LED.
void IRMitsubishiAC::send() {
checksum(); // Ensure correct checksum before sending.
_irsend.sendMitsubishiAC(remote_state);
}
// Return a pointer to the internal state date of the remote.
uint8_t* IRMitsubishiAC::getRaw() {
checksum();
return remote_state;
}
// Calculate the checksum for the current internal state of the remote.
void IRMitsubishiAC::checksum() {
uint8_t sum = 0;
// Checksum is simple addition of all previous bytes stored
// as a 8 bit value.
for (uint8_t i = 0; i < 17; i++)
sum += remote_state[i];
remote_state[17] = sum & 0xFFU;
}
// Set the requested power state of the A/C to off.
void IRMitsubishiAC::on() {
// state = ON;
remote_state[5] |= MITSUBISHI_AC_POWER;
}
// Set the requested power state of the A/C to off.
void IRMitsubishiAC::off() {
// state = OFF;
remote_state[5] &= ~MITSUBISHI_AC_POWER;
}
// Set the requested power state of the A/C.
void IRMitsubishiAC::setPower(bool state) {
if (state)
on();
else
off();
}
// Return the requested power state of the A/C.
bool IRMitsubishiAC::getPower() {
return((remote_state[5] & MITSUBISHI_AC_POWER) != 0);
}
// Set the temp. in deg C
void IRMitsubishiAC::setTemp(uint8_t temp) {
temp = std::max((uint8_t) MITSUBISHI_AC_MIN_TEMP, temp);
temp = std::min((uint8_t) MITSUBISHI_AC_MAX_TEMP, temp);
remote_state[7] = temp - MITSUBISHI_AC_MIN_TEMP;
}
// Return the set temp. in deg C
uint8_t IRMitsubishiAC::getTemp() {
return(remote_state[7] + MITSUBISHI_AC_MIN_TEMP);
}
// Set the speed of the fan, 0-6.
// 0 is auto, 1-5 is the speed, 6 is silent.
void IRMitsubishiAC::setFan(uint8_t fan) {
// Bounds check
if (fan > MITSUBISHI_AC_FAN_SILENT)
fan = MITSUBISHI_AC_FAN_MAX; // Set the fan to maximum if out of range.
if (fan == MITSUBISHI_AC_FAN_AUTO) { // Automatic is a special case.
remote_state[9] = 0b10000000 | (remote_state[9] & 0b01111000);
return;
} else if (fan >= MITSUBISHI_AC_FAN_MAX) {
fan--; // There is no spoon^H^H^Heed 5 (max), pretend it doesn't exist.
}
remote_state[9] &= 0b01111000; // Clear the previous state
remote_state[9] |= fan;
}
// Return the requested state of the unit's fan.
uint8_t IRMitsubishiAC::getFan() {
uint8_t fan = remote_state[9] & 0b111;
if (fan == MITSUBISHI_AC_FAN_MAX)
return MITSUBISHI_AC_FAN_SILENT;
return fan;
}
// Return the requested climate operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getMode() {
return(remote_state[6]);
}
// Set the requested climate operation mode of the a/c unit.
void IRMitsubishiAC::setMode(uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
switch (mode) {
case MITSUBISHI_AC_AUTO: break;
case MITSUBISHI_AC_COOL: break;
case MITSUBISHI_AC_DRY: break;
case MITSUBISHI_AC_HEAT: break;
default: mode = MITSUBISHI_AC_AUTO;
}
remote_state[6] = mode;
}
// Set the requested vane operation mode of the a/c unit.
void IRMitsubishiAC::setVane(uint8_t mode) {
mode = std::min(mode, (uint8_t) 0b111); // bounds check
mode |= 0b1000;
mode <<= 3;
remote_state[9] &= 0b11000111; // Clear the previous setting.
remote_state[9] |= mode;
}
// Return the requested vane operation mode of the a/c unit.
uint8_t IRMitsubishiAC::getVane() {
return ((remote_state[9] & 0b00111000) >> 3);
}
#endif

View File

@ -1,65 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017 David Conran
#ifndef IR_MITSUBISHI_H_
#define IR_MITSUBISHI_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include "IRremoteESP8266.h"
#include "IRsend.h"
// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII
// M M M I T S U U B B I S H H I
// M M M I T SSS U U BBBB I SSS HHHHH I
// M M I T S U U B B I S H H I
// M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII
// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote
// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran
// Constants
#define MITSUBISHI_AC_AUTO 0x20U
#define MITSUBISHI_AC_COOL 0x18U
#define MITSUBISHI_AC_DRY 0x10U
#define MITSUBISHI_AC_HEAT 0x08U
#define MITSUBISHI_AC_POWER 0x20U
#define MITSUBISHI_AC_FAN_AUTO 0U
#define MITSUBISHI_AC_FAN_MAX 5U
#define MITSUBISHI_AC_FAN_REAL_MAX 4U
#define MITSUBISHI_AC_FAN_SILENT 6U
#define MITSUBISHI_AC_MIN_TEMP 16U // 16C
#define MITSUBISHI_AC_MAX_TEMP 31U // 31C
#define MITSUBISHI_AC_VANE_AUTO 0U
#define MITSUBISHI_AC_VANE_AUTO_MOVE 7U
#if SEND_MITSUBISHI_AC
class IRMitsubishiAC {
public:
explicit IRMitsubishiAC(uint16_t pin);
void stateReset();
void send();
void begin();
void on();
void off();
void setPower(bool state);
bool getPower();
void setTemp(uint8_t temp);
uint8_t getTemp();
void setFan(uint8_t fan);
uint8_t getFan();
void setMode(uint8_t mode);
uint8_t getMode();
void setVane(uint8_t mode);
uint8_t getVane();
uint8_t* getRaw();
private:
uint8_t remote_state[MITSUBISHI_AC_STATE_LENGTH];
void checksum();
IRsend _irsend;
};
#endif
#endif // IR_MITSUBISHI_H_

View File

@ -1,120 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017 David Conran
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// NN NN IIIII KK KK AAA IIIII
// NNN NN III KK KK AAAAA III
// NN N NN III KKKK AA AA III
// NN NNN III KK KK AAAAAAA III
// NN NN IIIII KK KK AA AA IIIII
// Constants
// Ref:
// https://github.com/markszabo/IRremoteESP8266/issues/309
#define NIKAI_TICK 500U
#define NIKAI_HDR_MARK_TICKS 8U
#define NIKAI_HDR_MARK (NIKAI_HDR_MARK_TICKS * NIKAI_TICK)
#define NIKAI_HDR_SPACE_TICKS 8U
#define NIKAI_HDR_SPACE (NIKAI_HDR_SPACE_TICKS * NIKAI_TICK)
#define NIKAI_BIT_MARK_TICKS 1U
#define NIKAI_BIT_MARK (NIKAI_BIT_MARK_TICKS * NIKAI_TICK)
#define NIKAI_ONE_SPACE_TICKS 2U
#define NIKAI_ONE_SPACE (NIKAI_ONE_SPACE_TICKS * NIKAI_TICK)
#define NIKAI_ZERO_SPACE_TICKS 4U
#define NIKAI_ZERO_SPACE (NIKAI_ZERO_SPACE_TICKS * NIKAI_TICK)
#define NIKAI_MIN_GAP_TICKS 17U
#define NIKAI_MIN_GAP (NIKAI_MIN_GAP_TICKS * NIKAI_TICK)
#if SEND_NIKAI
// Send a Nikai TV formatted message.
//
// Args:
// data: The message to be sent.
// nbits: The bit size of the message being sent. typically NIKAI_BITS.
// repeat: The number of times the message is to be repeated.
//
// Status: ALPHA / Untested.
//
// Ref: https://github.com/markszabo/IRremoteESP8266/issues/309
void IRsend::sendNikai(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Set 38kHz IR carrier frequency & a 1/3 (33%) duty cycle.
enableIROut(38, 33);
// We always send a message, even for repeat=0, hence '<= repeat'.
for (uint16_t i=0; i <= repeat; i++) {
// Header
mark(NIKAI_HDR_MARK);
space(NIKAI_HDR_SPACE);
// Data
sendData(NIKAI_BIT_MARK, NIKAI_ONE_SPACE, NIKAI_BIT_MARK,
NIKAI_ZERO_SPACE, data, nbits, true);
// Footer
mark(NIKAI_BIT_MARK);
space(NIKAI_MIN_GAP);
}
}
#endif
#if DECODE_NIKAI
// Decode the supplied Nikai message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of bits to expect in the data portion.
// Typically NIKAI_BITS.
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: ALPHA / Untested.
//
bool IRrecv::decodeNikai(decode_results *results, uint16_t nbits, bool strict) {
if (results->rawlen < 2 * nbits + HEADER + FOOTER - 1)
return false; // Can't possibly be a valid Nikai message.
if (strict && nbits != NIKAI_BITS)
return false; // We expect Nikai to be a certain sized message.
uint64_t data = 0;
uint16_t offset = OFFSET_START;
// Header
if (!matchMark(results->rawbuf[offset], NIKAI_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = results->rawbuf[offset++] * RAWTICK /
NIKAI_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], NIKAI_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = results->rawbuf[offset++] * RAWTICK /
NIKAI_HDR_SPACE_TICKS;
// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
NIKAI_BIT_MARK_TICKS * m_tick,
NIKAI_ONE_SPACE_TICKS * s_tick,
NIKAI_BIT_MARK_TICKS * m_tick,
NIKAI_ZERO_SPACE_TICKS * s_tick);
if (data_result.success == false) return false;
data = data_result.data;
offset += data_result.used;
// Footer
if (!matchMark(results->rawbuf[offset++], NIKAI_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], NIKAI_MIN_GAP_TICKS * s_tick))
return false;
// Compliance
// Success
results->bits = nbits;
results->value = data;
results->decode_type = NIKAI;
results->command = 0;
results->address = 0;
return true;
}
#endif

View File

@ -1,196 +0,0 @@
// Copyright 2015 Kristian Lauszus
// Copyright 2017 David Conran
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC
// P P A A NN N A A S O O NN N I C
// PPPP AAAAA N N N AAAAA SSS O O N N N I C
// P A A N NN A A S O O N NN I C
// P A A N N A A SSSS OOO N N IIIII CCCC
// Panasonic protocol originally added by Kristian Lauszus from:
// https://github.com/z3t0/Arduino-IRremote
// (Thanks to zenwheel and other people at the original blog post)
// Constants
// Ref:
// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152
#define PANASONIC_TICK 432U
#define PANASONIC_HDR_MARK_TICKS 8U
#define PANASONIC_HDR_MARK (PANASONIC_HDR_MARK_TICKS * PANASONIC_TICK)
#define PANASONIC_HDR_SPACE_TICKS 4U
#define PANASONIC_HDR_SPACE (PANASONIC_HDR_SPACE_TICKS * PANASONIC_TICK)
#define PANASONIC_BIT_MARK_TICKS 1U
#define PANASONIC_BIT_MARK (PANASONIC_BIT_MARK_TICKS * PANASONIC_TICK)
#define PANASONIC_ONE_SPACE_TICKS 3U
#define PANASONIC_ONE_SPACE (PANASONIC_ONE_SPACE_TICKS * PANASONIC_TICK)
#define PANASONIC_ZERO_SPACE_TICKS 1U
#define PANASONIC_ZERO_SPACE (PANASONIC_ZERO_SPACE_TICKS * PANASONIC_TICK)
#define PANASONIC_MIN_COMMAND_LENGTH_TICKS 300UL
#define PANASONIC_MIN_COMMAND_LENGTH (PANASONIC_MIN_COMMAND_LENGTH_TICKS * \
PANASONIC_TICK)
#define PANASONIC_END_GAP 5000U // See issue #245
#define PANASONIC_MIN_GAP_TICKS (PANASONIC_MIN_COMMAND_LENGTH_TICKS - \
(PANASONIC_HDR_MARK_TICKS + PANASONIC_HDR_SPACE_TICKS + \
PANASONIC_BITS * (PANASONIC_BIT_MARK_TICKS + PANASONIC_ONE_SPACE_TICKS) + \
PANASONIC_BIT_MARK_TICKS))
#define PANASONIC_MIN_GAP ((uint32_t)(PANASONIC_MIN_GAP_TICKS * PANASONIC_TICK))
#if (SEND_PANASONIC || SEND_DENON)
// Send a Panasonic formatted message.
//
// Args:
// data: The message to be sent.
// nbits: The number of bits of the message to be sent. (PANASONIC_BITS).
// repeat: The number of times the command is to be repeated.
//
// Status: BETA / Should be working.
//
// Note:
// This protocol is a modified version of Kaseikyo.
void IRsend::sendPanasonic64(uint64_t data, uint16_t nbits, uint16_t repeat) {
enableIROut(36700U); // Set IR carrier frequency of 36.7kHz.
IRtimer usecTimer = IRtimer();
for (uint16_t i = 0; i <= repeat; i++) {
usecTimer.reset();
// Header
mark(PANASONIC_HDR_MARK);
space(PANASONIC_HDR_SPACE);
// Data
sendData(PANASONIC_BIT_MARK, PANASONIC_ONE_SPACE,
PANASONIC_BIT_MARK, PANASONIC_ZERO_SPACE,
data, nbits, true);
// Footer
mark(PANASONIC_BIT_MARK);
space(std::max((uint32_t) PANASONIC_MIN_COMMAND_LENGTH -
usecTimer.elapsed(),
PANASONIC_MIN_GAP));
}
}
// Send a Panasonic formatted message.
//
// Args:
// address: The manufacturer code.
// data: The data portion to be sent.
// nbits: The number of bits of the message to be sent. (PANASONIC_BITS).
// repeat: The number of times the command is to be repeated.
//
// Status: STABLE.
//
// Note:
// This protocol is a modified version of Kaseikyo.
void IRsend::sendPanasonic(uint16_t address, uint32_t data, uint16_t nbits,
uint16_t repeat) {
sendPanasonic64(((uint64_t) address << 32) | (uint64_t) data, nbits, repeat);
}
// Calculate the raw Panasonic data based on device, subdevice, & function.
//
// Args:
// manufacturer: A 16-bit manufacturer code. e.g. 0x4004 is Panasonic.
// device: An 8-bit code.
// subdevice: An 8-bit code.
// function: An 8-bit code.
// Returns:
// A raw uint64_t Panasonic message.
//
// Status: BETA / Should be working..
//
// Note:
// Panasonic 48-bit protocol is a modified version of Kaseikyo.
// Ref:
// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
uint64_t IRsend::encodePanasonic(uint16_t manufacturer,
uint8_t device,
uint8_t subdevice,
uint8_t function) {
uint8_t checksum = device ^ subdevice ^ function;
return (((uint64_t) manufacturer << 32) |
((uint64_t) device << 24) |
((uint64_t) subdevice << 16) |
((uint64_t) function << 8) |
checksum);
}
#endif // (SEND_PANASONIC || SEND_DENON)
#if (DECODE_PANASONIC || DECODE_DENON)
// Decode the supplied Panasonic message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of data bits to expect.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA / Should be working.
// Note:
// Panasonic 48-bit protocol is a modified version of Kaseikyo.
// Ref:
// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152
// http://www.hifi-remote.com/wiki/index.php?title=Panasonic
bool IRrecv::decodePanasonic(decode_results *results, uint16_t nbits,
bool strict, uint32_t manufacturer) {
if (results->rawlen < 2 * nbits + HEADER + FOOTER - 1)
return false; // Not enough entries to be a Panasonic message.
if (strict && nbits != PANASONIC_BITS)
return false; // Request is out of spec.
uint64_t data = 0;
uint16_t offset = OFFSET_START;
// Header
if (!matchMark(results->rawbuf[offset], PANASONIC_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = results->rawbuf[offset++] * RAWTICK /
PANASONIC_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], PANASONIC_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = results->rawbuf[offset++] * RAWTICK /
PANASONIC_HDR_SPACE_TICKS;
// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
PANASONIC_BIT_MARK_TICKS * m_tick,
PANASONIC_ONE_SPACE_TICKS * s_tick,
PANASONIC_BIT_MARK_TICKS * m_tick,
PANASONIC_ZERO_SPACE_TICKS * s_tick);
if (data_result.success == false) return false;
data = data_result.data;
offset += data_result.used;
// Footer
if (!match(results->rawbuf[offset++], PANASONIC_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], PANASONIC_END_GAP))
return false;
// Compliance
uint32_t address = data >> 32;
uint32_t command = data & 0xFFFFFFFF;
if (strict) {
if (address != manufacturer) // Verify the Manufacturer code.
return false;
// Verify the checksum.
uint8_t checksumOrig = data & 0xFF;
uint8_t checksumCalc = ((data >> 24) ^ (data >> 16) ^ (data >> 8)) & 0xFF;
if (checksumOrig != checksumCalc)
return false;
}
// Success
results->value = data;
results->address = address;
results->command = command;
results->decode_type = PANASONIC;
results->bits = nbits;
return true;
}
#endif // (DECODE_PANASONIC || DECODE_DENON)

View File

@ -1,175 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017 David Conran
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// SSSS AAA MMM SSSS U U N N GGGG
// S A A M M M S U U NN N G
// SSS AAAAA M M M SSS U U N N N G GG
// S A A M M S U U N NN G G
// SSSS A A M M SSSS UUU N N GGG
// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/
// Constants
// Ref:
// http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
#define SAMSUNG_TICK 560U
#define SAMSUNG_HDR_MARK_TICKS 8U
#define SAMSUNG_HDR_MARK (SAMSUNG_HDR_MARK_TICKS * SAMSUNG_TICK)
#define SAMSUNG_HDR_SPACE_TICKS 8U
#define SAMSUNG_HDR_SPACE (SAMSUNG_HDR_SPACE_TICKS * SAMSUNG_TICK)
#define SAMSUNG_BIT_MARK_TICKS 1U
#define SAMSUNG_BIT_MARK (SAMSUNG_BIT_MARK_TICKS * SAMSUNG_TICK)
#define SAMSUNG_ONE_SPACE_TICKS 3U
#define SAMSUNG_ONE_SPACE (SAMSUNG_ONE_SPACE_TICKS * SAMSUNG_TICK)
#define SAMSUNG_ZERO_SPACE_TICKS 1U
#define SAMSUNG_ZERO_SPACE (SAMSUNG_ZERO_SPACE_TICKS * SAMSUNG_TICK)
#define SAMSUNG_RPT_SPACE_TICKS 4U
#define SAMSUNG_RPT_SPACE (SAMSUNG_RPT_SPACE_TICKS * SAMSUNG_TICK)
#define SAMSUNG_MIN_MESSAGE_LENGTH_TICKS 193U
#define SAMSUNG_MIN_MESSAGE_LENGTH (SAMSUNG_MIN_MESSAGE_LENGTH_TICKS * \
SAMSUNG_TICK)
#define SAMSUNG_MIN_GAP_TICKS (SAMSUNG_MIN_MESSAGE_LENGTH_TICKS - \
(SAMSUNG_HDR_MARK_TICKS + SAMSUNG_HDR_SPACE_TICKS + \
SAMSUNG_BITS * (SAMSUNG_BIT_MARK_TICKS + SAMSUNG_ONE_SPACE_TICKS) + \
SAMSUNG_BIT_MARK_TICKS))
#define SAMSUNG_MIN_GAP (SAMSUNG_MIN_GAP_TICKS * SAMSUNG_TICK)
#if SEND_SAMSUNG
// Send a Samsung formatted message.
// Samsung has a separate message to indicate a repeat, like NEC does.
// TODO(crankyoldgit): Confirm that is actually how Samsung sends a repeat.
// The refdoc doesn't indicate it is true.
//
// Args:
// data: The message to be sent.
// nbits: The bit size of the message being sent. typically SAMSUNG_BITS.
// repeat: The number of times the message is to be repeated.
//
// Status: BETA / Should be working.
//
// Ref: http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
void IRsend::sendSAMSUNG(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Set 38kHz IR carrier frequency & a 1/3 (33%) duty cycle.
enableIROut(38, 33);
IRtimer usecTimer = IRtimer();
// We always send a message, even for repeat=0, hence '<= repeat'.
for (uint16_t i=0; i <= repeat; i++) {
usecTimer.reset();
// Header
mark(SAMSUNG_HDR_MARK);
space(SAMSUNG_HDR_SPACE);
// Data
sendData(SAMSUNG_BIT_MARK, SAMSUNG_ONE_SPACE, SAMSUNG_BIT_MARK,
SAMSUNG_ZERO_SPACE, data, nbits, true);
// Footer
mark(SAMSUNG_BIT_MARK);
space(std::max((uint32_t) SAMSUNG_MIN_GAP,
(uint32_t) (SAMSUNG_MIN_MESSAGE_LENGTH -
usecTimer.elapsed())));
}
}
// Construct a raw Samsung message from the supplied customer(address) &
// command.
//
// Args:
// customer: The customer code. (aka. Address)
// command: The command code.
// Returns:
// A raw 32-bit Samsung message suitable for sendSAMSUNG().
//
// Status: BETA / Should be working.
uint32_t IRsend::encodeSAMSUNG(uint8_t customer, uint8_t command) {
customer = reverseBits(customer, sizeof(customer) * 8);
command = reverseBits(command, sizeof(command) * 8);
return((command ^ 0xFF) | (command << 8) |
(customer << 16) | (customer << 24));
}
#endif
#if DECODE_SAMSUNG
// Decode the supplied Samsung message.
// Samsung messages whilst 32 bits in size, only contain 16 bits of distinct
// data. e.g. In transmition order:
// customer_byte + customer_byte(same) + address_byte + invert(address_byte)
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of bits to expect in the data portion. Typically SAMSUNG_BITS.
// strict: Flag to indicate if we strictly adhere to the specification.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: STABLE
//
// Note:
// LG 32bit protocol appears near identical to the Samsung protocol.
// They differ on their compliance criteria and how they repeat.
// Ref:
// http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * nbits + HEADER + FOOTER - 1)
return false; // Can't possibly be a valid Samsung message.
if (strict && nbits != SAMSUNG_BITS)
return false; // We expect Samsung to be 32 bits of message.
uint64_t data = 0;
uint16_t offset = OFFSET_START;
// Header
if (!matchMark(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = results->rawbuf[offset++] * RAWTICK /
SAMSUNG_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = results->rawbuf[offset++] * RAWTICK /
SAMSUNG_HDR_SPACE_TICKS;
// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
SAMSUNG_BIT_MARK_TICKS * m_tick,
SAMSUNG_ONE_SPACE_TICKS * s_tick,
SAMSUNG_BIT_MARK_TICKS * m_tick,
SAMSUNG_ZERO_SPACE_TICKS * s_tick);
if (data_result.success == false) return false;
data = data_result.data;
offset += data_result.used;
// Footer
if (!matchMark(results->rawbuf[offset++], SAMSUNG_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], SAMSUNG_MIN_GAP_TICKS * s_tick))
return false;
// Compliance
// According to the spec, the customer (address) code is the first 8
// transmitted bits. It's then repeated. Check for that.
uint8_t address = data >> 24;
if (strict && address != ((data >> 16) & 0xFF))
return false;
// Spec says the command code is the 3rd block of transmitted 8-bits,
// followed by the inverted command code.
uint8_t command = (data & 0xFF00) >> 8;
if (strict && command != ((data & 0xFF) ^ 0xFF))
return false;
// Success
results->bits = nbits;
results->value = data;
results->decode_type = SAMSUNG;
// command & address need to be reversed as they are transmitted LSB first,
results->command = reverseBits(command, sizeof(command) * 8);
results->address = reverseBits(address, sizeof(address) * 8);
return true;
}
#endif

View File

@ -1,151 +0,0 @@
// Copyright 2017 stufisher
#include "ir_Trotec.h"
#include "IRremoteESP8266.h"
#include "IRutils.h"
// Constants
#define TROTEC_HDR_MARK 5952U
#define TROTEC_HDR_SPACE 7364U
#define TROTEC_ONE_MARK 592U
#define TROTEC_ONE_SPACE 1560U
#define TROTEC_ZERO_MARK 592U
#define TROTEC_ZERO_SPACE 592U
#define TROTEC_GAP 6184U
#define TROTEC_GAP_END 1500U // made up value
#if SEND_TROTEC
void IRsend::sendTrotec(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
if (nbytes < TROTEC_COMMAND_LENGTH)
return;
enableIROut(36);
for (uint16_t r = 0; r <= repeat; r++) {
// Header
mark(TROTEC_HDR_MARK);
space(TROTEC_HDR_SPACE);
// Data
for (uint16_t i = 0; i < nbytes; i++)
sendData(TROTEC_ONE_MARK, TROTEC_ONE_SPACE, TROTEC_ZERO_MARK,
TROTEC_ZERO_SPACE, data[i], 8, false);
// Footer
mark(TROTEC_ONE_MARK);
space(TROTEC_GAP);
mark(TROTEC_ONE_MARK);
space(TROTEC_GAP_END);
}
}
IRTrotecESP::IRTrotecESP(uint16_t pin) : _irsend(pin) {
stateReset();
}
void IRTrotecESP::begin() {
_irsend.begin();
}
void IRTrotecESP::send() {
checksum();
_irsend.sendTrotec(trotec);
}
void IRTrotecESP::checksum() {
uint8_t sum = 0;
uint8_t i;
for (i = 2; i < 8; i++) sum += trotec[i];
trotec[8] = sum & 0xFF;
}
void IRTrotecESP::stateReset() {
for (uint8_t i = 2; i < TROTEC_COMMAND_LENGTH; i++)
trotec[i] = 0x0;
trotec[0] = TROTEC_INTRO1;
trotec[1] = TROTEC_INTRO2;
setPower(false);
setTemp(TROTEC_DEF_TEMP);
setSpeed(TROTEC_FAN_MED);
setMode(TROTEC_AUTO);
}
uint8_t* IRTrotecESP::getRaw() {
checksum();
return trotec;
}
void IRTrotecESP::setPower(bool state) {
if (state)
trotec[2] |= (TROTEC_ON << 3);
else
trotec[2] &= ~(TROTEC_ON << 3);
}
uint8_t IRTrotecESP::getPower() {
return trotec[2] & (TROTEC_ON << 3);
}
void IRTrotecESP::setSpeed(uint8_t speed) {
trotec[2] = (trotec[2] & 0xcf) | (speed << 4);
}
uint8_t IRTrotecESP::getSpeed() {
return trotec[2] & 0x30;
}
void IRTrotecESP::setMode(uint8_t mode) {
trotec[2] = (trotec[2] & 0xfc) | mode;
}
uint8_t IRTrotecESP::getMode() {
return trotec[2] & 0x03;
}
void IRTrotecESP::setTemp(uint8_t temp) {
if (temp < TROTEC_MIN_TEMP)
temp = TROTEC_MIN_TEMP;
else if (temp > TROTEC_MAX_TEMP)
temp = TROTEC_MAX_TEMP;
trotec[3] = (trotec[3] & 0x80) | (temp - TROTEC_MIN_TEMP);
}
uint8_t IRTrotecESP::getTemp() {
return trotec[3] & 0x7f;
}
void IRTrotecESP::setSleep(bool sleep) {
if (sleep)
trotec[3] |= (TROTEC_SLEEP_ON << 7);
else
trotec[3] &= ~(TROTEC_SLEEP_ON << 7);
}
bool IRTrotecESP::getSleep(void) {
return trotec[3] & (TROTEC_SLEEP_ON << 7);
}
void IRTrotecESP::setTimer(uint8_t timer) {
if (timer > TROTEC_MAX_TIMER) timer = TROTEC_MAX_TIMER;
if (timer) {
trotec[5] |= (TROTEC_TIMER_ON << 6);
trotec[6] = timer;
} else {
trotec[5] &= ~(TROTEC_TIMER_ON << 6);
trotec[6] = 0;
}
}
uint8_t IRTrotecESP::getTimer() {
return trotec[6];
}
#endif // SEND_TROTEC

View File

@ -1,80 +0,0 @@
// Copyright 2017 stufisher
#ifndef IR_TROTEC_H_
#define IR_TROTEC_H_
#include "IRremoteESP8266.h"
#include "IRsend.h"
// Constants
// Byte 0
#define TROTEC_INTRO1 0x12
// Byte 1
#define TROTEC_INTRO2 0x34
// Byte 2
#define TROTEC_AUTO 0
#define TROTEC_COOL 1
#define TROTEC_DRY 2
#define TROTEC_FAN 3
#define TROTEC_ON 1
#define TROTEC_OFF 0
#define TROTEC_FAN_LOW 1
#define TROTEC_FAN_MED 2
#define TROTEC_FAN_HIGH 3
// Byte 3
#define TROTEC_MIN_TEMP 18
#define TROTEC_MAX_TEMP 32
#define TROTEC_DEF_TEMP 25
#define TROTEC_SLEEP_ON 1
// Byte 5
#define TROTEC_TIMER_ON 1
// Byte 6
#define TROTEC_MIN_TIMER 0
#define TROTEC_MAX_TIMER 23
#if SEND_TROTEC
class IRTrotecESP {
public:
explicit IRTrotecESP(uint16_t pin);
void send();
void begin();
void setPower(bool state);
uint8_t getPower();
void setTemp(uint8_t temp);
uint8_t getTemp();
void setSpeed(uint8_t fan);
uint8_t getSpeed();
uint8_t getMode();
void setMode(uint8_t mode);
bool getSleep();
void setSleep(bool sleep);
uint8_t getTimer();
void setTimer(uint8_t timer);
uint8_t* getRaw();
private:
uint8_t trotec[TROTEC_COMMAND_LENGTH];
void stateReset();
void checksum();
IRsend _irsend;
};
#endif
#endif // IR_TROTEC_H_

View File

@ -1,144 +0,0 @@
// Copyright 2009 Ken Shirriff
// Copyright 2017 David Conran
#include <algorithm>
#include "IRrecv.h"
#include "IRsend.h"
#include "IRtimer.h"
#include "IRutils.h"
// W W H H Y Y N N TTTTT EEEEE RRRRR
// W W H H Y Y NN N T E R R
// W W W HHHHH Y N N N T EEE RRRR
// W W W H H Y N NN T E R R
// WWW H H Y N N T EEEEE R R
// Whynter A/C ARC-110WD added by Francesco Meschia
// Whynter originally added from https://github.com/shirriff/Arduino-IRremote/
// Constants
#define WHYNTER_TICK 50U
#define WHYNTER_HDR_MARK_TICKS 57U
#define WHYNTER_HDR_MARK (WHYNTER_HDR_MARK_TICKS * WHYNTER_TICK)
#define WHYNTER_HDR_SPACE_TICKS 57U
#define WHYNTER_HDR_SPACE (WHYNTER_HDR_SPACE_TICKS * \
WHYNTER_TICK)
#define WHYNTER_BIT_MARK_TICKS 15U
#define WHYNTER_BIT_MARK (WHYNTER_BIT_MARK_TICKS * WHYNTER_TICK)
#define WHYNTER_ONE_SPACE_TICKS 43U
#define WHYNTER_ONE_SPACE (WHYNTER_ONE_SPACE_TICKS * \
WHYNTER_TICK)
#define WHYNTER_ZERO_SPACE_TICKS 15U
#define WHYNTER_ZERO_SPACE (WHYNTER_ZERO_SPACE_TICKS * \
WHYNTER_TICK)
#define WHYNTER_MIN_COMMAND_LENGTH_TICKS 2160U // Completely made up value.
#define WHYNTER_MIN_COMMAND_LENGTH (WHYNTER_MIN_COMMAND_LENGTH_TICKS * \
WHYNTER_TICK)
#define WHYNTER_MIN_GAP_TICKS (WHYNTER_MIN_COMMAND_LENGTH_TICKS - \
(2 * (WHYNTER_BIT_MARK_TICKS + WHYNTER_ZERO_SPACE_TICKS) + \
WHYNTER_BITS * (WHYNTER_BIT_MARK_TICKS + WHYNTER_ONE_SPACE_TICKS)))
#define WHYNTER_MIN_GAP (WHYNTER_MIN_GAP_TICKS * WHYNTER_TICK)
#if SEND_WHYNTER
// Send a Whynter message.
//
// Args:
// data: message to be sent.
// nbits: Nr. of bits of the message to be sent.
// repeat: Nr. of additional times the message is to be sent.
//
// Status: STABLE
//
// Ref:
// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
void IRsend::sendWhynter(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Set IR carrier frequency
enableIROut(38);
IRtimer usecTimer = IRtimer();
for (uint16_t i = 0; i <= repeat; i++) {
usecTimer.reset();
// Header
mark(WHYNTER_BIT_MARK);
space(WHYNTER_ZERO_SPACE);
mark(WHYNTER_HDR_MARK);
space(WHYNTER_HDR_SPACE);
// Data
sendData(WHYNTER_BIT_MARK, WHYNTER_ONE_SPACE, WHYNTER_BIT_MARK,
WHYNTER_ZERO_SPACE, data, nbits, true);
// Footer
mark(WHYNTER_BIT_MARK);
space(std::max(WHYNTER_MIN_COMMAND_LENGTH - usecTimer.elapsed(),
WHYNTER_MIN_GAP));
}
}
#endif
#if DECODE_WHYNTER
// Decode the supplied Whynter message.
//
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of data bits to expect.
// strict: Flag indicating if we should perform strict matching.
// Returns:
// boolean: True if it can decode it, false if it can't.
//
// Status: BETA Strict mode is ALPHA.
//
// Ref:
// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
bool IRrecv::decodeWhynter(decode_results *results, uint16_t nbits,
bool strict) {
if (results->rawlen < 2 * nbits + 2 * HEADER + FOOTER - 1)
return false; // We don't have enough entries to possibly match.
// Compliance
if (strict && nbits != WHYNTER_BITS)
return false; // Incorrect nr. of bits per spec.
uint16_t offset = OFFSET_START;
// Header
// Sequence begins with a bit mark and a zero space.
// These are typically small, so we'll prefer to do the calibration
// on the much larger header mark & space that are next.
if (!matchMark(results->rawbuf[offset++], WHYNTER_BIT_MARK)) return false;
if (!matchSpace(results->rawbuf[offset++], WHYNTER_ZERO_SPACE)) return false;
// Main header mark and space
if (!matchMark(results->rawbuf[offset], WHYNTER_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = results->rawbuf[offset++] * RAWTICK /
WHYNTER_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], WHYNTER_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = results->rawbuf[offset++] * RAWTICK /
WHYNTER_HDR_SPACE_TICKS;
// Data
uint64_t data = 0;
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
WHYNTER_BIT_MARK_TICKS * m_tick,
WHYNTER_ONE_SPACE_TICKS * s_tick,
WHYNTER_BIT_MARK_TICKS * m_tick,
WHYNTER_ZERO_SPACE_TICKS * s_tick);
if (data_result.success == false) return false;
data = data_result.data;
offset += data_result.used;
// Footer
if (!matchMark(results->rawbuf[offset++], WHYNTER_BIT_MARK_TICKS * m_tick))
return false;
if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], WHYNTER_MIN_GAP_TICKS * s_tick))
return false;
// Success
results->decode_type = WHYNTER;
results->bits = nbits;
results->value = data;
results->address = 0;
results->command = 0;
return true;
}
#endif

View File

@ -1,139 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend_test.h"
#include "IRsend.h"
#include "gtest/gtest.h"
// Tests sendData().
// Test sending zero bits.
TEST(TestSendData, SendZeroBits) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1, 0, true);
EXPECT_EQ("", irsend.outputStr());
}
// Test sending zero and one.
TEST(TestSendData, SendSingleBit) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
EXPECT_EQ("m1s2", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b0, 1, true);
EXPECT_EQ("m3s4", irsend.outputStr());
}
// Test sending bit order.
TEST(TestSendData, TestingBitSendOrder) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b10, 2, true);
EXPECT_EQ("m1s2m3s4", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b10, 2, false);
EXPECT_EQ("m3s4m1s2", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b0001, 4, false);
EXPECT_EQ("m1s2m3s4m3s4m3s4", irsend.outputStr());
}
// Test sending typical data.
TEST(TestSendData, SendTypicalData) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1010110011110000, 16, true);
EXPECT_EQ("m1s2m3s4m1s2m3s4m1s2m1s2m3s4m3s4m1s2m1s2m1s2m1s2m3s4m3s4m3s4m3s4",
irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0x1234567890ABCDEF, 64, true);
EXPECT_EQ("m3s4m3s4m3s4m1s2m3s4m3s4m1s2m3s4m3s4m3s4m1s2m1s2m3s4m1s2m3s4m3s4"
"m3s4m1s2m3s4m1s2m3s4m1s2m1s2m3s4m3s4m1s2m1s2m1s2m1s2m3s4m3s4m3s4"
"m1s2m3s4m3s4m1s2m3s4m3s4m3s4m3s4m1s2m3s4m1s2m3s4m1s2m3s4m1s2m1s2"
"m1s2m1s2m3s4m3s4m1s2m1s2m3s4m1s2m1s2m1s2m1s2m3s4m1s2m1s2m1s2m1s2",
irsend.outputStr());
}
// Test sending more than expected bits.
TEST(TestSendData, SendOverLargeData) {
IRsendTest irsend(4);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0xFFFFFFFFFFFFFFFF, 70, true);
EXPECT_EQ("m3s4m3s4m3s4m3s4m3s4m3s4"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2"
"m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2m1s2",
irsend.outputStr());
}
// Test inverting the output.
TEST(TestIRSend, InvertedOutput) {
IRsendTest irsend(4, true);
irsend.begin();
irsend.sendData(1, 2, 3, 4, 0b1, 1, true);
EXPECT_EQ("s1m2", irsend.outputStr());
irsend.sendData(1, 2, 3, 4, 0b0, 1, true);
EXPECT_EQ("s3m4", irsend.outputStr());
}
// Test typical use of sendRaw().
TEST(TestSendRaw, GeneralUse) {
IRsendTest irsend(4);
IRrecv irrecv(0);
irsend.begin();
// NEC C3E0E0E8 as measured in #204
uint16_t rawData[67] = {8950, 4500, 550, 1650, 600, 1650, 550, 550, 600, 500,
600, 550, 550, 550, 600, 1650, 550, 1650, 600, 1650,
600, 1650, 550, 1700, 550, 550, 600, 550, 550, 550,
600, 500, 600, 550, 550, 1650, 600, 1650, 600, 1650,
550, 550, 600, 500, 600, 500, 600, 550, 550, 550,
600, 1650, 550, 1650, 600, 1650, 600, 500, 650, 1600,
600, 500, 600, 550, 550, 550, 600};
irsend.sendRaw(rawData, 67, 38);
EXPECT_EQ(
"m8950s4500"
"m550s1650m600s1650m550s550m600s500m600s550m550s550m600s1650m550s1650"
"m600s1650m600s1650m550s1700m550s550m600s550m550s550m600s500m600s550"
"m550s1650m600s1650m600s1650m550s550m600s500m600s500m600s550m550s550"
"m600s1650m550s1650m600s1650m600s500m650s1600m600s500m600s550m550s550"
"m600", irsend.outputStr());
irsend.reset();
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
EXPECT_EQ(
"m8950s4500"
"m550s1650m600s1650m550s550m600s500m600s550m550s550m600s1650m550s1650"
"m600s1650m600s1650m550s1700m550s550m600s550m550s550m600s500m600s550"
"m550s1650m600s1650m600s1650m550s550m600s500m600s500m600s550m550s550"
"m600s1650m550s1650m600s1650m600s500m650s1600m600s500m600s550m550s550"
"m600", irsend.outputStr());
ASSERT_TRUE(irrecv.decodeNEC(&irsend.capture, NEC_BITS, false));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0xC3E0E0E8, irsend.capture.value);
}
// Incorrect handling of decodes from Raw. i.e. There is no gap recorded at
// the end of a command when using the interrupt code. sendRaw() best emulates
// this for unit testing purposes. sendGC() and sendXXX() will add the trailing
// gap. Users won't see this in normal use.
TEST(TestSendRaw, NoTrailingGap) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t rawData[67] = {9000, 4500, 650, 550, 650, 1650, 600, 550, 650, 550,
600, 1650, 650, 550, 600, 1650, 650, 1650, 650, 1650,
600, 550, 650, 1650, 650, 1650, 650, 550, 600, 1650,
650, 1650, 650, 550, 650, 550, 650, 1650, 650, 550,
650, 550, 650, 550, 600, 550, 650, 550, 650, 550,
650, 1650, 600, 550, 650, 1650, 650, 1650, 650, 1650,
650, 1650, 650, 1650, 650, 1650, 600};
irsend.sendRaw(rawData, 67, 38);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(NEC_BITS, irsend.capture.bits);
}

View File

@ -1,106 +0,0 @@
// Copyright 2017 David Conran
#ifndef TEST_IRSEND_TEST_H_
#define TEST_IRSEND_TEST_H_
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <iostream>
#include <sstream>
#include <string>
#include "IRrecv.h"
#include "IRsend.h"
#define OUTPUT_BUF 1000U
#define RAW_BUF 1000U
class IRsendTest: public IRsend {
public:
uint32_t output[OUTPUT_BUF];
uint16_t last;
uint16_t rawbuf[RAW_BUF];
decode_results capture;
explicit IRsendTest(uint16_t x, bool i = false) : IRsend(x, i) {
reset();
}
void reset() {
last = 0;
output[last] = 0;
}
std::string outputStr() {
std::stringstream result;
if (last == 0 && output[0] == 0)
return "";
for (uint16_t i = 0; i <= last; i++) {
if ((i & 1) != outputOff ) // Odd XOR outputOff
result << "s";
else
result << "m";
result << output[i];
}
reset();
return result.str();
}
void makeDecodeResult(uint16_t offset = 0) {
capture.decode_type = UNKNOWN;
capture.bits = 0;
capture.rawlen = last + 1 - offset;
capture.overflow = (last - offset >= (int16_t) RAW_BUF);
capture.repeat = false;
capture.address = 0;
capture.command = 0;
capture.value = 0;
capture.rawbuf = rawbuf;
for (uint16_t i = 0;
(i < RAW_BUF - 1) && (offset < OUTPUT_BUF);
i++, offset++)
if (output[offset] / RAWTICK > UINT16_MAX)
rawbuf[i + 1] = UINT16_MAX;
else
rawbuf[i + 1] = output[offset] / RAWTICK;
}
void dumpRawResult() {
std::cout << std::dec;
if (capture.rawlen == 0) return;
std::cout << "uint16_t rawbuf["<< capture.rawlen - 1 << "] = {";
for (uint16_t i = 1; i < capture.rawlen; i++) {
if (i % 8 == 1)
std::cout << std::endl << " ";
std::cout << (capture.rawbuf[i] * RAWTICK);
// std::cout << "(" << capture.rawbuf[i] << ")";
if (i < capture.rawlen - 1)
std::cout << ", ";
}
std::cout << "};" << std::endl;
}
void addGap(uint32_t usecs) {
space(usecs);
}
protected:
uint16_t mark(uint16_t usec) {
if (last >= OUTPUT_BUF)
return 0;
if (last & 1) // Is odd? (i.e. last call was a space())
output[++last] = usec;
else
output[last] += usec;
return 0;
}
void space(uint32_t time) {
if (last >= OUTPUT_BUF)
return;
if (last & 1) { // Is odd? (i.e. last call was a space())
output[last] += time;
} else {
output[++last] = time;
}
}
};
#endif // TEST_IRSEND_TEST_H_

View File

@ -1,91 +0,0 @@
// Copyright 2017 David Conran
#include "IRutils.h"
#include <stdint.h>
#include "gtest/gtest.h"
// Tests reverseBits().
// Tests reverseBits for typical use.
TEST(ReverseBitsTest, TypicalUse) {
EXPECT_EQ(0xF, reverseBits(0xF0, 8));
EXPECT_EQ(0xFFFF, reverseBits(0xFFFF0000, 32));
EXPECT_EQ(0x555500005555FFFF, reverseBits(0xFFFFAAAA0000AAAA, 64));
EXPECT_EQ(0, reverseBits(0, 64));
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, reverseBits(0xFFFFFFFFFFFFFFFF, 64));
}
// Tests reverseBits for bit size values <= 1
TEST(ReverseBitsTest, LessThanTwoBitsReversed) {
EXPECT_EQ(0x12345678, reverseBits(0x12345678, 1));
EXPECT_EQ(1234, reverseBits(1234, 0));
}
// Tests reverseBits for bit size larger than a uint64_t.
TEST(ReverseBitsTest, LargerThan64BitsReversed) {
EXPECT_EQ(0, reverseBits(0, 65));
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, reverseBits(0xFFFFFFFFFFFFFFFF, 100));
EXPECT_EQ(0x555500005555FFFF, reverseBits(0xFFFFAAAA0000AAAA, 3000));
}
// Tests reverseBits for bit sizes less than all the data stored.
TEST(ReverseBitsTest, LessBitsReversedThanInputHasSet) {
EXPECT_EQ(0xF8, reverseBits(0xF1, 4));
EXPECT_EQ(0xF5, reverseBits(0xFA, 4));
EXPECT_EQ(0x12345678FFFF0000, reverseBits(0x123456780000FFFF, 32));
}
// Tests for uint64ToString()
TEST(TestUint64ToString, TrivialCases) {
EXPECT_EQ("0", uint64ToString(0)); // Default base (10)
EXPECT_EQ("0", uint64ToString(0, 2)); // Base-2
EXPECT_EQ("0", uint64ToString(0, 8)); // Base-8
EXPECT_EQ("0", uint64ToString(0, 10)); // Base-10
EXPECT_EQ("0", uint64ToString(0, 16)); // Base-16
EXPECT_EQ("1", uint64ToString(1, 2)); // Base-2
EXPECT_EQ("2", uint64ToString(2, 8)); // Base-8
EXPECT_EQ("3", uint64ToString(3, 10)); // Base-10
EXPECT_EQ("4", uint64ToString(4, 16)); // Base-16
}
TEST(TestUint64ToString, NormalUse) {
EXPECT_EQ("12345", uint64ToString(12345));
EXPECT_EQ("100", uint64ToString(4, 2));
EXPECT_EQ("3039", uint64ToString(12345, 16));
EXPECT_EQ("123456", uint64ToString(123456));
EXPECT_EQ("1E240", uint64ToString(123456, 16));
EXPECT_EQ("FEEDDEADBEEF", uint64ToString(0xfeeddeadbeef, 16));
}
TEST(TestUint64ToString, Max64Bit) {
EXPECT_EQ("18446744073709551615", uint64ToString(UINT64_MAX)); // Default
EXPECT_EQ("1111111111111111111111111111111111111111111111111111111111111111",
uint64ToString(UINT64_MAX, 2)); // Base-2
EXPECT_EQ("1777777777777777777777", uint64ToString(UINT64_MAX, 8)); // Base-8
EXPECT_EQ("18446744073709551615", uint64ToString(UINT64_MAX, 10)); // Base-10
EXPECT_EQ("FFFFFFFFFFFFFFFF", uint64ToString(UINT64_MAX, 16)); // Base-16
}
TEST(TestUint64ToString, Max32Bit) {
EXPECT_EQ("4294967295", uint64ToString(UINT32_MAX)); // Default
EXPECT_EQ("37777777777", uint64ToString(UINT32_MAX, 8)); // Base-8
EXPECT_EQ("4294967295", uint64ToString(UINT32_MAX, 10)); // Base-10
EXPECT_EQ("FFFFFFFF", uint64ToString(UINT32_MAX, 16)); // Base-16
}
TEST(TestUint64ToString, InterestingCases) {
// Previous hacky-code didn't handle leading zeros in the lower 32 bits.
EXPECT_EQ("100000000", uint64ToString(0x100000000, 16));
EXPECT_EQ("100000001", uint64ToString(0x100000001, 16));
}
TEST(TestUint64ToString, SillyBases) {
// If we are given a silly base, we should defer to Base-10.
EXPECT_EQ("12345", uint64ToString(12345, 0)); // Super silly, makes no sense.
EXPECT_EQ("12345", uint64ToString(12345, 1)); // We don't do unary.
EXPECT_EQ("12345", uint64ToString(12345, 100)); // We can't print base-100.
EXPECT_EQ("12345", uint64ToString(12345, 37)); // Base-37 is one to far.
EXPECT_EQ("9IX", uint64ToString(12345, 36)); // But we *can* do base-36.
}

View File

@ -1,419 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "ir_Daikin.h"
#include "gtest/gtest.h"
// Tests for sendDaikin().
// Test sending typical data only.
TEST(TestSendDaikin, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
uint8_t daikin_code[DAIKIN_COMMAND_LENGTH] = {
0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20,
0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00,
0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE3};
irsend.reset();
irsend.sendDaikin(daikin_code);
EXPECT_EQ(
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428"
"m428s29428"
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428"
"m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280"
"m428s29428", irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendDaikin, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint8_t daikin_code[DAIKIN_COMMAND_LENGTH] = {
0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20,
0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00,
0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE3};
irsend.reset();
irsend.sendDaikin(daikin_code, DAIKIN_COMMAND_LENGTH, 1);
EXPECT_EQ(
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428"
"m428s29428"
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428"
"m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280"
"m428s29428"
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428"
"m428s29428"
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428"
"m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280"
"m428s29428", irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendDaikin, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
uint8_t daikin_short_code[DAIKIN_COMMAND_LENGTH - 1] = {
0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20,
0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00,
0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00};
irsend.reset();
irsend.sendDaikin(daikin_short_code, DAIKIN_COMMAND_LENGTH - 1);
ASSERT_EQ("", irsend.outputStr());
uint8_t daikin_long_code[DAIKIN_COMMAND_LENGTH + 1] = {
0x11, 0xDA, 0x27, 0xF0, 0x00, 0x00, 0x00, 0x20,
0x11, 0xDA, 0x27, 0x00, 0x00, 0x41, 0x1E, 0x00,
0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE3, 0x11};
irsend.reset();
irsend.sendDaikin(daikin_long_code, DAIKIN_COMMAND_LENGTH + 1);
ASSERT_EQ(
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s1280m428s428m428s428"
"m428s29428"
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s428m428s428m428s428m428s428m428s428m428s1280m428s428"
"m428s428m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s1280"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s29428", irsend.outputStr());
}
// Tests for IRDaikinESP class.
TEST(TestDaikinClass, Power) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.on();
EXPECT_TRUE(irdaikin.getPower());
irdaikin.off();
EXPECT_FALSE(irdaikin.getPower());
irdaikin.setPower(true);
EXPECT_TRUE(irdaikin.getPower());
irdaikin.setPower(false);
EXPECT_FALSE(irdaikin.getPower());
}
TEST(TestDaikinClass, Temperature) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.setTemp(0);
EXPECT_EQ(DAIKIN_MIN_TEMP, irdaikin.getTemp());
irdaikin.setTemp(255);
EXPECT_EQ(DAIKIN_MAX_TEMP, irdaikin.getTemp());
irdaikin.setTemp(DAIKIN_MIN_TEMP);
EXPECT_EQ(DAIKIN_MIN_TEMP, irdaikin.getTemp());
irdaikin.setTemp(DAIKIN_MAX_TEMP);
EXPECT_EQ(DAIKIN_MAX_TEMP, irdaikin.getTemp());
irdaikin.setTemp(DAIKIN_MIN_TEMP - 1);
EXPECT_EQ(DAIKIN_MIN_TEMP, irdaikin.getTemp());
irdaikin.setTemp(DAIKIN_MAX_TEMP + 1);
EXPECT_EQ(DAIKIN_MAX_TEMP, irdaikin.getTemp());
irdaikin.setTemp(DAIKIN_MIN_TEMP + 1);
EXPECT_EQ(DAIKIN_MIN_TEMP + 1, irdaikin.getTemp());
irdaikin.setTemp(21);
EXPECT_EQ(21, irdaikin.getTemp());
irdaikin.setTemp(25);
EXPECT_EQ(25, irdaikin.getTemp());
irdaikin.setTemp(29);
EXPECT_EQ(29, irdaikin.getTemp());
}
TEST(TestDaikinClass, OperatingMode) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.setMode(DAIKIN_AUTO);
EXPECT_EQ(DAIKIN_AUTO, irdaikin.getMode());
irdaikin.setMode(DAIKIN_COOL);
EXPECT_EQ(DAIKIN_COOL, irdaikin.getMode());
irdaikin.setMode(DAIKIN_HEAT);
EXPECT_EQ(DAIKIN_HEAT, irdaikin.getMode());
irdaikin.setMode(DAIKIN_DRY);
EXPECT_EQ(DAIKIN_DRY, irdaikin.getMode());
irdaikin.setMode(DAIKIN_FAN);
EXPECT_EQ(DAIKIN_FAN, irdaikin.getMode());
irdaikin.setMode(DAIKIN_FAN + 1);
EXPECT_EQ(DAIKIN_AUTO, irdaikin.getMode());
irdaikin.setMode(DAIKIN_AUTO + 1);
EXPECT_EQ(DAIKIN_AUTO, irdaikin.getMode());
irdaikin.setMode(255);
EXPECT_EQ(DAIKIN_AUTO, irdaikin.getMode());
}
TEST(TestDaikinClass, VaneSwing) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.setSwingHorizontal(true);
irdaikin.setSwingVertical(false);
irdaikin.setSwingHorizontal(true);
EXPECT_TRUE(irdaikin.getSwingHorizontal());
EXPECT_FALSE(irdaikin.getSwingVertical());
irdaikin.setSwingVertical(true);
EXPECT_TRUE(irdaikin.getSwingHorizontal());
EXPECT_TRUE(irdaikin.getSwingVertical());
irdaikin.setSwingHorizontal(false);
EXPECT_FALSE(irdaikin.getSwingHorizontal());
EXPECT_TRUE(irdaikin.getSwingVertical());
irdaikin.setSwingVertical(false);
EXPECT_FALSE(irdaikin.getSwingHorizontal());
EXPECT_FALSE(irdaikin.getSwingVertical());
}
TEST(TestDaikinClass, QuietMode) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.setQuiet(true);
EXPECT_TRUE(irdaikin.getQuiet());
irdaikin.setQuiet(false);
EXPECT_FALSE(irdaikin.getQuiet());
irdaikin.setQuiet(true);
EXPECT_TRUE(irdaikin.getQuiet());
irdaikin.setPowerful(true);
EXPECT_FALSE(irdaikin.getQuiet());
}
TEST(TestDaikinClass, PowerfulMode) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.setPowerful(true);
EXPECT_TRUE(irdaikin.getPowerful());
irdaikin.setPowerful(false);
EXPECT_FALSE(irdaikin.getPowerful());
irdaikin.setPowerful(true);
EXPECT_TRUE(irdaikin.getPowerful());
irdaikin.setQuiet(true);
EXPECT_FALSE(irdaikin.getPowerful());
}
TEST(TestDaikinClass, FanSpeed) {
IRDaikinESP irdaikin(0);
irdaikin.begin();
irdaikin.setFan(0);
EXPECT_EQ(0, irdaikin.getFan());
irdaikin.setFan(255);
EXPECT_EQ(DAIKIN_FAN_MAX, irdaikin.getFan());
irdaikin.setFan(DAIKIN_FAN_MAX);
EXPECT_EQ(DAIKIN_FAN_MAX, irdaikin.getFan());
irdaikin.setFan(DAIKIN_FAN_MAX + 1);
EXPECT_EQ(DAIKIN_FAN_MAX, irdaikin.getFan());
irdaikin.setFan(DAIKIN_FAN_MAX - 1);
EXPECT_EQ(DAIKIN_FAN_MAX - 1, irdaikin.getFan());
irdaikin.setFan(DAIKIN_FAN_MIN);
EXPECT_EQ(DAIKIN_FAN_MIN, irdaikin.getFan());
irdaikin.setFan(DAIKIN_FAN_MIN + 1);
EXPECT_EQ(DAIKIN_FAN_MIN + 1, irdaikin.getFan());
irdaikin.setFan(3);
EXPECT_EQ(3, irdaikin.getFan());
irdaikin.setFan(DAIKIN_FAN_AUTO);
EXPECT_EQ(DAIKIN_FAN_AUTO, irdaikin.getFan());
}
TEST(TestDaikinClass, MessageConstuction) {
IRDaikinESP irdaikin(0);
IRsendTest irsend(4);
irdaikin.begin();
irsend.begin();
irdaikin.setFan(DAIKIN_FAN_MIN);
irdaikin.setMode(DAIKIN_COOL);
irdaikin.setTemp(27);
irdaikin.setSwingVertical(false);
irdaikin.setSwingHorizontal(true);
irdaikin.setQuiet(false);
irdaikin.setPower(true);
// Check everything for kicks.
EXPECT_EQ(DAIKIN_FAN_MIN, irdaikin.getFan());
EXPECT_EQ(DAIKIN_COOL, irdaikin.getMode());
EXPECT_EQ(27, irdaikin.getTemp());
EXPECT_FALSE(irdaikin.getSwingVertical());
EXPECT_TRUE(irdaikin.getSwingHorizontal());
EXPECT_FALSE(irdaikin.getQuiet());
EXPECT_TRUE(irdaikin.getPower());
irsend.reset();
irsend.sendDaikin(irdaikin.getRaw());
EXPECT_EQ(
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s29428"
"m3650s1623"
"m428s1280m428s428m428s428m428s428m428s1280m428s428m428s428m428s428"
"m428s428m428s1280m428s428m428s1280m428s1280m428s428m428s1280m428s1280"
"m428s1280m428s1280m428s1280m428s428m428s428m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s1280m428s428m428s428m428s428m428s1280m428s1280m428s428m428s428"
"m428s428m428s1280m428s1280m428s428m428s1280m428s1280m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s1280m428s1280m428s428m428s428"
"m428s1280m428s1280m428s1280m428s1280m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s1280m428s1280"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s428m428s428m428s428m428s428m428s428"
"m428s428m428s428m428s428m428s1280m428s1280m428s1280m428s1280m428s428"
"m428s29428", irsend.outputStr());
}

View File

@ -1,207 +0,0 @@
// Copyright 2017 Jonny Graham
#include "IRsend.h"
#include "IRsend_test.h"
#include "ir_Fujitsu.h"
#include "gtest/gtest.h"
template<typename T, size_t size>
::testing::AssertionResult ArraysMatch(const T (&expected)[size],
const T* actual) {
for (size_t i(0); i < size; ++i) {
if (expected[i] != actual[i]) {
int e = expected[i];
int a = actual[i];
return ::testing::AssertionFailure() << "array[" << i
<< "] (" << std::hex << a << std::dec << ") != expected[" << i
<< "] (" << std::hex << e << std::dec << ")";
}
}
return ::testing::AssertionSuccess();
}
// Tests for Mitsubishi A/C methods.
// Test sending typical data only.
TEST(TestSendFujitsuAC, GetRawDefault) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
fujitsuACSender.setCmd(FUJITSU_AC_CMD_TURN_ON);
fujitsuACSender.setSwing(FUJITSU_AC_SWING_BOTH);
fujitsuACSender.setMode(FUJITSU_AC_MODE_COOL);
fujitsuACSender.setFanSpeed(FUJITSU_AC_FAN_HIGH);
fujitsuACSender.setTemp(24);
uint8_t expected[16] = {0x14, 0x63, 0x0, 0x10, 0x10, 0xFE, 0x9, 0x30,
0x81, 0x1, 0x31, 0x0, 0x0, 0x0, 0x20, 0xFD};
EXPECT_TRUE(ArraysMatch(expected, fujitsuACSender.getRaw()));
}
TEST(TestSendFujitsuAC, GetRawTurnOff) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
fujitsuACSender.off();
uint8_t expected[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02, 0xFD};
EXPECT_TRUE(ArraysMatch(expected, fujitsuACSender.getRaw()));
}
TEST(TestSendFujitsuAC, GetRawStepHoriz) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
fujitsuACSender.stepHoriz();
uint8_t expected[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x79, 0x86};
EXPECT_TRUE(ArraysMatch(expected, fujitsuACSender.getRaw()));
}
TEST(TestSendFujitsuAC, GetRawStepVert) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
fujitsuACSender.stepVert();
uint8_t expected[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x6C, 0x93};
EXPECT_TRUE(ArraysMatch(expected, fujitsuACSender.getRaw()));
}
TEST(TestSendFujitsuAC, GetRawWithSwingHoriz) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
fujitsuACSender.setCmd(FUJITSU_AC_CMD_STAY_ON);
fujitsuACSender.setSwing(FUJITSU_AC_SWING_HORIZ);
fujitsuACSender.setMode(FUJITSU_AC_MODE_COOL);
fujitsuACSender.setFanSpeed(FUJITSU_AC_FAN_QUIET);
fujitsuACSender.setTemp(25);
uint8_t expected[16] = {0x14, 0x63, 0x0, 0x10, 0x10, 0xFE, 0x9, 0x30,
0x90, 0x1, 0x24, 0x0, 0x0, 0x0, 0x20, 0xFB};
EXPECT_TRUE(ArraysMatch(expected, fujitsuACSender.getRaw()));
}
TEST(TestSendFujitsuAC, GetRawWithFan) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
fujitsuACSender.setCmd(FUJITSU_AC_CMD_STAY_ON);
fujitsuACSender.setSwing(FUJITSU_AC_SWING_HORIZ);
fujitsuACSender.setMode(FUJITSU_AC_MODE_FAN);
fujitsuACSender.setFanSpeed(FUJITSU_AC_FAN_MED);
fujitsuACSender.setTemp(20); // temp doesn't matter for fan
// but it is sent by the RC anyway
uint8_t expected[16] = {0x14, 0x63, 0x0, 0x10, 0x10, 0xFE, 0x9, 0x30,
0x40, 0x3, 0x22, 0x0, 0x0, 0x0, 0x20, 0x4B};
EXPECT_TRUE(ArraysMatch(expected, fujitsuACSender.getRaw()));
}
TEST(TestSendFujitsuAC, GenerateMessage) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
IRsendTest irsend(4);
fujitsuACSender.begin();
irsend.begin();
fujitsuACSender.setCmd(FUJITSU_AC_CMD_STAY_ON);
fujitsuACSender.setSwing(FUJITSU_AC_SWING_BOTH);
fujitsuACSender.setMode(FUJITSU_AC_MODE_COOL);
fujitsuACSender.setFanSpeed(FUJITSU_AC_FAN_HIGH);
fujitsuACSender.setTemp(24);
EXPECT_EQ(FUJITSU_AC_FAN_HIGH, fujitsuACSender.getFanSpeed());
EXPECT_EQ(FUJITSU_AC_MODE_COOL, fujitsuACSender.getMode());
EXPECT_EQ(24, fujitsuACSender.getTemp());
EXPECT_EQ(FUJITSU_AC_SWING_BOTH, fujitsuACSender.getSwing());
EXPECT_EQ(FUJITSU_AC_CMD_STAY_ON, fujitsuACSender.getCmd());
irsend.reset();
irsend.sendFujitsuAC(fujitsuACSender.getRaw(), FUJITSU_AC_STATE_LENGTH);
EXPECT_EQ(
"m3224s1574m448s367m448s367m448s1182m448s367m448s1182m448s367m448s367m448"
"s367m448s1182m448s1182m448s367m448s367m448s367m448s1182m448s1182m448s367"
"m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448"
"s367m448s367m448s367m448s367m448s1182m448s367m448s367m448s367m448s367m448"
"s367m448s367m448s367m448s1182m448s367m448s367m448s367m448s367m448s1182"
"m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s367"
"m448s367m448s1182m448s367m448s367m448s367m448s367m448s367m448s367m448s367"
"m448s367m448s1182m448s1182m448s367m448s367m448s367m448s367m448s367m448s367"
"m448s367m448s367m448s367m448s1182m448s1182m448s367m448s367m448s367m448"
"s367m448s367m448s367m448s367m448s1182m448s367m448s367m448s367m448s1182m448"
"s1182m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448"
"s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448"
"s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448"
"s367m448s367m448s367m448s367m448s367m448s1182m448s367m448s367m448s367m448"
"s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182m448s8100",
irsend.outputStr());
}
TEST(TestSendFujitsuAC, GenerateShortMessage) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
IRsendTest irsend(4);
fujitsuACSender.begin();
irsend.begin();
fujitsuACSender.off();
EXPECT_EQ(FUJITSU_AC_CMD_TURN_OFF, fujitsuACSender.getCmd());
irsend.reset();
irsend.sendFujitsuAC(fujitsuACSender.getRaw(), FUJITSU_AC_STATE_LENGTH_SHORT);
EXPECT_EQ(
"m3224s1574m448s367m448s367m448s1182m448s367m448s1182m448s367m448s367m448"
"s367m448s1182m448s1182m448s367m448s367m448s367m448s1182m448s1182m448s367"
"m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367"
"m448s367m448s367m448s367m448s1182m448s367m448s367m448s367m448s367m448s367"
"m448s367m448s367m448s1182m448s367m448s367m448s367m448s367m448s1182m448s367"
"m448s367m448s367m448s367m448s367m448s367m448s1182m448s367m448s1182m448"
"s1182m448s1182m448s1182m448s1182m448s1182m448s8100",
irsend.outputStr());
}
// Issue #275
TEST(TestSendFujitsuAC, Issue275) {
IRFujitsuAC fujitsuACSender = IRFujitsuAC(4);
IRsendTest irsend(4);
fujitsuACSender.begin();
irsend.begin();
irsend.reset();
fujitsuACSender.setCmd(FUJITSU_AC_CMD_TURN_OFF);
irsend.sendFujitsuAC(fujitsuACSender.getRaw(), FUJITSU_AC_STATE_LENGTH_SHORT);
EXPECT_EQ(
// Header
"m3224s1574"
// 0 0 1 0 1 0 0 0 (0x28)
"m448s367m448s367m448s1182m448s367m448s1182m448s367m448s367m448s367"
// 1 1 0 0 0 1 1 0 (0xC6)
"m448s1182m448s1182m448s367m448s367m448s367m448s1182m448s1182m448s367"
// 0 0 0 0 0 0 0 0 (0x00)
"m448s367m448s367m448s367m448s367m448s367m448s367m448s367m448s367"
// 0 0 0 0 1 0 0 0 (0x08)
"m448s367m448s367m448s367m448s367m448s1182m448s367m448s367m448s367"
// 0 0 0 0 1 0 0 0 (0x08)
"m448s367m448s367m448s367m448s367m448s1182m448s367m448s367m448s367"
// 0 1 0 0 0 0 0 0 (0x40)
"m448s367m448s1182m448s367m448s367m448s367m448s367m448s367m448s367"
// 1 0 1 1 1 1 1 1 (0xBF)
"m448s1182m448s367m448s1182m448s1182m448s1182m448s1182m448s1182m448s1182"
// Footer
"m448s8100", irsend.outputStr());
irsend.reset();
// Per report in Issue #275
uint16_t off[115] = {
3350, 1650,
450, 400, 450, 450, 450, 1250, 450, 400, 450, 1250, 450, 400, 450, 400,
450, 400, 450, 1250, 450, 1250, 450, 400, 450, 400, 450, 400, 450, 1250,
450, 1250, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400,
450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400,
450, 1250, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400,
450, 400, 450, 1250, 450, 400, 450, 400, 450, 400, 450, 400, 450, 1250,
450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 400, 450, 1250,
450, 400, 450, 1250, 450, 1250, 450, 1250, 450, 1250, 450, 1250,
450, 1250, 450};
irsend.sendRaw(off, 115, 38);
EXPECT_EQ(
// Header
"m3350s1650"
// 0 0 1 0 1 0 0 0 (0x28)
"m450s400m450s450m450s1250m450s400m450s1250m450s400m450s400m450s400"
// 1 1 0 0 0 1 1 0 (0xC6)
"m450s1250m450s1250m450s400m450s400m450s400m450s1250m450s1250m450s400"
// 0 0 0 0 0 0 0 0 (0x00)
"m450s400m450s400m450s400m450s400m450s400m450s400m450s400m450s400"
// 0 0 0 0 1 0 0 0 (0x08)
"m450s400m450s400m450s400m450s400m450s1250m450s400m450s400m450s400"
// 0 0 0 0 1 0 0 0 (0x08)
"m450s400m450s400m450s400m450s400m450s1250m450s400m450s400m450s400"
// 0 1 0 0 0 0 0 0 (0x40)
"m450s400m450s1250m450s400m450s400m450s400m450s400m450s400m450s400"
// 1 0 1 1 1 1 1 1 (0xBF)
"m450s1250m450s400m450s1250m450s1250m450s1250m450s1250m450s1250m450s1250"
// Footer
"m450",
irsend.outputStr());
}

View File

@ -1,68 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendGlobalCache().
// Test sending a typical command wihtout a repeat.
TEST(TestSendGlobalCache, NonRepeatingCode) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified NEC TV "Power On" from Global Cache with no repeats
uint16_t gc_test[71] = {38000, 1, 1, 342, 172, 21, 22, 21, 21, 21, 65, 21, 21,
21, 22, 21, 22, 21, 21, 21, 22, 21, 65, 21, 65, 21,
22, 21, 65, 21, 65, 21, 65, 21, 65, 21, 65, 21, 65,
21, 22, 21, 22, 21, 21, 21, 22, 21, 22, 21, 65, 21,
22, 21, 21, 21, 65, 21, 65, 21, 65, 21, 64, 22, 65,
21, 22, 21, 65, 21, 1519};
irsend.sendGC(gc_test, 71);
irsend.makeDecodeResult();
EXPECT_EQ("m8892s4472m546s572m546s546m546s1690m546s546m546s572m546s572"
"m546s546m546s572m546s1690m546s1690m546s572m546s1690m546s1690"
"m546s1690m546s1690m546s1690m546s1690m546s572m546s572m546s546"
"m546s572m546s572m546s1690m546s572m546s546m546s1690m546s1690"
"m546s1690m546s1664m572s1690m546s572m546s1690m546s39494",
irsend.outputStr());
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(NEC_BITS, irsend.capture.bits);
EXPECT_EQ(0x20DF827D, irsend.capture.value);
EXPECT_EQ(0x4, irsend.capture.address);
EXPECT_EQ(0x41, irsend.capture.command);
}
// Test sending typical command with repeats.
TEST(TestSendGlobalCache, RepeatCode) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Sherwood (NEC-like) "Power On" from Global Cache with 2 repeats
uint16_t gc_test[75] = {38000, 2, 69, 341, 171, 21, 64, 21, 64, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 64, 21, 64, 21, 21,
21, 64, 21, 21, 21, 21, 21, 21, 21, 64, 21, 21, 21,
64, 21, 21, 21, 21, 21, 21, 21, 64, 21, 21, 21, 21,
21, 21, 21, 21, 21, 64, 21, 64, 21, 64, 21, 21, 21,
64, 21, 64, 21, 64, 21, 1600, 341, 85, 21, 3647};
irsend.sendGC(gc_test, 75);
irsend.makeDecodeResult();
EXPECT_EQ("m8866s4446m546s1664m546s1664m546s546m546s546m546s546m546s546"
"m546s546m546s1664m546s1664m546s546m546s1664m546s546m546s546"
"m546s546m546s1664m546s546m546s1664m546s546m546s546m546s546"
"m546s1664m546s546m546s546m546s546m546s546m546s1664m546s1664"
"m546s1664m546s546m546s1664m546s1664m546s1664m546s41600"
"m8866s2210m546s94822"
"m8866s2210m546s94822", irsend.outputStr());
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(NEC_BITS, irsend.capture.bits);
EXPECT_EQ(0xC1A28877, irsend.capture.value);
EXPECT_EQ(0x4583, irsend.capture.address);
EXPECT_EQ(0x11, irsend.capture.command);
}

View File

@ -1,192 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendGree().
// Test sending typical data only.
TEST(TestSendGreeChars, SendData) {
IRsendTest irsend(4);
irsend.begin();
uint8_t gree_code[GREE_STATE_LENGTH] = {
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
irsend.reset();
irsend.sendGree(gree_code);
EXPECT_EQ(
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000", irsend.outputStr());
}
TEST(TestSendGreeUint64, SendData) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF);
EXPECT_EQ(
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000", irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendGreeChars, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint8_t gree_code[GREE_STATE_LENGTH] = {
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
irsend.reset();
irsend.sendGree(gree_code, GREE_STATE_LENGTH, 1);
EXPECT_EQ(
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000"
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000", irsend.outputStr());
}
TEST(TestSendGreeUint64, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF, GREE_BITS, 1);
EXPECT_EQ(
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000"
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s19000", irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendGreeChars, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
uint8_t gree_short_code[GREE_STATE_LENGTH - 1] = {
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD};
uint8_t gree_long_code[GREE_STATE_LENGTH + 1] = {
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12};
irsend.reset();
irsend.sendGree(gree_short_code, GREE_STATE_LENGTH - 1);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
irsend.sendGree(gree_long_code, GREE_STATE_LENGTH + 1);
ASSERT_EQ(
"m9000s4000"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s540m620s540m620s1600m620s540m620s1600m620s1600m620s540m620s540"
"m620s540m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540"
"m620s540m620s540m620s540m620s1600m620s1600m620s1600m620s1600m620s540"
"m620s540m620s1600m620s540"
"m620s19000"
"m620s540m620s540m620s540m620s540m620s1600m620s540m620s540m620s1600"
"m620s1600m620s1600m620s540m620s1600m620s540m620s1600m620s540m620s1600"
"m620s1600m620s540m620s1600m620s1600m620s540m620s540m620s1600m620s1600"
"m620s1600m620s1600m620s1600m620s1600m620s540m620s1600m620s1600m620s1600"
"m620s540m620s1600m620s540m620s540m620s1600m620s540m620s540m620s540"
"m620s19000", irsend.outputStr());
}
TEST(TestSendGreeUint64, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF, GREE_BITS - 1);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
irsend.sendGree(0x1234567890ABCDEF, GREE_BITS + 1);
ASSERT_EQ("", irsend.outputStr());
}
TEST(TestSendGree, CompareUint64ToCharResults) {
IRsendTest irsend_chars(4);
IRsendTest irsend_uint64(0);
uint8_t gree_code[GREE_STATE_LENGTH] = {
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
irsend_chars.begin();
irsend_uint64.begin();
irsend_chars.reset();
irsend_uint64.reset();
irsend_chars.sendGree(gree_code);
irsend_uint64.sendGree(0x1234567890ABCDEF);
ASSERT_EQ(irsend_chars.outputStr(), irsend_uint64.outputStr());
uint8_t gree_zero_code[GREE_STATE_LENGTH] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
irsend_chars.reset();
irsend_uint64.reset();
irsend_chars.sendGree(gree_zero_code);
irsend_uint64.sendGree((uint64_t) 0x0);
ASSERT_EQ(irsend_chars.outputStr(), irsend_uint64.outputStr());
}

View File

@ -1,432 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "ir_Kelvinator.h"
#include "gtest/gtest.h"
// Tests for sendKelvinator().
// Test sending typical data only.
TEST(TestSendKelvinator, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
uint8_t kelv_code[KELVINATOR_STATE_LENGTH] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0};
irsend.reset();
irsend.sendKelvinator(kelv_code);
EXPECT_EQ(
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560"
"m675s39900"
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s1560"
"m675s39900", irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendKelvinator, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint8_t kelv_code[KELVINATOR_STATE_LENGTH] = {
0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0};
irsend.reset();
irsend.sendKelvinator(kelv_code, KELVINATOR_STATE_LENGTH, 1);
EXPECT_EQ(
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560"
"m675s39900"
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s1560"
"m675s39900"
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560"
"m675s39900"
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s1560"
"m675s39900", irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendKelvinator, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
uint8_t kelv_short_code[15] = {0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10};
uint8_t kelv_long_code[17] = {0x19, 0x0B, 0x80, 0x50, 0x00, 0x00, 0x00, 0xE0,
0x19, 0x0B, 0x80, 0x70, 0x00, 0x00, 0x10, 0xf0,
0x00};
irsend.reset();
irsend.sendKelvinator(kelv_short_code, 15);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
// Shouldn't be different from the SendDataOnly. We just don't send the
// extra data.
irsend.sendKelvinator(kelv_long_code, 17);
ASSERT_EQ(
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560"
"m675s39900"
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s520m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s1560"
"m675s39900", irsend.outputStr());
}
// Tests for IRKelvinatorAC class.
TEST(TestKelvinatorClass, Power) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.on();
EXPECT_TRUE(irkelv.getPower());
irkelv.off();
EXPECT_FALSE(irkelv.getPower());
irkelv.setPower(true);
EXPECT_TRUE(irkelv.getPower());
irkelv.setPower(false);
EXPECT_FALSE(irkelv.getPower());
}
TEST(TestKelvinatorClass, Temperature) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setTemp(0);
EXPECT_EQ(KELVINATOR_MIN_TEMP, irkelv.getTemp());
irkelv.setTemp(255);
EXPECT_EQ(KELVINATOR_MAX_TEMP, irkelv.getTemp());
irkelv.setTemp(KELVINATOR_MIN_TEMP);
EXPECT_EQ(KELVINATOR_MIN_TEMP, irkelv.getTemp());
irkelv.setTemp(KELVINATOR_MAX_TEMP);
EXPECT_EQ(KELVINATOR_MAX_TEMP, irkelv.getTemp());
irkelv.setTemp(KELVINATOR_MIN_TEMP - 1);
EXPECT_EQ(KELVINATOR_MIN_TEMP, irkelv.getTemp());
irkelv.setTemp(KELVINATOR_MAX_TEMP + 1);
EXPECT_EQ(KELVINATOR_MAX_TEMP, irkelv.getTemp());
irkelv.setTemp(17);
EXPECT_EQ(17, irkelv.getTemp());
irkelv.setTemp(21);
EXPECT_EQ(21, irkelv.getTemp());
irkelv.setTemp(25);
EXPECT_EQ(25, irkelv.getTemp());
irkelv.setTemp(29);
EXPECT_EQ(29, irkelv.getTemp());
}
TEST(TestKelvinatorClass, OperatingMode) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setTemp(24);
irkelv.setMode(KELVINATOR_AUTO);
EXPECT_EQ(KELVINATOR_AUTO, irkelv.getMode());
EXPECT_EQ(KELVINATOR_AUTO_TEMP, irkelv.getTemp());
irkelv.setMode(KELVINATOR_COOL);
EXPECT_EQ(KELVINATOR_COOL, irkelv.getMode());
irkelv.setMode(KELVINATOR_HEAT);
EXPECT_EQ(KELVINATOR_HEAT, irkelv.getMode());
irkelv.setTemp(24);
irkelv.setMode(KELVINATOR_DRY);
EXPECT_EQ(KELVINATOR_DRY, irkelv.getMode());
EXPECT_EQ(KELVINATOR_AUTO_TEMP, irkelv.getTemp());
irkelv.setMode(KELVINATOR_FAN);
EXPECT_EQ(KELVINATOR_FAN, irkelv.getMode());
irkelv.setMode(KELVINATOR_HEAT + 1);
EXPECT_EQ(KELVINATOR_AUTO, irkelv.getMode());
irkelv.setMode(255);
EXPECT_EQ(KELVINATOR_AUTO, irkelv.getMode());
}
TEST(TestKelvinatorClass, VaneSwing) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setSwingHorizontal(true);
irkelv.setSwingVertical(false);
irkelv.setSwingHorizontal(true);
EXPECT_TRUE(irkelv.getSwingHorizontal());
EXPECT_FALSE(irkelv.getSwingVertical());
irkelv.setSwingVertical(true);
EXPECT_TRUE(irkelv.getSwingHorizontal());
EXPECT_TRUE(irkelv.getSwingVertical());
irkelv.setSwingHorizontal(false);
EXPECT_FALSE(irkelv.getSwingHorizontal());
EXPECT_TRUE(irkelv.getSwingVertical());
irkelv.setSwingVertical(false);
EXPECT_FALSE(irkelv.getSwingHorizontal());
EXPECT_FALSE(irkelv.getSwingVertical());
}
TEST(TestKelvinatorClass, QuietMode) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setQuiet(true);
EXPECT_TRUE(irkelv.getQuiet());
irkelv.setQuiet(false);
EXPECT_FALSE(irkelv.getQuiet());
irkelv.setQuiet(true);
EXPECT_TRUE(irkelv.getQuiet());
}
TEST(TestKelvinatorClass, IonFilter) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setIonFilter(true);
EXPECT_TRUE(irkelv.getIonFilter());
irkelv.setIonFilter(false);
EXPECT_FALSE(irkelv.getIonFilter());
irkelv.setIonFilter(true);
EXPECT_TRUE(irkelv.getIonFilter());
}
TEST(TestKelvinatorClass, Light) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setLight(true);
EXPECT_TRUE(irkelv.getLight());
irkelv.setLight(false);
EXPECT_FALSE(irkelv.getLight());
irkelv.setLight(true);
EXPECT_TRUE(irkelv.getLight());
}
TEST(TestKelvinatorClass, XFan) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setXFan(true);
EXPECT_TRUE(irkelv.getXFan());
irkelv.setXFan(false);
EXPECT_FALSE(irkelv.getXFan());
irkelv.setXFan(true);
EXPECT_TRUE(irkelv.getXFan());
}
TEST(TestKelvinatorClass, TurboFan) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setTurbo(true);
EXPECT_TRUE(irkelv.getTurbo());
irkelv.setTurbo(false);
EXPECT_FALSE(irkelv.getTurbo());
irkelv.setFan(2);
irkelv.setTurbo(true);
EXPECT_TRUE(irkelv.getTurbo());
// Turbo mode is turned off if the temperature is changed.
irkelv.setFan(3);
EXPECT_FALSE(irkelv.getTurbo());
// But only when it is changed, not set to the same value again.
irkelv.setTurbo(true);
irkelv.setFan(3);
EXPECT_TRUE(irkelv.getTurbo());
}
TEST(TestKelvinatorClass, FanSpeed) {
IRKelvinatorAC irkelv(0);
irkelv.begin();
irkelv.setFan(0);
EXPECT_EQ(0, irkelv.getFan());
irkelv.setFan(255);
EXPECT_EQ(KELVINATOR_FAN_MAX, irkelv.getFan());
irkelv.setFan(KELVINATOR_FAN_MAX);
EXPECT_EQ(KELVINATOR_FAN_MAX, irkelv.getFan());
irkelv.setFan(KELVINATOR_FAN_MAX + 1);
EXPECT_EQ(KELVINATOR_FAN_MAX, irkelv.getFan());
irkelv.setFan(KELVINATOR_FAN_MAX - 1);
EXPECT_EQ(KELVINATOR_FAN_MAX - 1, irkelv.getFan());
irkelv.setFan(1);
EXPECT_EQ(1, irkelv.getFan());
irkelv.setFan(1);
EXPECT_EQ(1, irkelv.getFan());
irkelv.setFan(3);
EXPECT_EQ(3, irkelv.getFan());
}
TEST(TestKelvinatorClass, MessageConstuction) {
IRKelvinatorAC irkelv(0);
IRsendTest irsend(4);
irkelv.begin();
irsend.begin();
irkelv.setFan(1);
irkelv.setMode(KELVINATOR_COOL);
irkelv.setTemp(27);
irkelv.setSwingVertical(false);
irkelv.setSwingHorizontal(true);
irkelv.setIonFilter(true);
irkelv.setQuiet(false);
irkelv.setLight(false);
irkelv.setPower(true);
irkelv.setTurbo(false);
irkelv.setXFan(true);
// Check everything for kicks.
EXPECT_EQ(1, irkelv.getFan());
EXPECT_EQ(KELVINATOR_COOL, irkelv.getMode());
EXPECT_EQ(27, irkelv.getTemp());
EXPECT_FALSE(irkelv.getSwingVertical());
EXPECT_TRUE(irkelv.getSwingHorizontal());
EXPECT_TRUE(irkelv.getIonFilter());
EXPECT_FALSE(irkelv.getQuiet());
EXPECT_FALSE(irkelv.getLight());
EXPECT_TRUE(irkelv.getPower());
EXPECT_FALSE(irkelv.getTurbo());
EXPECT_TRUE(irkelv.getXFan());
irsend.reset();
irsend.sendKelvinator(irkelv.getRaw());
EXPECT_EQ(
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s1560m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s1560m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s1560"
"m675s39900"
"m8990s4490"
"m675s1560m675s520m675s520m675s1560m675s1560m675s520m675s1560m675s520"
"m675s1560m675s1560m675s520m675s1560m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s1560m675s1560"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s520"
"m675s520m675s1560m675s520"
"m675s19950"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s520m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s520m675s520m675s520"
"m675s520m675s520m675s520m675s520m675s1560m675s1560m675s1560m675s1560"
"m675s39900", irsend.outputStr());
}

View File

@ -1,694 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "ir_Mitsubishi.h"
#include "gtest/gtest.h"
// Tests for sendMitsubishi().
// Test sending typical data only.
TEST(TestSendMitsubishi, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendMitsubishi(0xE242);
EXPECT_EQ(
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580"
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580", irsend.outputStr());
irsend.reset();
irsend.sendMitsubishi(0x0);
EXPECT_EQ(
"m300s900m300s900m300s900m300s900m300s900m300s900m300s900m300s900"
"m300s900m300s900m300s900m300s900m300s900m300s900m300s900m300s900"
"m300s53580"
"m300s900m300s900m300s900m300s900m300s900m300s900m300s900m300s900"
"m300s900m300s900m300s900m300s900m300s900m300s900m300s900m300s900"
"m300s53580", irsend.outputStr());
irsend.reset();
irsend.sendMitsubishi(0x4321);
EXPECT_EQ(
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s2100"
"m300s900m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100"
"m300s53580"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s2100"
"m300s900m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100"
"m300s53580", irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendMitsubishi, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendMitsubishi(0xE242, MITSUBISHI_BITS, 0); // 0 repeat.
EXPECT_EQ(
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580", irsend.outputStr());
irsend.reset();
irsend.sendMitsubishi(0xE242, MITSUBISHI_BITS, 1); // 1 repeat.
EXPECT_EQ(
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580"
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580", irsend.outputStr());
irsend.sendMitsubishi(0xE242, MITSUBISHI_BITS, 2); // 2 repeats.
EXPECT_EQ(
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580"
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580"
"m300s2100m300s2100m300s2100m300s900m300s900m300s900m300s2100m300s900"
"m300s900m300s2100m300s900m300s900m300s900m300s900m300s2100m300s900"
"m300s53580", irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendMitsubishi, SendUsualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendMitsubishi(0x0, 8);
EXPECT_EQ(
"m300s900m300s900m300s900m300s900m300s900m300s900m300s900m300s900"
"m300s53580"
"m300s900m300s900m300s900m300s900m300s900m300s900m300s900m300s900"
"m300s53580", irsend.outputStr());
irsend.reset();
irsend.sendMitsubishi(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"m300s900m300s900m300s900m300s2100m300s900m300s900m300s2100m300s900"
"m300s900m300s900m300s2100m300s2100m300s900m300s2100m300s900m300s900"
"m300s900m300s2100m300s900m300s2100m300s900m300s2100m300s2100m300s900"
"m300s900m300s2100m300s2100m300s2100m300s2100m300s900m300s900m300s900"
"m300s2100m300s900m300s900m300s2100m300s900m300s900m300s900m300s900"
"m300s2100m300s900m300s2100m300s900m300s2100m300s900m300s2100m300s2100"
"m300s2100m300s2100m300s900m300s900m300s2100m300s2100m300s900m300s2100"
"m300s2100m300s2100m300s2100m300s900m300s2100m300s2100m300s2100m300s2100"
"m300s53580"
"m300s900m300s900m300s900m300s2100m300s900m300s900m300s2100m300s900"
"m300s900m300s900m300s2100m300s2100m300s900m300s2100m300s900m300s900"
"m300s900m300s2100m300s900m300s2100m300s900m300s2100m300s2100m300s900"
"m300s900m300s2100m300s2100m300s2100m300s2100m300s900m300s900m300s900"
"m300s2100m300s900m300s900m300s2100m300s900m300s900m300s900m300s900"
"m300s2100m300s900m300s2100m300s900m300s2100m300s900m300s2100m300s2100"
"m300s2100m300s2100m300s900m300s900m300s2100m300s2100m300s900m300s2100"
"m300s2100m300s2100m300s2100m300s900m300s2100m300s2100m300s2100m300s2100"
"m300s53580", irsend.outputStr());
}
// Decode normal Mitsubishi messages.
TEST(TestDecodeMitsubishi, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Mitsubishi 16-bit message.
irsend.reset();
irsend.sendMitsubishi(0xC2B8);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(MITSUBISHI_BITS, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendMitsubishi(0x0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(MITSUBISHI_BITS, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendMitsubishi(0xFFFF);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(MITSUBISHI_BITS, irsend.capture.bits);
EXPECT_EQ(0xFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Non-standard Mitsubishi sizes should fail with strict.
irsend.reset();
// 12 bits.
irsend.sendMitsubishi(0xFFF, 12);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 12, true));
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 64, true));
// 32 bits.
irsend.sendMitsubishi(0xFFF, 32);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 12, true));
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 32, true));
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 64, true));
}
// Decode normal repeated Mitsubishi messages.
TEST(TestDecodeMitsubishi, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Mitsubishi 16-bit message with 2 repeats.
irsend.reset();
irsend.sendMitsubishi(0xC2B8, MITSUBISHI_BITS, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(MITSUBISHI_BITS, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Normal Mitsubishi 16-bit message with 0 repeats.
irsend.reset();
irsend.sendMitsubishi(0xC2B8, MITSUBISHI_BITS, 0);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(MITSUBISHI_BITS, irsend.capture.bits);
EXPECT_EQ(0xC2B8, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode unsupported Mitsubishi messages.
TEST(TestDecodeMitsubishi, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendMitsubishi(0x0, 8); // Illegal sized Mitsubishi 8-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, 8, false));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 64, false));
irsend.reset();
// Illegal sized Mitsubishi 64-bit message.
irsend.sendMitsubishi(0xFEDCBA9876543210, 64);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture, 64, false));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFEDCBA9876543210, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
// Should fail when we are after a shorter message than we got.
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, 8, false));
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeMitsubishi, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Mitsubishi "Power On" (16-bit) code from Global Cache.
uint16_t gc_test[37] = {33000, 1, 1, 10, 70, 10, 70, 10, 70, 10, 30, 10, 30,
10, 30, 10, 70, 10, 30, 10, 30, 10, 70, 10, 30,
10, 30, 10, 30, 10, 30, 10, 70, 10, 30, 10, 936};
irsend.sendGC(gc_test, 37);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeMitsubishi(&irsend.capture));
EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
EXPECT_EQ(MITSUBISHI_BITS, irsend.capture.bits);
EXPECT_EQ(0xE242, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-Mitsubishi example via GlobalCache
TEST(TestDecodeMitsubishi, FailToDecodeNonMitsubishiExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20, 20, 20, 20,
20, 20, 20, 127, 20, 61, 9, 20, 20, 61, 20, 20, 20,
61, 20, 61, 20, 61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture));
ASSERT_FALSE(irrecv.decodeMitsubishi(&irsend.capture, MITSUBISHI_BITS,
false));
}
// Tests for Mitsubishi A/C methods.
// Test sending typical data only.
TEST(TestSendMitsubishiAC, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
uint8_t mitsub_code[MITSUBISHI_AC_STATE_LENGTH] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x06, 0x30,
0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F};
irsend.reset();
irsend.sendMitsubishiAC(mitsub_code);
EXPECT_EQ(
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m440s17100"
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m440s17100", irsend.outputStr());
}
// Test sending with repeats.
TEST(TestSendMitsubishiAC, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
uint8_t mitsub_code[MITSUBISHI_AC_STATE_LENGTH] = {
0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x06, 0x30,
0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F};
irsend.sendMitsubishiAC(mitsub_code, MITSUBISHI_AC_STATE_LENGTH, 0);
EXPECT_EQ(
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m440s17100", irsend.outputStr());
irsend.reset();
irsend.sendMitsubishiAC(mitsub_code, MITSUBISHI_AC_STATE_LENGTH, 2);
EXPECT_EQ(
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m440s17100"
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m440s17100"
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m440s17100", irsend.outputStr());
}
// Test sending atypical sizes.
TEST(TestSendMitsubishiAC, SendUnexpectedSizes) {
IRsendTest irsend(4);
irsend.begin();
uint8_t mitsub_short_code[17] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20,
0x08, 0x06, 0x30, 0x45, 0x67, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t mitsub_long_code[19] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20,
0x08, 0x06, 0x30, 0x45, 0x67, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,
0x00};
irsend.reset();
irsend.sendMitsubishiAC(mitsub_short_code, 17);
ASSERT_EQ("", irsend.outputStr());
irsend.reset();
irsend.sendMitsubishiAC(mitsub_long_code, 19);
ASSERT_EQ(
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m440s17100"
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s1300m450s1300m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s1300m450s420m450s420m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s1300m450s1300m450s1300m450s1300m450s1300m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m440s17100", irsend.outputStr());
}
// Tests for IRMitsubishiAC class.
TEST(TestMitsubishiACClass, Power) {
IRMitsubishiAC mitsub(0);
mitsub.begin();
mitsub.on();
EXPECT_TRUE(mitsub.getPower());
mitsub.off();
EXPECT_FALSE(mitsub.getPower());
mitsub.setPower(true);
EXPECT_TRUE(mitsub.getPower());
mitsub.setPower(false);
EXPECT_FALSE(mitsub.getPower());
}
TEST(TestMitsubishiACClass, Temperature) {
IRMitsubishiAC mitsub(0);
mitsub.begin();
mitsub.setTemp(0);
EXPECT_EQ(MITSUBISHI_AC_MIN_TEMP, mitsub.getTemp());
mitsub.setTemp(255);
EXPECT_EQ(MITSUBISHI_AC_MAX_TEMP, mitsub.getTemp());
mitsub.setTemp(MITSUBISHI_AC_MIN_TEMP);
EXPECT_EQ(MITSUBISHI_AC_MIN_TEMP, mitsub.getTemp());
mitsub.setTemp(MITSUBISHI_AC_MAX_TEMP);
EXPECT_EQ(MITSUBISHI_AC_MAX_TEMP, mitsub.getTemp());
mitsub.setTemp(MITSUBISHI_AC_MIN_TEMP - 1);
EXPECT_EQ(MITSUBISHI_AC_MIN_TEMP, mitsub.getTemp());
mitsub.setTemp(MITSUBISHI_AC_MAX_TEMP + 1);
EXPECT_EQ(MITSUBISHI_AC_MAX_TEMP, mitsub.getTemp());
mitsub.setTemp(17);
EXPECT_EQ(17, mitsub.getTemp());
mitsub.setTemp(21);
EXPECT_EQ(21, mitsub.getTemp());
mitsub.setTemp(25);
EXPECT_EQ(25, mitsub.getTemp());
mitsub.setTemp(30);
EXPECT_EQ(30, mitsub.getTemp());
}
TEST(TestMitsubishiACClass, OperatingMode) {
IRMitsubishiAC mitsub(0);
mitsub.begin();
mitsub.setMode(MITSUBISHI_AC_AUTO);
EXPECT_EQ(MITSUBISHI_AC_AUTO, mitsub.getMode());
mitsub.setMode(MITSUBISHI_AC_COOL);
EXPECT_EQ(MITSUBISHI_AC_COOL, mitsub.getMode());
mitsub.setMode(MITSUBISHI_AC_HEAT);
EXPECT_EQ(MITSUBISHI_AC_HEAT, mitsub.getMode());
mitsub.setMode(MITSUBISHI_AC_DRY);
EXPECT_EQ(MITSUBISHI_AC_DRY, mitsub.getMode());
mitsub.setMode(MITSUBISHI_AC_AUTO + 1);
EXPECT_EQ(MITSUBISHI_AC_AUTO, mitsub.getMode());
mitsub.setMode(255);
EXPECT_EQ(MITSUBISHI_AC_AUTO, mitsub.getMode());
}
TEST(TestMitsubishiACClass, VaneMode) {
IRMitsubishiAC mitsub(0);
mitsub.begin();
mitsub.setVane(MITSUBISHI_AC_VANE_AUTO);
EXPECT_EQ(MITSUBISHI_AC_VANE_AUTO, mitsub.getVane());
mitsub.setVane(MITSUBISHI_AC_VANE_AUTO + 1);
EXPECT_EQ(MITSUBISHI_AC_VANE_AUTO + 1, mitsub.getVane());
mitsub.setVane(MITSUBISHI_AC_VANE_AUTO_MOVE);
EXPECT_EQ(MITSUBISHI_AC_VANE_AUTO_MOVE, mitsub.getVane());
mitsub.setVane(MITSUBISHI_AC_VANE_AUTO_MOVE + 1);
EXPECT_EQ(MITSUBISHI_AC_VANE_AUTO_MOVE, mitsub.getVane());
mitsub.setVane(MITSUBISHI_AC_VANE_AUTO_MOVE - 1);
EXPECT_EQ(MITSUBISHI_AC_VANE_AUTO_MOVE - 1, mitsub.getVane());
}
TEST(TestMitsubishiACClass, FanSpeed) {
IRMitsubishiAC mitsub(0);
mitsub.begin();
mitsub.setFan(MITSUBISHI_AC_FAN_AUTO);
EXPECT_EQ(MITSUBISHI_AC_FAN_AUTO, mitsub.getFan());
mitsub.setFan(255);
EXPECT_EQ(MITSUBISHI_AC_FAN_REAL_MAX, mitsub.getFan());
mitsub.setFan(MITSUBISHI_AC_FAN_MAX);
EXPECT_EQ(MITSUBISHI_AC_FAN_REAL_MAX, mitsub.getFan());
mitsub.setFan(MITSUBISHI_AC_FAN_MAX - 1);
EXPECT_EQ(MITSUBISHI_AC_FAN_MAX - 1, mitsub.getFan());
mitsub.setFan(1);
EXPECT_EQ(1, mitsub.getFan());
mitsub.setFan(2);
EXPECT_EQ(2, mitsub.getFan());
mitsub.setFan(3);
EXPECT_EQ(3, mitsub.getFan());
mitsub.setFan(4);
EXPECT_EQ(4, mitsub.getFan());
mitsub.setFan(MITSUBISHI_AC_FAN_SILENT);
EXPECT_EQ(MITSUBISHI_AC_FAN_SILENT, mitsub.getFan());
mitsub.setFan(MITSUBISHI_AC_FAN_SILENT + 1);
EXPECT_EQ(MITSUBISHI_AC_FAN_REAL_MAX, mitsub.getFan());
}
TEST(TestMitsubishiACClass, MessageConstuction) {
IRMitsubishiAC mitsub(0);
IRsendTest irsend(4);
mitsub.begin();
irsend.begin();
mitsub.setFan(1);
mitsub.setMode(MITSUBISHI_AC_COOL);
mitsub.setTemp(27);
mitsub.setVane(3);
mitsub.on();
// Check everything for kicks.
EXPECT_EQ(1, mitsub.getFan());
EXPECT_EQ(MITSUBISHI_AC_COOL, mitsub.getMode());
EXPECT_EQ(27, mitsub.getTemp());
EXPECT_EQ(3, mitsub.getVane());
EXPECT_TRUE(mitsub.getPower());
irsend.reset();
irsend.sendMitsubishiAC(mitsub.getRaw());
EXPECT_EQ(
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s1300m450s1300m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s1300m450s420"
"m440s17100"
"m3400s1750"
"m450s1300m450s1300m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s1300m450s1300"
"m450s420m450s1300m450s1300m450s420m450s420m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s1300m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420m450s420"
"m450s1300m450s1300m450s420m450s1300m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s1300m450s1300m450s420m450s420"
"m450s1300m450s420m450s420m450s1300m450s1300m450s420m450s1300m450s420"
"m450s1300m450s1300m450s1300m450s420m450s420m450s1300m450s1300m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420"
"m450s420m450s420m450s420m450s1300m450s420m450s420m450s1300m450s420"
"m440s17100", irsend.outputStr());
}

View File

@ -1,210 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendNikai().
// Test sending typical data only.
TEST(TestSendNikai, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendNikai(0xD5F2A); // Nikai TV Power Off.
EXPECT_EQ("m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500",
irsend.outputStr());
irsend.reset();
}
// Test sending with different repeats.
TEST(TestSendNikai, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendNikai(0xD5F2A, NIKAI_BITS, 1); // 1 repeat.
EXPECT_EQ("m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500",
irsend.outputStr());
irsend.sendNikai(0xD5F2A, NIKAI_BITS, 2); // 2 repeat.
EXPECT_EQ("m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500"
"m4000s4000"
"m500s2000m500s2000m500s2000m500s2000m500s1000m500s1000m500s2000"
"m500s1000m500s2000m500s1000m500s2000m500s1000m500s1000m500s1000"
"m500s1000m500s1000m500s2000m500s2000m500s1000m500s2000m500s1000"
"m500s2000m500s1000m500s2000m500s8500",
irsend.outputStr());
}
// Tests for decodeNikai().
// Decode normal Nikai messages.
TEST(TestDecodeNikai, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Nikai 24-bit message.
irsend.reset();
irsend.sendNikai(0x123456);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, true));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(NIKAI_BITS, irsend.capture.bits);
EXPECT_EQ(0x123456, irsend.capture.value);
irsend.reset();
irsend.sendNikai(0x101);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, true));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(NIKAI_BITS, irsend.capture.bits);
EXPECT_EQ(0x101, irsend.capture.value);
}
// Decode normal repeated Nikai messages.
TEST(TestDecodeNikai, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Nikai 24-bit message.
irsend.reset();
irsend.sendNikai(0xD5F2A, NIKAI_BITS, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, true));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(NIKAI_BITS, irsend.capture.bits);
EXPECT_EQ(0xD5F2A, irsend.capture.value);
}
TEST(TestDecodeNikai, NormalDecodeWithNonStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Illegal under length (16-bit) message
irsend.reset();
irsend.sendNikai(0x0, 16);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, true));
// And it should fail when we expect more bits.
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, false));
// Should pass if strict off if we ask for correct nr. of bits sent.
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, 16, false));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(16, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
// Should fail as we are expecting less bits than there are.
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, 12, false));
}
// Decode (non-standard) 64-bit messages.
// Decode unsupported Nikai messages.
TEST(TestDecodeNikai, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal size Nikai 64-bit message.
irsend.sendNikai(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeNikai(&irsend.capture, 64, false));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
}
// Decode real example via Issue #309
TEST(TestDecodeNikai, DecodeExamples) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Nikai TV Power Off from Issue #309
uint16_t rawdata_off[100] = {4060, 3918,
508, 2004, 508, 2002, 510, 2002, 508, 2004, 506, 1050, 508, 1048,
510, 2004, 508, 1048, 508, 2002, 510, 1050, 508, 2004, 510, 1048,
508, 1050, 508, 1048, 508, 1050, 508, 1050, 508, 2004, 508, 2002,
510, 1048, 508, 2004, 508, 1050, 506, 2004, 508, 1048, 510, 2002,
456, 8446,
3956, 3998,
508, 2004, 508, 2002, 508, 2004, 508, 1978, 532, 1050, 508, 1050,
508, 2002, 508, 1050, 508, 2004, 508, 1050, 508, 2002, 510, 1050,
508, 1050, 508, 1048, 508, 1050, 508, 1050, 508, 2002, 510, 2002,
508, 1050, 508, 2002, 510, 1050, 508, 2002, 508};
irsend.sendRaw(rawdata_off, 100, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(NIKAI_BITS, irsend.capture.bits);
EXPECT_EQ(0xD5F2A, irsend.capture.value);
// Nikai TV Volume Up from Issue #309
uint16_t rawdata_volup[52] = {3972, 4002,
504, 1982, 526, 2010, 502, 2010, 502, 2010, 500, 1056, 502, 1056,
502, 2010, 500, 1056, 502, 2010, 502, 2010, 500, 2010, 502, 2010,
502, 1056, 502, 1056, 502, 1056, 500, 1056, 502, 2010, 502, 2010,
500, 1056, 502, 2008, 502, 1054, 504, 1054, 504, 1054, 500, 1056,
450};
irsend.reset();
irsend.sendRaw(rawdata_volup, 52, 38);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(NIKAI, irsend.capture.decode_type);
EXPECT_EQ(NIKAI_BITS, irsend.capture.bits);
EXPECT_EQ(0xD0F2F, irsend.capture.value);
}
// Fail to decode a non-Nikai example via GlobalCache
TEST(TestDecodeNikai, FailToDecodeNonNikaiExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t gc_test[71] = {38000, 1, 1, 172, 172, 22, 64, 22, 64, 22, 64, 22, 21,
22, 21, 22, 21, 22, 11, 22, 21, 22, 128, 22, 64, 22,
64, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 64,
22, 21, 22, 21, 22, 64, 22, 64, 22, 21, 22, 21, 22,
64, 22, 21, 22, 64, 22, 64, 22, 21, 22, 21, 22, 64,
22, 64, 22, 21, 22, 1820};
irsend.sendGC(gc_test, 71);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture));
ASSERT_FALSE(irrecv.decodeNikai(&irsend.capture, NIKAI_BITS, false));
}

View File

@ -1,457 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for encodePanasonic().
TEST(TestEncodePanasonic, General) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodePanasonic(0, 0, 0, 0));
EXPECT_EQ(0x101010101, irsend.encodePanasonic(1, 1, 1, 1));
EXPECT_EQ(0xFFFF, irsend.encodePanasonic(0, 0, 0, 0xFF));
EXPECT_EQ(0xFF00FF, irsend.encodePanasonic(0, 0, 0xFF, 0));
EXPECT_EQ(0xFF0000FF, irsend.encodePanasonic(0, 0xFF, 0, 0));
EXPECT_EQ(0xFFFF00000000, irsend.encodePanasonic(0xFFFF, 0, 0, 0));
EXPECT_EQ(0xFFFFFFFFFFFF, irsend.encodePanasonic(0xFFFF, 0xFF, 0xFF, 0xFF));
EXPECT_EQ(0x40040190ED7C, irsend.encodePanasonic(0x4004, 0x01, 0x90, 0xED));
}
// Tests for sendPanasonic64().
// Test sending typical data only.
TEST(TestSendPanasonic64, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendPanasonic64(0x0);
EXPECT_EQ(
"m3456s1728"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s129600", irsend.outputStr());
irsend.reset();
irsend.sendPanasonic64(0x40040190ED7C);
EXPECT_EQ(
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600", irsend.outputStr());
irsend.reset();
irsend.sendPanasonic64(0xFFFFFFFFFFFF);
EXPECT_EQ(
"m3456s1728"
"m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296"
"m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296"
"m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296"
"m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296"
"m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296"
"m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296m432s1296"
"m432s129600", irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendPanasonic64, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendPanasonic64(0x40040190ED7C, PANASONIC_BITS, 0); // 0 repeats.
EXPECT_EQ(
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600", irsend.outputStr());
irsend.reset();
irsend.sendPanasonic64(0x40040190ED7C, PANASONIC_BITS, 1); // 1 repeat.
EXPECT_EQ(
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600"
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600", irsend.outputStr());
irsend.sendPanasonic64(0x40040190ED7C, PANASONIC_BITS, 2); // 2 repeats.
EXPECT_EQ(
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600"
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600"
"m3456s1728"
"m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s432m432s1296"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432"
"m432s129600", irsend.outputStr());
}
// Test sending an atypical data size.
TEST(TestSendPanasonic64, SendUnusualSize) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendPanasonic64(0x0, 8);
EXPECT_EQ(
"m3456s1728"
"m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432"
"m432s129600", irsend.outputStr());
irsend.reset();
irsend.sendPanasonic64(0x1234567890ABCDEF, 64);
EXPECT_EQ(
"m3456s1728"
"m432s432m432s432m432s432m432s1296m432s432m432s432m432s1296m432s432"
"m432s432m432s432m432s1296m432s1296m432s432m432s1296m432s432m432s432"
"m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s1296m432s432"
"m432s432m432s1296m432s1296m432s1296m432s1296m432s432m432s432m432s432"
"m432s1296m432s432m432s432m432s1296m432s432m432s432m432s432m432s432"
"m432s1296m432s432m432s1296m432s432m432s1296m432s432m432s1296m432s1296"
"m432s1296m432s1296m432s432m432s432m432s1296m432s1296m432s432m432s1296"
"m432s1296m432s1296m432s1296m432s432m432s1296m432s1296m432s1296m432s1296"
"m432s129600", irsend.outputStr());
}
// Tests for sendPanasonic().
TEST(TestSendPanasonic, CompareToSendPanasonic64) {
IRsendTest panasonic(4);
IRsendTest panasonic64(0);
panasonic.begin();
panasonic64.begin();
panasonic.reset();
panasonic64.reset();
panasonic.sendPanasonic(0x4004, 0x0190ED7C);
panasonic64.sendPanasonic64(0x40040190ED7C);
EXPECT_EQ(panasonic64.outputStr(), panasonic.outputStr());
panasonic.sendPanasonic(0x0, 0x0);
panasonic64.sendPanasonic64(0x0);
EXPECT_EQ(panasonic64.outputStr(), panasonic.outputStr());
panasonic.sendPanasonic(0x0, 0x0, 8);
panasonic64.sendPanasonic64(0x0, 8);
EXPECT_EQ(panasonic64.outputStr(), panasonic.outputStr());
panasonic.sendPanasonic(0x1234, 0x567890AB, 64);
panasonic64.sendPanasonic64(0x1234567890AB, 64);
EXPECT_EQ(panasonic64.outputStr(), panasonic.outputStr());
panasonic.sendPanasonic(0x1234, 0x567890AB, PANASONIC_BITS, 2);
panasonic64.sendPanasonic64(0x1234567890AB, PANASONIC_BITS, 2);
EXPECT_EQ(panasonic64.outputStr(), panasonic.outputStr());
}
// Tests for decodePanasonic().
// Decode normal Panasonic messages.
TEST(TestDecodePanasonic, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Panasonic 48-bit message.
irsend.reset();
irsend.sendPanasonic64(0x40040190ED7C);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x0190ED7C, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal Panasonic 48-bit message.
irsend.reset();
irsend.sendPanasonic64(irsend.encodePanasonic(0x4004, 0x12, 0x34, 0x56));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x400412345670, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x12345670, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
// Synthesised Normal Panasonic 48-bit message.
irsend.reset();
irsend.sendPanasonic64(irsend.encodePanasonic(0x4004, 0x1, 0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x400401010101, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x1010101, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Decode normal repeated Panasonic messages.
TEST(TestDecodePanasonic, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Panasonic 48-bit message with 2 repeats.
irsend.reset();
irsend.sendPanasonic64(0x40040190ED7C, PANASONIC_BITS, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x190ED7C, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.makeDecodeResult(2 * PANASONIC_BITS + 4);
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
irsend.makeDecodeResult(2 * (2 * PANASONIC_BITS + 4));
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
}
// Decode Panasonic messages with unsupported values.
TEST(TestDecodePanasonic, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendPanasonic64(0x0); // Illegal value Panasonic 48-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, false));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
// Illegal address/Manufacturer code. The rest is legal.
irsend.sendPanasonic64(irsend.encodePanasonic(0, 1, 2, 3));
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, false));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x1020300, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x1020300, irsend.capture.command);
}
// Decode Panasonic messages with unsupported size/lengths.
TEST(TestDecodePanasonic, DecodeWithNonStrictSize) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendPanasonic64(0x12345678, 32); // Illegal size Panasonic message.
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
irsend.makeDecodeResult();
// Should fail with strict when we ask for the wrong bit size.
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, 32, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, 32, false));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(32, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x12345678, irsend.capture.command);
// Illegal over length (56-bit) message.
irsend.reset();
irsend.sendPanasonic64(irsend.encodePanasonic(0x4004, 1, 2, 3), 56);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
// Shouldn't pass if strict off and wrong bit size.
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, false));
// Re-decode with correct bit size.
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, 56, true));
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, 56, false));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(56, irsend.capture.bits);
EXPECT_EQ(0x400401020300, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x01020300, irsend.capture.command);
}
// Decode (non-standard) 64-bit messages.
TEST(TestDecodePanasonic, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size Panasonic 64-bit message.
irsend.sendPanasonic64(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, 64, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, 64, false));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0xFFFFFFFF, irsend.capture.address);
EXPECT_EQ(0xFFFFFFFF, irsend.capture.command);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodePanasonic, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Panasonic code from Global Cache.
uint16_t gc_test[103] = {37000, 1, 1, 126, 64, 16, 17, 16, 49, 15, 16, 16, 16,
16, 16, 16, 17, 15, 17, 15, 17, 15, 17, 15, 16, 16,
16, 16, 16, 16, 17, 15, 49, 16, 16, 16, 16, 16, 17,
15, 17, 15, 17, 15, 17, 15, 16, 16, 16, 16, 16, 16,
49, 15, 49, 16, 17, 15, 17, 15, 49, 16, 16, 16, 17,
16, 17, 15, 17, 15, 49, 16, 49, 15, 49, 16, 17, 16,
49, 15, 49, 16, 17, 15, 48, 16, 16, 16, 49, 15, 48,
16, 49, 15, 49, 16, 49, 15, 17, 15, 16, 16, 2721};
irsend.sendGC(gc_test, 103);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, true));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x0190ED7C, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x0190ED7C, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}
// Fail to decode a non-Panasonic example via GlobalCache
TEST(TestDecodePanasonic, FailToDecodeNonPanasonicExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[39] = {38000, 1, 1, 322, 162, 20, 61, 20, 61, 20, 20, 20, 20,
20, 20, 20, 127, 20, 61, 9, 20, 20, 61, 20, 20, 20,
61, 20, 61, 20, 61, 20, 20, 20, 20, 20, 20, 20, 884};
irsend.sendGC(gc_test, 39);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture));
ASSERT_FALSE(irrecv.decodePanasonic(&irsend.capture, PANASONIC_BITS, false));
}
// Failing to decode Panasonic in Issue #245
TEST(TestDecodePanasonic, DecodeIssue245) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
uint16_t rawData[100] = {3550, 1750, 500, 450, 500, 1300, 500, 450, 500, 450,
500, 450, 500, 450, 500, 450, 500, 450, 500, 450,
500, 450, 500, 450, 500, 450, 500, 450, 500, 1300,
500, 450, 500, 450, 500, 450, 500, 450, 500, 450,
500, 450, 500, 450, 500, 450, 500, 450, 500, 1300,
500, 450, 500, 450, 500, 450, 500, 450, 500, 450,
500, 450, 500, 450, 500, 450, 500, 1300, 500, 450,
500, 1300, 500, 1300, 500, 1300, 500, 1300, 500, 450,
500, 450, 500, 1300, 500, 450, 500, 1300, 500, 1300,
500, 1300, 500, 1300, 500, 450, 500, 1300, 500, 5000};
irsend.sendRaw(rawData, 100, 37);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodePanasonic(&irsend.capture));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040100BCBD, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x100BCBD, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
irsend.reset();
irsend.sendRaw(rawData, 99, 37);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
EXPECT_EQ(PANASONIC_BITS, irsend.capture.bits);
EXPECT_EQ(0x40040100BCBD, irsend.capture.value);
EXPECT_EQ(0x4004, irsend.capture.address);
EXPECT_EQ(0x100BCBD, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
}

View File

@ -1,276 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendSAMSUNG().
// Test sending typical data only.
TEST(TestSendSamsung, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSAMSUNG(0xE0E09966); // Samsung TV Power On.
EXPECT_EQ("m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s560m560s560m560s1680m560s1680"
"m560s560m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s560m560s108080",
irsend.outputStr());
irsend.reset();
}
// Test sending with different repeats.
TEST(TestSendSamsung, SendWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSAMSUNG(0xE0E09966, SAMSUNG_BITS, 1); // 1 repeat.
EXPECT_EQ("m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s560m560s560m560s1680m560s1680"
"m560s560m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s560m560s108080"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s560m560s560m560s1680m560s1680"
"m560s560m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s560m560s108080"
, irsend.outputStr());
irsend.sendSAMSUNG(0xE0E09966, SAMSUNG_BITS, 2); // 2 repeats.
EXPECT_EQ("m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s560m560s560m560s1680m560s1680"
"m560s560m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s560m560s108080"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s560m560s560m560s1680m560s1680"
"m560s560m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s560m560s108080"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s1680m560s560m560s560m560s560"
"m560s560m560s560m560s1680m560s560m560s560m560s1680m560s1680"
"m560s560m560s560m560s1680m560s560m560s1680m560s1680m560s560"
"m560s560m560s1680m560s1680m560s560m560s108080"
, irsend.outputStr());
}
// Tests for encodeSAMSUNG().
TEST(TestEncodeSamsung, NormalEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0xFF, irsend.encodeSAMSUNG(0, 0));
EXPECT_EQ(0x8080807F, irsend.encodeSAMSUNG(1, 1));
EXPECT_EQ(0xF8F805FA, irsend.encodeSAMSUNG(0x1F, 0xA0));
EXPECT_EQ(0xA0A0CC33, irsend.encodeSAMSUNG(0x05, 0x33));
EXPECT_EQ(0xFFFFFF00, irsend.encodeSAMSUNG(0xFF, 0xFF));
EXPECT_EQ(0xE0E09966, irsend.encodeSAMSUNG(0x07, 0x99));
}
// Tests for decodeSAMSUNG().
// Decode normal Samsung messages.
TEST(TestDecodeSamsung, NormalDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Samsung 32-bit message.
irsend.reset();
irsend.sendSAMSUNG(0xE0E09966);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0xE0E09966, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
// Synthesised Normal Samsung 32-bit message.
irsend.reset();
irsend.sendSAMSUNG(irsend.encodeSAMSUNG(0x07, 0x99));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0xE0E09966, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
// Synthesised Normal Samsung 32-bit message.
irsend.reset();
irsend.sendSAMSUNG(irsend.encodeSAMSUNG(0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0x8080807F, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x1, irsend.capture.command);
}
// Decode normal repeated Samsung messages.
TEST(TestDecodeSamsung, NormalDecodeWithRepeatAndStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Normal Samsung 32-bit message.
irsend.reset();
irsend.sendSAMSUNG(0xE0E09966, SAMSUNG_BITS, 2);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0xE0E09966, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
}
// Decode unsupported Samsung messages.
TEST(TestDecodeSamsung, DecodeWithNonStrictValues) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendSAMSUNG(0x0); // Illegal value Samsung 32-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, false));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0x0, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSAMSUNG(0x12345678); // Illegal value Samsung 32-bit message.
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
// Should pass if strict off.
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, false));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0x12345678, irsend.capture.value);
EXPECT_EQ(0x48, irsend.capture.address);
EXPECT_EQ(0x6A, irsend.capture.command);
// Illegal over length (36-bit) message.
irsend.reset();
irsend.sendSAMSUNG(irsend.encodeSAMSUNG(0, 0), 36);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
// Shouldn't pass if strict off and wrong expected bit size.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, false));
// Re-decode with correct bit size.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, 36, true));
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, 36, false));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(36, irsend.capture.bits);
EXPECT_EQ(0xFF, irsend.capture.value); // We told it to expect 8 bits less.
EXPECT_EQ(0x00, irsend.capture.address);
EXPECT_EQ(0x00, irsend.capture.command);
// Illegal under length (16-bit) message
irsend.reset();
irsend.sendSAMSUNG(irsend.encodeSAMSUNG(0x0, 0x0), 16);
irsend.makeDecodeResult();
// Should fail with strict on.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
// And it should fail when we expect more bits.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, false));
// Should pass if strict off if we ask for correct nr. of bits sent.
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, 16, false));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(16, irsend.capture.bits);
EXPECT_EQ(0xFF, irsend.capture.value); // We told it to expect 4 bits less.
EXPECT_EQ(0x00, irsend.capture.address);
EXPECT_EQ(0x00, irsend.capture.command);
// Should fail as we are expecting less bits than there are.
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, 12, false));
}
// Decode (non-standard) 64-bit messages.
// Decode unsupported Samsung messages.
TEST(TestDecodeSamsung, Decode64BitMessages) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Illegal value & size Samsung 64-bit message.
irsend.sendSAMSUNG(0xFFFFFFFFFFFFFFFF, 64);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture, 64, false));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0xFF, irsend.capture.address);
EXPECT_EQ(0xFF, irsend.capture.command);
}
// Decode a 'real' example via GlobalCache
TEST(TestDecodeSamsung, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Samsung TV Power On from Global Cache.
uint16_t gc_test[71] = {38000, 1, 1, 172, 172, 22, 64, 22, 64, 22, 64, 22, 21,
22, 21, 22, 21, 22, 21, 22, 21, 22, 64, 22, 64, 22,
64, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 64,
22, 21, 22, 21, 22, 64, 22, 64, 22, 21, 22, 21, 22,
64, 22, 21, 22, 64, 22, 64, 22, 21, 22, 21, 22, 64,
22, 64, 22, 21, 22, 1820};
irsend.sendGC(gc_test, 71);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSAMSUNG(&irsend.capture));
EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
EXPECT_EQ(SAMSUNG_BITS, irsend.capture.bits);
EXPECT_EQ(0xE0E09966, irsend.capture.value);
EXPECT_EQ(0x07, irsend.capture.address);
EXPECT_EQ(0x99, irsend.capture.command);
}
// Fail to decode a non-Samsung example via GlobalCache
TEST(TestDecodeSamsung, FailToDecodeNonSamsungExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Modified a few entries to unexpected values, based on previous test case.
uint16_t gc_test[71] = {38000, 1, 1, 172, 172, 22, 64, 22, 64, 22, 64, 22, 21,
22, 21, 22, 21, 22, 11, 22, 21, 22, 128, 22, 64, 22,
64, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 64,
22, 21, 22, 21, 22, 64, 22, 64, 22, 21, 22, 21, 22,
64, 22, 21, 22, 64, 22, 64, 22, 21, 22, 21, 22, 64,
22, 64, 22, 21, 22, 1820};
irsend.sendGC(gc_test, 71);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture));
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, SAMSUNG_BITS, false));
}

View File

@ -1,72 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendSherwood().
// Test sending typical data only.
TEST(TestSendSherwood, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877);
EXPECT_EQ("m8960s4480m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s1680m560s1680m560s108080"
"m8960s2240m560s108080", irsend.outputStr());
}
// Test sending typical data with extra repeats.
TEST(TestSendSherwood, SendDataWithRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877, 32, 2);
EXPECT_EQ("m8960s4480m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s1680m560s1680m560s108080"
"m8960s2240m560s108080"
"m8960s2240m560s108080", irsend.outputStr());
}
// Test sending typical data with explicit no repeats.
TEST(TestSendSherwood, SendDataWithZeroRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877, 32, 0);
// Should have a single NEC repeat, as we always send one.
EXPECT_EQ("m8960s4480m560s1680m560s1680m560s560m560s560m560s560m560s560"
"m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s560m560s560"
"m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680"
"m560s1680m560s560m560s1680m560s1680m560s1680m560s108080"
"m8960s2240m560s108080", irsend.outputStr());
}
// Test that a typical Sherwood send decodes as the appropriate NEC value.
TEST(TestSendSherwood, DecodesAsNEC) {
IRsendTest irsend(4);
IRrecv irrecv(0);
irsend.begin();
irsend.reset();
irsend.sendSherwood(0xC1A28877);
irsend.makeDecodeResult();
EXPECT_TRUE(irrecv.decodeNEC(&irsend.capture));
EXPECT_EQ(NEC, irsend.capture.decode_type);
EXPECT_EQ(NEC_BITS, irsend.capture.bits);
EXPECT_EQ(0xC1A28877, irsend.capture.value);
EXPECT_EQ(0x4583, irsend.capture.address);
EXPECT_EQ(0x11, irsend.capture.command);
}

View File

@ -1,323 +0,0 @@
// Copyright 2017 David Conran
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
// Tests for sendSony().
// Test sending typical data only.
TEST(TestSendSony, SendDataOnly) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSony(0);
// We expect three 20-bit commands to be sent.
EXPECT_EQ("m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m600s600m600s600m600s600m600s45600", irsend.outputStr());
irsend.reset();
irsend.sendSony(0x240C, SONY_20_BITS);
// We expect three 20-bit commands to be sent.
EXPECT_EQ("m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600", irsend.outputStr());
irsend.reset();
irsend.sendSony(0x240C, SONY_15_BITS);
// We expect three 15-bit commands to be sent.
EXPECT_EQ("m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s45600"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s45600"
"m2400s600m600s600m1200s600m600s600m600s600m1200s600m600s600"
"m600s600m600s600m600s600m600s600m600s600m1200s600m1200s600m600s600"
"m600s45600", irsend.outputStr());
irsend.reset();
irsend.sendSony(0xA90, SONY_12_BITS);
// We expect three 15-bit commands to be sent.
EXPECT_EQ("m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s45600"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s45600"
"m2400s600m1200s600m600s600m1200s600m600s600m1200s600m600s600"
"m600s600m1200s600m600s600m600s600m600s600m600s45600",
irsend.outputStr());
}
// Test sending with different repeats.
TEST(TestSendSony, SendWithDiffRepeats) {
IRsendTest irsend(4);
irsend.begin();
irsend.reset();
irsend.sendSony(0x240C, SONY_20_BITS, 0); // Send a command with 0 repeats.
EXPECT_EQ("m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600", irsend.outputStr());
irsend.sendSony(0x240C, SONY_20_BITS, 1); // Send a command with 1 repeat.
EXPECT_EQ("m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600", irsend.outputStr());
irsend.sendSony(0x240C, SONY_20_BITS, 3); // Send a command with 3 repeats.
EXPECT_EQ("m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600"
"m2400s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600"
"m600s600m600s600m1200s600m600s600m600s600m600s600m600s600m600s600"
"m600s600m1200s600m1200s600m600s600m600s45600", irsend.outputStr());
}
// Tests for encodeSony().
TEST(TestEncodeSony, NormalSonyEncoding) {
IRsendTest irsend(4);
EXPECT_EQ(0x0, irsend.encodeSony(SONY_12_BITS, 0, 0));
EXPECT_EQ(0xA90, irsend.encodeSony(SONY_12_BITS, 21, 1));
EXPECT_EQ(0xFFF, irsend.encodeSony(SONY_12_BITS, 0x7F, 0x1F));
EXPECT_EQ(0x0, irsend.encodeSony(SONY_15_BITS, 0, 0));
EXPECT_EQ(0x5480, irsend.encodeSony(SONY_15_BITS, 21, 1));
EXPECT_EQ(0x5455, irsend.encodeSony(SONY_15_BITS, 21, 0xAA));
EXPECT_EQ(0x7FFF, irsend.encodeSony(SONY_15_BITS, 0x7F, 0xFF));
EXPECT_EQ(0x0, irsend.encodeSony(SONY_20_BITS, 0, 0, 0));
EXPECT_EQ(0x81080, irsend.encodeSony(SONY_20_BITS, 1, 1, 1));
EXPECT_EQ(0xFFFFF, irsend.encodeSony(SONY_20_BITS, 0x7F, 0x1F, 0xFF));
}
TEST(TestEncodeSony, SonyEncodingWithOversizedValues) {
IRsendTest irsend(4);
EXPECT_EQ(0xFFF, irsend.encodeSony(SONY_12_BITS, 0xFFFF, 0xFFFF));
EXPECT_EQ(0x7FFF, irsend.encodeSony(SONY_15_BITS, 0xFFFF, 0xFFFF));
EXPECT_EQ(0xFFFFF, irsend.encodeSony(SONY_20_BITS, 0xFFFF, 0xFFFF, 0xFFFF));
}
// Tests for decodeSony().
// Decode normal Sony messages.
TEST(TestDecodeSony, NormalSonyDecodeWithStrict) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Synthesised Normal Sony 20-bit message.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_20_BITS, 0x1, 0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(SONY_20_BITS, irsend.capture.bits);
EXPECT_EQ(0x81080, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x81, irsend.capture.command);
// Synthesised Normal Sony 15-bit message.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_15_BITS, 21, 1), SONY_15_BITS);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(SONY_15_BITS, irsend.capture.bits);
EXPECT_EQ(0x5480, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(21, irsend.capture.command);
// Synthesised Normal Sony 12-bit message.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_12_BITS, 21, 1), SONY_12_BITS);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(SONY_12_BITS, irsend.capture.bits);
EXPECT_EQ(0xA90, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(21, irsend.capture.command);
}
// Decode unexpected Sony messages. i.e longer than minimum etc.
TEST(TestDecodeSony, SonyDecodeWithUnexpectedLegalSize) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
// Synthesised Normal Sony 20-bit message decoded when looking for 12-bits
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_20_BITS, 0x1, 0x1, 0x1));
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, SONY_MIN_BITS));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(SONY_20_BITS, irsend.capture.bits);
EXPECT_EQ(0x81080, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x81, irsend.capture.command);
// Synthesised Normal Sony 12-bit message when expecting 20-bits.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_12_BITS, 21, 1), SONY_12_BITS);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(SONY_12_BITS, irsend.capture.bits);
EXPECT_EQ(0xA90, irsend.capture.value);
EXPECT_EQ(1, irsend.capture.address);
EXPECT_EQ(21, irsend.capture.command);
// 12-bit message should be regected when using strict and a different size.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_12_BITS, 21, 1), SONY_12_BITS);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
// 15-bit message should be regected when using strict and a different size.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_15_BITS, 21, 1), SONY_15_BITS);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
// 20-bit message should be regected when using strict and a different size.
irsend.reset();
irsend.sendSony(irsend.encodeSony(SONY_20_BITS, 1, 1, 1), SONY_20_BITS);
irsend.makeDecodeResult();
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
ASSERT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
}
// Decode unsupported Sony messages. i.e non-standard sizes.
TEST(TestDecodeSony, SonyDecodeWithIllegalSize) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendSony(0xFF, 8); // Illegal 8-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_MIN_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(8, irsend.capture.bits);
EXPECT_EQ(0xFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSony(0x1FFF, 13); // Illegal 13-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_MIN_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(13, irsend.capture.bits);
EXPECT_EQ(0x1FFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSony(0x1FFFF, 17); // Illegal 17-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_MIN_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(17, irsend.capture.bits);
EXPECT_EQ(0x1FFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
irsend.sendSony(0x1FFFFF, 21); // Illegal 21-bit Sony-like message.
irsend.makeDecodeResult();
// Should fail with strict on.
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_MIN_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_15_BITS, true));
EXPECT_FALSE(irrecv.decodeSony(&irsend.capture, SONY_20_BITS, true));
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(21, irsend.capture.bits);
EXPECT_EQ(0x1FFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
irsend.reset();
// Illegal 64-bit (max) Sony-like message.
irsend.sendSony(0xFFFFFFFFFFFFFFFF, 64, 0);
irsend.makeDecodeResult();
// Should work with a 'normal' match (not strict)
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(64, irsend.capture.bits);
EXPECT_EQ(0xFFFFFFFFFFFFFFFF, irsend.capture.value);
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
// Decode unsupported Sony messages. i.e non-standard sizes.
TEST(TestDecodeSony, DecodeGlobalCacheExample) {
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
// Sony "Power On" from Global Cache.
uint16_t gc_test[29] = {40000, 1, 1, 96, 24, 24, 24, 48, 24, 48, 24, 48, 24,
24, 24, 48, 24, 24, 24, 48, 24, 24, 24, 24, 24, 24,
24, 24, 1013};
irsend.sendGC(gc_test, 29);
irsend.makeDecodeResult();
// Without strict.
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture));
EXPECT_EQ(SONY, irsend.capture.decode_type);
EXPECT_EQ(12, irsend.capture.bits);
EXPECT_EQ(0x750, irsend.capture.value);
EXPECT_EQ(0x1, irsend.capture.address);
EXPECT_EQ(0x2E, irsend.capture.command);
// With strict and correct size.
ASSERT_TRUE(irrecv.decodeSony(&irsend.capture, SONY_12_BITS, true));
}

View File

@ -1,106 +0,0 @@
// Quick and dirty tool to decode GlobalCache (GC) codes
// Copyright 2017 Jorge Cisneros
#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <string>
#include "IRsend.h"
#include "IRsend_test.h"
#define MAX_GC_CODE_LENGHT 512
void str_to_uint16(char *str, uint16_t *res) {
char *end;
errno = 0;
intmax_t val = strtoimax(str, &end, 10);
if (errno == ERANGE || val < 0 || val > UINT16_MAX ||
end == str || *end != '\0')
return;
*res = (uint16_t) val;
}
std::string encoding(decode_results *results) {
switch (results->decode_type) {
default:
case UNKNOWN: return "UNKNOWN"; break;
case NEC: return "NEC"; break;
case NEC_LIKE: return "NEC (non-strict)"; break;
case SONY: return "SONY"; break;
case RC5: return "RC5"; break;
case RC5X: return "RC5X"; break;
case RC6: return "RC6"; break;
case RCMM: return "RCMM"; break;
case DISH: return "DISH"; break;
case SHARP: return "SHARP"; break;
case JVC: return "JVC"; break;
case SANYO: return "SANYO"; break;
case SANYO_LC7461: return "SANYO_LC7461"; break;
case MITSUBISHI: return "MITSUBISHI"; break;
case SAMSUNG: return "SAMSUNG"; break;
case LG: return "LG"; break;
case WHYNTER: return "WHYNTER"; break;
case AIWA_RC_T501: return "AIWA_RC_T501"; break;
case PANASONIC: return "PANASONIC"; break;
case DENON: return "DENON"; break;
case COOLIX: return "COOLIX"; break;
case NIKAI: return "NIKAI"; break;
}
}
void usage_error(char * name) {
std::cerr << "Usage: " << name << " [-raw] <global_code>" << std::endl;
}
int main(int argc, char * argv[]) {
int argv_offset = 1;
bool dumpraw = false;
// Check the invocation/calling usage.
if (argc < 2 || argc > 3) {
usage_error(argv[0]);
return 1;
}
if (strncmp("-raw", argv[argv_offset], 4) == 0) {
dumpraw = true;
argv_offset++;
}
if (argc - argv_offset != 1) {
usage_error(argv[0]);
return 1;
}
uint16_t gc_test[MAX_GC_CODE_LENGHT];
int index = 0;
char *pch;
char *saveptr1;
pch = strtok_r(argv[argv_offset], ",", &saveptr1);
while (pch != NULL && index < MAX_GC_CODE_LENGHT) {
str_to_uint16(pch, &gc_test[index]);
pch = strtok_r(NULL, ",", &saveptr1);
index++;
}
IRsendTest irsend(4);
IRrecv irrecv(4);
irsend.begin();
irsend.reset();
irsend.sendGC(gc_test, index);
irsend.makeDecodeResult();
irrecv.decode(&irsend.capture);
std::cout << "Code GC length " << index << std::endl
<< "Code type " << irsend.capture.decode_type
<< " (" << encoding(&irsend.capture) << ")" << std::endl
<< "Code bits " << irsend.capture.bits << std::endl
<< "Code value 0x" << std::hex << irsend.capture.value << std::endl
<< "Code address 0x" << std::hex << irsend.capture.address << std::endl
<< "Code command 0x" << std::hex << irsend.capture.command << std::endl;
if (dumpraw || irsend.capture.decode_type == UNKNOWN)
irsend.dumpRawResult();
return 0;
}

View File

@ -10,6 +10,8 @@
- [Jonny Graham](https://github.com/jonnygraham/)
- [Stu Fisher](https://github.com/stufisher/)
- [Jorge Cisneros](https://github.com/jorgecis/)
- [Denes Varga](https://github.com/denxhun/)
- [Brett T. Warden](https://github.com/bwarden/)
All contributors can be found on the [contributors site](https://github.com/markszabo/IRremoteESP8266/graphs/contributors).

View File

@ -1,7 +1,7 @@
_(Please use this template for reporting issues. You can delete what ever is not relevant. Giving us this information will help us help you faster. Please also read the [FAQ](https://github.com/markszabo/IRremoteESP8266/wiki/Frequently-Asked-Questions) & [Troubleshooting Guide](https://github.com/markszabo/IRremoteESP8266/wiki/Troubleshooting-Guide). Your problem may already have an answer there.)_
### Version/revison of the library used
_Typically located in the `library.json` file in the root directory of the library.
_Typically located in the `library.json` & `src/IRremoteESP8266.h` files in the root directory of the library.
e.g. v2.0.0, or 'master' as at 1st of June, 2017. etc._
### Expected behavior
@ -30,10 +30,13 @@ _What can we do to (pref. reliably) repeat what is happening?_
_Include all relevant code snippets or links to the actual code files. Tip: [How to quote your code so it is still readable](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)._
#### Circuit diagram and hardware used (if applicable)
_Link to an image of the circuit diagram used._
_Link to an image of the circuit diagram used. Part number of the IR receiver module etc._
### I have followed the steps in the [Troubleshooting Guide](https://github.com/markszabo/IRremoteESP8266/wiki/Troubleshooting-Guide) & read the [FAQ](https://github.com/markszabo/IRremoteESP8266/wiki/Frequently-Asked-Questions)
_Yes/No._
### Has this library/code previously worked as expected for you?
_Yes/No. If "Yes", which version last worked for you?_
### Other useful information
_More information is always welcome. Be verbose._

View File

@ -23,6 +23,9 @@ lib/googletest/**/*
# GCC pre-compiled headers.
**/*.gch
# Python compiled files
**/*.pyc
# Unit Test builds
test/*.o
test/*.a
@ -32,8 +35,12 @@ test/*_test
tools/*.o
tools/*.a
tools/gc_decode
tools/mode2_decode
.pioenvs
.piolibdeps
.clang_complete
.gcc-flags.json
#Cygwin builds
*.exe

View File

@ -1,3 +1,4 @@
[submodule "lib/googletest"]
path = lib/googletest
url = https://github.com/google/googletest.git
branch = v1.8.x

View File

@ -0,0 +1,3 @@
[style]
based_on_style: google
indent_width: 2

View File

@ -20,6 +20,7 @@ install:
- arduino --board $BD --save-prefs
- arduino --pref "compiler.warning_level=all" --save-prefs
- sudo apt-get install jq
- sudo pip install pylint
script:
# Check that everything compiles.
- arduino --verify --board $BD $PWD/examples/IRrecvDemo/IRrecvDemo.ino
@ -38,14 +39,17 @@ script:
- arduino --verify --board $BD $PWD/examples/LGACSend/LGACSend.ino
- arduino --verify --board $BD $PWD/examples/TurnOnArgoAC/TurnOnArgoAC.ino
- arduino --verify --board $BD $PWD/examples/IRMQTTServer/IRMQTTServer.ino
- arduino --verify --board $BD $PWD/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino
# Also check the tools programs compile.
- (cd tools; make all)
# Check for lint issues.
- shopt -s nullglob
- python cpplint.py --extensions=c,cc,cpp,ino --headers=h,hpp {src,test,tools}/*.{h,c,cc,cpp,hpp,ino} examples/*/*.{h,c,cc,cpp,hpp,ino}
- pylint {src,test,tools}/*.py
- shopt -u nullglob
# Build and run the unit tests.
- (cd test; make run)
- (cd tools; make run_tests)
# Check the version numbers match.
- LIB_VERSION=$(egrep "^#define\s+_IRREMOTEESP8266_VERSION_\s+" src/IRremoteESP8266.h | cut -d\" -f2)
- test ${LIB_VERSION} == "$(jq -r .version library.json)"

View File

@ -0,0 +1,78 @@
# IRremote ESP8266 Library
[![Build Status](https://travis-ci.org/markszabo/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/markszabo/IRremoteESP8266)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/markszabo/IRremoteESP8266.svg)](http://isitmaintained.com/project/markszabo/IRremoteESP8266 "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/markszabo/IRremoteESP8266.svg)](http://isitmaintained.com/project/markszabo/IRremoteESP8266 "Percentage of issues still open")
[![GitLicense](https://gitlicense.com/badge/markszabo/IRremoteESP8266)](https://gitlicense.com/license/markszabo/IRremoteESP8266)
This library enables you to **send _and_ receive** infra-red signals on an [ESP8266 using the Arduino framework](https://github.com/esp8266/Arduino) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* etc.
## v2.5.2 Now Available
Version 2.5.2 of the library is now [available](https://github.com/markszabo/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/markszabo/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
#### Upgrading from pre-v2.5
The library has changed from using constants declared as `#define` to
[const](https://google.github.io/styleguide/cppguide.html#Constant_Names) with
the appropriate naming per the
[C++ style guide](https://google.github.io/styleguide/cppguide.html).
This may potentially cause old programs to not compile.
The most likely externally used `#define`s have been _aliased_ for limited
backward compatibility for projects using the old style. Going forward, only the
new `kConstantName` style will be supported for new protocol additions.
In the unlikely case it does break your code, then you may have been referencing
something you likely should not have. You should be able to quickly determine
the new name from the old. e.g. `CONSTANT_NAME` to `kConstantName`.
Use common sense or examining the library's code if this does affect code.
## Troubleshooting
Before reporting an issue or asking for help, please try to follow our [Troubleshooting Guide](https://github.com/markszabo/IRremoteESP8266/wiki/Troubleshooting-Guide) first.
## Frequently Asked Questions
Some common answers to common questions and problems are on our [F.A.Q. wiki page](https://github.com/markszabo/IRremoteESP8266/wiki/Frequently-Asked-Questions).
## Installation
##### Official releases via the Arduino IDE v1.8+ (Windows & Linux)
1. Click the _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items.
1. Enter `IRremoteESP8266` into the _"Filter your search..."_ top right search box.
1. Click on the IRremoteESP8266 result of the search.
1. Select the version you wish to install and click _"Install"_.
##### Manual Installation for Windows
1. Click on _"Clone or Download"_ button, then _"[Download ZIP](https://github.com/markszabo/IRremoteESP8266/archive->master.zip)"_ on the page.
1. Extract the contents of the downloaded zip file.
1. Rename the extracted folder to _"IRremoteESP8266"_.
1. Move this folder to your libraries directory. (under windows: `C:\Users\YOURNAME\Documents\Arduino\libraries\`)
1. Restart your Arduino IDE.
1. Check out the examples.
##### Using Git to install library ( Linux )
```
cd ~/Arduino/libraries
git clone https://github.com/markszabo/IRremoteESP8266.git
```
###### To Update to the latest version of the library
```
cd ~/Arduino/libraries/IRremoteESP8266 && git pull
```
## Contributing
If you want to [contribute](.github/CONTRIBUTING.md#how-can-i-contribute) to this project, consider:
- [Report](.github/CONTRIBUTING.md#reporting-bugs) bugs and errors
- Ask for enhancements
- Improve our documentation
- [Create issues](.github/CONTRIBUTING.md#reporting-bugs) and [pull requests](.github/CONTRIBUTING.md#pull-requests)
- Tell other people about this library
## Contributors
Available [here](.github/Contributors.md)
## Library History
This library was originally based on Ken Shirriff's work (https://github.com/shirriff/Arduino-IRremote/)
[Mark Szabo](https://github.com/markszabo/IRremoteESP8266) has updated the IRsend class to work on ESP8266 and [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) the receiving & decoding part (IRrecv class).
As of v2.0, the library was almost entirely re-written with the ESP8266's resources in mind.

View File

@ -0,0 +1,308 @@
# Release Notes
## _v2.5.2 (20181021)_
**[Bug Fixes]**
- Add missing send() method to IRPanasonicAC class. (#545)
- Add missing sendWhirlpoolAC() to IRMQTTServer.ino (#558)
**[Features]**
- Add IR receiving support to IRMQTTServer. (#543)
- Pioneer support (#547)
- Add support for a second LG protocol variant. (#552)
- Support for short Panasonic A/C messages. (#553)
- Add support for Panasonic CKP series A/Cs. (#554)
- Experimental timer/clock support for Panasonic A/Cs. (#546)
- Add Made With Magic (MWM) support (#557)
**[Misc]**
- Grammar and typo fixes (#541, #549)
- Increase Panasonic A/C message tolerances. (#542)
- Added command mode2_decode in tools/ (#557)
- General code style cleanup (#560)
## _v2.5.1 (20181002)_
**[Bug Fixes]**
- Correct the byte used for Samsung AC Swing. (#529)
- Fix not sending Samsung A/C messages in IRMQTTServer. (#529)
**[Features]**
- Experimental support for Electra A/C messages. (#528)
- Experimental support for Panasonic A/C messages. (#535)
- Samsung A/C fixes & improvements (#529)
- IRMQTTServer v0.6.0 (#530)
**[Misc]**
- Change required WifiManager lib version to v0.14
- Add alias for RAWTICK to kRawTick. (#535)
- Update sendLutron() status. (#515)
- Remove leftover debug message in IRrecvDumpV2 (#526)
## _v2.5.0 (20180919)_
**[Bug Fixes]**
- Fix HTML menu error for GICABLE in IRMQTTServer. (#516)
- Fix Mitsubishi A/C mode setting. (#514)
- Add missing ',' in auto analyse tool generated code. (#513)
- Fix Fujitsu checksum validation. (#501)
- Remove errant Repeat debug statement in IRMQTTServer. (#507)
**[Features]**
- Mitsubishi A/C decode improvements. (#514)
- Basic support for Whirlpool A/C messages. (#511)
- Basic support for Samsung A/C messages. (#512)
- Experimental support for detailed Samsung A/C messages. (#521)
- Experimental support for detailed Coolix A/C messages. (#518)
- Experimental support for Lutron protocol. (#516)
- Calculate and use average values for timings in analysing tool. (#513)
**[Misc]**
- Style change from using #define's for constants to `const kConstantName`.
- Improve the JVC example code.
## _v2.4.3 (20180727)_
**[Bug Fixes]**
- Handle Space Gaps better in auto analyse tool. (#482)
- Correct min repeat for GICABLE in IRMQTTServer. (#494)
**[Features]**
- Add static IP config option to IRMQTTServer (#480)
- Full decoding/encoding support for the Haier YRW02 A/C. (#485 #486 #487)
**[Misc]**
- Update LG (28-bit) HDR mark and space timings. (#492)
- Spelling and grammar fixes (#491)
## _v2.4.2 (20180601)_
**[Bug Fixes]**
- Timing Fix: Update the period offset compensation.
**[Features]**
- Improvements for IRMQTTServer example (#466)
## _v2.4.1 (20180520)_
**[Bug Fixes]**
- Fix crash in IRMQTTServer when compiled under Arduino IDE. (#455)
- Default bit length not set for RCMM in IRMQTTServer example. (#456)
- Bad acknowledgements for some A/C protocols in IRMQTTServer example. (#460)
**[Features]**
- Allow disabling the use of delay() calls. (#450)
- Initial support for G.I. Cable protocol. (#458)
- Support of Hitachi A/C 13 & 53 byte messages. (#461)
**[Misc]**
- Auto Analyse Raw Data script converted to Python. (#454)
## _v2.4.0 (20180407)_
**[Bug Fixes]**
- Add missing WiFi.begin() call to IRGCTCPServer example. (#433)
- Add missing sendHaierAC() to IRMQTTServer example. (#434 & #444)
- Make mqtt clientid unique in IRMQTTServer example. (#444)
**[Features]**
- Initial Mitsubishi projector protocol support. (#442)
- Experimental support of Hitachi A/C messages. (#445)
- Improve transmission pulse modulation support.
Allow disabling of transmission frequency modulation.(#439)
**[Misc]**
- IRMQTTServer example improvements. (#444)
## _v2.3.3 (20180302)_
**[Bug Fixes]**
- Ensure the IR LED is off before we start. (#405)
**[Features]**
- Experimental decode support for Gree HVAC units (#397)
- Initial support for Haier A/Cs. (#409)
- Improve timing accuracy of unit tests. (#403)
- Rework matchData() to handle equal total data bit time protocols. (#408)
**[Misc]**
- Add startup text to IRrecvDumpV2 and IRrecvDemo (#412)
- Tweak timings on Fujitsu A/C header (#418)
- AutoAnalyseRawData.sh: Add some support for handling larger than 64 bit codes. (#419)
- Use better comments for send GPIO in examples. (#425)
## _v2.3.2 (20180126)_
**[Bug Fixes]**
- Integer underflow caused device not to respond in `sendJVC()` (#401)
**[Features]**
- Initial support for sending & receiving Carrier HVAC codes. (#387)
- Add Pronto HEX code support to _gc_decode_ tool. (#388)
**[Misc]**
- Make mDNS independent of MQTT in IRMQTTServer example code. (#390 #391)
## _v2.3.1 (20171229)_
**[Bug Fixes]**
- Setting `#define SEND_FUJITSU_AC false` caused a compilation error (#375)
- Integer underflow caused huge `space()` in `sendGeneric()` (#381)
**[Features]**
- Support sending & receiving Lasertag codes. (#374)
- Reduce the library footprint by using a new `sendGeneric()` routine. (#373)
**[Misc]**
- Lots of grammar & typo fixes. (#378)
- Update keywords.txt for Arduino IDE users (#371)
- Update pins in examples so they are compatible with Adafruit boards. (#383)
## _v2.3.0 (20171208)_
**[Bug Fixes]**
- Panasonic-based protocols had incorrect message gap. (#358)
- Formatting error for large rawData values in example code. (#355)
- Off-by-one error in payload_copy malloc. (#337)
- Off-by-one error in unit test helper routines (#363)
**[Features]**
- Support sending and receiving Midea A/C codes.
- Support for receiving Kelvinator A/C codes. (#332)
- Support more operation features for Daikin A/Cs.
- Support for decoding Daikin A/Cs.
- Support sending and receiving Toshiba A/Cs. (#333)
- Support sending and receiving AR-DB1 Fujitsu A/C codes. (#367)
- Add new AutoAnalyseRawData.sh & RawToGlobalCache.sh tools (#345) (#343)
- Support for MagiQuest wands. (#365)
**[Misc]**
- Add checksum verification to Kelvinator A/C decodes. (#348)
- Changes to the threshold reporting of UNKNOWN messages (#347)
- Major re-work of Daikin A/C support.
- Sending for all A/Cs added to MQTT example code.
- MQTT example code improvements. (#334)
- IRrecvDumpV2 significant output improvements. (#363)
- Improved unit test coverage for the library.
## _v2.2.1 (20171025)_
**[Features]**
- Support for sending and decoding Nikai TV messages. (#311, #313)
- gc_decode: External utility to decode Global Cache codes. (#308, #312)
- IRMQTTServer: Example code to send IR messages via HTTP & MQTT. (#316, #323)
- Improve converting 64bit values to hexadecimal. (#318)
**[Misc]**
- IRrecvDump.ino code is now deprecated. Use IRrecvDumpV2.ino instead. (#314)
## _v2.2.0 (20170922)_
**[Bug Fixes]**
- Add printing output of RC-MM and RC-5X protocols in example code. (#284)
- LG timing improvements based on observations (#291)
**[Features]**
- Automatic capture timing calibration for some protocols. (#268)
- Support for creating & sending Trotec AC codes. (#279)
- Support for creating & sending Argo Ulisse 13 DCI codes. (#280 #300)
- Move to 2 microsecond timing resolution for capture of codes. (#287)
- Capture buffer changes:
- Size at runtime. (#276)
- Message timeout at runtime. (#294)
- Simplify creating & using a second buffer (#303)
- New example code:
- Trotec A/C (#279)
- LG A/C units (#289)
- Argo Ulisse 13 DCI codes. (#300)
## _v2.1.1 (20170711)_
**[Bug Fixes]**
- GlobalCache incorrectly using hardware offset for period calc. (#267)
**[Features]**
- Support reporting of 'NEC'-like 32-bit protocols. e.g. Apple TV remote (#265)
- Add an example of sendRaw() to IRsendDemo.ino (#270)
## _v2.1.0 (20170704)_
**[Features]**
- Support for sending Pronto IR codes. (#248)
- Support for sending Fujitsu A/C codes. (#88)
- Minor improvements to examples.
## _v2.0.3 (20170618)_
**[Bug fixes]**
- Capture buffer could become corrupt after large message, breaking subsequent decodes. (#253)
## _v2.0.2 (20170615)_
**[Bug fixes]**
- Correct decode issue introduced in v2.0.1 affecting multiple protocol decoders (#243)
- Correct post-message gap for the Panasonic protocol(s) (#245)
- Incorrect display of the decoded uint64_t value in the example code. (#245)
## _v2.0.1 (20170614)_
**[Bug fixes]**
- Decoding protocols when it doesn't detect a post-command gap, and there is no more data. (#243)
- Incorrect minimum size calculation when there is no post-command gap. (#243)
## _v2.0.0 - 64 bit support and major improvements (20170612)_
**[Misc]**
- This is almost a complete re-write of the library.
**[Features]**
- All suitable protocols now handle 64-bit data messages and are repeatable via an optional argument.
- Unit tests for all protocols.
- Far better and stricter decoding for most protocols.
- Address & command decoding for protocols where that information is available.
- Much more precise timing for generation of signals sent.
- Lower duty-cycles for some protocols.
- Several new protocols added, and some new sending and decoding routines for existing ones.
- Ability to optionally chose which protocols are included, enabling faster decoding and smaller code footprints if desired.
- Support for far larger capture buffers. (e.g. RAWLEN > 256)
**[Bug fixes]**
- Numerous bug fixes.
## _v1.2.0 (20170429)_
**[Features]**
- Add ability to copy IR capture buffer, and continue capturing. Means faster and better IR command decoding.
- Reduce IRAM usage by 28 bytes.
- Improve capture of RC-MM & Panasonic protocols.
- Upgrade IRrecvDumpV2 to new IR capture buffer. Much fewer corrupted/truncated IR messages.
## _v1.1.1 (20170413)_
**[Bug fixes]**
- Fix a reported problem when sending the LG protocol. Preemptive fix for possible similar cases.
- Fix minor issues in examples.
**[Features]**
- Add documentation to some examples to aid new people.
- Add ALPHA support for RC-MM protocol. (Known to be currently not 100% working.)

View File

@ -11,7 +11,8 @@
* Based on Ken Shirriff's IrsendDemo
* Version 0.1 July, 2009
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by IR_LED below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -23,12 +24,13 @@
* have enough current to drive the IR LED effectively.
* * Make sure you have the IR LED polarity correct.
* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity
* * Typical digital camera/phones can be used to see if the IR LED is flashed.
* Replace the IR LED with a normal LED if you don't have a digital camera
* when debugging.
* * Typical digital camera/phones can be used to see if the IR LED is
* flashed. Replace the IR LED with a normal LED if you don't have a digital
* camera when debugging.
* * Avoid using the following pins unless you really know what you are doing:
* * Pin 0/D3: Can interfere with the boot/program mode & support circuits.
* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere.
* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will
* interfere.
* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere.
* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs
* for your first time. e.g. ESP-12 etc.
@ -44,12 +46,15 @@
// These codes can be found in GC's Control Tower database.
uint16_t Samsung_power_toggle[71] = {
38000, 1, 1, 170, 170, 20, 63, 20, 63, 20, 63, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 63, 20, 63, 20, 63, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 63, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 63, 20,
20, 20, 63, 20, 63, 20, 63, 20, 63, 20, 63, 20, 63, 20, 1798};
38000, 1, 1, 170, 170, 20, 63, 20, 63, 20, 63, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 63, 20, 63, 20, 63, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 63, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 63, 20, 20, 20, 63, 20,
63, 20, 63, 20, 63, 20, 63, 20, 63, 20, 1798};
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2)
#define IR_LED 4 // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(IR_LED); // Set the GPIO to be used to sending the message.
void setup() {
irsend.begin();
@ -58,6 +63,10 @@ void setup() {
void loop() {
Serial.println("Toggling power");
#if SEND_GLOBALCACHE
irsend.sendGC(Samsung_power_toggle, 71);
#else // SEND_GLOBALCACHE
Serial.println("Can't send because SEND_GLOBALCACHE has been disabled.");
#endif // SEND_GLOBALCACHE
delay(10000);
}

View File

@ -9,7 +9,7 @@
* For more codes, visit: https://irdb.globalcache.com/
*
* How to use this program:
* 1) Update "ssid" and "password" below for your WIFI network.
* 1) Update "kSsid" and "kPassword" below for your WIFI network.
* 2) Compile and upload the sketch to your ESP8266 module.
* 3) (Optional) Use the serial connection to confirm it started and get the
* IP address.
@ -46,14 +46,16 @@
#include <WiFiClient.h>
#include <WiFiServer.h>
const char* ssid = "..."; // Put your WIFI SSID here.
const char* password = "..."; // Put your WIFI password here.
const char* kSsid = "..."; // Put your WIFI SSID here.
const char* kPassword = "..."; // Put your WIFI Password here.
WiFiServer server(4998); // Uses port 4998.
WiFiClient client;
uint16_t *code_array;
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2)
#define IR_LED 4 // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(IR_LED); // Set the GPIO to be used to sending the message.
void sendGCString(String str) {
int16_t index;
@ -89,7 +91,9 @@ void sendGCString(String str) {
count++;
} while (index != -1);
#if SEND_GLOBALCACHE
irsend.sendGC(code_array, count); // All done. Send it.
#endif // SEND_GLOBALCACHE
free(code_array); // Free up the memory allocated.
}
@ -99,7 +103,7 @@ void setup() {
delay(100);
Serial.println(" ");
Serial.println("IR TCP Server");
WiFi.begin(kSsid, kPassword);
while (WiFi.status() != WL_CONNECTED) {
delay(900);
Serial.print(".");
@ -107,7 +111,7 @@ void setup() {
server.begin();
IPAddress myAddress = WiFi.localIP();
Serial.println(myAddress);
Serial.println(myAddress.toString());
irsend.begin();
}

View File

@ -7,7 +7,7 @@ build_flags = -DMQTT_MAX_PACKET_SIZE=512
lib_deps_builtin =
lib_deps_external =
PubSubClient
WifiManager@0.12
WifiManager@0.14
[env:nodemcuv2]
platform = espressif8266

View File

@ -3,7 +3,8 @@
* Version 0.2 June, 2017
* Copyright 2015 Mark Szabo
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -35,13 +36,15 @@
#include <IRsend.h>
#include <WiFiClient.h>
const char* ssid = ".....";
const char* password = ".....";
const char* kSsid = ".....";
const char* kPassword = ".....";
MDNSResponder mdns;
ESP8266WebServer server(80);
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
void handleRoot() {
server.send(200, "text/html",
@ -61,7 +64,9 @@ void handleIr() {
for (uint8_t i = 0; i < server.args(); i++) {
if (server.argName(i) == "code") {
uint32_t code = strtoul(server.arg(i).c_str(), NULL, 10);
#if SEND_NEC
irsend.sendNEC(code, 32);
#endif // SEND_NEC
}
}
handleRoot();
@ -85,7 +90,7 @@ void setup(void) {
irsend.begin();
Serial.begin(115200);
WiFi.begin(ssid, password);
WiFi.begin(kSsid, kPassword);
Serial.println("");
// Wait for connection
@ -95,9 +100,9 @@ void setup(void) {
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.println(kSsid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println(WiFi.localIP().toString());
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");

View File

@ -1,6 +1,9 @@
/*
* IRremoteESP8266: IRrecvDemo - demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* This is very simple teaching code to show you how to use the library.
* If you are trying to decode your Infra-Red remote(s) for later replay,
* use the IRrecvDumpV2.ino example code instead of this.
* An IR detector/demodulator must be connected to the input kRecvPin.
* Copyright 2009 Ken Shirriff, http://arcfn.com
* Example circuit diagram:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-receiving
@ -22,15 +25,20 @@
// An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU
// board).
uint16_t RECV_PIN = 14;
const uint16_t kRecvPin = 14;
IRrecv irrecv(RECV_PIN);
IRrecv irrecv(kRecvPin);
decode_results results;
void setup() {
Serial.begin(115200);
irrecv.enableIRIn(); // Start the receiver
while (!Serial) // Wait for the serial connection to be establised.
delay(50);
Serial.println();
Serial.print("IRrecvDemo is now running and waiting for IR message on Pin ");
Serial.println(kRecvPin);
}
void loop() {

View File

@ -86,10 +86,10 @@ void dump(decode_results *results) {
if (i % 100 == 0)
yield(); // Preemptive yield every 100th entry to feed the WDT.
if (i & 1) {
Serial.print(results->rawbuf[i] * RAWTICK, DEC);
Serial.print(results->rawbuf[i] * kRawTick, DEC);
} else {
Serial.print(", ");
Serial.print((uint32_t) results->rawbuf[i] * RAWTICK, DEC);
Serial.print((uint32_t) results->rawbuf[i] * kRawTick, DEC);
}
}
Serial.println("};");

View File

@ -0,0 +1,262 @@
/*
* IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv
* An IR detector/demodulator must be connected to the input kRecvPin.
*
* Copyright 2009 Ken Shirriff, http://arcfn.com
* Copyright 2017 David Conran
*
* Example circuit diagram:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-receiving
*
* Changes:
* 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.
* Version 0.2 April, 2017
* - Decode from a copy of the data so we can start capturing faster thus
* reduce the likelihood of miscaptures.
* Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009,
*/
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRutils.h>
// The following are only needed for extended decoding of A/C Messages
#include <ir_Coolix.h>
#include <ir_Daikin.h>
#include <ir_Fujitsu.h>
#include <ir_Gree.h>
#include <ir_Haier.h>
#include <ir_Hitachi.h>
#include <ir_Kelvinator.h>
#include <ir_Midea.h>
#include <ir_Mitsubishi.h>
#include <ir_Panasonic.h>
#include <ir_Samsung.h>
#include <ir_Toshiba.h>
// ==================== start of TUNEABLE PARAMETERS ====================
// An IR detector/demodulator is connected to GPIO pin 14
// e.g. D5 on a NodeMCU board.
const uint16_t kRecvPin = 14;
// The Serial connection baud rate.
// i.e. Status message will be sent to the PC at this baud rate.
// Try to avoid slow speeds like 9600, as you will miss messages and
// cause other problems. 115200 (or faster) is recommended.
// NOTE: Make sure you set your Serial Monitor to the same speed.
const uint32_t kBaudRate = 115200;
// As this program is a special purpose capture/decoder, let us use a larger
// than normal buffer so we can handle Air Conditioner remote codes.
const uint16_t kCaptureBufferSize = 1024;
// kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a
// message ended.
// This parameter is an interesting trade-off. The longer the timeout, the more
// complex a message it can capture. e.g. Some device protocols will send
// multiple message packets in quick succession, like Air Conditioner remotes.
// Air Coniditioner protocols often have a considerable gap (20-40+ms) between
// packets.
// The downside of a large timeout value is a lot of less complex protocols
// send multiple messages when the remote's button is held down. The gap between
// them is often also around 20+ms. This can result in the raw data be 2-3+
// times larger than needed as it has captured 2-3+ messages in a single
// capture. Setting a low timeout value can resolve this.
// So, choosing the best kTimeout value for your use particular case is
// quite nuanced. Good luck and happy hunting.
// NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms.
#if DECODE_AC
// Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator
// A value this large may swallow repeats of some protocols
const uint8_t kTimeout = 50;
#else // DECODE_AC
// Suits most messages, while not swallowing many repeats.
const uint8_t kTimeout = 15;
#endif // DECODE_AC
// Alternatives:
// const uint8_t kTimeout = 90;
// Suits messages with big gaps like XMP-1 & some aircon units, but can
// accidentally swallow repeated messages in the rawData[] output.
//
// const uint8_t kTimeout = kMaxTimeoutMs;
// This will set it to our currently allowed maximum.
// Values this high are problematic because it is roughly the typical boundary
// where most messages repeat.
// e.g. It will stop decoding a message and start sending it to serial at
// precisely the time when the next message is likely to be transmitted,
// and may miss it.
// Set the smallest sized "UNKNOWN" message packets we actually care about.
// This value helps reduce the false-positive detection rate of IR background
// noise as real messages. The chances of background IR noise getting detected
// as a message increases with the length of the kTimeout value. (See above)
// The downside of setting this message too large is you can miss some valid
// short messages for protocols that this library doesn't yet decode.
//
// Set higher if you get lots of random short UNKNOWN messages when nothing
// should be sending a message.
// Set lower if you are sure your setup is working, but it doesn't see messages
// from your device. (e.g. Other IR remotes work.)
// NOTE: Set this value very high to effectively turn off UNKNOWN detection.
const uint16_t kMinUnknownSize = 12;
// ==================== end of TUNEABLE PARAMETERS ====================
// Use turn on the save buffer feature for more complete capture coverage.
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results; // Somewhere to store the results
// Display the human readable state of an A/C message if we can.
void dumpACInfo(decode_results *results) {
String description = "";
#if DECODE_DAIKIN
if (results->decode_type == DAIKIN) {
IRDaikinESP ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_DAIKIN
#if DECODE_FUJITSU_AC
if (results->decode_type == FUJITSU_AC) {
IRFujitsuAC ac(0);
ac.setRaw(results->state, results->bits / 8);
description = ac.toString();
}
#endif // DECODE_FUJITSU_AC
#if DECODE_KELVINATOR
if (results->decode_type == KELVINATOR) {
IRKelvinatorAC ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_KELVINATOR
#if DECODE_MITSUBISHI_AC
if (results->decode_type == MITSUBISHI_AC) {
IRMitsubishiAC ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_MITSUBISHI_AC
#if DECODE_TOSHIBA_AC
if (results->decode_type == TOSHIBA_AC) {
IRToshibaAC ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_TOSHIBA_AC
#if DECODE_GREE
if (results->decode_type == GREE) {
IRGreeAC ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_GREE
#if DECODE_MIDEA
if (results->decode_type == MIDEA) {
IRMideaAC ac(0);
ac.setRaw(results->value); // Midea uses value instead of state.
description = ac.toString();
}
#endif // DECODE_MIDEA
#if DECODE_HAIER_AC
if (results->decode_type == HAIER_AC) {
IRHaierAC ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_HAIER_AC
#if DECODE_HAIER_AC_YRW02
if (results->decode_type == HAIER_AC_YRW02) {
IRHaierACYRW02 ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_HAIER_AC_YRW02
#if DECODE_SAMSUNG_AC
if (results->decode_type == SAMSUNG_AC) {
IRSamsungAc ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_SAMSUNG_AC
#if DECODE_COOLIX
if (results->decode_type == COOLIX) {
IRCoolixAC ac(0);
ac.setRaw(results->value); // Coolix uses value instead of state.
description = ac.toString();
}
#endif // DECODE_COOLIX
#if DECODE_PANASONIC_AC
if (results->decode_type == PANASONIC_AC &&
results->bits > kPanasonicAcShortBits) {
IRPanasonicAc ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_PANASONIC_AC
#if DECODE_HITACHI_AC
if (results->decode_type == HITACHI_AC) {
IRHitachiAc ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_HITACHI_AC
// If we got a human-readable description of the message, display it.
if (description != "") Serial.println("Mesg Desc.: " + description);
}
// The section of code run only once at start-up.
void setup() {
Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY);
while (!Serial) // Wait for the serial connection to be establised.
delay(50);
Serial.println();
Serial.print("IRrecvDumpV2 is now running and waiting for IR input on Pin ");
Serial.println(kRecvPin);
#if DECODE_HASH
// Ignore messages with less than minimum on or off pulses.
irrecv.setUnknownThreshold(kMinUnknownSize);
#endif // DECODE_HASH
irrecv.enableIRIn(); // Start the receiver
}
// The repeating section of the code
//
void loop() {
// Check if the IR code has been received.
if (irrecv.decode(&results)) {
// Display a crude timestamp.
uint32_t now = millis();
Serial.printf("Timestamp : %06u.%03u\n", now / 1000, now % 1000);
if (results.overflow)
Serial.printf(
"WARNING: IR code is too big for buffer (>= %d). "
"This result shouldn't be trusted until this is resolved. "
"Edit & increase kCaptureBufferSize.\n",
kCaptureBufferSize);
// Display the basic output of what we found.
Serial.print(resultToHumanReadableBasic(&results));
dumpACInfo(&results); // Display any extra A/C info if we have it.
yield(); // Feed the WDT as the text output can take a while to print.
// Display the library version the message was captured with.
Serial.print("Library : v");
Serial.println(_IRREMOTEESP8266_VERSION_);
Serial.println();
// Output RAW timing info of the result.
Serial.println(resultToTimingInfo(&results));
yield(); // Feed the WDT (again)
// Output the results as source code
Serial.println(resultToSourceCode(&results));
Serial.println(""); // Blank line between entries
yield(); // Feed the WDT (again)
}
}

View File

@ -4,7 +4,8 @@
* Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009,
* Copyright 2009 Ken Shirriff, http://arcfn.com
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -33,7 +34,9 @@
#include <IRremoteESP8266.h>
#include <IRsend.h>
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
// Example of data captured by IRrecvDumpV2.ino
uint16_t rawData[67] = {9000, 4500, 650, 550, 650, 1650, 600, 550, 650, 550,
@ -50,13 +53,19 @@ void setup() {
}
void loop() {
#if SEND_NEC
Serial.println("NEC");
irsend.sendNEC(0x00FFE01FUL, 32);
#endif // SEND_NEC
delay(2000);
#if SEND_SONY
Serial.println("Sony");
irsend.sendSony(0xa90, 12, 2);
#endif // SEND_SONY
delay(2000);
#if SEND_RAW
Serial.println("a rawData capture from IRrecvDumpV2");
irsend.sendRaw(rawData, 67, 38); // Send a raw data capture at 38kHz.
#endif // SEND_RAW
delay(2000);
}

View File

@ -6,7 +6,7 @@
* Version 1.0 June, 2017
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2), unless you
* change the irsend() value below.
* change the kIrLed value below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -35,7 +35,9 @@
#include <IRremoteESP8266.h>
#include <IRsend.h>
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
// Panasonic Plasma TV Descrete code (Power On).
// Acquired from:
@ -96,10 +98,15 @@ void setup() {
}
void loop() {
#if SEND_PRONTO
Serial.println("Sending a Samsung TV 'on' command.");
irsend.sendPronto(samsungProntoCode, 72);
delay(2000);
Serial.println("Sending a Panasonic Plasma TV 'on' command.");
irsend.sendPronto(panasonicProntoCode, 104);
delay(2000);
#else // SEND_PRONTO
Serial.println("Can't send because SEND_PRONTO has been disabled.");
delay(10000);
#endif // SEND_PRONTO
}

View File

@ -4,7 +4,8 @@
* Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, Copyright 2009 Ken Shirriff, http://arcfn.com
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -33,12 +34,13 @@
#include <IRremoteESP8266.h>
#include <IRsend.h>
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
#define PanasonicPower 0x100BCBD // Panasonic Power button
const uint16_t kPanasonicAddress = 0x4004; // Panasonic address (Pre data)
const uint32_t kPanasonicPower = 0x100BCBD; // Panasonic Power button
const uint16_t kJVCPower = 0xC5E8;
#define JVCPower 0xC5E8
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2)
IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
void setup() {
irsend.begin();
@ -46,11 +48,16 @@ void setup() {
void loop() {
// This should turn your TV on and off
irsend.sendPanasonic(PanasonicAddress, PanasonicPower);
#if SEND_PANASONIC
irsend.sendPanasonic(kPanasonicAddress, kPanasonicPower);
#else // SEND_PANASONIC
Serial.println("Can't send because SEND_PANASONIC has been disabled.");
#endif // SEND_PANASONIC
irsend.sendJVC(JVCPower, 16, 0); // hex value, 16 bits, no repeat
// see http://www.sbprojects.com/knowledge/ir/jvc.php for information
delayMicroseconds(50);
irsend.sendJVC(JVCPower, 16, 1); // hex value, 16 bits, repeat
delayMicroseconds(50);
#if SEND_JVC
irsend.sendJVC(kJVCPower, 16, 1); // hex value, 16 bits, single repeat
#else // SEND_JVC
Serial.println("Can't send because SEND_JVC has been disabled.");
#endif // SEND_JVC
delay(10000); // Wait 10 seconds before we repeat everything.
}

View File

@ -45,7 +45,11 @@ void Ac_Send_Code(uint32_t code) {
Serial.print(" : ");
Serial.println(code, HEX);
#if SEND_LG
irsend.sendLG(code, 28);
#else // SEND_LG
Serial.println("Can't send because SEND_LG has been disabled.");
#endif // SEND_LG
}
void Ac_Activate(unsigned int temperature, unsigned int air_flow,
@ -60,9 +64,9 @@ void Ac_Activate(unsigned int temperature, unsigned int air_flow,
else
ac_msbits4 = 0; // cooling
unsigned int ac_msbits5 = (temperature < 15) ? 0 : temperature - 15;
unsigned int ac_msbits6;
unsigned int ac_msbits6 = 0;
if (0 <= air_flow && air_flow <= 2) {
if (air_flow <= 2) {
if (kAc_Type == 0)
ac_msbits6 = kAc_Flow_Tower[air_flow];
else
@ -128,7 +132,7 @@ void setup() {
}
void loop() {
char b;
char b = ' ';
Serial.println("# a : mode or temp b : air_flow, temp, swing, clean,"
" cooling/heating");
Serial.println("# 0 : off 0");
@ -158,7 +162,7 @@ void loop() {
default:
Serial.println("b="); // Prompt User for input
while (Serial.available() == 0) {}
char b = Serial.read();
b = Serial.read();
}
/*
@ -171,8 +175,8 @@ void loop() {
# 4 : air_flow 0 ~ 3 : flow
# + : temp + 1
# - : temp - 1
# c : cooling
# h : heating
# c : cooling
# h : heating
# m : change cooling to air clean, air clean to cooling
*/
Serial.print("a : ");
@ -194,7 +198,7 @@ void loop() {
Ac_Change_Air_Swing(1);
break;
case '3': // 1 : clean on, power on
if (b == '0' | b == '1')
if (b == '0' || b == '1')
Ac_Air_Clean(b);
break;
case '4':

View File

@ -1,5 +1,6 @@
/* Copyright 2017 crankyoldgit
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
/* Copyright 2017, 2018 crankyoldgit
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -29,10 +30,11 @@
#include <IRsend.h>
#include <ir_Argo.h>
IRArgoAC argoir(4); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRArgoAC ac(kIrLed); // Set the GPIO to be used to sending the message.
void setup() {
argoir.begin();
ac.begin();
Serial.begin(115200);
}
@ -40,13 +42,17 @@ void loop() {
Serial.println("Sending...");
// Set up what we want to send. See ir_Argo.cpp for all the options.
argoir.setPower(true);
argoir.setFan(ARGO_FAN_1);
argoir.setCoolMode(ARGO_COOL_AUTO);
argoir.setTemp(25);
ac.setPower(true);
ac.setFan(kArgoFan1);
ac.setCoolMode(kArgoCoolAuto);
ac.setTemp(25);
#if SEND_ARGO
// Now send the IR signal.
argoir.send();
ac.send();
#else // SEND_ARGO
Serial.println("Can't send because SEND_ARGO has been disabled.");
#endif // SEND_ARGO
delay(5000);
}

View File

@ -1,6 +1,7 @@
/* Copyright 2016 sillyfrog
/* Copyright 2017 sillyfrog
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -30,10 +31,11 @@
#include <IRsend.h>
#include <ir_Daikin.h>
IRDaikinESP dakinir(D2); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRDaikinESP ac(kIrLed); // Set the GPIO to be used to sending the message
void setup() {
dakinir.begin();
ac.begin();
Serial.begin(115200);
}
@ -42,15 +44,26 @@ void loop() {
Serial.println("Sending...");
// Set up what we want to send. See ir_Daikin.cpp for all the options.
dakinir.on();
dakinir.setFan(1);
dakinir.setMode(DAIKIN_COOL);
dakinir.setTemp(25);
dakinir.setSwingVertical(0);
dakinir.setSwingHorizontal(0);
ac.on();
ac.setFan(1);
ac.setMode(kDaikinCool);
ac.setTemp(25);
ac.setSwingVertical(false);
ac.setSwingHorizontal(false);
// Set the current time to 1:33PM (13:33)
// Time works in minutes past midnight
ac.setCurrentTime(13 * 60 + 33);
// Turn off about 1 hour later at 2:30PM (14:30)
ac.enableOffTimer(14 * 60 + 30);
// Display what we are going to send.
Serial.println(ac.toString());
// Now send the IR signal.
dakinir.send();
#if SEND_DAIKIN
ac.send();
#endif // SEND_DAIKIN
delay(5000);
delay(15000);
}

View File

@ -0,0 +1,50 @@
// Copyright 2017 Jonny Graham, 2018 David Conran
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Fujitsu.h>
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRFujitsuAC ac(kIrLed);
void printState() {
// Display the settings.
Serial.println("Fujitsu A/C remote is in the following state:");
Serial.printf(" %s\n", ac.toString().c_str());
// Display the encoded IR sequence.
unsigned char* ir_code = ac.getRaw();
Serial.print("IR Code: 0x");
for (uint8_t i = 0; i < ac.getStateLength(); i++)
Serial.printf("%02X", ir_code[i]);
Serial.println();
}
void setup() {
ac.begin();
Serial.begin(115200);
delay(200);
// Set up what we want to send. See ir_Fujitsu.cpp for all the options.
Serial.println("Default state of the remote.");
printState();
Serial.println("Setting desired state for A/C.");
ac.setCmd(kFujitsuAcCmdTurnOn);
ac.setSwing(kFujitsuAcSwingBoth);
ac.setMode(kFujitsuAcModeCool);
ac.setFanSpeed(kFujitsuAcFanHigh);
ac.setTemp(24); // 24C
}
void loop() {
// Now send the IR signal.
Serial.println("Sending IR command to A/C ...");
#if SEND_FUJITSU_AC
ac.send();
#else // SEND_FUJITSU_AC
Serial.println("Can't send because SEND_FUJITSU_AC has been disabled.");
#endif // SEND_FUJITSU_AC
printState();
delay(5000);
}

View File

@ -1,6 +1,7 @@
/* Copyright 2016 David Conran
/* Copyright 2016, 2018 David Conran
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -29,29 +30,23 @@
#include <IRsend.h>
#include <ir_Kelvinator.h>
IRKelvinatorAC kelvir(D2); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRKelvinatorAC ac(kIrLed); // Set the GPIO to be used for sending messages.
void printState() {
// Display the settings.
Serial.println("Kelvinator A/C remote is in the following state:");
Serial.printf(" Basic\n Power: %d, Mode: %d, Temp: %dC, Fan Speed: %d\n",
kelvir.getPower(), kelvir.getMode(), kelvir.getTemp(),
kelvir.getFan());
Serial.printf(" Options\n X-Fan: %d, Light: %d, Ion Filter: %d\n",
kelvir.getXFan(), kelvir.getLight(), kelvir.getIonFilter());
Serial.printf(" Swing (V): %d, Swing (H): %d, Turbo: %d, Quiet: %d\n",
kelvir.getSwingVertical(), kelvir.getSwingHorizontal(),
kelvir.getTurbo(), kelvir.getQuiet());
Serial.printf(" %s\n", ac.toString().c_str());
// Display the encoded IR sequence.
unsigned char* ir_code = kelvir.getRaw();
unsigned char* ir_code = ac.getRaw();
Serial.print("IR Code: 0x");
for (uint8_t i = 0; i < KELVINATOR_STATE_LENGTH; i++)
for (uint8_t i = 0; i < kKelvinatorStateLength; i++)
Serial.printf("%02X", ir_code[i]);
Serial.println();
}
void setup() {
kelvir.begin();
ac.begin();
Serial.begin(115200);
delay(200);
@ -60,21 +55,23 @@ void setup() {
Serial.println("Default state of the remote.");
printState();
Serial.println("Setting desired state for A/C.");
kelvir.on();
kelvir.setFan(1);
kelvir.setMode(KELVINATOR_COOL);
kelvir.setTemp(26);
kelvir.setSwingVertical(false);
kelvir.setSwingHorizontal(true);
kelvir.setXFan(true);
kelvir.setIonFilter(false);
kelvir.setLight(true);
ac.on();
ac.setFan(1);
ac.setMode(kKelvinatorCool);
ac.setTemp(26);
ac.setSwingVertical(false);
ac.setSwingHorizontal(true);
ac.setXFan(true);
ac.setIonFilter(false);
ac.setLight(true);
}
void loop() {
// Now send the IR signal.
#if SEND_KELVINATOR
Serial.println("Sending IR command to A/C ...");
kelvir.send();
ac.send();
#endif // SEND_KELVINATOR
printState();
delay(5000);
}

View File

@ -1,6 +1,7 @@
/* Copyright 2017 David Conran
/* Copyright 2017, 2018 David Conran
*
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -29,25 +30,23 @@
#include <IRsend.h>
#include <ir_Mitsubishi.h>
IRMitsubishiAC mitsubir(D2); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRMitsubishiAC ac(kIrLed); // Set the GPIO used for sending messages.
void printState() {
// Display the settings.
Serial.println("Mitsubishi A/C remote is in the following state:");
Serial.printf(" Power: %d, Mode: %d, Temp: %dC, Fan Speed: %d," \
" Vane Mode: %d\n",
mitsubir.getPower(), mitsubir.getMode(), mitsubir.getTemp(),
mitsubir.getFan(), mitsubir.getVane());
Serial.printf(" %s\n", ac.toString().c_str());
// Display the encoded IR sequence.
unsigned char* ir_code = mitsubir.getRaw();
unsigned char* ir_code = ac.getRaw();
Serial.print("IR Code: 0x");
for (uint8_t i = 0; i < MITSUBISHI_AC_STATE_LENGTH; i++)
for (uint8_t i = 0; i < kMitsubishiACStateLength; i++)
Serial.printf("%02X", ir_code[i]);
Serial.println();
}
void setup() {
mitsubir.begin();
ac.begin();
Serial.begin(115200);
delay(200);
@ -55,17 +54,19 @@ void setup() {
Serial.println("Default state of the remote.");
printState();
Serial.println("Setting desired state for A/C.");
mitsubir.on();
mitsubir.setFan(1);
mitsubir.setMode(MITSUBISHI_AC_COOL);
mitsubir.setTemp(26);
mitsubir.setVane(MITSUBISHI_AC_VANE_AUTO);
ac.on();
ac.setFan(1);
ac.setMode(kMitsubishiAcCool);
ac.setTemp(26);
ac.setVane(kMitsubishiAcVaneAuto);
}
void loop() {
// Now send the IR signal.
#if SEND_MITSUBISHI_AC
Serial.println("Sending IR command to A/C ...");
mitsubir.send();
ac.send();
#endif // SEND_MITSUBISHI_AC
printState();
delay(5000);
}

View File

@ -0,0 +1,71 @@
/* Copyright 2017, 2018 David Conran
*
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
* Suggested circuit:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-sending
*
* Common mistakes & tips:
* * Don't just connect the IR LED directly to the pin, it won't
* have enough current to drive the IR LED effectively.
* * Make sure you have the IR LED polarity correct.
* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity
* * Typical digital camera/phones can be used to see if the IR LED is flashed.
* Replace the IR LED with a normal LED if you don't have a digital camera
* when debugging.
* * Avoid using the following pins unless you really know what you are doing:
* * Pin 0/D3: Can interfere with the boot/program mode & support circuits.
* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere.
* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere.
* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs
* for your first time. e.g. ESP-12 etc.
*/
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Toshiba.h>
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRToshibaAC ac(kIrLed); // Set the GPIO to be used for sending messages.
void printState() {
// Display the settings.
Serial.println("Toshiba A/C remote is in the following state:");
Serial.printf(" %s\n", ac.toString().c_str());
// Display the encoded IR sequence.
unsigned char* ir_code = ac.getRaw();
Serial.print("IR Code: 0x");
for (uint8_t i = 0; i < kToshibaACStateLength; i++)
Serial.printf("%02X", ir_code[i]);
Serial.println();
}
void setup() {
ac.begin();
Serial.begin(115200);
delay(200);
// Set up what we want to send. See ir_Toshiba.cpp for all the options.
Serial.println("Default state of the remote.");
printState();
Serial.println("Setting desired state for A/C.");
ac.on();
ac.setFan(1);
ac.setMode(kToshibaAcCool);
ac.setTemp(26);
}
void loop() {
// Now send the IR signal.
#if SEND_TOSHIBA_AC
Serial.println("Sending IR command to A/C ...");
ac.send();
#endif // SEND_TOSHIBA_AC
printState();
delay(5000);
}

View File

@ -0,0 +1,17 @@
[platformio]
lib_extra_dirs = ../../
src_dir=.
[common]
build_flags =
lib_deps_builtin =
lib_deps_external =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
build_flags = ${common.build_flags}
lib_deps =
${common.lib_deps_builtin}
${common.lib_deps_external}

View File

@ -1,5 +1,6 @@
/* Copyright 2017 stufisher
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
* as specified by kIrLed below.
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
@ -29,10 +30,11 @@
#include <IRsend.h>
#include <ir_Trotec.h>
IRTrotecESP trotecir(D2); // An IR LED is controlled by GPIO pin 4 (D2)
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
IRTrotecESP ac(kIrLed); // Set the GPIO to be used for sending messages.
void setup() {
trotecir.begin();
ac.begin();
Serial.begin(115200);
}
@ -40,13 +42,17 @@ void loop() {
Serial.println("Sending...");
// Set up what we want to send. See ir_Trotec.cpp for all the options.
trotecir.setPower(true);
trotecir.setSpeed(TROTEC_FAN_LOW);
trotecir.setMode(TROTEC_COOL);
trotecir.setTemp(25);
ac.setPower(true);
ac.setSpeed(kTrotecFanLow);
ac.setMode(kTrotecCool);
ac.setTemp(25);
// Now send the IR signal.
trotecir.send();
#if SEND_TROTEC
ac.send();
#else // SEND_TROTEC
Serial.println("Can't send because SEND_TROTEC has been disabled.");
#endif // SEND_TROTEC
delay(5000);
}

View File

@ -0,0 +1,17 @@
[platformio]
lib_extra_dirs = ../../
src_dir=.
[common]
build_flags =
lib_deps_builtin =
lib_deps_external =
[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
build_flags = ${common.build_flags}
lib_deps =
${common.lib_deps_builtin}
${common.lib_deps_external}

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