-
Notifications
You must be signed in to change notification settings - Fork 839
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for sending & decoding Pioneer 64bit codes. Pioneer codes are essentially two NEC 32-bit codes back to back. * Unit tests * Examples updated. * Tests on real devices. Appears to work fine.
- Loading branch information
1 parent
ec75c50
commit 75c7fe3
Showing
13 changed files
with
400 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2009 Ken Shirriff | ||
// Copyright 2017, 2018 David Conran | ||
|
||
#ifndef IR_NEC_H_ | ||
#define IR_NEC_H_ | ||
|
||
#include <stdint.h> | ||
#include "IRremoteESP8266.h" | ||
|
||
// N N EEEEE CCCC | ||
// NN N E C | ||
// N N N EEE C | ||
// N NN E C | ||
// N N EEEEE CCCC | ||
|
||
// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ | ||
|
||
// Constants | ||
// Ref: | ||
// http://www.sbprojects.com/knowledge/ir/nec.php | ||
const uint16_t kNecTick = 560; | ||
const uint16_t kNecHdrMarkTicks = 16; | ||
const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick; | ||
const uint16_t kNecHdrSpaceTicks = 8; | ||
const uint16_t kNecHdrSpace = kNecHdrSpaceTicks * kNecTick; | ||
const uint16_t kNecBitMarkTicks = 1; | ||
const uint16_t kNecBitMark = kNecBitMarkTicks * kNecTick; | ||
const uint16_t kNecOneSpaceTicks = 3; | ||
const uint16_t kNecOneSpace = kNecOneSpaceTicks * kNecTick; | ||
const uint16_t kNecZeroSpaceTicks = 1; | ||
const uint16_t kNecZeroSpace = kNecZeroSpaceTicks * kNecTick; | ||
const uint16_t kNecRptSpaceTicks = 4; | ||
const uint16_t kNecRptSpace = kNecRptSpaceTicks * kNecTick; | ||
const uint16_t kNecRptLength = 4; | ||
const uint16_t kNecMinCommandLengthTicks = 193; | ||
const uint32_t kNecMinCommandLength = kNecMinCommandLengthTicks * kNecTick; | ||
const uint32_t kNecMinGap = kNecMinCommandLength - | ||
(kNecHdrMark + kNecHdrSpace + kNECBits * (kNecBitMark + kNecOneSpace) + | ||
kNecBitMark); | ||
const uint16_t kNecMinGapTicks = kNecMinCommandLengthTicks - | ||
(kNecHdrMarkTicks + kNecHdrSpaceTicks + | ||
kNECBits * (kNecBitMarkTicks + kNecOneSpaceTicks) + | ||
kNecBitMarkTicks); | ||
|
||
#endif // IR_NEC_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Copyright 2009 Ken Shirriff | ||
// Copyright 2017, 2018 David Conran | ||
// Copyright 2018 Kamil Palczewski | ||
|
||
#define __STDC_LIMIT_MACROS | ||
#include <stdint.h> | ||
#include <algorithm> | ||
#include "IRrecv.h" | ||
#include "IRsend.h" | ||
#include "IRutils.h" | ||
#include "ir_NEC.h" | ||
|
||
// PPPP III OOO N N EEEE EEEE RRRR | ||
// P P I O O NN N E E R R | ||
// PPPP I O O N N N EEE EEE RRRR | ||
// P I O O N NN E E R R | ||
// P III OOO N N EEEE EEEE R RR | ||
|
||
// Ref: | ||
// http://adrian-kingston.com/IRFormatPioneer.htm | ||
|
||
#if SEND_PIONEER | ||
// Send a raw Pioneer formatted message. | ||
// | ||
// Args: | ||
// data: The message to be sent. | ||
// nbits: The number of bits of the message to be sent. | ||
// Typically kPioneerBits. | ||
// repeat: The number of times the command is to be repeated. | ||
// | ||
// Status: BETA / Expected to be working. | ||
// | ||
// Ref: | ||
// http://adrian-kingston.com/IRFormatPioneer.htm | ||
void IRsend::sendPioneer(const uint64_t data, const uint16_t nbits, | ||
const uint16_t repeat) { | ||
// If nbits is to big, or is odd, abort. | ||
if (nbits > sizeof(data) * 8 || nbits % 2 == 1) return; | ||
|
||
// send 1st part of the code | ||
sendNEC(data >> (nbits / 2), nbits / 2, 0); | ||
// send 2nd part of the code | ||
sendNEC(data & (((uint64_t) 1 << (nbits / 2)) - 1), nbits / 2, repeat); | ||
} | ||
|
||
// Calculate the raw Pioneer data code based on two NEC sub-codes | ||
// Args: | ||
// address A 16-bit "published" NEC value. | ||
// command: A 16-bit "published" NEC value. | ||
// Returns: | ||
// A raw 64-bit Pioneer message code. | ||
// | ||
// Status: BETA / Expected to work. | ||
// | ||
// Note: | ||
// Address & Command can be take from a decode result OR from the spreadsheets | ||
// located at: | ||
// https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers | ||
// where the first part is considered the address, | ||
// and the second the command. | ||
// e.g. | ||
// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20. | ||
uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) { | ||
return (((uint64_t) encodeNEC(address >> 8, address & 0xFF)) << 32) | | ||
encodeNEC(command >> 8, command & 0xFF); | ||
} | ||
#endif // SEND_PIONEER | ||
|
||
#if DECODE_PIONEER | ||
// Decode the supplied Pioneer 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 kPioneerBits. | ||
// 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. (Self decodes & real examples) | ||
// | ||
bool IRrecv::decodePioneer(decode_results *results, const uint16_t nbits, | ||
const bool strict) { | ||
if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1) | ||
return false; // Can't possibly be a valid Pioneer message. | ||
if (strict && nbits != kPioneerBits) | ||
return false; // Not strictly an Pioneer message. | ||
|
||
uint64_t data = 0; | ||
uint16_t offset = kStartOffset; | ||
|
||
for (uint16_t section = 0; section < 2; section++) { | ||
// Header | ||
if (!matchMark(results->rawbuf[offset], kNecHdrMark)) return false; | ||
// Calculate how long the lowest tick time is based on the header mark. | ||
uint32_t mark_tick = results->rawbuf[offset++] * kRawTick / | ||
kNecHdrMarkTicks; | ||
if (!matchSpace(results->rawbuf[offset], kNecHdrSpace)) return false; | ||
// Calculate how long the common tick time is based on the header space. | ||
uint32_t space_tick = results->rawbuf[offset++] * kRawTick / | ||
kNecHdrSpaceTicks; | ||
// | ||
// Data | ||
match_result_t data_result = matchData(&(results->rawbuf[offset]), | ||
nbits / 2, | ||
kNecBitMarkTicks * mark_tick, | ||
kNecOneSpaceTicks * space_tick, | ||
kNecBitMarkTicks * mark_tick, | ||
kNecZeroSpaceTicks * space_tick); | ||
if (data_result.success == false) return false; | ||
uint8_t command = data_result.data >> 8; | ||
uint8_t command_inverted = data_result.data; | ||
uint8_t address = data_result.data >> 24; | ||
uint8_t address_inverted = data_result.data >> 16; | ||
// Compliance | ||
if (strict) { | ||
if (command != (command_inverted ^ 0xFF)) | ||
return false; // Command integrity failed. | ||
if (address != (address_inverted ^ 0xFF)) | ||
return false; // Address integrity failed. | ||
} | ||
data = (data << (nbits / 2)) + data_result.data; | ||
offset += data_result.used; | ||
// NEC-like commands and addresses are technically in LSB first order so the | ||
// final versions have to be reversed. | ||
uint16_t code = reverseBits((command << 8) + address, 16); | ||
if (section) | ||
results->command = code; | ||
else | ||
results->address = code; | ||
|
||
// Footer | ||
if (!matchMark(results->rawbuf[offset++], kNecBitMarkTicks * mark_tick)) | ||
return false; | ||
if (offset < results->rawlen && | ||
!matchAtLeast(results->rawbuf[offset++], kNecMinGapTicks * space_tick)) | ||
return false; | ||
} | ||
|
||
// Success | ||
results->bits = nbits; | ||
results->value = data; | ||
results->decode_type = PIONEER; | ||
return true; | ||
} | ||
#endif // DECODE_PIONEER |
Oops, something went wrong.