-
Notifications
You must be signed in to change notification settings - Fork 835
Adding support for a new IR protocol
This is a quick guide of most of the steps required to add a new simple protocol to the library. This guide makes the assumption that the protocol is NOT larger than 64 bits.
Take a look at the Supported Protocols document. See if we've already documented support for your Air Conditioner/Heat Pump.
Obtain a IR Demodulator Hardware component, and build this circuit, and then compile and run the IRrecvDumpV2 example code on your ESP device. Monitor the serial output from the ESP module. The output should tell you what it knows about your protocol if it is supported, or list it as UNKNOWN
if it doesn't know what it is.
See & read the FAQ.
Read the Writing Code Guide.
There are a number of automated checks that will not forgive incorrect or messy code. It may seem harsh, but it's there to help keep the library code readable. Code that doesn't pass won't be merged. Don't worry too much as help is given to first timers. :)
If it is, or the protocol is larger than 64 bits you probably want to follow these steps instead.
We will need that information later. Do some research to see if you can find any/all of the following:
- The operation manual.
- The specification for the IR protocol.
- Links to any other implementations and projects that support your device and/or protocol.
- Photos of the remote control etc.
For the purposes of this document, I'm going to assume the Device/Protocol is called "TestExample".
Use the circuit and program (IRrecvDumpV2) described above to capture a few simple messages from the remote.
- Include the entire text of the output of the IRrecvDumpV2 program for the given messages. e.g. Including the timestamp, library version, and most importantly, the
uint16_t rawData[] = {...};
line.
Use the auto_analyse_raw_data.py program.
Run the uint16_t rawData[] = {...};
output through the auto_analyse_raw_data.py program to examine and provide that output. It's a basic tool to do some rough analysis of the protocol and make some guesses to it's structure and parameters.
If you use the -g -n TestExample
arguments to the program, it will give you some example code that can reproduce & decode the IR message.
Log an issue (or fork your own repo/branch and send a PR) to add experimental support for the protocol.
Report all the information you've collected in a new issue.
If you've got all that information, it can be likely fairly easily added to the library.
That means, you can capture IR messages and they can be converted to a long, single hexidecimal code for your protocol via the auto_analyse_raw_data.py program, and you should be able to recreate the same signal using that hex code using the newly added sendTestExample()
routine once the following is finished.
If there is already a file for the device under src/ir_*.cpp, you should add to that. If not, then copy a simple protocol (such as ir_Inax.cpp to src/ir_YourProtocol.cpp
and use the generated code in place of the existing void IRsend::sendInax()
routine. Do a search & replace and other obvious edits you may need to make it suit what you are adding.
Add const uint16_t kTestExampleBits = NN;
where NN is the line the auto analyse tool told you it probably was to src/IRremoteESP8266.h
Search for kLastDecodeType
. You will need to add your protocol name here to register it.
e.g.
DAIKIN152, // 70
MITSUBISHI136,
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = MITSUBISHI136,
};
becomes
DAIKIN152, // 70
MITSUBISHI136,
TESTEXAMPLE,
// Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = TESTEXAMPLE,
};
Keep the protocol name here UPPERCASE.
Edit IRutils.cpp
In the appropriate alphabetical place add:
else if (!strcasecmp(str, "TESTEXAMPLE"))
return decode_type_t::TESTEXAMPLE;
In the appropriate alphabetical place add:
case TESTEXAMPLE:
result = F("TESTEXAMPLE");
break;
Add the #define SEND_TESTEXAMPLE true
to src/IRremoteESP8266.h in the appropriate place.
Edit src/IRsend.h
Add the following in the appropriate/obvious place:
#if SEND_TESTEXAMPLE
void sendTestExample(const uint64_t data, const uint16_t nbits = kTestExampleBits,
const uint16_t repeat = kNoRepeat);
#endif // SEND_TESTEXAMPLE
Edit src/IRsend.cpp
Add the number of bits to the uint16_t IRsend::defaultBits(const decode_type_t protocol)
function in the obvious place.
Add to the 64 bit IRsend::send()
function.
i.e. bool IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat)
The following:
#if SEND_TESTEXAMPLE
case TESTEXAMPLE:
sendTestExample(data, nbits, min_repeat);
break;
#endif // SEND_TESTEXAMPLE
Please put it in alphabetical order to keep things nice. :)
Edit test/Makefile
Append ir_TestExample.o
to the end of the PROTOCOLS =
line(s).
e.g.
ir_Trotec.o ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o
becomes
ir_Trotec.o ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_TestExample.o
Append to the end of the file:
ir_TestExample.o : $(USER_DIR)/ir_TestExample.cpp $(COMMON_DEPS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_TestExample.cpp
Congratulations! If everything went well you should now be able to compile and send using the IRsend::sendTestExample()
procedure.
Update tools/Makefile
The exact same steps again as per test/Makefile
Copy test/ir_Inax_test.cpp to test/ir_TestExample_test.cpp
and modify as needed to suit your new protocol. Remove any decoding sections if you haven't implemented that yet.
Add it to test/Makefile
Append to the end of the file:
ir_TestExample_test.o : ir_TestExample_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_TestExample_test.cpp
ir_TestExample_test : $(COMMON_OBJ) ir_TestExample_test.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
Find the line(s)/section starting with TESTS =
and append ir_TestExample_test
to it.
e.g.:
ir_Inax_test ir_Neoclima_test ir_Amcor_test
becomes
ir_Inax_test ir_Neoclima_test ir_Amcor_test ir_TestExample_test
See the guide entry for that.
All the steps up to and including Edit IRutils.cpp need to have been completed before you can perform these steps.
Add #define DECODE_TESTEXAMPLE true
to src/IRremoteESP8266.h in the appropriate place. i.e. Adjacent to SEND_TESTEXAMPLE
.
Edit src/IRrecv.h
Add the following in the appropriate/obvious place in the private:
section of class IRrecv
:
#if DECODE_TESTEXAMPLE
bool decodeTestExample(decode_results *results, const uint16_t nbits = kTestExampleBits,
const bool strict = true);
#endif // DECODE_TESTEXAMPLE
Edit src/IRrecv.cpp
You need to add your new decodeTestExample()
function to the main IRrecv::decode()
function.
Search for this line:
// Typically new protocols are added above this line.
and add in your decoder so it looks like:
#if DECODE_TESTEXAMPLE
DPRINTLN("Attempting TestExample decode");
if (decodeTestExample(results)) return true;
#endif // DECODE_TESTEXAMPLE
// Typically new protocols are added above this line.
ToDo: Add the rest of receive/decode etc.