Arduino-IRremote/src/ir_Template.hpp

219 lines
8.5 KiB
C++

/*
Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu
Our fantasy protocol is a standard protocol, so we can use this standard
template without too much work. Some protocols are quite unique and will require
considerably more work in this file! It is way beyond the scope of this text to
explain how to reverse engineer "unusual" IR protocols. But, unless you own an
oscilloscope, the starting point is probably to use the ReceiveDump.ino sketch and
try to spot the pattern!
Before you start, make sure the IR library is working OK:
# Open up the Arduino IDE
# Load up the ReceiveDump.ino example sketch
# Run it
# Analyze your data to have an idea, what is the header timing, the bit timing, the address, the command and the checksum of your protocol.
Now we can start to add our new protocol...
1. Copy this file to : ir_<YourProtocolName>.hpp
2. Replace all occurrences of "Shuzu" with the name of your protocol.
3. Tweak the #defines to suit your protocol.
4. If you're lucky, tweaking the #defines will make the decode and send() function
work.
You have now written the code to support your new protocol!
To integrate it into the IRremote library, you must search for "BOSEWAVE"
and add your protocol in the same way as it is already done for BOSEWAVE.
You have to change the following files:
IRSend.hpp IRsend::write(IRData *aIRSendData + uint_fast8_t aNumberOfRepeats)
IRProtocol.h Add it to decode_type_t
IRReceive.hpp IRrecv::decode() + printActiveIRProtocols(Print *aSerial) + getProtocolString(decode_type_t aProtocol)
IRremote.hpp At 3 occurrences of DECODE_XXX
IRremoteInt.h Add the declaration of the decode and send function
Now open the Arduino IDE, load up the ReceiveDump.ino sketch, and run it.
Hopefully it will compile and upload.
If it doesn't, you've done something wrong. Check your work and look carefully at the error messages.
If you get this far, I will assume you have successfully added your new protocol
At last, delete this giant instructional comment.
If you want us to include your work in the library so others may benefit
from your hard work, you have to extend the examples
IRremoteInfo, SmallReceiver, simple Receiver, SendDemo and UnitTest too
as well as the Readme.md
It is not an act, but required for completeness.
Thanks
The maintainer
*/
/*
* ir_Shuzu.cpp
*
* Contains functions for receiving and sending Shuzu IR Protocol ...
*
* Copyright (C) 2022 Shuzu Guru
* shuzu.guru@gmail.com
*
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
*
************************************************************************************
* MIT License
*
* Copyright (c) 2022 Unknown Contributor :-)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
************************************************************************************
*/
#ifndef _IR_SHUZU_HPP
#define _IR_SHUZU_HPP
#include <Arduino.h>
//#define DEBUG // Activate this for lots of lovely debug output from this decoder.
#include "IRremoteInt.h" // evaluates the DEBUG for IR_DEBUG_PRINT
//#define SEND_SHUZU 1 // for testing
//#define DECODE_SHUZU 1 // for testing
//==============================================================================
//
//
// S H U Z U
//
//
//==============================================================================
// see: https://www....
// LSB first, 1 start bit + 16 bit address + 8 bit command + 1 stop bit.
#define SHUZU_ADDRESS_BITS 16 // 16 bit address
#define SHUZU_COMMAND_BITS 8 // Command
#define SHUZU_BITS (SHUZU_ADDRESS_BITS + SHUZU_COMMAND_BITS) // The number of bits in the protocol
#define SHUZU_UNIT 560
#define SHUZU_HEADER_MARK (16 * SHUZU_UNIT) // The length of the Header:Mark
#define SHUZU_HEADER_SPACE (8 * SHUZU_UNIT) // The length of the Header:Space
#define SHUZU_BIT_MARK SHUZU_UNIT // The length of a Bit:Mark
#define SHUZU_ONE_SPACE (3 * SHUZU_UNIT) // The length of a Bit:Space for 1's
#define SHUZU_ZERO_SPACE SHUZU_UNIT // The length of a Bit:Space for 0's
#define SHUZU_REPEAT_HEADER_SPACE (4 * SHUZU_UNIT) // 2250
#define SHUZU_REPEAT_SPACE 45000
#define SHUZU_OTHER 1234 // Other things you may need to define
//+=============================================================================
//
void IRsend::sendShuzu(uint16_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats) {
// Set IR carrier frequency
enableIROut(38);
uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
while (tNumberOfCommands > 0) {
// Header
mark(SHUZU_HEADER_MARK);
space(SHUZU_HEADER_SPACE);
// Address (device and subdevice)
sendPulseDistanceWidthData(SHUZU_BIT_MARK, SHUZU_ONE_SPACE, SHUZU_BIT_MARK, SHUZU_ZERO_SPACE, aAddress,
SHUZU_ADDRESS_BITS, PROTOCOL_IS_LSB_FIRST, SEND_NO_STOP_BIT); // false -> LSB first
// Command + stop bit
sendPulseDistanceWidthData(SHUZU_BIT_MARK, SHUZU_ONE_SPACE, SHUZU_BIT_MARK, SHUZU_ZERO_SPACE, aCommand,
SHUZU_COMMAND_BITS, PROTOCOL_IS_LSB_FIRST, SEND_STOP_BIT); // false, true -> LSB first, stop bit
tNumberOfCommands--;
// skip last delay!
if (tNumberOfCommands > 0) {
// send repeated command in a fixed raster
delay(SHUZU_REPEAT_SPACE / MICROS_IN_ONE_MILLI);
}
}
IrReceiver.restartAfterSend();
}
//+=============================================================================
//
/*
* First check for right data length
* Next check start bit
* Next try the decode
* Last check stop bit
*/
bool IRrecv::decodeShuzu() {
// Check we have the right amount of data (28). The +4 is for initial gap, start bit mark and space + stop bit mark
if (decodedIRData.rawDataPtr->rawlen != (2 * SHUZU_BITS) + 4) {
// no debug output, since this check is mainly to determine the received protocol
return false;
}
// Check header "space"
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], SHUZU_HEADER_MARK)
|| !matchSpace(decodedIRData.rawDataPtr->rawbuf[2], SHUZU_HEADER_SPACE)) {
IR_DEBUG_PRINT(F("Shuzu: "));
IR_DEBUG_PRINTLN(F("Header mark or space length is wrong"));
return false;
}
// false -> LSB first
if (!decodePulseDistanceData(SHUZU_BITS, 3, SHUZU_BIT_MARK, SHUZU_ONE_SPACE, SHUZU_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST)) {
IR_DEBUG_PRINT(F("Shuzu: "));
IR_DEBUG_PRINTLN(F("Decode failed"));
return false;
}
// Stop bit
if (!matchMark(decodedIRData.rawDataPtr->rawbuf[3 + (2 * SHUZU_BITS)], SHUZU_BIT_MARK)) {
IR_DEBUG_PRINT(F("Shuzu: "));
IR_DEBUG_PRINTLN(F("Stop bit mark length is wrong"));
return false;
}
// Success
// decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value
uint8_t tCommand = decodedIRData.decodedRawData >> SHUZU_ADDRESS_BITS; // upper 8 bits of LSB first value
uint8_t tAddress = decodedIRData.decodedRawData & 0xFFFF; // lowest 16 bit of LSB first value
/*
* Check for repeat
*/
if (decodedIRData.rawDataPtr->rawbuf[0] < ((SHUZU_REPEAT_SPACE + (SHUZU_REPEAT_SPACE / 4)) / MICROS_PER_TICK)) {
decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST;
}
decodedIRData.command = tCommand;
decodedIRData.address = tAddress;
decodedIRData.numberOfBits = SHUZU_BITS;
decodedIRData.protocol = BOSEWAVE; // we have no SHUZU code
return true;
}
#endif // _IR_SHUZU_HPP