#include "IRremote.h" //============================================================================== // SSSS H H AAA RRRR PPPP // S H H A A R R P P // SSS HHHHH AAAAA RRRR PPPP // S H H A A R R P // SSSS H H A A R R P //============================================================================== // Sharp and DISH support by Todd Treece: http://unionbridge.org/design/ircommand // // The send function has the necessary repeat built in because of the need to // invert the signal. // // Sharp protocol documentation: // http://www.sbprojects.com/knowledge/ir/sharp.htm // // Here is the LIRC file I found that seems to match the remote codes from the // oscilloscope: // Sharp LCD TV: // http://lirc.sourceforge.net/remotes/sharp/GA538WJSA #define SHARP_BITS 15 #define SHARP_ONE_SPACE 1805 //#define SHARP_ONE_SPACE 1850 #define SHARP_ADDR_BITS 5 #define SHARP_DATA_BITS 8 #define SHARP_BIT_MARK_SEND 250 #define SHARP_BIT_MARK_RECV 150 #define SHARP_ZERO_SPACE 795 #define SHARP_GAP 600000 #define SHARP_REPEAT_SPACE 3000 #define SHARP_TOGGLE_MASK 0x3FF //+============================================================================= #if SEND_SHARP void IRsend::sendSharpRaw(unsigned long data, int nbits) { enableIROut(38); // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission // much more reliable. That's the exact behavior of CD-S6470 remote control. for (int n = 0; n < 3; n++) { sendPulseDistanceWidthData(SHARP_BIT_MARK_SEND, SHARP_ONE_SPACE, SHARP_BIT_MARK_SEND, SHARP_ZERO_SPACE, data, nbits); // for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { // if (data & mask) { // mark (SHARP_BIT_MARK_SEND); // space(SHARP_ONE_SPACE); // } else { // mark (SHARP_BIT_MARK_SEND); // space(SHARP_ZERO_SPACE); // } // } mark(SHARP_BIT_MARK_SEND); space(SHARP_ZERO_SPACE); delay(40); data = data ^ SHARP_TOGGLE_MASK; } space(0); // Always end with the LED off } #endif //+============================================================================= // Sharp send compatible with data obtained through decodeSharp() // ^^^^^^^^^^^^^ FUNCTION MISSING! // #if SEND_SHARP void IRsend::sendSharp(unsigned int address, unsigned int command) { sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS); /* * Use this code instead of the line above to be code compatible to the decoded values from decodeSharp */ // //Change address to big-endian (five bits swap place) // address = (address & 0x10) >> 4 | (address & 0x01) << 4 | (address & 0x08) >> 2 | (address & 0x02) << 2 | (address & 0x04) ; // //Change command to big-endian (eight bit swap place) // command = (command & 0xF0) >> 4 | (command & 0x0F) << 4; // command = (command & 0xCC) >> 2 | (command & 0x33) << 2; // command = (command & 0xAA) >> 1 | (command & 0x55) << 1; // sendSharpRaw((address << 10) | (command << 2) | 0, SHARP_BITS); } #endif // SEND_SHARP //+============================================================================= // Sharp decode function written based on Sharp protocol documentation: // http://www.sbprojects.com/knowledge/ir/sharp.htm // Tesded on a DENON AVR-1804 reciever #if DECODE_SHARP bool IRrecv::decodeSharp() { unsigned long addr = 0; // Somewhere to build our address unsigned long data = 0; // Somewhere to build our data unsigned long lastData = 0; // Somewhere to store last data int offset = 1; //skip long space int loops = 1; //number of bursts // Check we have the right amount of data // Either one burst or three where second is inverted // The setting #define _GAP 5000 in IRremoteInt.h will give one burst and possibly three calls to this function if (irparams.rawlen == (SHARP_BITS + 1) * 2) loops = 1; else if (irparams.rawlen == (SHARP_BITS + 1) * 2 * 3) loops = 3; else return false; // Check the first mark to see if it fits the SHARP_BIT_MARK_RECV length if (!MATCH_MARK(results.rawbuf[offset], SHARP_BIT_MARK_RECV)) return false; //check the first pause and see if it fits the SHARP_ONE_SPACE or SHARP_ZERO_SPACE length if (!(MATCH_SPACE(results.rawbuf[offset + 1], SHARP_ONE_SPACE) || MATCH_SPACE(results.rawbuf[offset + 1], SHARP_ZERO_SPACE))) return false; // Read the bits in for (int j = 0; j < loops; j++) { data = 0; addr = 0; addr = decodePulseDistanceData(SHARP_ADDR_BITS, offset, SHARP_BIT_MARK_SEND, SHARP_ONE_SPACE, SHARP_ZERO_SPACE); // for (int i = 0; i < SHARP_ADDR_BITS; i++) { // // Each bit looks like: SHARP_BIT_MARK_RECV + SHARP_ONE_SPACE -> 1 // // or : SHARP_BIT_MARK_RECV + SHARP_ZERO_SPACE -> 0 // if (!MATCH_MARK(results.rawbuf[offset++], SHARP_BIT_MARK_RECV)) // return false; // // IR data is big-endian, so we shuffle it in from the right: // if (MATCH_SPACE(results.rawbuf[offset], SHARP_ONE_SPACE)) // addr += 1 << i; // else if (MATCH_SPACE(results.rawbuf[offset], SHARP_ZERO_SPACE)) // addr = addr; // else // return false; // offset++; // } data = decodePulseDistanceData( SHARP_DATA_BITS, offset + SHARP_ADDR_BITS, SHARP_BIT_MARK_SEND, SHARP_ONE_SPACE, SHARP_ZERO_SPACE); // for (int i = 0; i < SHARP_DATA_BITS; i++) { // // Each bit looks like: SHARP_BIT_MARK_RECV + SHARP_ONE_SPACE -> 1 // // or : SHARP_BIT_MARK_RECV + SHARP_ZERO_SPACE -> 0 // if (!MATCH_MARK(results.rawbuf[offset++], SHARP_BIT_MARK_RECV)) // return false; // // IR data is big-endian, so we shuffle it in from the right: // if (MATCH_SPACE(results.rawbuf[offset], SHARP_ONE_SPACE)) // data += 1 << i; // else if (MATCH_SPACE(results.rawbuf[offset], SHARP_ZERO_SPACE)) // data = data; // else // return false; // offset++; // //Serial.print(i); // //Serial.print(":"); // //Serial.println(data, HEX); // } //skip exp bit (mark+pause), chk bit (mark+pause), mark and long pause before next burst offset += 6; //Check if last burst data is equal to this burst (lastData already inverted) if (lastData != 0 && data != lastData) return false; //save current burst of data but invert (XOR) the last 10 bits (8 data bits + exp bit + chk bit) lastData = data ^ 0xFF; } // Success results.bits = SHARP_BITS; results.value = data; results.address = addr; results.decode_type = SHARP; return true; } bool IRrecv::decodeSharp(decode_results *aResults) { bool aReturnValue = decodeSharp(); *aResults = results; return aReturnValue; } #endif