Mercurial > tote
changeset 153:78335bffa4b8 teensy31
Remove all extra cruft
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Sun, 28 Jun 2015 23:02:02 +0200 |
| parents | eb22807ec66d |
| children | 8c4bb05fd129 |
| files | start/IRLremote-1.7.3/IRLremote.cpp start/IRLremote-1.7.3/IRLremote.h start/IRLremote-1.7.3/Readme.md start/IRLremote-1.7.3/dev/Interpreting Decoded IR Signals (v2.43).htm start/IRLremote-1.7.3/examples/Advanced/Receive_Custom/Receive_Custom.ino start/IRLremote-1.7.3/examples/Advanced/Receive_NEC_Led_Minimal/Receive_NEC_Led_Minimal.ino start/IRLremote-1.7.3/examples/Advanced/Receive_PinChangeInterrupt_Uno_Api/PinChangeInterrupt.ino start/IRLremote-1.7.3/examples/Advanced/Receive_PinChangeInterrupt_Uno_Api/Receive_PinChangeInterrupt_Uno_Api.ino start/IRLremote-1.7.3/examples/Advanced/Receive_Raw/Receive_Raw.ino start/IRLremote-1.7.3/examples/Advanced/Transceive_HoodLoader2/Transceive_HoodLoader2.ino start/IRLremote-1.7.3/examples/Advanced/Transceive_Minimal/Transceive_Minimal.ino start/IRLremote-1.7.3/examples/Demos/Receive_Blocking/Receive_Blocking.ino start/IRLremote-1.7.3/examples/Demos/Receive_NoBlocking/IRLremote.cpp start/IRLremote-1.7.3/examples/Demos/Receive_NoBlocking/IRLremote.h start/IRLremote-1.7.3/examples/Demos/Receive_NoBlocking/Receive_NoBlocking.ino start/IRLremote-1.7.3/examples/Demos/Receive_PinChangeInterrupt_Basic/Receive_PinChangeInterrupt_Basic.ino start/IRLremote-1.7.3/examples/Demos/Send_Button/Send_Button.ino start/IRLremote-1.7.3/examples/Demos/Send_Serial/Send_Serial.ino start/IRLremote-1.7.3/examples/Demos/Transceive/Transceive.ino start/IRLremote-1.7.3/header.jpg start/IRLremote-1.7.3/keywords.txt start/IRLremote.cpp start/IRLremote.h start/battery.h start/battery.ino start/beep.h start/beep.ino start/clock.ino start/creep.ino start/ir.h start/ir.ino start/leg.h start/leg.ino start/servos.ino start/start.ino |
| diffstat | 35 files changed, 26 insertions(+), 5563 deletions(-) [+] |
line wrap: on
line diff
--- a/start/IRLremote-1.7.3/IRLremote.cpp Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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. -*/ - -#include <IRLremote.h> - -//================================================================================ -// User function helper -//================================================================================ - -// ensure available() returns false -uint8_t IRLProtocol = 0; -uint16_t IRLAddress = 0; -uint32_t IRLCommand = 0; - -// Called when directly received correct IR Signal -// Do not use Serial inside, it can crash your Arduino! -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // For no user function set we need to pause IR - // to not overwrite the actual values until they are read. - if (IRLProtocol) return; - IRLAddress = address; - IRLCommand = command; - IRLProtocol = protocol; -} - -void decodeIR(const uint16_t duration){ - // add your own protocols here or create your own decoding function - // you can overwrite this function in your .ino file - decodeAll(duration); -}
--- a/start/IRLremote-1.7.3/IRLremote.h Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,778 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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 IRLREMOTE_H -#define IRLREMOTE_H - -#include <Arduino.h> - -//missing 1.0.6 definition workaround -#if ARDUINO == 106 -#define NOT_AN_INTERRUPT -1 -#endif - -// board type detection -#if defined(__MK20DX128__) || defined(__MK20DX256__) -#define IRLREMOTE_ARM -#define IRLREMOTE_TEENSY3 -#elif defined(__SAM3X8E__) -#define IRLREMOTE_ARM -#define IRLREMOTE_DUE -#else -// default to assuming everything else is avr for now -#define IRLREMOTE_AVR -#endif - -// delay_basic is only for avrs. with ARM sending is currently not possible -#ifdef IRLREMOTE_AVR -#include <util/delay_basic.h> -#endif - -//================================================================================ -// Definitions -//================================================================================ - -//NEC -//IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,-78,(16,-4,1,-173)*) -// Lead + Space logic -#define NEC_HZ 38400 -#define NEC_PULSE 564UL -#define NEC_BLOCKS 4 -#define NEC_ADDRESS_LENGTH 16 -#define NEC_COMMAND_LENGTH 16 -#define NEC_LENGTH 2 + NEC_BLOCKS*8*2 // 2 for lead + space, each block has 8bits: mark and space -#define NEC_TIMEOUT NEC_PULSE*173 -#define NEC_MARK_LEAD NEC_PULSE*16 -#define NEC_SPACE_LEAD NEC_PULSE*8 -#define NEC_SPACE_HOLDING NEC_PULSE*4 -#define NEC_MARK_ZERO NEC_PULSE*1 -#define NEC_MARK_ONE NEC_PULSE*1 -#define NEC_SPACE_ZERO NEC_PULSE*1 -#define NEC_SPACE_ONE NEC_PULSE*3 - -//PANASONIC -//IRP notation: {37k,432}<1,-1|1,-3>(8,-4,3:8,1:8,D:8,S:8,F:8,(D^S^F):8,1,-173)+ -// Lead + Space logic -#define PANASONIC_HZ 37000 -#define PANASONIC_PULSE 432UL -#define PANASONIC_BLOCKS 6 -#define PANASONIC_ADDRESS_LENGTH 16 -#define PANASONIC_COMMAND_LENGTH 32 -#define PANASONIC_LENGTH 2 + PANASONIC_BLOCKS*8*2 // 2 for lead + space, each block has 8bits: mark and space -#define PANASONIC_TIMEOUT PANASONIC_PULSE*173 -#define PANASONIC_MARK_LEAD PANASONIC_PULSE*8 -#define PANASONIC_SPACE_LEAD PANASONIC_PULSE*4 -#define PANASONIC_SPACE_HOLDING 0 // no holding function in this protocol -#define PANASONIC_MARK_ZERO PANASONIC_PULSE*1 -#define PANASONIC_MARK_ONE PANASONIC_PULSE*1 -#define PANASONIC_SPACE_ZERO PANASONIC_PULSE*1 -#define PANASONIC_SPACE_ONE PANASONIC_PULSE*3 - -/* -Panasonic pulse demonstration: - -*---------| |------------| |---------| |---| ... -| |--------- -* | | | | | | | ... | | -* | | | | | | | ... | | -* |------------------------| |---| |---| |- ... |---| -* | Lead Mark | Lead Space | Logical 1 | Log 0 | Data |End| - -*/ - -//SONY 8, 12, 15, 20 -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:8,^22200) -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m) + -// Lead + Mark logic -#define SONY_HZ 40000 -#define SONY_PULSE 600UL -#define SONY_BLOCKS_8 1 -#define SONY_BLOCKS_12 2 -#define SONY_BLOCKS_15 2 -#define SONY_BLOCKS_20 3 -#define SONY_ADDRESS_LENGTH_8 0 -#define SONY_ADDRESS_LENGTH_12 5 -#define SONY_ADDRESS_LENGTH_15 8 -#define SONY_ADDRESS_LENGTH_20 13 -#define SONY_COMMAND_LENGTH_8 8 -#define SONY_COMMAND_LENGTH_12 7 -#define SONY_COMMAND_LENGTH_15 7 -#define SONY_COMMAND_LENGTH_20 7 -#define SONY_LENGTH_8 2 + (8-1)*2 // 2 for lead + space, -1 for mark end, 8 bit -#define SONY_LENGTH_12 2 + (7+5-1)*2 // 2 for lead + space, -1 for mark end, 12 bit -#define SONY_LENGTH_15 2 + (7+8-1)*2 // 2 for lead + space, -1 for mark end, 15 bit -#define SONY_LENGTH_20 2 + (7+5+8-1)*2 // 2 for lead + space, -1 for mark end, 20 bit -#define SONY_TIMEOUT_8 22200 -#define SONY_TIMEOUT 45000 // 12, 15, 20 have the same timeout -#define SONY_MARK_LEAD SONY_PULSE*4 -#define SONY_SPACE_LEAD SONY_PULSE*1 -#define SONY_SPACE_HOLDING 0 // no holding function in this protocol -#define SONY_MARK_ZERO SONY_PULSE*1 -#define SONY_MARK_ONE SONY_PULSE*2 -#define SONY_SPACE_ZERO SONY_PULSE*1 -#define SONY_SPACE_ONE SONY_PULSE*1 - -typedef enum IRType{ - IR_NO_PROTOCOL, // 0 - IR_USER, // 1 - IR_ALL, // 2 - IR_NEC, // ... - IR_PANASONIC, - IR_SONY8, - IR_SONY12, - IR_SONY15, - IR_SONY20, - // add new protocols here - IR_RAW, -}; - -// definitions to use decoding functions with extra accuracy -#define IR_EXTRA_ACCURACY true -#define IR_NO_EXTRA_ACCURACY false - -// definition for sending to determine what should be send first -#define IR_ADDRESS_FIRST true -#define IR_COMMAND_FIRST false - -// definition to convert an uint8_t array to an uint16_t/uint32_t at any position (thx timeage!) -#define UINT16_AT_OFFSET(p_to_8, offset) ((uint16_t)*((const uint16_t *)((p_to_8)+(offset)))) -#define UINT32_AT_OFFSET(p_to_8, offset) ((uint32_t)*((const uint32_t *)((p_to_8)+(offset)))) - -// definition to get the higher value -#define MAX(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) - -// definition to get the lower value -#define MIN(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) - -//================================================================================ -// Prototypes -//================================================================================ - -// attach the interrupt function -template <IRType irType> -inline void IRLbegin(const uint8_t interrupt) __attribute__((always_inline)); - -// dettach the interrupt function -inline void IRLend(const uint8_t interrupt) __attribute__((always_inline)); - -// variables for IR processing if no user function was set -extern uint8_t IRLProtocol; -extern uint16_t IRLAddress; -extern uint32_t IRLCommand; - -// functions to use if no user function was set -inline bool IRLavailable(void) __attribute__((always_inline)); -inline void IRLreset(void) __attribute__((always_inline)); -inline uint8_t IRLgetProtocol(void) __attribute__((always_inline)); -inline uint16_t IRLgetAddress(void) __attribute__((always_inline)); -inline uint32_t IRLgetCommand(void) __attribute__((always_inline)); - -// function called on a valid IR event, must be overwritten by the user -void __attribute__((weak)) IREvent(uint8_t protocol, uint16_t address, uint32_t command); - -// optinal user function called when the user wants to implement its own decoding function -void __attribute__((weak)) decodeIR(const uint16_t duration); - -// called by interrupt CHANGE -template <IRType irType> -inline void IRLinterrupt(void) __attribute__((always_inline)); - -// special decode function for each protocol -inline void decodeAll(const uint16_t duration) __attribute__((always_inline)); -template <bool extraAccuracy> inline void decodeNec(const uint16_t duration); -template <bool extraAccuracy> inline void decodePanasonic(const uint16_t duration) __attribute__((always_inline)); -template <bool extraAccuracy> inline void decodeSony8(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony12(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony15(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony20(const uint16_t duration); -inline void decodeRaw(const uint16_t duration) __attribute__((always_inline)); - -// functions to check if the received data is valid with the protocol checksums -inline bool IRLcheckInverse0(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckInverse1(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckHolding(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckXOR0(uint8_t data[]) __attribute__((always_inline)); - -// default decoder helper function -template <uint8_t irLength, uint16_t timeoutThreshold, uint16_t markLeadThreshold, uint16_t spaceLeadThreshold, - uint16_t spaceLeadHoldingThreshold, uint16_t markThreshold, uint16_t spaceThreshold, - uint16_t markTimeout, uint16_t spaceTimeout> - inline bool IRLdecode(uint16_t duration, uint8_t data[]) __attribute__((always_inline)); - -// functions to send the protocol -template <IRType irType> -inline void IRLwrite(const uint8_t pin, uint16_t address, uint32_t command) __attribute__((always_inline)); - -template <uint8_t addressLength, uint8_t commandLength, - uint16_t Hz, bool addressFirst, - uint16_t markLead, uint16_t spaceLead, - uint16_t markZero, uint16_t markOne, - uint16_t spaceZero, uint16_t spaceOne> - inline void IRLsend(volatile uint8_t * outPort, uint8_t bitmask, uint16_t address, uint32_t command) __attribute__((always_inline)); - -// functions to set the pin high or low (with bitbang pwm) -inline void IRLmark(const uint16_t Hz, volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) __attribute__((always_inline)); -inline void IRLspace(volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) __attribute__((always_inline)); - -//================================================================================ -// Inline Implementations (receive) -//================================================================================ - -template <IRType irType> -void IRLbegin(const uint8_t interrupt){ - // attach the function that decodes the signals - attachInterrupt(interrupt, IRLinterrupt<irType>, CHANGE); -} - -void IRLend(const uint8_t interrupt){ - // release the interrupt, if its NOT_AN_INTERRUPT the detach function does nothing - detachInterrupt(interrupt); - // also make sure to call reset() after end() if you use the intern reading functions -} - -bool IRLavailable(void){ - return IRLProtocol; -} - -void IRLreset(void){ - IRLProtocol = 0; -} - -uint8_t IRLgetProtocol(void){ - return IRLProtocol; -} - -uint16_t IRLgetAddress(void){ - return IRLAddress; -} - -uint32_t IRLgetCommand(void){ - return IRLCommand; -} - -template <IRType irType> -void IRLinterrupt(void){ - //save the duration between the last reading - static uint32_t lastTime = 0; - uint32_t time = micros(); - uint32_t duration_32 = time - lastTime; - lastTime = time; - - // calculate 16 bit duration. On overflow set duration to a clear timeout - uint16_t duration = 0xFFFF; - if (duration_32 <= 0xFFFF) - duration = duration_32; - - // determinate which decode function must be called - switch (irType){ - case IR_USER: - // userfunction that can be overwritten - decodeIR(duration); - break; - case IR_ALL: - decodeAll(duration); - break; - case IR_NEC: - decodeNec<IR_NO_EXTRA_ACCURACY>(duration); - break; - case IR_PANASONIC: - decodePanasonic<IR_NO_EXTRA_ACCURACY>(duration); - break; - //case IR_SONY8: - // decodeSony8<IR_NO_EXTRA_ACCURACY>(duration); - // break; - case IR_SONY12: - decodeSony12<IR_NO_EXTRA_ACCURACY>(duration); - break; - //case IR_SONY15: - // decodeSony15<IR_NO_EXTRA_ACCURACY>(duration); - // break; - //case IR_SONY20: - // decodeSony20<IR_NO_EXTRA_ACCURACY>(duration); - // break; - case IR_RAW: - decodeRaw(duration); - break; - } -} - -void decodeAll(const uint16_t duration){ - // go through all known protocols and decode with more (resource unfriendly) accuration - decodeNec<IR_EXTRA_ACCURACY>(duration); - decodePanasonic<IR_EXTRA_ACCURACY>(duration); - decodeSony12<IR_EXTRA_ACCURACY>(duration); -} - -template <bool extraAccuracy> void decodeNec(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[NEC_BLOCKS]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) // no accuracy set at the moment, no conflict detected yet - newInput = IRLdecode <NEC_LENGTH, (NEC_TIMEOUT + NEC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (NEC_MARK_LEAD + NEC_SPACE_ONE) / 2, (NEC_SPACE_LEAD + NEC_SPACE_HOLDING) / 2, // markLeadThreshold, spaceLeadThreshold - (NEC_SPACE_HOLDING + NEC_SPACE_ONE) / 2, 0, // spaceLeadHoldingThreshold, markThreshold - (NEC_SPACE_ONE + NEC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <NEC_LENGTH, (NEC_TIMEOUT + NEC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (NEC_MARK_LEAD + NEC_SPACE_ONE) / 2, (NEC_SPACE_LEAD + NEC_SPACE_HOLDING) / 2, // markLeadThreshold, spaceLeadThreshold - (NEC_SPACE_HOLDING + NEC_SPACE_ONE) / 2, 0, // spaceLeadHoldingThreshold, markThreshold - (NEC_SPACE_ONE + NEC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // Check if the protcol's checksum is correct - bool holding; - if (IRLcheckInverse1(data) || (holding = IRLcheckHolding(data))){ - // normally NEC also check for the inverse of the address. - // newer remotes dont have this because of the wide used protocol all addresses were already used - // to make it less complicated its left out and the user can check the command inverse himself if needed - //if (!holding && !extended && !IRLcheckInverse0(data)) - // return; - - // save address + command and trigger event - uint16_t address = UINT16_AT_OFFSET(data, 0); - uint32_t command = UINT16_AT_OFFSET(data, 2); - IREvent(IR_NEC, address, command); - } - } -} - -template <bool extraAccuracy> void decodePanasonic(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[PANASONIC_BLOCKS]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) // no accuracy set at the moment, no conflict detected yet - newInput = IRLdecode <PANASONIC_LENGTH, (PANASONIC_TIMEOUT + PANASONIC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (PANASONIC_MARK_LEAD + PANASONIC_SPACE_ONE) / 2, (PANASONIC_SPACE_LEAD + PANASONIC_SPACE_ONE) / 2, // markLeadThreshold, spaceLeadThreshold - 0, 0, // spaceLeadHoldingThreshold, markThreshold - (PANASONIC_SPACE_ONE + PANASONIC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <PANASONIC_LENGTH, (PANASONIC_TIMEOUT + PANASONIC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (PANASONIC_MARK_LEAD + PANASONIC_SPACE_ONE) / 2, (PANASONIC_SPACE_LEAD + PANASONIC_SPACE_ONE) / 2, // markLeadThreshold, spaceLeadThreshold - 0, 0, // spaceLeadHoldingThreshold, markThreshold - (PANASONIC_SPACE_ONE + PANASONIC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // Check if the protcol's checksum is correct - if (IRLcheckXOR0(data)){ - uint16_t address = UINT16_AT_OFFSET(data, 0); - uint32_t command = UINT32_AT_OFFSET(data, 2); IREvent(IR_PANASONIC, address, command); - return; - } - } -} - -template <bool extraAccuracy> void decodeSony12(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[SONY_BLOCKS_12]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) - newInput = IRLdecode <SONY_LENGTH_12, (SONY_TIMEOUT + SONY_MARK_LEAD) / 2, // irLength, timeoutThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, 0, // markLeadThreshold, spaceLeadThreshold - 0, (SONY_MARK_ONE + SONY_MARK_ZERO) / 2, // spaceLeadHoldingThreshold, markThreshold - 0, // spaceThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, SONY_MARK_ONE>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <SONY_LENGTH_12, (SONY_TIMEOUT + SONY_MARK_LEAD) / 2, // irLength, timeoutThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, 0, // markLeadThreshold, spaceLeadThreshold - 0, (SONY_MARK_ONE + SONY_MARK_ZERO) / 2, // spaceLeadHoldingThreshold, markThreshold - 0, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // protocol has no checksum - uint16_t address = UINT16_AT_OFFSET(data, 0) >> 7; - uint32_t command = data[0] & 0x7F; - IREvent(IR_SONY12, address, command); - return; - } -} - -void decodeRaw(const uint16_t duration){ - //TODO, use advanced raw example instead -} - -bool IRLcheckInverse0(uint8_t data[]){ - // check if byte 2 and is the inverse of byte 3 - if (uint8_t((data[0] ^ (~data[1]))) == 0) - return true; - else return false; -} - -bool IRLcheckInverse1(uint8_t data[]){ - // check if byte 0 and is the inverse of byte 1 - if (uint8_t((data[2] ^ (~data[3]))) == 0) - return true; - else return false; -} - -bool IRLcheckHolding(uint8_t data[]){ - // check if at least the command is always 1 - if (data[2] == 0xFF && data[3] == 0xFF) - return true; - else return false; -} - -bool IRLcheckXOR0(uint8_t data[]){ - // this function is used for panasonic checksum - if (uint8_t(data[2] ^ data[3] ^ data[4]) == data[5]) - return true; - else return false; -} - -// multifunctional template for receiving -template <uint8_t irLength, uint16_t timeoutThreshold, uint16_t markLeadThreshold, uint16_t spaceLeadThreshold, - uint16_t spaceLeadHoldingThreshold, uint16_t markThreshold, uint16_t spaceThreshold, - uint16_t markTimeout, uint16_t spaceTimeout> - bool IRLdecode(uint16_t duration, uint8_t data[]){ - - // variables for ir processing - static uint8_t count = 0; - - // if timeout always start next possible reading and abort any pending readings - if (duration >= timeoutThreshold) - count = 1; - - // on a reset (error in decoding) we are waiting for a timeout to start a new reading again - // this is to not conflict with other protocols while they are sending 0/1 which might be similar to a lead in another protocol - else if (count == 0) - return false; - - // check pulses for mark/space and lead + logical 0/1 seperate - else{ - // Mark pulses (odd numbers) - if (count % 2 == 1){ - // check Mark Lead (needs a timeout or a correct signal) - if (markLeadThreshold && count == 1){ - // lead is okay// wrong lead - if (duration <= markLeadThreshold){ - count = 0; - return false; - } - } - - else{ - // check for timeout if needed (might be a different protocol) - if (markTimeout && duration > markTimeout){ - count = 0; - return false; - } - - // only check values if the protocol has different logical space pulses - else if (markThreshold){ - - // get number of the Mark Bits (starting from zero) - uint8_t length; - // only save every 2nd value, substract the first two lead pulses - if (!spaceThreshold) - length = (count / 2) - 1; - // special case: spaces and marks both have data in the pulse - else length = count - 2; - - // move bits and write 1 or 0 depending on the duration - // 1.7: changed from MSB to LSB. somehow takes a bit more flash but is correct and easier to handle. - data[length / 8] >>= 1; - if (duration > markThreshold) - data[length / 8] |= 0x80; - //else // normally not needed through the bitshift - // data[length / 8] &= ~0x80; - } - - // check last input (always a mark) - if (count > irLength){ - count = 0; - return true; - } - } - } - - // Space pulses (even numbers) - else{ - //check Space Lead/Space Holding - if (spaceLeadThreshold && count == 2){ - // normal Space, next reading - if (duration > spaceLeadThreshold); - - // Button holding (if supported by protocol) - else if (spaceLeadHoldingThreshold && duration > spaceLeadHoldingThreshold){ - // set command to 0xFF if button is held down - if (irLength == (4 * 8 * 2 + 2)){ - data[0] = data[1] = 0x00; - data[2] = data[3] = 0xFF; - } - count = 0; - return true; - } - // wrong space - else { - count = 0; - return false; - } - } - else{ - // check for timeout if needed (might be a different protocol) - if (spaceTimeout && duration > spaceTimeout){ - count = 0; - return false; - } - - // only check values if the protocol has different logical space pulses - else if (spaceThreshold){ - - // get number of the Space Bits (starting from zero) - uint8_t length; - // only save every 2nd value, substract the first two lead pulses - if (!markThreshold) - length = (count / 2) - 2; - // special case: spaces and marks both have data in the pulse - else length = count - 2; - - // move bits and write 1 or 0 depending on the duration - // 1.7: changed from MSB to LSB. somehow takes a bit more flash but is correct and easier to handle. - data[length / 8] >>= 1; - if (duration > spaceThreshold) - data[length / 8] |= 0x80; - //else // normally not needed through the bitshift - // data[length / 8] &= ~0x80; - } - } - } - - // next reading, no errors - count++; - } - - // no valid input (yet) - return false; -} - -//================================================================================ -// Inline Implementations (send) -//================================================================================ - -template <IRType irType> -void IRLwrite(const uint8_t pin, uint16_t address, uint32_t command) -{ - // get the port mask and the pointers to the out/mode registers for faster access - uint8_t bitMask = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - volatile uint8_t * outPort = portOutputRegister(port); - volatile uint8_t * modePort = portModeRegister(port); - - // set pin to OUTPUT and LOW - *modePort |= bitMask; - *outPort &= ~bitMask; - - // disable interrupts - uint8_t oldSREG = SREG; - cli(); - - switch (irType){ - - case IR_NEC: - // NEC only sends the data once - if (command == 0xFFF) - // send holding indicator - IRLsend<0, 0, NEC_HZ, 0, NEC_MARK_LEAD, NEC_SPACE_HOLDING, - 0, 0, 0, 0> - (outPort, bitMask, address, command); - else - // send data - IRLsend<NEC_ADDRESS_LENGTH, NEC_COMMAND_LENGTH, NEC_HZ, IR_ADDRESS_FIRST, NEC_MARK_LEAD, NEC_SPACE_LEAD, - NEC_MARK_ZERO, NEC_MARK_ONE, NEC_SPACE_ZERO, NEC_SPACE_ONE> - (outPort, bitMask, address, command); - break; - - case IR_PANASONIC: //TODO test - // send data - IRLsend<PANASONIC_ADDRESS_LENGTH, PANASONIC_COMMAND_LENGTH, PANASONIC_HZ, IR_ADDRESS_FIRST, PANASONIC_MARK_LEAD, PANASONIC_SPACE_LEAD, - PANASONIC_MARK_ZERO, PANASONIC_MARK_ONE, PANASONIC_SPACE_ZERO, PANASONIC_SPACE_ONE> - (outPort, bitMask, address, command); - break; - - case IR_SONY12: //TODO test, address -1? - // repeat 3 times - for (uint8_t i = 0; i < 3; i++) - // send data - IRLsend<SONY_ADDRESS_LENGTH_12, SONY_COMMAND_LENGTH_12, SONY_HZ, IR_COMMAND_FIRST, SONY_MARK_LEAD, SONY_SPACE_LEAD, - SONY_MARK_ZERO, SONY_MARK_ONE, SONY_SPACE_ZERO, SONY_SPACE_ONE> - (outPort, bitMask, address, command); - break; - } - - // enable interrupts - SREG = oldSREG; - - // set pin to INPUT again to be save - *modePort &= ~bitMask; -} - -// multifunctional template for sending -template <uint8_t addressLength, uint8_t commandLength, - uint16_t Hz, bool addressFirst, - uint16_t markLead, uint16_t spaceLead, - uint16_t markZero, uint16_t markOne, - uint16_t spaceZero, uint16_t spaceOne> - void IRLsend(volatile uint8_t * outPort, uint8_t bitmask, uint16_t address, uint32_t command){ - - // send lead mark - if (markLead) - IRLmark(Hz, outPort, bitmask, markLead); - - // send lead space - if (spaceLead) - IRLspace(outPort, bitmask, spaceLead); - - // abort if input values are both the same (sending a holding signal for example) - if (markOne != markZero || spaceOne != spaceZero) - { - // go through all bits - for (uint8_t i = 0; i < (addressLength + commandLength); i++){ - // determine if its a logical one or zero, starting with address or command - bool bitToSend; - if (addressFirst && i < addressLength || !addressFirst && i >= commandLength){ - bitToSend = address & 0x01; - address >>= 1; - } - else{ - bitToSend = command & 0x01; - command >>= 1; - } - - // send logic mark bits if needed - if (markOne != markZero){ - // modulate if spaces dont have logic, else only every even number - if (spaceOne == spaceZero || spaceOne != spaceZero && i % 2 == 0) - { - if (bitToSend) - IRLmark(Hz, outPort, bitmask, markOne); - else - IRLmark(Hz, outPort, bitmask, markZero); - } - } - else - IRLmark(Hz, outPort, bitmask, markOne); - - // send logic space bits if needed - if (spaceOne != spaceZero){ - // modulate if marks dont have logic, else only every odd number - if (markOne == markZero || markOne != markZero && i % 2 == 1){ - if (bitToSend) - IRLspace(outPort, bitmask, spaceOne); - else - IRLspace(outPort, bitmask, spaceZero); - } - } - else - IRLspace(outPort, bitmask, spaceOne); - } - } - - // finish mark - IRLmark(Hz, outPort, bitmask, markZero); //TODO zero or one for sony? - IRLspace(outPort, bitmask, 0); -} - -void IRLmark(const uint16_t Hz, volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) { - /* - Bitbangs PWM in the given Hz number for the given time - ________________________________________________________________________________ - Delay calculation: - F_CPU/1.000.000 to get number of cycles/uS - /3 to get the number of loops needed for 1ms (1loop = 3 cycles) - - Multiply with the number of ms delay: - 1/kHz to get the seconds - * 1.000.000 to get it in uS - /2 to get half of a full pulse - - Substract the while, portmanipulation, loop overhead /3 loop cycles - - F_CPU(16.000.000) 1 * 1.000.000(pulse in uS) 12(overhead) - ========================== * ========================== - ============== - 1.000.000 * 3(loop cycles) Hz * 2(half of a pulse) 3(loop cycles) - - <==> - - F_CPU(16.000.000) - (12(overhead) * Hz * 2(half of a pulse)) - =========================================================== - Hz * 2(half of a on/off pulse) * 3(loop cycles) - - ________________________________________________________________________________ - Iterations calculation: - Devide time with cycles in while loop - Multiply this with the cycles per uS - cycles per while loop: 3(loop cycles) * delay + overhead - - time * (F_CPU(16.000.000) / 1.000.000) - ====================================== - delay*3(loop cycles) + overhead - */ - - const uint32_t loopCycles = 3; - const uint32_t overHead = 12; // just a guess from try + error - uint8_t delay = (F_CPU - (overHead * Hz * 2UL)) / (Hz * 2UL * loopCycles); - uint16_t iterations = (time*(F_CPU / 1000000UL)) / (delay * loopCycles + overHead); - - while (iterations--){ - // flip pin state and wait for the calculated time - *outPort ^= bitMask; -#ifdef IRLREMOTE_AVR - _delay_loop_1(delay); -#else - // ARM TODO? -#endif - } -} - -void IRLspace(volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) { - // Sends an IRLspace for the specified number of microseconds. - // A IRLspace is no output, so the PWM output is disabled. - *outPort &= ~bitMask; // write pin LOW - delayMicroseconds(time); - //_delay_loop_2(time*(F_CPU/1000000UL)/4UL); -} - -#endif \ No newline at end of file
--- a/start/IRLremote-1.7.3/Readme.md Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ -IRLremote 1.7.3 -=============== - - - -New lightweight IR library with different, smarter implementation. - -This library is way more efficient than the "standard" IR library from Ken Shirriff -and should be a replacement of the library (sorry for that ;D). - -**The main improvements are:** -* Faster decoding (on the fly) -* Huge Ram improvements (13 bytes ram to decode NEC) -* Huge Flash improvements (less than 1kb flash to decode NEC) -* Receiving and sending possible -* Very accurate even when pointing in different directions -* Easy to use/Customizable -* Maximum error correction -* Uses pin interrupt function/No timer needed -* PCINT also usable for advanced users -* Perfect for Attinys -* Written in C, only uses C++ templates -* IDE 1.5.8 compatible - -**Supported Protocols** -* NEC -* Panasonic -* Sony 12 -* Ask me for more - -**Planned features:** -* Test sending functions (for Panasonic, Sony etc) -* Add more protocols -* Improve bit banging PWM? -* Improve PCInt? -* Add Raw dump + sending option + improve raw function -* Add High/Low compare for unknown protocols - -[Comment for feedback on my blog post.](http://nicohood.wordpress.com/2014/09/20/new-lightweight-infrared-library-for-arduino/) - -Installation/How to use -======================= - -Download the zip, extract and remove the "-master" of the folder. -Install the library [as described here](http://arduino.cc/en/pmwiki.php?n=Guide/Libraries). - -### Receiving - -See [this reference](http://arduino.cc/en/pmwiki.php?n=Reference/AttachInterrupt) for choosing the right interrupt pin -(not all pins are usable for decoding). -If you cannot use one of these pins, you might want to try the advanced PCINT example. - -Try the examples to see how it works. -**I recommend to check the example ReceiveInterrupt or ReceiveBlocking.** - -One you know what protocol your remote uses, choose yours from one of these options and change it in the setup(): -```cpp -typedef enum IRType{ - IR_NO_PROTOCOL, // 0 - IR_USER, // 1 - IR_ALL, // 2 - IR_NEC, // ... - IR_PANASONIC, - IR_SONY8, // soon - IR_SONY12, - IR_SONY15, // soon - IR_SONY20, // soon - // add new protocols here - IR_RAW, -}; -``` -Each protocol number (Serial output in the examples) is equal to one of these names, starting from zero. -So if you get protocol 3 this means its NEC. By default the library tries to decode all known protocols. - -**You can save a lot of ram/flash/performance by using a fixed protocol** like IR_NEC instead of IR_ALL in the begin function. -If you choose a single protocol, keep in mind that accuracy is then set very low to get **maximal recognition and less code size**. -If you want to use more protocols or keep away different IR input devices which might cause problems, see the **advanced custom receiving example**. - -The IR_USER IRType is for custom protocols/protocol combinations. See advanced examples. -There is also an example for raw output and a PCINT version. **With the basic PCINT version you can also -decrease flash size even more and be more flexible with your sending pin!** - -**Keep in mind that from v1.6 to v1.7 the bit order has changed -and command and address might be a different value now.** - -### Sending - -**For sending see the SendSerial/Button examples.** You first have to read the codes of your remote with one of the receiving examples. -Choose your protocol in the sending sketch and use your address and command if choice. - -Sending for Panasonic and Sony12 is not confirmed to work, since I have no device here to test. -Let me know if it works! - -**Keep in mind that from v1.6 to v1.7 the bit order has changed -and command and address might be a different value now.** - -### Adding new protocols - -Informations about IR protocols can be found [here](http://www.hifi-remote.com/johnsfine/DecodeIR.html) -(a bit hard to understand but try it if you want to create a new protocol). -=> Website is offline, see /dev for an offline version of the website - -You can also ask me to implement any new protocol, just file it as issue on Github or contact me on my blog. - -More projects + contact can be found here: -http://nicohood.wordpress.com/ - -How it works -============ - -**The idea is: minimal implementation with maximal recognition. -You can decode more than one protocol at the same time.** - -The trick is to only check the border between logical zero and one -to terminate space/mark and rely on the lead/length/checksum as error correction. -Lets say a logical 0 is 500ms and 1 is 1000ms. Then the border would be 750ms -to get maximum recognition instead of using just 10%. - -Other protocols use different timings, leads, length, checksums -so it shouldn't interfere with other protocols even with this method. - -This gives the library very small implementation with maximum recognition. -You can point into almost every possible direction in the room without wrong signals. - -It saves a lot of ram because it decodes the signals "on the fly" when an interrupt occurs. -That's why you should not add too many protocols at once to exceed the time of the next signal. -However its so fast, its shouldn't make any difference since we are talking about ms, not us. - -**In comparison to Ken's lib**, he records the signals (with timer interrupts) in a buffer which takes a lot of ram. -Then you need to check in the main loop if the buffer has any valid signals. -It checks every signal, that's why its slow and takes a lot of flash. -And it also checks about 10~20% from the original value. Lets say a pulse is 100ms. Then 80-120ms is valid. -That's why the recognition is worse. And he also doesn't check the protocol intern error correction. -For example NEC has an inverse in the command: the first byte is the inverse of the 2nd byte. Its easy to filter wrong signals then. -So every protocol has its built in checksums, which we will use. And I also check for timeouts and start new readings if the signal timed out. -The only positive thing is that with the timer the pin is more flexible. However i will try to implement a PCINT version later. - -For sending I decided to use Bitbang. This works on every MCU and on any PIN. He used proper timers, -but only PIN 3 is usable for sending (an interrupt pin). Bitbang might have problems with other interrupts but should work relyable. -You can turn off interrupts before sending if you like to ensure a proper sending. -Normal IR devices shouldn't complain about a bit intolerance in the PWM signal. Just try to keep interrupts short. - -Check ReceiveNECLed for a minimal implementation example. -The code itself seems to be a bit organized but I had to implement a lot of functions inline -to get maximum optimization. - -This text should not attack the library from Ken. It's a great library with a lot of work and the most used IR library yet. -It is just worth a comparison and might be still useful like the old SoftSerial against the new one. - -Version History -=============== -``` -1.7.3 Release (27.11.2014) -* Fixed critical Typo in decoding function -* Fixed weak function variable type -* Updated Raw Example slightly - -1.7.2 Release (18.11.2014) -* Added always inline macro -* Changed duration to 16 bit -* Added easier PCINT map definitions -* Fixed ARM compilation for receiving (sending is still not working) - -1.7.1 Release (15.11.2014) -* Added 16u2 HoodLoader2 example - -1.7 Release (15.11.2014) -* Changed IR bit order from MSB to correct LSB - * This improved the overall handling and also reduced flash usage -* Improved, extended sending function -* Added Receive Send Example -* Added smaller Basic PCINT function - -1.6 Release (14.11.2014) -* Reworked decoding template -* Added Sony 12 protocol -* Added PCINT example for advanced users - -1.5.1 Release (21.09.2014) -* improved Bitbang PWM -* fixed SendSerial example - -1.5.0 Release (20.09.2014) -* huge Ram and Flash improvements -* new library structure -* compacter code/new structure -* more examples -* more than one protocol possible at the same time -* customizable decoding functions - -1.4.7 Release (13.09.2014) -* changed NEC to template - -1.4.6 Release (30.08.2014) -* fixed writing address + command bug -* added sending function for NEC -* added Led example - -1.4.5 Release (30.08.2014) -* fixed raw protocol - -1.4.4 Release (07.08.2014) -* added raw protocol (broken) - -1.4.3 Release (06.08.2014) -* changed and improved a lot of stuff -* rearranged classes -* removed older versions - -1.0 - 1.3 (17.03.2014 - 03.5.2014) -* Release and minor fixes -``` - -Licence and Copyright -===================== -If you use this library for any cool project let me know! - -``` -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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. -```
--- a/start/IRLremote-1.7.3/dev/Interpreting Decoded IR Signals (v2.43).htm Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1474 +0,0 @@ -<html><head> -<meta http-equiv="content-type" content="text/html; charset=windows-1252"> -<title>Interpreting Decoded IR Signals (v2.43)</title> -</head> -<body alink="#996600" background="Interpreting%20Decoded%20IR%20Signals%20(v2.43)-Dateien/bg.jpg" bgcolor="#ffffff" link="#3366cc" text="#000000" vlink="#666666"> - -<table width="750"><tbody><tr><td><center> -<script type="text/javascript"><!-- -google_ad_client = "pub-2040680936936450"; -/* 468x60, created 4/17/09 */ -google_ad_slot = "7283198346"; -google_ad_width = 468; -google_ad_height = 60; -//--> -</script> -<script type="text/javascript" src="Interpreting%20Decoded%20IR%20Signals%20%28v2.43%29-Dateien/show_ads.js"> -</script> -</center> -</td></tr></tbody></table> -<p> - -</p><blockquote> -<a href="#Introduction">Introduction</a><br><br> - -<table> -<tbody><tr><td valign="top" width="140"> -<a href="#48-NEC">48-NEC</a><br> -<a href="#48-NEC1">48-NEC1</a><br> -<a href="#48-NEC2">48-NEC2</a><br> -<a href="#AdNotam">AdNotam</a><br> -<a href="#AirAsync">AirAsync</a><br> -<a href="#AirB?-????">AirB?-????</a><br> -<a href="#Aiwa">Aiwa</a><br> -<a href="#AK">AK</a><br> -<a href="#Akai">Akai</a><br> -<a href="#Amino">Amino</a><br> -<a href="#Anthem">Anthem</a><br> -<a href="#Apple">Apple</a><br> -<a href="#Archer">Archer</a><br> -<a href="#Async">Async</a><br> -<a href="#Blaupunkt">Blaupunkt</a><br> -<a href="#Bose">Bose</a><br> -<a href="#CanalSat">CanalSat</a><br> -<a href="#Denon">Denon</a><br> -<a href="#Denon">Denon{1}</a><br> -<a href="#Denon">Denon{2}</a><br> -<a href="#Denon-K">Denon-K</a><br> -<a href="#Dgtec">Dgtec</a><br> -<a href="#DirecTV">DirecTV</a><br> -<a href="#Dishplayer">Dishplayer</a><br> -<a href="#Dish_Network">Dish_Network</a><br> -<a href="#Emerson">Emerson</a><br> -<a href="#F12">F12</a><br> -</td> - -<td valign="top" width="144"> -<a href="#Fujitsu">Fujitsu</a><br> -<a href="#Fujitsu-56">Fujitsu-56</a><br> -<a href="#G.I.%20Cable">G.I. Cable</a><br> -<a href="#G.I.%20Cable">G.I. Cable{1}</a><br> -<a href="#G.I.4DTV">G.I.4DTV</a><br> -<a href="#Grundig16">Grundig16</a><br> -<a href="#Grundig16">Grundig16-30</a><br> -<a href="#GXB">GXB</a><br> -<a href="#IODATAn">IODATA<i>n</i></a><br> -<a href="#IODATAn">IODATA<i>n</i>-<i>x</i>-<i>y</i></a><br> -<a href="#Jerrold">Jerrold</a><br> -<a href="#JVC">JVC</a><br> -<a href="#JVC">JVC{2}</a><br> -<a href="#JVC-48">JVC-48</a><br> -<a href="#JVC-56">JVC-56</a><br> -<a href="#Kaseikyo">Kaseikyo</a><br> -<a href="#Kaseikyo-???-???">Kaseikyo-???-???</a><br> -<a href="#Kaseikyo56">Kaseikyo56</a><br> -<a href="#Kaseikyo56-???-???">Kaseikyo56-???-???</a><br> -<a href="#Kathrein">Kathrein</a><br> -<a href="#Konka">Konka</a><br> -<a href="#Lumagen">Lumagen</a><br> -<a href="#Lutron">Lutron</a><br> -<a href="#Matsui">Matsui</a><br> -<a href="#MCE">MCE</a><br> -<a href="#Metz19">Metz19</a><br> -</td> - -<td valign="top" width="142"> -<a href="#Mitsubishi">Mitsubishi</a><br> -<a href="#Mitsubishi-K">Mitsubishi-K</a><br> -<a href="#NEC">NEC</a><br> -<a href="#NEC1">NEC1</a><br> -<a href="#NEC2">NEC2</a><br> -<a href="#NECx">NECx</a><br> -<a href="#NECx1">NECx1</a><br> -<a href="#NECx2">NECx2</a><br> -<a href="#Nokia">Nokia</a><br> -<a href="#Nokia12">Nokia12</a><br> -<a href="#Nokia32">Nokia32</a><br> -<a href="#NRC16">NRC16</a><br> -<a href="#NRC17">NRC17</a><br> -<a href="#OrtekMCE">OrtekMCE</a><br> -<a href="#Pace%20MSS">Pace MSS</a><br> -<a href="#Panasonic">Panasonic</a><br> -<a href="#Panasonic2">Panasonic2</a><br> -<a href="#Panasonic_Old">Panasonic_Old</a><br> -<a href="#PCTV">PCTV</a><br> -<a href="#pid-0001">pid-0001</a><br> -<a href="#pid-0003">pid-0003</a><br> -<a href="#pid-0004">pid-0004</a><br> -<a href="#pid-002A">pid-002A</a><br> -<a href="#pid-0083">pid-0083</a><br> -<a href="#Pioneer">Pioneer</a><br> -<a href="#Proton">Proton</a><br> -</td> - -<td valign="top" width="131"> -<a href="#RC5">RC5</a><br> -<a href="#RC5-7F">RC5-7F</a><br> -<a href="#RC5-7F-57">RC5-7F-57</a><br> -<a href="#RC5x">RC5x</a><br> -<a href="#RC5-?-??">RC5-?-??</a><br> -<a href="#RC6">RC6</a><br> -<a href="#RC6-6-20">RC6-6-20</a><br> -<a href="#RC6-?-??">RC6-?-??</a><br> -<a href="#RCA">RCA</a><br> -<a href="#RCA">RCA(Old)</a><br> -<a href="#RCA-38">RCA-38</a><br> -<a href="#RCA-38">RCA-38(Old)</a><br> -<a href="#RECS80">RECS80</a><br> -<a href="#Replay">Replay</a><br> -<a href="#Samsung20">Samsung20</a><br> -<a href="#Samsung36">Samsung36</a><br> -<a href="#Sampo">Sampo</a><br> -<a href="#ScAtl-6">ScAtl-6</a><br> -<a href="#Sejin-M-38">Sejin-<i>M</i>-38</a><br> -<a href="#Sejin-M-38">Sejin-<i>M</i>-56</a><br> -<a href="#Sharp">Sharp</a><br> -<a href="#Sharp">Sharp{1}</a><br> -<a href="#Sharp">Sharp{2}</a><br> -<a href="#SharpDVD">SharpDVD</a><br> -<a href="#SIM2">SIM2</a><br> -<a href="#Solidtek16">Solidtek16</a><br> -</td> - -<td valign="top" width="130"> -<a href="#Solidtek20">Solidtek20</a><br> -<a href="#Somfy">Somfy</a><br> -<a href="#Sony8">Sony8</a><br> -<a href="#Sony12">Sony12</a><br> -<a href="#Sony15">Sony15</a><br> -<a href="#Sony20">Sony20</a><br> -<a href="#StreamZap">StreamZap</a><br> -<a href="#Sunfire">Sunfire</a><br> -<a href="#TDC-38">TDC-38</a><br> -<a href="#TDC-38">TDC-56</a><br> -<a href="#Teac-K">Teac-K</a><br> -<a href="#Thomson">Thomson</a><br> -<a href="#Thomson7">Thomson7</a><br> -<a href="#Tivo">Tivo</a><br> -<a href="#Velleman">Velleman</a><br> -<a href="#Velodyne">Velodyne</a><br> -<a href="#Viewstar">Viewstar</a><br> -<a href="#X10">X10</a><br> -<a href="#X10">X10.<i>n</i></a><br> -<a href="#XMP">XMP</a><br> -<a href="#XMP">XMP-1</a><br> -<a href="#XMP">XMP-2</a><br> -<a href="#XX">XX</a><br> -<a href="#Zaptor">Zaptor</a><br> -<a href="#Zenith">Zenith</a><br> -<a href="#?1-??-??-??">?1-??-??-??</a><br> -</td></tr></tbody></table> - -<h2><a name="Introduction">Introduction</a></h2> -The primary purpose of this document is to explain any peculiarities of the decoding of each protocol. -Click in the list above on each protocol name to get any information specific to decodes with that name. -<p>If you don't understand the advanced information (IRP notation, etc.) at the start of each of those -entries, don't worry about that and please don't let it stop you from reading the text below that. In many -cases there is important protocol-specific information you will need in order to use the data from -the decode.</p> -<h3>Decode problems</h3> -The decoder only looks at one IR signal at a time. Sometimes it gives contradictory -results for a signal. The best way to determine which result is correct is to -compare with the decodes of other signals for the same device. -<h3><a name="spurious">Spurious decodes and non-robust protocols</a></h3> -Most IR protocols have enough internal consistency checks that the decoder can reliably -tell whether that protocol is present in a learned signal and can reliably decode the -device, subdevice and OBC numbers. If the signal is learned badly enough, the decoder -may fail to find that protocol in the signal. But it is very unlikely to decode it -with the wrong numbers or to imagine that protocol is a bad learn of something else. - <p>Some protocols are not robust. A totally unrelated IR signal can accidentally - fit the pattern of such a protocol resulting in a spurious decode. When you - get a decode for a non-robust protocol you need to exercise some judgment - about whether to believe or ignore that decode. Usually you can decide based - on decodes of other signals of the same device.</p> -<h3><a name="jp1">EFC, JP1, KeyMoves, Upgrades, etc.</a></h3> -Much of this document assumes DecodeIr is being used with JP1 or at least with a JP1 -capable remote. But some people will be using DecodeIr with other types of remote. -<p>If your remote is not OneForAll brand and is not one of the models of Radio Shack (or a few -other brands) that uses the same design as OneForAll, then everything this document says -about JP1, KeyMoves, Upgrades, KM, RM (RemoteMaster), and EFC numbers has no meaning for -your use. Just ignore those references and the rest of this doc should apply to your use. -Also ignore the EFC numbers in the actual output from DecodeIr.</p> -<p>If you are using a OneForAll type remote but have neither a JP1 cable nor a remote model -that can be upgraded by .wav file, then nothing about Upgrades, KM, RM, and OBC numbers -applies to your use. If the decodes you get include EFC numbers and you know (or can -ask in a forum) which setup code is right (corresponds to the protocol, device and -subdevice of the decode) then you can use those EFC numbers in KeyMoves. Note that -the decoding process cannot directly tell you which setup code is needed to -generate the signal. If you post a question in an appropriate forum with the protocol name, -device number, subdevice number, and which model OneForAll type remote you have, someone -will probably identify the setup code for you.</p> -<h3><a name="toggle">Toggle bits</a></h3> -Several different protocols include something called a toggle bit. This means that each command -has two or more different forms. Some protocols (e.g. RC5) alternate the toggle on each key press, while -others change the toggle to indicate a start or end frame. -<p>An alternating toggle lets the device receiving the commands distinguish between a long press -of a button and two short presses. For example, if you press and hold the '1' button -the remote continuously sends repeats of a single form of the '1' command. But if you -press '1', release it and press it again the remote will switch to the other form of the -command for the second press.</p> -<p>When you learn such a command you are capturing just one form of the command and -every use will send that same form. If you use that learned signal and press the same button twice -in a row, the device receiving the signal will see that as one long press rather than two -short ones. For keys, such as digits, where one long press has a different meaning than -two short presses, that gets quite inconvenient.</p> -<p>With OneForAll type remotes, using an upgrade or KeyMove will solve that problem.</p> -<p>For some of these protocols, for some models of Pronto remote, there is a condensed -encoding of the Pronto Hex that will solve the problem.</p> - -<h3><a name="repeat">Repeat frames and dittos</a></h3> -<p>DecodeIR v2.37 and later versions have a look-ahead facility that is not present in earlier ones. - This distinguishes between two styles of data passed to them by the calling application. The - remote control programming applications IR.exe and RMIR pass signals learned by a UEI remote - that has itself performed a partial analysis of the signal. The data is passed in a structured - form, divided into Once, Repeat and Extra sections. The data in each of these sections can be - viewed in IR.exe if the "Force Learned Timings" option on the Advanced menu is selected. Because - of this analysis, DecodeIR does not see the original signal in full and cannot determine such - things as the number of repeats of the signal that were sent. Other applications such as the - IRScope software for the IR Widget send the entire signal as unstructured data, which enables - IR.exe to identify the number of repeats.</p> -<p>The look-ahead facility checks successive frames within a single signal to see if they are - repeats – either identical repeats or, in certain protocols, frames of a repeat sequence - that have a distinctive marker in either the start or end frame, or both, of the sequence. If a - protocol has distinctive start or end frame markers and either or both of the start and end frames - are missing, this is reported in the Misc field of the decode (but at present this may not be - implemented for all protocols with such markers). If the data has been passed in an unstructured - form then the number of repeats in the signal will also be reported in the Misc field in a form - like "4 frames", or in version 2.39 and later, "+ 3 copies".</p> -<p>In the case of unstructured data, DecodeIR v2.38 extends the look-ahead to protocols in which repeat - action is signalled not by a full repeat of the frame but by a much shorter frame that does not carry - the signal data (or occasionally carries just part of this data). These frames serve - as "ditto marks". If present then the number of such frames is reported in the Misc field - in a form like "3 dittos", or in version 2.39 and later, "+ 3 dittos". If there - are no repeat frames or ditto marks, then to avoid ambiguity this is reported as "no repeat".</p> - -<h3><a name="MiniComboExecutors">Mini Combos</a></h3> -Some UEI protocol executors are "mini-combos". This means they support more than one -device number within one setup code using single-byte hex commands. There will be more -than one possible EFC number for each OBC number. DecodeIr can't determine the correct -EFC number by looking at the IR signal, because it isn't a characteristic of the signal. -It is a characteristic of the fixed data used in creation of the setup code. -<p>DecodeIr will list two or three different EFC numbers for each OBC number. -The sequence of those two or three EFC numbers is consistent across all the decodes. -So once you find out which position in that list is correct for one OBC of a given device -number and setup code, that position will be correct for the EFC list of any other OBC of -the same device and setup code (except that for RC-5 the decision of whether or not the OBC -number is above 63 is treated as being part of the device number).</p> - -<h3><a name="ReadingIRP">Brief and incomplete guide to reading IRP</a></h3> - -<b>General</b>: {carrier frequency, time unit, sequencing rule} -Mitsubishi:<b>{32.6k,300}</b><1,-3|1,-7>(D:8,F:8,1,-80)+ <br> -<i>Carrier Frequency</i>: Hz; e.g. 38.3k; default is 0k--no modulation<br> -<i>Time Unit</i>: Integer that can represent durations. Suffix u (default) is microseconds, p denotes number of pulses of the carrier.<br> -<i>Sequencing Rule</i>: lsb|msb; lsb (default) means the least significant bit of a binary form is sent first. <br> -<b>BitSpec</b>: Rule for the translating bit sequences to duration -sequences. <ZeroPulseSeq|OnePulseSeq|TwoPulseSeq....>. Most IR -protocols use only <ZeroPulseSeq|OnePulseSeq>, and the sequence is - simply OnDuration,OffDuration. Example: NEC uses <1,-1|1,-3><br> - -<b>Bitfield</b>: D:NumberOfBits:StartingBit. E.g. if D=71= 01000111, D:2:5 means x<b>10</b>xxxxx. - D:2:5 = 10b = 2. ~ is the bitwise complement operator. ~D -=10111000. Specifying the StartingBit is optional. D:6 is equivalent to -D:6:0.<br> - -<b>IRStream</b>: The sequence of data. Enclosed in parentheses, items separated by commas. -A trailing + means send one or more times. A trailing 3 means send 3 times; 3+ means at least 3 times. -A trailing * means send zero or more times. NEC2: {38.4k,564}<1,-1|1,-3><b>(16,-8,D:8,S:8,F:8,~F:8,1,-78)+</b> <br> - -<b>Durations</b>: no suffix means duration is expressed in Time Units, as defined above. -m is milliseconds, u microsec, p pulses. No prefix means a flash, a preceeding - (minus) means a gap.<br> - -<b>Extent</b>: A gap which trails a signal. The trailing gap is adjusted to make the total length of signal -plus trailing gap equal to the extent. Notation is like a gap duration, except ^ replaces the minus sign. -RC-5:(1:1,~F:1:6,T:1,D:5,F:6,<b>^114m</b>)+ <br> - -<b>Expressions</b>: names, numbers and bitfields connected by standard symbols for arithmetic and logical -operations. Enclosed in parentheses. Panasonic: {37k,432}<1,-1|1,-3>(8,-4,2:8,32:8,D:8,S:8,F:8,<b>(D^S^F)</b>:8,1,-173)+ - <br> - -<b>Permitted operators in decreasing order of precedence:</b><br> -<code> - unary – (negation)<br> - ** (exponentiation)<br> - * /, % (multiplication, integer division, modulo) (* is also used in IRStreams)<br> - +, – (addition, subtraction (+ is also used in IRStreams)<br> - & (bitwise AND)<br> - ^ (exclusive OR) (also used in extents)<br> - | (OR)<br> - ~ (complement) is permitted in Bitfields</code><br> - -<b>Definitions</b>: expressions separated by commas, enclosed in curly brackets. -GI Cable: {38.7k,490}<1,-4.5|1,-9>(18,-9,F:8,D:4,C:4,1,-84,(18,-4.5,1,-178)*) -<b>{C = -(D + F:4 + F:4:4)}</b> <br> -<b>Assignments</b>: For example T=T+1, which can be used to describe the RC-5 toggle bit.<br> -<b>Variations</b>: Up to 3 expressions enclosed in square brackets. The first variation is -sent on the first transmission, second for middle transmissons, and the third for the final transmission. -E.g. the Zaptor toggle bit is zero until the last frame: [T=0] [T=0] [T=1]<br> -<a href="http://www.hifi-remote.com/wiki/index.php?title=IRP_Notation"> The IRP specification by Graham Dixon</a><br> -<a href="http://www.hifi-remote.com/forums/dload.php?action=file&file_id=6996"> Practical explanation of IR signals and IRP by Vicky Getz</a> - - -<h2><a name="48-NEC">48-NEC</a></h2> -If you get a decode whose protocol name is -simply "48-NEC" that indicates the learned signal is not complete (usually caused by -not holding the original remote's button long enough during learning). Enough of -the signal is present to accurately determining the device, subdevice and OBC numbers. -But not enough is present to determine whether the protocol is 48-NEC1 or 48-NEC2. - -<h2><a name="48-NEC1">48-NEC1</a></h2> -IRP notation: {564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,E:8,~E:8,1,-??,(16,-4,1,-??)*) -<br> -EFC translation: LSB -<p>This protocol signals repeats by the use of <a href="#repeat">dittos</a>.</p> - -<h2><a name="48-NEC2">48-NEC2</a></h2> -IRP notation: {564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,E:8,~E:8,1,-??)+ -<br> -EFC translation: LSB - -<h2><a name="AdNotam">AdNotam</a></h2> -IRP notation: {35.7Khz,895,msb}<1,-1|1,-3>(0:1,1:1,D:6,F:6,^114m)+ -<br> -<p>Very similar to RC5, except AdNotam uses two start bits, and no toggle bit. - - -</p><h2><a name="AirAsync">AirAsync</a></h2> -IRP notation: {37.7Khz,840}<1|-1>( 1,B:8,-2 ... ) -<p>This protocol uses asynchronous data transmission that sends an 8-bit byte with 1 start bit, -8 data bits and 2 stop bits. The minimum signal is one byte. The protocol is reported as -AirAsync<i>n</i>-xx.yy. ... -where <i>n</i> is the number of bytes and xx, yy, ... are the byte values in hexadecimal notation. -</p> - -<h2><a name="AirB?-????">AirB?-????</a></h2> -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely. -If you see this decode from something other than an IR keyboard, you should probably ignore it.</p> - -<h2><a name="Aiwa">Aiwa</a></h2> -UEI protocol: 005E or 009E -<br> -IRP notation: {38k,550}<1,-1|1,-3>(16,-8,D:8,S:5,~D:8,~S:5,F:8,~F:8,1,-42,(16,-8,1,-165)*) -<br> -EFC translation: LSB -<p>This protocol signals repeats by the use of <a href="#repeat">dittos</a>.</p> -<p>The EFC numbering varies among the KM and RM versions of Aiwa. Using OBC numbers is less confusing.</p> -<p>When using a non-combo version of Aiwa in KM, you must combine the device and subdevice numbers as -device+256*subdevice to get the number KM calls "Device Code". (Since subdevice is usually zero, that -combination is trivial). In Aiwa combo in KM you use the subdevice as "parameter" (on the setup sheet) -and put the device in the byte2 column on the functions sheet. RM follows DecodeIr's naming of Device -and Subdevice.</p> - -<h2><a name="AK">AK</a></h2> -Documentation not written yet. - -<h2><a name="Akai">Akai</a></h2> -UEI protocol: 000D -<br> -IRP notation: {38k,289}<1,-2.6|1,-6.3>(D:3,F:7,1,^25.3m)+ <br> -EFC translation: LSB comp prefixed with last device bit -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> -<p>As of version 8.31, KM does not translate device to fixed data, nor OBC to EFC according to -the same rules used by DecodeIr. RM does translate consistently with DecodeIr, so you may find -it easier to use RM. If you use KM, you must change the device number as follows:</p> -<ul> -<li>Decoded device 0 or 4 --> KM device 3</li> -<li>Decoded device 1 or 5 --> KM device 2</li> -<li>Decoded device 2 or 6 --> KM device 1</li> -<li>Decoded device 3 or 7 --> KM device 0</li> -</ul> -<p>Also (in KM) you should use the EFC number from the decode not the OBC number. Akai protocol -uses the same EFC numbering across all JP1 remotes, so use of EFC is safe. KM uses different -OBC numbering than RM and DecodeIr, so use of OBCs isn't safe.</p> - -<h2><a name="Amino">Amino</a></h2> -UEI protocol: 019C -<br> -IRP notation: {56.0k,268,msb}<-1,1|1,-1>[T=1] [T=0] (7,-6,3,D:4,1:1,T:1,1:2,0:8,F:8,15:4,C:4,-79m)+<br> ------Variant: {36.0k,268,msb}<-1,1|1,-1>[T=1] [T=0] (7,-6,3,D:4,1:1,T:1,1:2,0:8,F:8,15:4,C:4,-79m)+ -<br>{C =(D:4+4*T+9+F:4+F:4:4+15)&15} [the arithmetic sum of the first 7 nibbles mod 15] -<br>T=1 for the first frame and T=0 for all repeat frames. -<br>DecodeIR v2.43 checks T and will report in the Misc field if the start or end frame is missing. -Amino equipment use both 36 and 56KHz, but the duration of the half-bit is -always 268. Zaptor is a closely related protocol which for which the half-bit duration is 330. -IRDecode v2.43 distinguishes between Amino and Zaptor in order of priority by 1)the position of the toggle bit, -2)the value of the next to last nibble, and 3)the measured duration of a half-bit. -<br> -EFC translation: MSB - -<h2><a name="Anthem">Anthem</a></h2> -UEI protocol: 0123 <br> -IRP notation: {38.0k,605}<1,-1|1,-3>((8000u,-4000u,D:8,S:8,E:8,C:8,1,-25m)3, -75m)+ {E=(64*U:2+F:6), C=~(D+S+E+255):8} -<br>Anthem framing is very similar to NEC, and also uses 32 bits of data. However, the leadout is much shorter. -The signal is sent at least3 times. - -<h2><a name="Apple">Apple</a></h2> -UEI protocol: 01E0 -<br> - -IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,D:8,S:8,C:1,F:7,I:8,1,-78,(16,-4,1,-173)*)<br> -C=1 if the number of 1 bits in the fields F and I is even. I is the remote ID. -<p> Apple uses the same framing as NEC1, with D=238 in normal use, 224 while pairing. S=135 </p> - -<h2><a name="Archer">Archer</a></h2> -IRP notation: {0k,12}<1,-3.3m|1,-4.7m>(F:5,1,-9.7m)+ <br> -EFC translation: 5-bit LSB -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> - -<h2><a name="Async">Async</a></h2> -<p>This protocol uses asynchronous data transmission that sends an 8-bit byte with 1 start bit, -8 data bits and 1 stop bit. The minimum signal is four bytes. The protocol is reported as -Async<i>n</i>:min-max:aa.bb...yy.zz -where <i>n</i> is the number of bytes, min-max is the range of durations - in microseconds that was taken as a single bit and aa.bb...yy.zz are -the first two and last two byte values in hexadecimal notation. -</p> - -<h2><a name="Blaupunkt">Blaupunkt</a></h2> -IRP notation: {30.3k,528}<-1,1|1,-1>(1,-5,1023:10,-39,1,-5,1:1,F:7,D:2,-230) - -<h2><a name="Bose">Bose</a></h2> -IRP notation: {500,msb}<1,-1|1,-3>(2,-3,F:8,~F:8,1,-???)+ <br> -EFC translation: MSB -The decode is intended to be consistent with the posted KM file: -<a href="http://www.hifi-remote.com/forums/dload.php?action=file&file_id=974">Bose-Wave-Radio-KM.txt</a> -and PB file: -<a href="http://www.hifi-remote.com/forums/dload.php?action=file&file_id=1389">Bose_Wave_Radio-PB.txt</a> - -<h2><a name="CanalSat">CanalSat</a></h2> -UEI protocol: 018C -<br> -IRP notation: {55.5k,250,msb}<-1,1|1,-1>(1:1,D:7,S:6,T:1,0:1,F:7,-89m)+ -<br> -EFC translation: 7-bit MSB. -<p>The <a href="#repeat">repeat frames</a> are not all identical. T toggles within a single signal, with T=0 -for the start frame and T=1 for all repeats. DecodeIR v2.37 and later check T and will report in the Misc -field if the start frame is missing.</p> - -<h2><a name="Denon">Denon, Denon{1} and Denon{2}</a></h2> -IRP notation: {38k,264}<1,-3|1,-7>(D:5,F:8,0:2,1,-165,D:5,~F:8,3:2,1,-165)+ -<br> -EFC translation: LSB -<p>A Denon signal has two halves, either one of which is enough to fully decode -the information. A significant fraction of Denon learned signals contain just -one half or have the halves separated so that DecodeIr can't process them -together. When one half is seen separate from the other, DecodeIr will name -the protocol Denon{1} or Denon{2} depending on which half is decoded. Denon, -Denon{1} and Denon{2} all represent the same protocol when they are correct. -But only Denon is robust. A Denon{1} or Denon{2} decode might be <a href="#spurious">spurious</a>.</p> - -<h2><a name="Denon-K">Denon-K</a></h2> -UEI protocol: 00CD -<br> -IRP notation: {37k,432}<1,-1,1,-3>(8,-4,84:8,50:8,0:4,D:4,S:4,F:12,((D*16)^S^(F*16)^(F:8:4)):8,1,-173)+ -<br> -EFC translation: LSB comp -<p>Denon-K is the member of the Kaseikyo family with OEM_code1=84 and OEM_code2=50.</p> -<p>Denon-K uses the same check byte rules as Panasonic protocol, but uses the data bits differently. -The Panasonic Combo protocol in KM can be used with some difficulty to produce Denon-K signals. -The Denon-K choice in RM uses the same protocol executor as Panasonic combo, but computes the hex commands -based on Denon's use of the Kaseikyo data bits.</p> - -<h2><a name="Dgtec">Dgtec</a></h2> -UEI protocol: 016A -<br> -IRP notation: {38k,560}<1,-1|1,-3>(16,-8,D:8,F:8,~F:8,1,^108m,(16,-4,1,^108m)+) -<br> -EFC translation: LSB comp -<p>This protocol signals repeats by the use of <a href="#repeat">dittos</a>.</p> - -<h2><a name="DirecTV">DirecTV</a></h2> -IRP notation: {38k,600,msb}<1,-1|1,-2|2,-1|2,-2>(5,(5,-2,D:4,F:8,C:4,1,-50)+) -{C=7*(F:2:6)+5*(F:2:4)+3*(F:2:2)+(F:2)} <br> -EFC translation: MSB -<p>There are six variants of the DirecTV protocol, distinguished in RemoteMaster by the parameter "Parm" on -the Setup page. The Parm value is shown in the Misc field of DecodeIR. The IRP notation above corresponds -to the default Parm=3. The various Parm values correspond to three different frequencies (the 38k in the above) -and two different lead-out times (the -50 in the above). The corresponding values are:</p> -<ul> -<li>Parm=0 : 40k, -15 -</li><li>Parm=1 : 40k, -50 -</li><li>Parm=2 : 38k, -15 -</li><li>Parm=3 : 38k, -50 -</li><li>Parm=4 : 57k, -15 -</li><li>Parm=5 : 57k, -50 -</li></ul> -<p>Portions of a dirty learn of a Sony signal may look like a DirecTV signal. So, if you get a DirecTV -decode together with a plausible Sony decode, believe the Sony decode and ignore the DirecTV. If you get -a DirecTV decode without a Sony decode for some functions of a Sony device, try relearning them; a DirecTV -decode for a signal meant for a Sony device is not likely to be correct.</p> -<p>This protocol was called Russound in versions of DecodeIR earlier than 2.40.</p> - -<h2><a name="Dishplayer">Dishplayer</a></h2> -UEI protocol: 010F -<br> -IRP notation: {38.4k,535,msb}<1,-5|1,-3>(1,-11,(F:6,U:5,D:2,1,-11)+) <br> -EFC translation: Not available in this version of DecodeIr -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> - -<h2><a name="Dish_Network">Dish_Network</a></h2> -UEI protocol: 0002 <br>IRP notation: {57.6k,400}<1,-7|1,-4>(1,-15,(F:-6,U:5,D:5,1,-15)+) -<br> -EFC translation: MSB comp 6 function bits followed by LSB comp low 2 unit bits. -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> -<p>The unit number shows up in the Subdevice field of DecodeIr's output. In KM, the "unit code" is -one greater than the unit number. So you must take the Subdevice from the decode and add one to -it and use that as the "unit code" in KM.</p> -<p>There are two variants of the protocol executor for DishNetwork with different -but compatible EFC numbering. The decoded EFC should work for both. But the -results may be less confusing if you use OBC numbers in KM or RM.</p> - -<h2><a name="EchoStar">EchoStar</a></h2> -UEI protocol: 0182 -<br> As of 2.42 DecodeIR shows this as RC5-7F - -<h2><a name="Emerson">Emerson</a></h2> -UEI protocol: 0065 -<br> -IRP notation: {36.7k,872}<1,-1|1,-3>(4,-4,D:6,F:6,~D:6,~F:6,1,-39)+ <br> -EFC translation: 6-bit LSB comp with 2-bit mini-combo -<p>Lists three different EFCs because this protocol is a <a href="#mini%20combo">mini combo</a>.</p> - -<h2><a name="F12">F12</a></h2> -UEI protocol: 001A -<br> -IRP notation: (Toshiba specification) K=(D:3,H:1,A:1,B:2,F:6) -{37.9k,422}<1,-3|3,-1>(K,-34,K) for A=1 or B=1 <br> -{37.9k,422}<1,-3|3,-1>(K,-34,K,-88,K,-34,K)+ for H=1. -Exactly one of H, A, or B can have a value of 1. If H=1 the signal can be sent repeatedly, and F can take any 6 bit value. -If A or B=1, the signal is sent once only per button press, and only a single bit of F can be non-zero. <p> -IRP notation: (JP1) K=(D:3,H:1,F:8) -{37.9k,422}<1,-3|3,-1>(K,-34,K) for H=0. <br> -{37.9k,422}<1,-3|3,-1>(K,-34,K,-88,K,-34,K)+ for H=1. <br> -A and B are subsumed into F, and the value of H is computed in the executor. H=A^B. -<br>EFC translation: lsb, but not computed in DecodeIR. -<br> DecodeIR reports H as the subdevice. This is useful when making a Pronto Hex file, -or other description based on durations. Remotes with executors (e.g. UEI remotes) normally compute the value of -H in the executor, and the "subdevice" is not needed as a parameter. - -</p><h2><a name="Fujitsu">Fujitsu</a></h2> -UEI protocol: 00F8 -<br> -IRP notation: {37k,432}<1,-1,1,-3>(8,-4,20:8,99:8,X:4,E:4,D:8,S:8,F:8,1,-110)+ -<br> -EFC translation: LSB comp -<p>Fujitsu is the member of the Kaseikyo family with OEM_code1=20 and OEM_code2=99.</p> -<p>There is no check byte, so the risk of an incorrectly decoded OBC is much higher than in -other Kaseikyo protocols.</p> - <p>00F8 requires 2-byte hex commands, so the decoded EFC number is generally not - useful. Use OBC number in upgrades or to compute Hex commands.</p> - -<h2><a name="Fujitsu-56">Fujitsu-56</a></h2> -IRP notation: {37k,432}<1,-1,1,-3>(8,-4,20:8,99:8,H:4,E:4,D:8,S:8,X:8,F:8,1,-110)+ - -<h2><a name="G.I. Cable">G.I. Cable and G.I. Cable{1}</a></h2> -UEI protocol: 00C4 -<br> -IRP notation: {38.7k,490}<1,-4.5|1,-9>(18,-9,F:8,D:4,C:4,1,-84,(18,-4.5,1,-178)*) -{C = -(D + F:4 + F:4:4)} <br> -EFC translation: LSB -<p>This protocol signals repeats by the use of <a href="#repeat">dittos</a>. -When the {1} is shown as part of the protocol name for G.I. Cable, it just means that the repeat -part of the signal is not present. That doesn't indicate any difference in the actual protocol nor -even any unreliability in the decode. It may indicate that use of the learned signal will be less -reliable, so you have more than usual reason to replace it with a <a href="#jp1">KeyMove, Upgrade</a> or cleaned -up version.</p> - -<h2><a name="G.I.4DTV">G.I.4DTV</a></h2> -UEI protocol: 00A4 -<br> -IRP notation: {37.3k,992}<1,-1|1,-3>(5,-2,F:6,D:2,C:4,1,-60)+ <br> -EFC translation: NONE -<p>This is a moderately robust protocol, but <a href="#spurious">spurious decodes</a> are still possible.</p> -<p>The official (UEI) protocol executor for G.I.4DTV does not support EFC numbers. If you are creating an -upgrade in KM or RM you should use OBC numbers, not EFC numbers. If you need the Hex Cmd for a KeyMove, -you should use the functions sheet of KM or RM to compute it for you from the OBC and device number.</p> - -<h2><a name="Grundig16">Grundig16 and Grundig16-30</a></h2> -UEI protocol: Grundig16 0112, Grundig16-30 00AB -<br>IRP notation for Grundig16: {35.7k,578,msb}<-4,2|-3,1,-1,1|-2,1,-2,1|-1,1,-3,1> -(806u,-2960u,1346u,T:1,F:8,D:7,-100)+ -<br>IRP notation for Grundig16-30: {30.3k,578,msb}<-4,2|-3,1,-1,1|-2,1,-2,1|-1,1,-3,1> -(806u,-2960u,1346u,T:1,F:8,D:7,-100)+ - <br> -EFC translation: MSB but with bit pairs translated data->hex by 00->00, 01->11, 10->01, 11-> -10 and off by one position. -<p>These are two variants of the same protocol, differing only in frequency. The IRP notation is corrected - from previous versions of this document, to bring it into line with what DecodeIR actually does.</p> - -<h2><a name="GXB">GXB</a></h2> -IRP notation: {38.3k,520,msb}<1,-3|3,-1>(1,-1,D:4,F:8,P:1,1,^???)+ -<p>Decoder for a nonstandard Xbox remote.</p> - -<h2><a name="IODATAn">IODATA</a><i>n</i> and IODATA<i>n</i>-<i>x</i>-<i>y</i></h2> -UEI protocol: not known. -<br> -IRP notation: {38k,550}<1,-1|1,-3>(16,-8,x:7,D:7,S:7,y:7,F:8,C:4,1,^108m)+ -{n = F:4 ^ F:4:4 ^ C:4} <br> -EFC translation: LSB -<p>This is potentially a class of protocols distinguished by values of <i>n</i>, <i>x</i> and <i>y</i> with - <i>n</i> = 0..15 and <i>x</i>, <i>y</i> = 0..127. If <i>x</i> and <i>y</i> are both zero, they are omitted. The only known example is IODATA1.</p> - -<h2><a name="Jerrold">Jerrold</a></h2> -UEI protocol: 0006 -<br> -IRP notation: {0k,44}<1,-7.5m|1,-11.5m>(F:5,1,-23.5m)+ -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> - -<h2><a name="JVC">JVC and JVC{2}</a></h2> -UEI protocol: 0034 -<br> -IRP notation: {38k,525}<1,-1|1,-3>(16,-8,(D:8,F:8,1,-45)+) <br> -EFC translation: LSB comp -<p>JVC{2} indicates a JVC signal from which the lead-in is missing. The JVC protocol has -lead-in on only the first frame, so it is quite easy to have it missing from a learned -signal. So when JVC{2} is correct, it means the same as JVC. But JVC{2} is not robust, -so <a href="#spurious">spurious decodes</a> are likely. It -is also very similar in structure and timing to <a href="#Mitsubishi">Mitsubishi</a> protocol, so that -DecodeIr has difficulty distinguishing one from the other. The device number, OBC and EFC -are all encoded the same way between the two. So if you have JVC{2} -decodes that you have reason to suspect should actually be Mitsubishi, you can try using -them as Mitsubishi without changing the numbers. However, true Mitsubishi signals will not -misdecode as JVC, just as JVC{2}. So if some of the signals for your device decode as JVC -and others as JVC{2}, you should trust all those decodes and not try Mitsubishi.</p> - -<h2><a name="JVC-48">JVC-48</a></h2> -UEI protocol: 001F or 00C9 or 00CD -<br> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,3:8,1:8,D:8,S:8,F:8,(D^S^F):8,1,-173)+ -<br> -EFC translation: LSB comp -<p>JVC-48 is the member of the Kaseikyo family with OEM_code1=3 and OEM_code2=31.</p> -<p>Panasonic protocol uses the same check byte rules as JVC-48, so you might want use the (more flexible) -Panasonic entries in KM or RM to produce a JVC-48 upgrade (by changing the OEM_code1 and OEM_code2 values). For simple -JVC-48 upgrades you get exactly the same results by directly selecting the "JVC-48" protocol.</p> - -<h2><a name="JVC-56">JVC-56</a></h2> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,3:8,1:8,D:8,S:8,X:8,F:8,(D^S^X^F):8,1,-173)+ - -<h2><a name="Kaseikyo">Kaseikyo</a></h2> -<p>Kaseikyo is a family of protocols that includes Panasonic, Mitsubishi-K, Fujitsu, Sharp-DVD and Teac-K. Each -protocol in the Kaseikyo family is identified by two numbers, known as OEM_code1 and OEM_code2.</p> -<p> - Most members of the family have minor structural differences from the generic - form. In those cases DecodeIR checks for the specific details (based on the - OEM codes) and if they are correct reports the protocol by name (see Panasonic - and Teak-K below). </p> -<p>In the few cases where the structure exactly fits my understanding of the Kaseikyo spec, -DecodeIR reports it as Kaseikyo-???-??? replacing the first ??? by the OEM_code1 and the second -??? by the OEM_code2.</p> - -<h2><a name="Kaseikyo-???-???">Kaseikyo-???-???</a></h2> -IRP notation: -{37k,432}<1,-1|1,-3>(8,-4,M:8,N:8,X:4,D:4,S:8,F:8,E:4,C:4,1,-173)+ - {X=M:4:0^M:4:4^N:4:0^N:4:4,C=D^S:4:0^S:4:4^F:4:0^F:4:4^E} -<br> -EFC translation: LSB comp -<p>This is the nominal form of the Kaseikyo. -It is most commonly seen with OEM codes 170.90, which -indicates "Sharp". I assume (haven't tested) that the SharpDVD protocol in KM generates these -Kaseikyo-170-90 signals. -We have also seen this protocol with OEM codes 3.32. I'm not sure what manufacturer that indicates.</p> -<p>The Kaseikyo protocol in KM seems to be designed to produce this nominal form of Kaseikyo for any -specified OEM codes and any constant value of E. That should be the way to reproduce any Kaseikyo-???-??? -decode other than SharpDVD, and might be better than SharpDVD for the Kaseikyo-170-90 signals.</p> - -<h2><a name="Kaseikyo56">Kaseikyo56</a></h2> -Kaseikyo56 is a lengthened version of the Kaseikyo family of protocols. It has the same OEM codes indicating -the same manufacturers as Kaseikyo, and it has the same variation (by manufacturer) in check byte and other -details as Kaseikyo. - -<h2><a name="Kaseikyo56-???-???">Kaseikyo56-???-???</a></h2> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,M:8,N:8,H:4,D:4,S:8,X:8,F:8,E:4,C:4,1,-173)+ - -<h2><a name="Kathrein">Kathrein</a></h2> -UEI protocol: 0066 -<br>IRP notation: {38k,540}<1,-1|1,-3>(16,-8,D:4,~D:4,F:8,~F:8,1,^105m,(16,-8,F:8,1,^105m)+) -<br>EFC translation: LSB comp -<p>This protocol signals repeats by the use of <a href="#repeat">dittos</a>. It is unusual in that the ditto - frame carries part of the signal data, specifically the function code (OBC) but not the device code.</p> - -<h2><a name="Konka">Konka</a></h2> -UEI protocol: 019B -<br> -IRP notation: {38k,500,msb}<1,-3|1,-5>(6,-6,D:8,F:8,1,-8,1,-46)+ <br> -EFC translation: MSB - -<h2><a name="Lumagen">Lumagen</a></h2> -IRP notation: {38.4k,416,msb}<1,-6|1,-12>(D:4,C:1,F:7,1,-26)+ {C = odd parity -for F} <br> -EFC translation: MSB prepended with C bit. -<p>This is a moderately robust protocol, but <a href="#spurious">spurious decodes</a> are still possible.</p> - -<h2><a name="Lutron">Lutron</a></h2> -IRP notation: {40k,2300,msb}<-1|1>(255:8,X:24,0:4)+ <br> -EFC translation: MSB of decoded signal. -<p>This is an unusual protocol in that an 8-bit device code and 8-bit OBC are encoded in a 24-bit - error-correcting code as the X of the IRP notation. This is constructed as follows. First two parity - bits are appended to the 16 data bits to give even parity for the two sets of 9 bits taken alternately. - The resulting 18-bit sequence is then treated as 6 octal digits (0-7) expressed in 3-bit binary code. - These are then re-coded in the 3-bit Gray code (also called, more descriptively, the reflected-binary code) - with a parity bit to give odd parity, so giving 6 4-bit groups treated as a single 24-bit sequence. The - whole thing allows any single-bit error in transmission to be identified and corrected.</p> - -<h2><a name="Matsui">Matsui</a></h2> -IRP notation: {38K,525}<1,-1|1,-3>(D:3,F:7,1,^30.5m)+ <br> -EFC translation: Not available in this version of DecodeIr -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> - -<h2><a name="MCE">MCE (RC6-6-32)</a></h2> -IRP notation: {36k,444,msb}<-1,1|1,-1>(6,-2,1:1,6:3,-2,2,OEM1:8,OEM2:8,T:1,D:7,F:8,-???)+ -<p>MCE is a member of the RC6 family. Technically it is RC6-6-32 with the standard toggle bit zero, with the - OEM1 field equal to 128, and with a nonstandard (for the RC6 family) toggle bit added. If all those - rules are met, DecodeIr will display the name as "MCE" and with the OEM2 field moved to the - subdevice position. Otherwise it will display RC6-6-32.</p> -<p>As of version 8.31, KM does not have built-in support for this protocol, but there are KM format upgrade - files available for Media Center (built by an expert who isn't limited to KM's built-in protocols). Those - upgrades should be adaptable to any RC6-6-32 code set (by changing the fixed data), if the one you have - doesn't already match the upgrade.</p> -<p>RM version 1.16 has support for RC6-6-32, which can be used for MCE upgrades. Version 1.17 will also have - direct support for MCE</p> -<h2><a name="Metz19">Metz19</a></h2> -IRP notation: (37.9K,106,msb)<4,-9|4,-16>(8,-22,T:1,D:3,~D:3,F:6,~F:6,4,-125m)+ <br> -The toggle bit T is inverted each time a new button press occurs. - -<h2><a name="Mitsubishi">Mitsubishi</a></h2> -UEI protocol: 0014 -<br> -IRP notation: {32.6k,300}<1,-3|1,-7>(D:8,F:8,1,-80)+ <br> -EFC translation: LSB comp -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely. It -is also very similar in structure and timing to <a href="#JVC">JVC{2}</a> protocol, so that -DecodeIr has difficulty distinguishing one from the other. The device number, OBC and EFC -are all encoded the same way between the two. So if you have Mitsubishi -decodes that you have reason to suspect should actually be JVC, you can try using -them as JVC without changing the numbers.</p> - -<h2><a name="Mitsubishi-K">Mitsubishi-K</a></h2> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,35:8,203:8,X:4,D:8,S:8,F:8,T:4,1,-100)+ -<br> -EFC translation: not available yet -<p>Mitsubishi-K is the member of the Kaseikyo family with OEM_code1=35 and OEM_code2=203.</p> - -<h2><a name="NEC">NEC</a></h2> -NEC is a family of similar protocols including NEC1, NEC2, Tivo, Pioneer, Apple, NECx1 and NECx2. -If you get a decode whose protocol name is -simply "NEC" that indicates the learned signal is not complete (usually caused by -not holding the original remote's button long enough during learning). Enough of -the signal is present to accurately determine the device, subdevice and OBC numbers. -But not enough is present to determine whether the protocol is NEC1 or NEC2. -<h3><a name="NEC12difference">Difference between NEC1 and NEC2</a></h3> -The difference between NEC1 and NEC2 only affects the signal sent by a long -keypress. A short press sends the same signal in NEC1 and NEC2. - -<h3><a name="Variant IRstreams in NEC protocols">Variant IRstreams in NEC protocols</a></h3> -For NEC1, NEC2, NECx1, and NECx2 protocols, the IRstream contains D:8,S:8,F:8,~F:8 <br> -However, some manufacturers (especially Yamaha and Onkyo) are breaking the "rule" that the 4th byte should be ~F:8<br> -Version 2.42 decodes these variants by adding suffixes to the protocol name depending on the IRstream:<br> --y1: D:8,S:8,F:8,~F:7,F:1:7 (complement all of F except the MSB)<br> --y2: D:8,S:8,F:8,F:1,~F:7:1 (complement all of F except the LSB)<br> --y3: D:8,S:8,F:8,F:1,~F:6:1,F:1:7 (complement all of F except MSB and LSB)<br> --f16: D:8,S:8,F:8,E:8 (no relationship between the 3rd and 4th bytes)<br> - -<h2><a name="NEC1">NEC1</a></h2> -IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,-78,(16,-4,1,-173)*) -<br> -EFC translation: LSB comp -<p>A few devices use NEC1 protocol at 40Khz, rather than the typical frequency. -When getting a decode of NEC1, if you notice that the frequency is closer to 40Khz than to 38Khz, -examine multiple learns from the same device to estimate whether the 40Khz frequency is a -learning error or a true characteristic of the device. If the 40Khz is correct, there are -methods in JP1, or MakeHex (whichever you are using) to reproduce NEC1 at 40Khz rather than the -usual frequency.</p> - -<h2><a name="NEC2">NEC2</a></h2> -IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,-78)+ <br> -EFC translation: LSB comp -<p>Pioneer is distinguished from NEC2 only by frequency. So if your learning system does not -learn frequency accurately, it won't accurately distinguish Pioneer from NEC2. All Pioneer signals -should have a device number in the range 160 to 175 and no subdevice. No NEC2 signal should fit those -rules. So you usually can determine whether the decision (by frequency) was wrong by checking the device numbers.</p> - -<h2><a name="NECx">NECx</a></h2> -If you get a decode whose protocol name is -simply "NECx" that indicates the learned signal is not complete (usually caused by -not holding the original remote's button long enough during learning). Enough of -the signal is present to accurately determining the device, subdevice and OBC numbers. -But not enough is present to determine the exact protocol, which is probably NECx1 or NECx2. This -incomplete learn also makes it harder to distinguish NEC from NECx, so a decode of "NECx" -might be NEC1 or NEC2 or even Tivo or Pioneer. - -<h2><a name="NECx1">NECx1</a></h2> -IRP notation: {38.4k,564}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F8,1,^108m,(8,-8,D:1,1,^108m)*) <br> -EFC translation: LSB comp -<br> Most, but not all NECx1 signals have S=D - -<h2><a name="NECx2">NECx2</a></h2> -IRP notation: {38.4k,564}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F8,1,^108m)+ <br> -EFC translation: LSB comp -<br> Most, but not all NECx2 signals have S=D - -<h2><a name="Nokia">Nokia</a></h2> -IRP notation: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:8,S:8,F:8,164,-???)+ -<br> -EFC translation: MSB - -<h2><a name="Nokia12">Nokia12</a></h2> -IRP notation: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:4,F:8,164,-???)+ -<br> -EFC translation: MSB - -<h2><a name="Nokia32">Nokia32</a></h2> -UEI protocol: 0173 -<br> -IRP notation: {36k,msb}<164,-276|164,-445|164,-614|164,-783>(412,-276,D:8,S:8,X:8,F:8,164,^100m)+ -<br> -EFC translation: MSB - -<h2><a name="NRC16">NRC16</a></h2> -Documentation not written yet. - -<h2><a name="NRC17">NRC17</a></h2> -UEI protocol: 00BD - -<h2><a name="OrtekMCE">OrtekMCE</a></h2> -UEI protocol: not known. -<br> -IRP notation: {38.6k,480}<1,-1|-1,1>(4,-1,D:5,P:2,F:6,C:4,-48m)+<br> -EFC translation: 6-bit LSB comp -<p>The <a href="#repeat">repeat frames</a> are not all identical. P is a - position code: 0 for the start frame of a repeat sequence, 2 for the -end frame and 1 for all frames in between. C is a checksum, 3 more than -the number of 1 bits in D, P, F together. DecodeIR v2.37 -and later check P and will report in the Misc field if either the start -or end frame, or both, is/are missing.</p> - -<h2><a name="Pace MSS">Pace MSS</a></h2> -IRP notation: {38k,630,msb}<1,-7|1,-11>(1,-5,1,-5,T:1,D:1,F:8,1,^120m)+ -<br> -EFC translation: Not available in this version of DecodeIr -<p>This is a moderately robust protocol, but <a href="#spurious">spurious decodes</a> are still possible.</p> - -<h2><a name="Panasonic">Panasonic</a></h2> -UEI protocol: 001F or 00C9 or 00CD -<br> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,2:8,32:8,D:8,S:8,F:8,(D^S^F):8,1,-173)+ -<br> -EFC translation: LSB comp -<p>Panasonic protocol is the most commonly seen member of the Kaseikyo family</p> - <p>OEM_code1 is 2 and OEM_code2 is 32 (or DecodeIr won't display the name as "Panasonic"). - So those values in KM or RM can be changed from the default 2 and 32 only - when using the Panasonic entry in KM or RM to produce some Kaseikyo variant - OTHER THAN Panasonic. When creating a Panasonic upgrade, don't change those - from the default values.</p> - -<h2><a name="Panasonic2">Panasonic2</a></h2> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,2:8,32:8,D:8,S:8,X:8,F:8,(D^S^X^F):8,1,-173)+ - -<h2><a name="Panasonic_Old">Panasonic_Old</a></h2> -UEI protocol: 0000 -<br> -IRP notation: {57.6k,833}<1,-1|1,-3>(4,-4,D:5,F:6,~D:5,~F:6,1,-???)+ <br> -EFC translation: 6-bit LSB comp with 2-bit mini-combo -<p>Lists three different EFCs because this protocol is a <a href="#mini%20combo">mini combo</a>.</p> - -<h2><a name="PCTV">PCTV</a></h2> -IRP notation: {38.4k,832}<0,-1|1,-0>(2,-8,1,D:8,F:8,2,-???) - -<h2><a name="pid-0001">pid-0001</a></h2> -UEI protocol: 0001 -<br>IRP notation: {0k,msb}<24,-9314|24,-13486>(24,-21148,(F:5,1,-28m)+) -<br>EFC translation: 5-bit MSB comp -<p>As of version 8.31 KM has seriously wrong OBC translation for pid-0001, so use only EFC's with KM.</p> - -<h2><a name="pid-0003">pid-0003</a></h2> -UEI protocol: 0003 -<br>IRP notation: {40.2k,389}<2,-2|3,-1>(F:8,~F:8,^102k)+ -<br>EFC translation: LSB - -<h2><a name="pid-0004">pid-0004</a></h2> -UEI protocol: 0004 -<br>IRP notation: {0k,msb}<12,-130|12,-372>(F:6,12,-27k)+ -<br>EFC translation: 6-bit MSB comp - -<h2><a name="pid-002A">pid-002A</a></h2> -UEI protocol: 002A -<br>IRP notation: {0k,10}<1,-5|1,-15>(1,-25, D:5,F:6, 1,-25,1,120m)+ -<br>EFC translation: 6-bit LSB comp -<br> Used primarily in Barco remotes. -<p>This is a moderately robust protocol, but <a href="#spurious">spurious decodes</a> are still possible.</p> - -<h2><a name="pid-0083">pid-0083</a></h2> -UEI protocol: 0083 -<br>EFC translation: 5-bit MSB comp -<br>IRP notation: {42.3K, 3000}<1,-3,1,-7|1,-7,1,-3>(F:5,1,-27)+ -<p>This protocol is a very limited design. We have seen it used only in the UEI setup code TV/0159, -which is for some TVs brand named Fisher, Sanyo and Sears. It is not likely that any other code -set uses this protocol. So if you get a correct decode of pid-0083 you probably have a TV that -can be controlled by the TV/0159 setup code.</p> -<p>As of version 8.31, KM does not translate OBC to EFC according to -the same rules used by DecodeIr. RM does translate consistently with DecodeIr, so you may find -it easier to use RM. If you use KM, you should use the EFC number from the decode not the OBC number. -Pid-0083 protocol -uses the same EFC numbering across all JP1 remotes, so use of EFC is safe. KM uses different -OBC numbering than RM and DecodeIr, so use of OBCs isn't safe.</p> - -<h2><a name="Pioneer">Pioneer</a></h2> -IRP notation: {40k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,-78)+ <br> -EFC translation: LSB comp -<p>Pioneer is distinguished from NEC2 only by frequency. So if your learning system does not -learn frequency accurately, it won't accurately distinguish Pioneer from NEC2. All Pioneer signals -should have a device number in the range 160 to 175 and no subdevice. No NEC2 signal should fit those -rules. So you usually can determine whether the decision (by frequency) was wrong by checking the device numbers.</p> - <p>Many Pioneer commands are sent as combinations of two different Pioneer signals. - This version of DecodeIr does not associate the two signals together into - one command. It decodes them separately. If you get more than one of the same - OBC from decoding a learned signal, that just means the learning system failed - to understand the repeat pattern. It does not mean a two part signal. But - if there are two different OBCs (with the same or different device numbers) - you have a two part Pioneer signal.</p> -<p>Including a two part Pioneer signal in a KeyMove or upgrade is a complex process that requires a good -understanding of Pioneer signals and of the Pioneer support in KM. The signals don't vary much among related Pioneer models. -So the best way to get an upgrade or hex cmd including such signals is to look through existing Pioneer upgrades in -the JP1 group and find one that already includes the same (or nearly same) signal.</p> - -<h2><a name="Proton">Proton</a></h2> -UEI protocol: 005C -<br> -IRP notation: {38k,500}<1,-1|1,-3>(16,-8,D:8,1,-8,F:8,1,^63m)+ <br> -EFC translation: LSB comp -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> - -<h2><a name="RC5">RC5</a></h2> -UEI protocol: 00E8 -<br> -IRP notation: {36k,msb,889}<1,-1|-1,1>(1:1,~F:1:6,T:1,D:5,F:6,^114m)+ <br> -EFC translation: 6-bit MSB comp with 2-bit mini-combo -<p>Lists three different EFCs because this protocol is a <a href="#mini%20combo">mini combo</a>.</p> - <p>What we call "device" is really the "System" and what we - call "OBC" is really the "Command". If you are using ProntoEdit - to create the RC5 signals directly, that GUI uses that correct (System and - Command) Philips terminology.</p> - - -<h2><a name="RC5-7F">RC5-7F</a></h2> -UEI protocol: 0182 -<br> -IRP notation: {36k,msb,889}<1,-1|-1,1>(1:1, D:1:5,T:1,D:5,F:7,^114m)+ <br> -EFC translation: 7-bit MSB comp - -<h2><a name="RC5-7F-57">RC5-7F-57</a></h2> -UEI protocol: 0182 -<br> -IRP notation: {57k,msb,889}<1,-1|-1,1>(1:1, D:1:5,T:1,D:5,F:7,^114m)+ <br> -EFC translation: 7-bit MSB comp - -<h2><a name="RC5x">RC5x</a></h2> -UEI protocol: 00F2 -<br> -IRP notation: {36k,msb,889}<1,-1|-1,1>(1:1,~S:1:6,T:1,D:5,-4,S:6,F:6,^114m)+ -<br> -EFC translation: NONE -<p>The official (UEI) protocol executor for RC5x does not support EFC numbers. If you are creating an -upgrade in KM or RM you should use OBC numbers, not EFC numbers. If you need the Hex Cmd for a KeyMove, -you should use the functions sheet of KM or RM to compute it for you from the OBC and subdevice number.</p> -<p>In the functions sheet in KM you must put the subdevice number in the byte2 column, which KM calls - "unit code".</p> - <p>What we call "Device" is really the "System". What we call - Subdevice is really the "Command". What we call "OBC" - is really the "Data". If you are using ProntoEdit to create the - RC5 signals directly, that GUI uses that correct (System, Command and Data) - Philips terminology.</p> - -<h2><a name="RC5-?-??">RC5-?-??</a></h2> -Just ignore this decode. It is almost certainly <a href="#spurious">spurious</a>. In case there is a new -protocol I don't know about yet in the family with RC5 and StreamZap, it will decode in this form producing -data to help me understand that protocol. - -<h2><a name="RC6">RC6</a></h2> -UEI protocol: 0058 -<br>IRP notation: {36k,444,msb}<-1,1|1,-1>(6,-2,1:1,0:3,<-2,2|2,-2>(T:1),D:8,F:8,^107m)+ -<br>EFC translation: MSB -<p>RC6 is the name used for the first member of the RC6 family of protocols. Technically this is -RC6-0-16, but DecodeIr will always display that as simply "RC6"</p> - -<h2><a name="RC6-6-20">RC6-6-20</a></h2> -IRP notation: {36k,444,msb}<-1,1|1,-1>(6,-2,1:1,6:3,<-2,2|2,-2>(T:1),D:8,S:4,F:8,-???)+ -<br>EFC translation: MSB -<p>This protocol is commonly used in Sky and Sky+ remotes. As of version 8.31, KM does not have built-in support -for this protocol, but there are KM format upgrade files available for Sky and Sky+ (built by an expert who isn't limited -to KM's built-in protocols). RM has built-in support for RC6-M-20n protocol, which can be used to make Sky and Sky+ -upgrades (or any other RC6-6-20 upgrades as long as the T bit is the same for all learned signals, as it is with Sky). -To use RC6-M-20n for RC6-6-20, you must leave the M field in RM's setup sheet with its default value of 6, and you -must set or leave the T field (if present) to the value shown in all the decodes (which I assume will be 0).</p> - -<h2><a name="RC6-?-??">RC6-?-??</a></h2> -IRP notation: {36k,444,msb}<-1,1|1,-1>(6,-2,1:1,M:3,<-2,2|2,-2>(T:1),???:??)+ - <p>This is the generic form for a decode of protocols in the RC6 family. DecodeIr - uses this form for all RC6 decodes, except RC6-0-16 which is displayed as - simply "RC6", RC6-6-24 which is displayed as "Replay" - and some RC6-6-32 which display as MCE.</p> -<p>The first ? in the protocol name is the M value in the RC6 spec. The ending ?? represents the number of data bits -in the signal.</p> - -<h2><a name="RCA">RCA and RCA(Old)</a></h2> -UEI protocols: 00AF (RCA), 002D(RCA(Old)) and 0114 (RCA Combo) -<br>IRP notation for RCA: {58k,460,msb}<1,-2|1,-4>(8,-8,D:4,F:8,~D:4,~F:8,1,-16)+ -<br>IRP notation for RCA(Old): {58k,460,msb}<1,-2|1,-4>(32,(8,-8,D:4,F:8,~D:4,~F:8,2,-16)+) -<br>EFC translation: MSB -<p>These are two very similar forms of RCA protocol which differ only in - that RCA(Old) has an extended lead-in -and a double-length ON pulse before the lead-out. They are so similar -that most RCA devices will accept either. -But some RCA devices only accept the one that really matches their own -remote. -In versions of DecodeIR prior to v2.40, RCA(Old) was decoded as a frame -of RCA{1} followed usually by a frame of RCA. The second frame now no -longer appears, so the protocol has been renamed to correspond to that -used in KM and RM.</p> - -<h2><a name="RCA-38">RCA-38 and RCA-38(Old)</a></h2> -UEI protocol: not known -<br>IRP notation for RCA-38: {38.7k,460,msb}<1,-2|1,-4>(8,-8,D:4,F:8,~D:4,~F:8,1,-16)+ -<br>IRP notation for RCA-38(Old): {38.7k,460,msb}<1,-2|1,-4>(32,(8,-8,D:4,F:8,~D:4,~F:8,2,-16)+) -<br>EFC translation: MSB -<p>These are recently discovered variants of the RCA protocol. They differ from RCA and RCA(Old) only in the - frequency, which is 38.7kHz instead of the standard 58kHz.</p> - -<h2><a name="RECS80">RECS80</a></h2> -UEI protocol: 0045, 0068, 0090 or ??? -<br>IRP notation for 0045: {38k,158,msb}<1,-31|1,-47>(1:1,T:1,D:3,F:6,1,-45m)+ -<br>IRP notation for 0068: {33.3k,180,msb}<1,-31|1,-47>(1:1,T:1,D:3,F:6,1,^138m)+ -<br>EFC translation: 6-bit MSB comp -<p>RECS80 is a family of related protocols with the same structure, but different timing. See also -Velleman </p> -<p>These are moderately non robust protocols, so <a href="#spurious">spurious decodes</a> are possible.</p> -<p>The timing differences are not definitive enough for DecodeIr to identify which RECS80 -version is which. Instead it displays the timing information in the "Misc" field of the -output. That will be three numbers formatted as in this example: (157/5048/7572).</p> -<p>Using those three numbers and the frequency, you should be able to determine whether -the signals fit the 0045 version, the 0068 version, the 0090 version or none of them. You should look at all -the learned signals for your device together when doing that. A single device won't mix -versions of RECS80, so any differences in frequency or timing between learns is -due to the IR learning process, not due to any differences among the correct signals. You -should find one RECS80 version that is a good enough fit for all signals of the device.</p> -<p>For 0045,</p> -<ul> -<li>frequency should be between 37000 and 39000</li> -<li>first timing number between 100 and 200</li> -<li>second timing number between 4500 and 5500</li> -<li>third timing number between 6800 and 8300</li> -</ul> -<p>For 0068,</p> -<ul> -<li>frequency should be between 32300 and 34300</li> -<li>first timing number between 130 and 250</li> -<li>second timing number between 5100 and 6300</li> -<li>third timing number between 7700 and 9500</li> -</ul> -<p>For 0090,</p> -<ul> -<li>frequency should be 0</li> -<li>first timing number between 0 and 40</li> -<li>second timing number between 4500 and 5500</li> -<li>third timing number between 6800 and 8300</li> -</ul> -<p>You may find decodes that don't quite fit either. If it almost fits, it may -be worth testing to see if it works, but it's most unlikely to work if the -second timing number is above the suggested max or the third timing number -is below the suggested min. For example, I found a decode with frequency -41879 and timing numbers (132,5092,7652). The three timing numbers are -perfect for protocol 0045, but the frequency is quite wrong. I have no -device to test with, but my guess is that it would work anyway. For -protocol 0068, the third number 7652 is below the minimum of 7700 making -it quite unlikely to work. I found a different device with frequency -33333 and timing (450,5770,8656). For 0068 all but the first number are -perfect and I would be quite surprised if it didn't work. For 0045 the second -number 5770 is too high for the max of 5500, so it's unlikely to work.</p> -<p>The decodes for RECS80 all report EFCs for protocol 0045. These are not -correct EFCs if you select a protocol other than 0045, so it is better to -use OBC numbers when creating a JP1 upgrade based on these decodes.</p> - -<h2><a name="Replay">Replay</a></h2> -UEI protocol: 0092 -<br>IRP notation: {36k,444,msb}<-1,1|1,-1>(6,-2,1:1,6:3,<-2,2|2,-2>(T:1),D:8,S:8,F:8,-???)+ -<br>EFC translation: MSB -<p>Replay is a member of the RC6 family. Technically it is RC6-6-24, but DecodeIr will always -display the name as "Replay". ProntoEdit calls this protocol "RC6 mode 6A" and KM has it under the -alternate name "RC-6a" as well as its primary name "Replay". RM has it under the alternate name "RC6-M-24n" as -well as its primary name "Replay".</p> -<p>DecodeIr's Subdevice field in is called "unit" in KM</p> -<p>In ProntoEdit, DecodeIr's "Device" is called "Customer Code"; DecodeIr's "Subdevice" is called "System"; -and DecodeIr's "OBC" is called "Command".</p> - -<h2><a name="Samsung20">Samsung20</a></h2> -IRP notation: {38.4k,564}<1,-1|1,-3>(8,-8,D:6,S:6,F:8,1,^???)+ -<br>EFC translation: LSB -<p>This is a moderately robust protocol, but <a href="#spurious">spurious decodes</a> are still possible.</p> - - -<h2><a name="Samsung36">Samsung36</a></h2> -UEI protocol: 01B5 -<br>IRP notation: {38k,500}<1,-1|1,-3>(9,-9,D:8,S:8,1,-9,E:4,F:8,-68u,~F:8,1,-118)+ -<br>EFC translation: LSB - -<h2><a name="Sampo">Sampo</a></h2> -IRP notation: {38.4k, 833}<1,-1|1,-3>(4,-4,D:6,F:6,S:6,~F:6,1,-39)+ -<br>EFC translation: Not available in this version of DecodeIr -<p>This is a moderately robust protocol, but <a href="#spurious">spurious decodes</a> are still possible.</p> - -<h2><a name="ScAtl-6">ScAtl-6</a></h2> -UEI protocol: 0078 -<br>IRP notation: {57.6k,846}<1,-1|1,-3>(4,-4,D:6,F:6,~D:6,~F:6,1,-40)+ -<br>EFC translation: 6-bit LSB comp - <p>ScAtl-6 is distinguished from Emerson only by frequency. So if you are using - a learning system that doesn't record the frequency accurately, then DecodeIr - can't accurately select between Emerson and ScAtl-6.</p> -<p>In KM, this protocol is named "Scientific Atlanta". Most Scientific Atlanta cable tuners use Panasonic_Old -protocol, not this protocol.</p> - -<h2><a name="Sejin-M-38">Sejin-<i>M</i>-38 and Sejin-<i>M</i>-56</a></h2> -UEI protocol: 0161 -<br> -IRP notation for Sejin-<i>M</i>-38: {38.8k,310,msb}<-1|1>(<8:4|4:4|2:4|1:4>(3,3:2,Dx:8,Fx:8,Fy:8,E:4,C:4,-L))+ -<br> -IRP notation for Sejin-<i>M</i>-56: {56.3k,310,msb}<-1|1>(<8:4|4:4|2:4|1:4>(3,3:2,Dx:8,Fx:8,Fy:8,E:4,C:4,-L))+ -<br> -In both cases E is a checksum seed (0 in all known examples) and C is a checksum given by -<br>C = Dx:4 + Dx:4:4 + Fx:4 + Fx:4:4 + Fy:4 + Fy:4:4 + E. -<br>EFC translation: For Sejin-1, MSB. For Sejin-2, EFC translation not available. -<p>The parameter <i>M</i> is either 1 or 2. It distinguishes two styles -of this protocol that have different purposes and very different -lead-out times L. The 8-bit parameter Dx is a signed integer. If Dx -> 0 then the style is Sejin-1, used for normal buttons of a remote -control. If Dx < 0 then the style is Sejin-2, used for signals of an - associated 2- or 3-button pointing device. E is a checksum seed, E=0 -in the only known examples. The checksum formula reflects that in the -UEI executor, so is -presumed correct.</p> - -<p>The protocol parameters Dx, Fx, Fy translate into device parameters -in different ways corresponding to the different uses of the protocol. -In Sejin-1 the device parameters are a Device Code, a SubDevice code and - an OBC as is common for many protocols. Sejin-2 has two sub-styles. -One corresponds to the displacement of a cursor or other pointer with -device parameters (X, Y) that -give the horizontal and vertical components of the displacement (and -which can be positive or negative). The other signals Button Up or -Button Down for any of the three buttons of the pointing device. The -Misc field of the DecodeIR output displays these device parameters for -the Sejin-2 signals. The relationship between these and the protocol -parameters is beyond the -scope of this document. The Misc field also displays an RMOBC value for - Sejin-2 signals, which is an artificial OBC value that can be used as -input to RemoteMaster to create the signal concerned.</p> - -<p>The protocol parameters for Sejin-1 include a bit that marks the end frame of a <a href="#repeat">repeat - sequence</a>. DecodeIR v2.37 and later check this and will report in the Misc field if the end frame is - missing. This will normally be due to the key still being held when the learning process ends, so that - the end frame gets omitted from the learned signal. For Sejin-2 signals that represent button operations - the signal does not repeat. A single frame is sent on button down, a different frame is sent once on - button up. Both frames can be detected and distinguished by DecodeIR v2.37 and later but the button up - frame will not normally be present in a learned signal.</p> - -<h2><a name="Sharp">Sharp, Sharp{1} and Sharp{2}</a></h2> -IRP notation: {38k,264}<1,-3|1,-7>(D:5,F:8,1:2,1,-165,D:5,~F:8,2:2,1,-165)+ -<br>EFC translation: LSB - <p>A Sharp signal has two halves, either one of which is enough to fully decode - the information. A significant fraction of Sharp learned signals contain just - one half or have the halves separated so that DecodeIr can't process them - together. When one half is seen separate from the other, DecodeIr will name - the protocol Sharp{1} or Sharp{2} depending on which half is decoded. Sharp, - Sharp{1} and Sharp{2} all represent the same protocol when they are correct. - But only Sharp is robust. A Sharp{1} or Sharp{2} decode might be <a href="#spurious">spurious</a>.</p> - - -<h2><a name="SharpDVD">SharpDVD</a></h2> -UEI protocol: 00F8 -<br> -IRP notation: {38k,400}<1,-1|1,-3>(8,-4,170:8,90:8,15:4,D:4,S:8,F:8,E:4,C:4,1,-48)+ {E=1,C=D^S:4:0^S:4:4^F:4:0^F:4:4^E:4} -<br> EFC translation: LSB comp -<p>SharpDVD is the member of the Kaseikyo family with OEM_code1=170 and OEM_code2=90.</p> - -<h2><a name="SIM2">SIM2</a></h2> -IRP notation: {38.8k,400}<3,-3|3,-7>(6,-7,D:8,F:8,3,-60m) - -<h2><a name="Solidtek16">Solidtek16</a></h2> -IRP notation: {38k}<-624,468|468-624>(1820,-590,0:1,D:4,F:7,S:1,C:4,1:1,-???) -<p> -This is a KeyBoard protocol. The make/break bit is decoded into the subdevice field.</p> - -<h2><a name="Solidtek20">Solidtek20</a></h2> -IRP notation: {38k}<-624,468|468-624>(1820,-590,0:1,D:4,S:6,F:6,C:4,1:1,-???) -<p> -This is a mouse protocol. The button press info is included in the Device field. The horizontal motion -is in the Subdevice field, and the vertical motion is in the OBC field.</p> -<p>The decode interface does not support returning negative Subdevice or OBC. So negative motions are -represented by adding 64 to them. The numbers 1 to 31 represent positive motion. The numbers 32 to 63 -are each 64 larger than the true negative motion, so 63 represents -1 and 32 represents -32.</p> - -<h2><a name="Somfy">Somfy</a></h2> -IRP notation: {35.7k}<308,-881|669,-520>(2072,-484,F:2,D:3,C:4,-2300)+ -<br>C is reported as SubDevice. It is probably a check nibble {C = F*4 + D + 3}. -<br>F = 1 for UP or 2 for DOWN. -<br>D = 1, 2 or 3 for the three observed devices, or D = 0 to control all devices together. - -<h2><a name="Sony8">Sony8</a></h2> -IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:8,^22200) -<br>EFC translation: LSB. - -<h2><a name="Sony12">Sony12</a></h2> -UEI protocol: 00CA -<br>IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ -<br>EFC translation: LSB. - -<h2><a name="Sony15">Sony15</a></h2> -UEI protocol: 00CA -<br>IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ -<br>EFC translation: LSB. - -<h2><a name="Sony20">Sony20</a></h2> -UEI protocol: 00DE -<br>IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m)+ -<br>EFC translation: LSB. - -<h2><a name="StreamZap">StreamZap</a></h2> -IRP notation: {36k,msb,889}<1,-1|-1,1>(1:1,~F:1:6,T:1,D:6,F:6,^114m)+ -<br>DecodeIR V2.43 decodes this as RC5-7F -<br>EFC translation: 6-bit MSB comp - -<h2><a name="StreamZap-57">StreamZap-57</a></h2> -IRP notation: {57k,msb,889}<1,-1|-1,1>(1:1,~F:1:6,T:1,D:6,F:6,^114m)+ -<br>DecodeIR V2.43 decodes this as RC5-7F-57 -<br>EFC translation: 6-bit MSB comp - - -<h2><a name="Sunfire">Sunfire</a></h2> -IRP notation: (38k,560,msb)<1,-1|3,-1>(16,-8, D:4,F:8,~D:4,~F:8 -32)+ -<br>EFC translation: Not available in this version of DecodeIr - -<h2><a name="TDC-38">TDC-38 and TDC-56</a></h2> -IRP notation for TDC-38: {38k,315,msb}<-1,1|1,-1>(1:1,D:5,S:5,F:7,-89m)+ -<br>IRP notation for TDC-56: {56.3k,213,msb}<-1,1|1,-1>(1:1,D:5,S:5,F:7,-89m)+ -<br>EFC translation: 7-bit MSB. -<p>There are two variants of this protocol, with different frequencies but with the same number of carrier - cycles in each burst, which makes the duration of a burst also differ. TDC-38 has a 38kHz carrier and is - used by Danish TDC IPTV. TDC-56 has a 56.3kHz carrier and is used by Italian ALICE Home TV box. These - implementations effectively use a 6-bit OBC as bit 0 of F is always the complement of bit 1, but there - are other implementations which do not follow that pattern.</p> - -<h2><a name="Teac-K">Teac-K</a></h2> -UEI protocol: 00BB -<br> -IRP notation: {37k,432}<1,-1|1,-3>(8,-4,67:8,83:8,X:4,D:4,S:8,F:8,T:8,1,-100,(8,-8,1,-100)+ -{T=D+S:4:0+S:4:4+F:4:0+F:4:4} <br> -EFC translation: LSB comp, two parts -<p>Teac-K is the member of the Kaseikyo family with OEM_code1=67 and OEM_code2=83.</p> -<p>Teac-K uses different repeat rules and a different check byte than other Kaseikyo protocols.</p> -<p>00BB requires 2-byte hex commands. DecodeIr returns both hex cmd bytes through the interface that usually -means one or the other (for mini combos) but in this case it means both.</p> -<p>This protocol signals repeats by the use of <a href="#repeat">dittos</a>.</p> - -<h2><a name="Thomson">Thomson</a></h2> -UEI protocol: 004B -<br>IRP notation: {33k,500}<1,-4|1,-9>(D:4,T:1,D:1:5,F:6,1,^80m)+ -<br>EFC translation: 6-bit LSB comp, or that prepended with extra device bit. -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> -<p>DecodeIR2.42 deprecates Thompson (5 bits of device, and 6 bits of function) and reports these - signals as Thompson7 (4 bits of device and 7 bits of function).</p> -<p>Thomson includes a <a href="#toggle">toggle bit</a> so using learned signals will have -operational problems. You should use <a href="#jp1">KeyMoves or Upgrades</a> based on the decoded values, -rather than continue to use the learned signals.</p> - <p>There are two different variants of UEI protocol 004B which have different - EFC numbering. The decode lists both possible EFCs so you could experiment - to discover which is right for your model. But, if you are creating an upgrade - (rather than just KeyMoves) it is better to use RM and use the OBC numbers - from the decode (which are stable across models of JP1 remote). As of version - 8.31, KM does not have support for Thomson protocol, so if you must make an - upgrade in KM you need to use pid:004B. For the URC-8040 and 8060 the second - decoded EFC should be right and the OBC values in KM should be wrong. For - most (maybe all) other models, the first decoded EFC should be right and KM's - default EFC to OBC translation should also be right.</p> - -<h2><a name="Thomson7">Thomson7</a></h2> -UEI protocol: 004B -<br>IRP notation: {33k,500}<1,-4|1,-9>(D:4,T:1,F:7,1,^80m)+ -<br>EFC translation: 7-bit LSB comp -<p>DecodeIR2.42 deprecates Thompson (5 bits of device, and 6 bits of function) and reports these - signals as Thompson7 (4 bits of device and 7 bits of function).</p> - -<h2><a name="Tivo">Tivo</a></h2> -IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,133:8,48:8,F:8,U:4,~F:4:4,1,-78,(16,-4,1,-173)*) -<br> -EFC translation: LSB comp - -<h2><a name="Velleman">Velleman</a></h2> -IRP notation: {38k,msb}<700,-5060|700,-7590>(1:1,T:1,D:3,F:6,1,-55m)+ -<br>EFC translation: 6-bit MSB comp -<p>Very similar to RECS80-0045, except on duration is longer</p> - -<h2><a name="Velodyne">Velodyne</a></h2> -IRP notation: -{38k,136,msb}<210,-760>(<0:1|0:1,-1|0:1,-2|0:1,-3|0:1,-4|0:1,-5|0:1,-6|0:1,-7|0:1,-8|0:1,-9|0:1,-10|0:1,-11|0:1,-12|0:1,-13|0:1,-14|0:1,-15>(S:4:4,C1:4,S:4,15:4,D:4,0:4,F:8,210u,-79m,S:4:4,C2:4,S:4,15:4,D:4,8:4,F:8,210u,-79m)+){C1=-(8+S+S::4+15+D+0+F+F::4),C2=-(8+S+S::4+15+D+8+F+F::4)) -<br> Velodyne is a close relative of XMP. - -<h2><a name="Viewstar">Viewstar</a></h2> -UEI protocol: 0021 -<br>IRP notation: {50.5k,337}<1,-8|1,-5>(F:5,1,-17)+ -<br>EFC translation: 5-bit LSB comp -<p>This is not a robust protocol, so <a href="#spurious">spurious decodes</a> are likely.</p> - -<h2><a name="X10">X10 and X10.<i>n</i></a></h2> -UEI protocol: 003F (X10.<i>n</i>), 01DF (X10) -<br>IRP notation for X10: {40.8k,565}<2,-12|7,-7>(7,-7,F:5,~F:5,21,-7)+ -<br>IRP notation for X10.<i>n</i>: {40.8k,565}<2,-12|7,-7>(F:5,N:-4,21,-7,(7,-7,F:5,~F:5,21,-7)+) -<br>EFC translation: LSB of 2*OBC+1 -<p>These are two variants of the same Home Automation protocol. They differ in that X10.<i>n</i> has a - distinctive start frame that carries a sequence number, the <i>n</i> of the protocol name, in addition - to the OBC. The repeat frames, and all frames of the X10 version, only carry the OBC. The value - of <i>n</i> runs from 0 to 15 (or some lower value) and then restarts again at 0. It is incremented on - each successive keypress. A valid X10.<i>n</i> signal must have at least one repeat frame. If this is - missing then the Misc column shows "invalid signal".</p> -<p>RemoteMaster has a single protocol, named X10 with PID 003F, that sends X10.<i>n</i> signals. This is - the same as the UEI protocol with that PID. There is no control over the value of <i>n</i>, this is - handled automatically by the remote. The newer UEI protocol, with PID 01DF, sends X10 signals.</p> - -<h2><a name="XMP">XMP, XMP-1 and XMP-2</a></h2> -UEI protocol: 016C -<br>IRP notation (without final frame): -{38k,136,msb}<210,-760>(<0:1|0:1,-1|0:1,-2|0:1,-3|0:1,-4|0:1,-5|0:1,-6|0:1,-7|0:1,-8|0:1,-9|0:1,-10|0:1,-11|0:1,-12|0:1,-13|0:1,-14|0:1,-15>(T=0,(S:4:4,C1:4,S:4,15:4,OEM:8,D:8,210u,-13.8m,S:4:4,C2:4,T:4,S:4,F:16,210u,-80.4m,T=8)+)){C1=-(15+S+S::4+15+OEM+OEM::4+D+D::4),C2=-(15+S+S:4+T+F+F::4+F::8+F::12)} -<br>IRP notation (with final -frame):{38k,136,msb}<210,-760>(<0:1|0:1,-1|0:1,-2|0:1,-3|0:1,-4|0:1,-5|0:1,-6|0:1,-7|0:1,-8|0:1,-9|0:1,-10|0:1,-11|0:1,-12|0:1,-13|0:1,-14|0:1,-15>(T=0,((S:4:4,C1:4,S:4,15:4,OEM:8,D:8,210u,-13.8m,S:4:4,C2:4,T:4,S:4,F:16,210u,[-80.4m][-80.4m][-13.8m],T=8)+,T=9)2)){C1=-(S+S::4+15+OEM+OEM::4+D+D::4),C2=-(S+S:4+T+F+F::4+F::8+F::12)} -<br>XMP uses one burst pair to encode numbers 0 to 15, with an on -duration of 210uS, and off duration of 760uS + n*136uS where n takes on -values of 0 to 15. -The checksum nibble is the complement of 15 plus the sum of the other 7 -nibbles, mod 16 - -<br><br>The Device code is D, the SubDevice code is S and there are two OBC values. OBC1 is the high byte -of F, OBC2 is the low byte of F. The OEM code is normally 0x44 and is reported in the Misc field only if it -has a different value. The XMP-1 protocol is XMP with OBC2 = 0. The OBC field in DecodeIR then shows OBC1. -The XMP-2 protocol is XMP with OBC1 = 0. The OBC field in DecodeIR then shows OBC2. -<br><p>This protocol has a 4-bit toggle T that is 0 for the first frame and normally 8 for all repeat frames. - There is, however, a variant in which a further frame with T=9 is sent after the button is released, - separated from the preceding frame by the short leadout of 13.8m that is used between two half-frames - rather than the long lead-out of 80.4m used at the end of all other frames. When this frame is detected - then the Misc field displays "With Final Frame". For this to be shown in a learned signal, the - button must be released before the learning process times out, so a short button press is needed.</p> - -<p>These are problem decodes because JP1 remotes don't typically learn these signals accurately enough -for a correct decode. NG Prontos also do a rotten job of learning these signals. Older Prontos seem to do -fairly well. DecodeIR v2.40 includes algorithms that attempt to reconstruct a valid XMP signal from a corrupt -learn, but it is impossible to correct all learning errors and there can be no certainty that a reconstruction -is actually correct.</p> -<p>In a correctly learned or fully reconstructed signal there will be an - "XMP", "XMP-1" or "XMP-2" decode with device, subdevice and OBC values -that can be used with RemoteMaster or any similar -program to regenerate a clean signal. The Misc field shows which -algorithms, if any, have been applied, as a list in brackets after any -decode data in this field. There are notes below on the reliability of -the various algorithms. When the protocol shows as (unqualified) XMP, -both OBC values are non-zero. The OBC and Hex fields show OBC1. The -corresponding values for OBC2 are shown in the Misc field.</p> -<p>The learned signal itself will certainly not be valid if any reconstruction algorithms have been applied and -it may not be so even if it has been decoded without reconstruction. The possible algorithm indicators in the -Misc field are as follows:</p> -<ul> -<li>End (= Endpoint): The lead-out burst is missing and has been inserted. This is almost certainly correct. -</li><li>Rec (= Recovery): Look-ahead has been used to recover a -missing burst from the following repeat frame. This is very likely to -be correct. -</li><li>Cor (= Correction): Two bursts have been coalesced in the -learning process, e.g. those for hex digits C and D, causing a C to -appear as D or vice versa. -The error has been identified and corrected. This is probably correct. -</li><li>Cal (= Calculated): A missing digit has been calculated from a -checksum. The digit is probably correct but it may be in the wrong -place. The most likely error in the reconstruction is that the two -digits of the OBC are the wrong way round. -</li><li>Cal2 (= Calculated 2) Two consecutive missing zero digits have - been identified, corresponding to a zero OBC. When this happens, the -signal will always be shown as XMP-1. The most likely error in the -reconstruction is that it should actually be XMP-2. -</li></ul> -<p>If a learned signal is good enough to be recognised as XMP but not good enough to be fully reconstructed, the -protocol will display with a name of the form -<br><br>XMP:136.218-0F0F441A0A800F00 -<br><br> - In IR.exe you'll need to widen the Protocol column to see the whole thing. This - represents intermediate data from an unsuccessful attempt to decode a XMP signal. - - The number in the position where the 136 is in this example represents the time scale. A number (like this -example) that is near 137 is reasonable. A number much further from 137 indicates a more serious learning or decoding -problem. -The number in the position where the .218 is in this example (it is not part of the 136) represents the level -of inconsistency in the individual hex digit decodes. A value greater than .100 means the hex digits aren't very -reliable.</p> -<p>The hex string, where the 0F0F441A0A800F00 is, is the decoded data. At least one digit is almost certainly wrong or -the whole decode wouldn't be displayed in this form. With a JP1 learning remote, the most common errors are that a -digit is actually missing, in which case the string will have fewer than 16 hex digits, or that two -or more digits which are decoded the same are actually different, so some of them are correct and some are one value -higher or lower. Although the reconstruction algorithms attempt to correct these types of errors, it is not always -possible. In this example I happen to know the correct signal. One of the three F's is really an E and one -of the two A's is really a 9. The correct string is 0E0F441A09800F00.</p> -<p>Almost all examples we've seen start with "0E0F441A0" or "060F44120". But we've also seen upgrades from UEI for -"0D1F441A0" and "0C2F441A0" and "0B3F441A0". -The last 4 digits of the whole 16 digit string (if they are correct) represent the Hex command needed to reproduce -the signal in a JP1 upgrade or KeyMove. DecodeIR shows them as two 8-bit OBC values, as described with the IRP -notation above.</p> - -<h2><a name="XX">XX</a></h2> -Documentation not written yet. - -<h2><a name="Zaptor">Zaptor</a></h2> -UEI protocol: unknown -<br>IRP notation: {36k,330,msb}<-1,1|1,-1>[T=0] [T=0] [T=1] (8,-6,2,D:8,T:1,S:7,F:8,E:4,C:4,-74m)+ - {C = (D:4+D:4:4+S:4+S:3:4+8*T+F:4+F:4:4+E)&15} -<br>where T=0 for all frames except the last, T=1 for last frame, E is a checksum seed. There is a 56KHz variant. -<br>EFC translation: MSB -<p>A protocol so far seen only in the Motorola Zaptor. See also Amino</p> - -<h2><a name="Zenith">Zenith</a></h2> -UEI protocol: 0022 -IRP notation: {40k,520,msb}<1,-10|1,-1,1,-8>(S:1,<1:2|2:2>(F:D),-90m)+ -<br>Before Version 2.43, this document has shown the IRP notation as -{40k,520,msb}<1,-1,1,-8|1,-10>(S:1,<1:2|2:2>(F:D),-90m)+ -<br>EFC translation: MSB -<p>An unusual protocol, in that the number of bits in the function code is variable. It is represented in - DecodeIR as the device code. There are also two lead-in styles, decoded as subdevice values 0 and 1. - Style 1 aka "double-start" is usually used in TV's, other appliances use 0 aka "single start". If the - device code is >8 then the bytes given in the Misc field as E = ... follow the OBC in the function - code value.</p> - -<h2><a name="?1-??-??-??">?1-??-??-??</a></h2> -An experimental decode I added based on the thread at -<a href="http://www.hifi-remote.com/forums/viewtopic.php?p=19168#19168">JP1-forum"Unknown - Protocol"</a> - -</blockquote> -<p> </p> -<table width="750"><tbody><tr><td><center> -<script type="text/javascript"><!-- -google_ad_client = "pub-2040680936936450"; -/* 468x60, created 4/17/09 */ -google_ad_slot = "7283198346"; -google_ad_width = 468; -google_ad_height = 60; -//--> -</script> -<script type="text/javascript" src="Interpreting%20Decoded%20IR%20Signals%20%28v2.43%29-Dateien/show_ads.js"> -</script> -</center> -</td></tr></tbody></table> - -</body></html> \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Advanced/Receive_Custom/Receive_Custom.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive_Custom - Receives IR signals with custom decoding function and blocks until the data is read. - */ - -#include "IRLremote.h" - -// see readme to choose the right pin (with an interrupt!) for your Arduino board -const int pinReceiveIR = digitalPinToInterrupt(2); - -void setup() { - // start serial debug output - Serial.begin(115200); - Serial.println("Startup"); - - // set protocol to user to use the decode function below - IRLbegin<IR_USER>(pinReceiveIR); -} - -void loop() { - // this will get the first valid input, and blocks until you reset below - if (IRLavailable()) { - // print as much as you want in this function - // see source to terminate what number is for each protocol - Serial.print("Protocol:"); - Serial.println(IRLgetProtocol()); - Serial.print("Address:"); - Serial.println(IRLgetAddress(), HEX); - Serial.print("Command:"); - Serial.println(IRLgetCommand(), HEX); - - // resume reading to get new values - IRLreset(); - } -} - -void decodeIR(const uint32_t duration) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - - // add the protocols you want to use here to reduce flash/ram/performance. - // you can use this to decode e.g. two remotes at the same time - // but dont need to check all of the other protocols. - // calling this function takes some small overhead though. - decodeNec<IR_EXTRA_ACCURACY>(duration); - decodePanasonic<IR_EXTRA_ACCURACY>(duration); -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Advanced/Receive_NEC_Led_Minimal/Receive_NEC_Led_Minimal.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive NEC Led Minimal - Receives IR and lights the LED on a valid signal. - - This should only demonstrate that you can use the IR sensor - from almost every direction with almost no flash/ram. - This method uses a minimal implementation of the PCINT example. - Please see the Demos on how to use the library API or the - PCINT functions. This sketch is only a minimal implementation. - - Flash usage (Uno): - BlinkWithoutDelay: 1,006 bytes flash, 15 bytes ram - IRL Receive NEC Led: 1,390 bytes flash, 22 bytes ram - - Ram usage (Uno): - 4bytes lastTime - for each protocol: - 4-6 bytes temporary work data - 1 byte temporary count - = 4+(n*(5~7)) bytes ram used - */ - -#include "IRLremote.h" - -//================================================================================ -// PCINT functions -//================================================================================ - -// PCINT definitions, edit and see data sheets for more information -#define PCINT_PIN 11 - -#define PCMSK *digitalPinToPCMSK(PCINT_PIN) -#define PCINT digitalPinToPCMSKbit(PCINT_PIN) -#define PCIE digitalPinToPCICRbit(PCINT_PIN) -#define PCPIN *portInputRegister(digitalPinToPort(PCINT_PIN)) - -#if (PCIE == 0) -#define PCINT_vect PCINT0_vect -#elif (PCIE == 1) -#define PCINT_vect PCINT1_vect -#elif (PCIE == 2) -#define PCINT_vect PCINT2_vect -#else -#error This board doesnt support PCINT ? -#endif - -// choose NEC for this demonstration (most common protocol) -#define PCINT_FUNCTION IRLinterrupt<IR_NEC> - -ISR(PCINT_vect) { - // that is the smallest possible version for a single pin. - // this wont work if you set more than one PCINT - // see the basic PCINT example for a correct version. - PCINT_FUNCTION(); -} - -//================================================================================ -// Main sketch -//================================================================================ - -const int pinLed = LED_BUILTIN; -unsigned long previousMillis = 0; - -void setup() { - // set LED to output - pinMode(pinLed, OUTPUT); - - // pin change mask registers decide which pins are enabled as triggers - PCMSK |= (1 << PCINT); - - // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors - PCICR |= (1 << PCIE); -} - -void loop() { - // turn led on LED for a few ms when received a valid IR signal - if (millis() - previousMillis < 100) - digitalWrite(pinLed, HIGH); - else - digitalWrite(pinLed, LOW); -} - -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - previousMillis = millis(); -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Advanced/Receive_PinChangeInterrupt_Uno_Api/PinChangeInterrupt.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -#include "pins_arduino.h" -/* - * an extension to the interrupt support for arduino. - * add pin change interrupts to the external interrupts, giving a way - * for users to have interrupts drive off of any pin. - * Refer to avr-gcc header files, arduino source and atmega datasheet. - */ - -/* - * Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts. - * The PCINT corresponding to the pin must be enabled and masked, and - * an ISR routine provided. Since PCINTs are per port, not per pin, the ISR - * must use some logic to actually implement a per-pin interrupt service. - */ - -/* Pin to interrupt map: - * D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2 - * D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0 - * A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1 - */ - -volatile uint8_t *port_to_pcmask[] = { - &PCMSK0, - &PCMSK1, - &PCMSK2 -}; - -static int PCintMode[24]; - -typedef void (*voidFuncPtr)(void); - -volatile static voidFuncPtr PCintFunc[24] = { - NULL -}; - -volatile static uint8_t PCintLast[3]; - -/* - * attach an interrupt to a specific pin using pin change interrupts. - */ -void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode) { - uint8_t bit = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - uint8_t slot; - volatile uint8_t *pcmask; - - // map pin to PCIR register - if (port == NOT_A_PORT) { - return; - } - else { - port -= 2; - pcmask = port_to_pcmask[port]; - } - - // -- Fix by Baziki. In the original sources it was a little bug, which cause analog ports to work incorrectly. - if (port == 1) { - slot = port * 8 + (pin - 14); - } - else { - slot = port * 8 + (pin % 8); - } - // --Fix end - PCintMode[slot] = mode; - PCintFunc[slot] = userFunc; - // set the mask - *pcmask |= bit; - // enable the interrupt - PCICR |= 0x01 << port; -} - -void PCdetachInterrupt(uint8_t pin) { - uint8_t bit = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - volatile uint8_t *pcmask; - - // map pin to PCIR register - if (port == NOT_A_PORT) { - return; - } - else { - port -= 2; - pcmask = port_to_pcmask[port]; - } - - // disable the mask. - *pcmask &= ~bit; - // if that's the last one, disable the interrupt. - if (*pcmask == 0) { - PCICR &= ~(0x01 << port); - } -} - -// common code for isr handler. "port" is the PCINT number. -// there isn't really a good way to back-map ports and masks to pins. -static void PCint(uint8_t port) { - uint8_t bit; - uint8_t curr; - uint8_t mask; - uint8_t pin; - - // get the pin states for the indicated port. - curr = *portInputRegister(port + 2); - mask = curr ^ PCintLast[port]; - PCintLast[port] = curr; - // mask is pins that have changed. screen out non pcint pins. - if ((mask &= *port_to_pcmask[port]) == 0) { - return; - } - // mask is pcint pins that have changed. - for (uint8_t i = 0; i < 8; i++) { - bit = 0x01 << i; - if (bit & mask) { - pin = port * 8 + i; - // Trigger interrupt if mode is CHANGE, or if mode is RISING and - // the bit is currently high, or if mode is FALLING and bit is low. - if ((PCintMode[pin] == CHANGE - || ((PCintMode[pin] == RISING) && (curr & bit)) - || ((PCintMode[pin] == FALLING) && !(curr & bit))) - && (PCintFunc[pin] != NULL)) { - PCintFunc[pin](); - } - } - } -} - - -ISR(PCINT0_vect) { - PCint(0); -} -ISR(PCINT1_vect) { - PCint(1); -} -ISR(PCINT2_vect) { - PCint(2); -}
--- a/start/IRLremote-1.7.3/examples/Advanced/Receive_PinChangeInterrupt_Uno_Api/Receive_PinChangeInterrupt_Uno_Api.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive_PinChangeInterrupt - Receives IR signals with custom Pin Change Interrupt function. - - This is a PCINT implementation with an attach PCINT API only usable with Arduino Uno. - I do not recommend to use it, because its very large. This was the first attempt - to use PCINT and has now improved with the PCINT Basic example. - This sketch is only here for legacy reasons. - - See second .ino file (next tab in IDE) for the pinchange implementation. - This is perfectly usable if you dont want to use your normal interrupts for IRL. - Keep in mind that this PCINT is not compatible with SoftSerial (at the moment). - */ - -#include "IRLremote.h" - -// function prototypes from 2nd .ino file -void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode); -void PCdetachInterrupt(uint8_t pin); - -// choose your pin (must be on a PCINT pin though) -const int pinReceiveIR = 4; - -// temporary variables to save latest IR input -uint8_t IRProtocol = 0; -uint16_t IRAddress = 0; -uint32_t IRCommand = 0; - -void setup() -{ - // start serial debug output - Serial.begin(115200); - Serial.println("Startup"); - - // choose your protocol here to reduce flash/ram/performance - // see readme for more information - PCattachInterrupt(pinReceiveIR, IRLinterrupt<IR_ALL>, CHANGE); -} - -void loop() { - // temporary disable interrupts and print newest input - uint8_t oldSREG = SREG; - cli(); - if (IRProtocol) { - // print as much as you want in this function - // see source to terminate what number is for each protocol - Serial.println(); - Serial.print("Protocol:"); - Serial.println(IRProtocol); - Serial.print("Address:"); - Serial.println(IRAddress, HEX); - Serial.print("Command:"); - Serial.println(IRCommand, HEX); - - // reset variable to not read the same value twice - IRProtocol = 0; - } - SREG = oldSREG; -} - -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - - // update the values to the newest valid input - IRProtocol = protocol; - IRAddress = address; - IRCommand = command; -}
--- a/start/IRLremote-1.7.3/examples/Advanced/Receive_Raw/Receive_Raw.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive_Raw - Receives IR signals and prints raw values to the Serial. - This also demonstrates how to implement your own decoding functions. - */ - -#include "IRLremote.h" - -// see readme to choose the right pin (with an interrupt!) for your Arduino board -const int pinReceiveIR = digitalPinToInterrupt(2); - -// variables to record raw values -#define IR_RAW_TIMEOUT 0xFFFF // 65535, max timeout -#define IR_RAW_BUFFER_SIZE 100 -uint32_t buffer[IR_RAW_BUFFER_SIZE]; -uint8_t count = 0; - -void setup() { - // start serial debug output - Serial.begin(115200); - Serial.println("Startup"); - - // set protocol to user to use the decode function below - IRLbegin<IR_USER>(pinReceiveIR); -} - -void loop() { - // check if raw buff is full or timed out. - // keep in mind that the defined timeout above might be in the output (by default 50000) - // so you dont get confused where the number is from. - uint8_t irBytes = RAWIRLavailable(); - if (irBytes) { - // print a mark - Serial.println("=========="); - - // go through the whole buffer and print values - for (int i = 0; i < irBytes; i++) { - Serial.print(i); - Serial.print(": "); - Serial.println(buffer[i], DEC); - } - - // reset for new reading - count = 0; - } -} - -void decodeIR(const uint16_t duration) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - - // block until data is read - if (RAWIRLavailable()) return; - - // save value and increase count - buffer[count++] = duration; - - // save last time in the buff too, to calculate timeout check - if (count != IR_RAW_BUFFER_SIZE) - buffer[count] = micros(); -} - -uint8_t RAWIRLavailable(void) { - // disable interrupts when checking for new input - uint8_t oldSREG = SREG; - cli(); - - // check if we have data - if (count) { - // check if buffer is full - if (count == IR_RAW_BUFFER_SIZE) { - SREG = oldSREG; - return count; - } - - // check if last reading was a timeout. - // no problem if count==0 because the if above prevents this - // anyways then it would just return 0 - if (buffer[count - 1] > IR_RAW_TIMEOUT) { - SREG = oldSREG; - return count; - } - - // check if reading timed out and save value. - // saving is needed to abord the check above next time. - unsigned long duration = micros() - buffer[count]; - if (duration >= IR_RAW_TIMEOUT) { - buffer[count++] = IR_RAW_TIMEOUT; - SREG = oldSREG; - return count; - } - } - - // continue, we can still save into the buffer or the buffer is empty - SREG = oldSREG; - return 0; -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Advanced/Transceive_HoodLoader2/Transceive_HoodLoader2.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Transceive HoodLoader2 - Receives IR signals with custom Pin Change Interrupt function. - - This sketch is especially made for the 16u2 combined with the HoodLoader2. - It lights the TX Led on any valid signal. - RX Led is on when a special signal is received. Then a signal is send out. - The Receiver is connected to PB1 (SCLK). - The Transmitter is connected to PB2 (MOSI). - - This is the very basic PCINT version to use almost any pin for the IRLremote. - All you need to do is look up the ports in the datasheet. - Keep in mind that this PCINT is not compatible with SoftSerial (at the moment). - */ - -#include "IRLremote.h" - -//================================================================================ -// PCINT functions -//================================================================================ - -// PCINT definitions, edit and see datasheets for more information -#define PCINT_PIN 1 - -#define PCMSK *digitalPinToPCMSK(PCINT_PIN) -#define PCINT digitalPinToPCMSKbit(PCINT_PIN) -#define PCIE digitalPinToPCICRbit(PCINT_PIN) -#define PCPIN *portInputRegister(digitalPinToPort(PCINT_PIN)) - -#if (PCIE == 0) -#define PCINT_vect PCINT0_vect -#elif (PCIE == 1) -#define PCINT_vect PCINT1_vect -#elif (PCIE == 2) -#define PCINT_vect PCINT2_vect -#else -#error This board doesnt support PCINT ? -#endif - -#define PCINT_FUNCTION IRLinterrupt<IR_ALL> - -// variable to save the last register state -volatile static uint8_t lastRegister; - -void attachPinChangeInterrupt(void) { - // save the current state first - lastRegister = PCPIN; - - // pin change mask registers decide which pins are enabled as triggers - PCMSK |= (1 << PCINT); - - // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors - PCICR |= (1 << PCIE); -} - -void detachPinChangeInterrupt(void) { - // disable the mask. - PCMSK &= ~(1 << PCINT); - - // if that's the last one, disable the interrupt. - if (PCMSK == 0) - PCICR &= ~(0x01 << PCIE); -} - -ISR(PCINT_vect) { - // get the new pin states for port, compare with the old state and save new state - // this is not needed if you only use a single PCINT pin - // to be complete i've added it anyways. The smaller version would be just to call PCINT_FUNCTION(); - uint8_t currRegister = PCPIN; - uint8_t changedPinMask = currRegister ^ lastRegister; - lastRegister = currRegister; - - // if our needed pin has changed, call the IRL interrupt function - if (changedPinMask & (1 << PCINT)) - PCINT_FUNCTION(); -} - -//================================================================================ -// Main sketch -//================================================================================ - -#ifndef USBCON -// workaround for undefined USBCON has to be placed in every sketch -// otherwise the timings wont work correctly -ISR(USB_GEN_vect) -{ - UDINT = 0; -} -#endif - -// variable to save the last update -unsigned long previousMillis = 0; - -// choose any pin to send IR signals -const int pinSendIR = 2; - -// variable to save a sending trigger -bool sendNow = false; - -void setup() { - TX_RX_LED_INIT; - // set LED to output - pinMode(LED_BUILTIN_TX, OUTPUT); - pinMode(LED_BUILTIN_RX, OUTPUT); - - // attach the new PinChangeInterrupt function above - attachPinChangeInterrupt(); -} - -void loop() { - // turn led on LED for a few ms when received a valid IR signal - if (millis() - previousMillis < 100) - digitalWrite(LED_BUILTIN_TX, LOW); - else - digitalWrite(LED_BUILTIN_TX, HIGH); - - // check if the input was a specific signal and send another signal out - if (sendNow) { - // turn on led - digitalWrite(LED_BUILTIN_RX, LOW); - - // send the data, no pin setting to OUTPUT needed - uint16_t address = 0x6361; - uint32_t command = 0xFE01; - - IRLwrite<IR_NEC>(pinSendIR, address, command); - - // turn off led and reset trigger - digitalWrite(LED_BUILTIN_RX, HIGH); - sendNow = false; - } -} - -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - previousMillis = millis(); - - // set the trigger if input signal is the choosen - if (protocol == IR_PANASONIC && address == 0x2002 && command == 0x813D1CA0) - sendNow = true; -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Advanced/Transceive_Minimal/Transceive_Minimal.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Transceive Minimal - Receives IR signals and blocks until the data is read. - On receiving a specific IR input it will send another IR signal out. - - This example is a minimal implementation of the library with a - receiving and sending part. Please see the Demos on how to use - the library API or the PCINT functions. - The trigger variable is used to not block in the ISR too long. - Avoid big function calls inside the ISR! - - Flash usage (Uno): - 1,310 bytes - Ram usage (Uno): - 21 bytes - */ - -#include "IRLremote.h" - -//================================================================================ -// PCINT functions -//================================================================================ - -// PCINT definitions, edit and see data sheets for more information -#define PCINT_PIN 11 - -#define PCMSK *digitalPinToPCMSK(PCINT_PIN) -#define PCINT digitalPinToPCMSKbit(PCINT_PIN) -#define PCIE digitalPinToPCICRbit(PCINT_PIN) -#define PCPIN *portInputRegister(digitalPinToPort(PCINT_PIN)) - -#if (PCIE == 0) -#define PCINT_vect PCINT0_vect -#elif (PCIE == 1) -#define PCINT_vect PCINT1_vect -#elif (PCIE == 2) -#define PCINT_vect PCINT2_vect -#else -#error This board doesnt support PCINT ? -#endif - -// choose Panasonic for this demonstration -#define PCINT_FUNCTION IRLinterrupt<IR_PANASONIC> - -ISR(PCINT_vect) { - // that is the smallest possible version for a single pin. - // this wont work if you set more than one PCINT - // see the basic PCINT example for a correct version. - PCINT_FUNCTION(); -} - -//================================================================================ -// Main sketch -//================================================================================ - -// choose any pin to send IR signals -const int pinSendIR = 3; - -// variable to save a sending trigger -bool sendNow = false; - -void setup() { - // pin change mask registers decide which pins are enabled as triggers - PCMSK |= (1 << PCINT); - - // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors - PCICR |= (1 << PCIE); -} - -void loop() { - // check if the input was a specific signal and send another signal out - if (sendNow) { - // send the data, no pin setting to OUTPUT needed - uint16_t address = 0x6361; - uint32_t command = 0xFE01; - - IRLwrite<IR_NEC>(pinSendIR, address, command); - - // reset trigger - sendNow = false; - } -} - -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - - // set the trigger if input signal is the choosen - if (protocol == IR_PANASONIC && address == 0x2002 && command == 0x813D1CA0) - sendNow = true; -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Demos/Receive_Blocking/Receive_Blocking.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive_Blocking - Receives IR signals and blocks until the data is read. - */ - -#include "IRLremote.h" - -// see readme to choose the right pin (with an interrupt!) for your Arduino board -const int pinReceiveIR = digitalPinToInterrupt(2); - -void setup() { - // start serial debug output - Serial.begin(115200); - Serial.println("Startup"); - - // choose your protocol here to reduce flash/ram/performance - // see readme for more information - IRLbegin<IR_ALL>(pinReceiveIR); -} - -void loop() { - // this will get the first valid input, and blocks until you reset below - if (IRLavailable()) { - // print as much as you want in this function - // see source to terminate what number is for each protocol - Serial.println(); - Serial.print("Protocol:"); - Serial.println(IRLgetProtocol()); - Serial.print("Address:"); - Serial.println(IRLgetAddress(), HEX); - Serial.print("Command:"); - Serial.println(IRLgetCommand(), HEX); - - // resume reading to get new values - IRLreset(); - } -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Demos/Receive_NoBlocking/IRLremote.cpp Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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. -*/ - -#include "IRLremote.h" - -//================================================================================ -// User function helper -//================================================================================ - -// ensure available() returns false -uint8_t IRLProtocol = 0; -uint16_t IRLAddress = 0; -uint32_t IRLCommand = 0; - -// Called when directly received correct IR Signal -// Do not use Serial inside, it can crash your Arduino! -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // For no user function set we need to pause IR - // to not overwrite the actual values until they are read. - if (IRLProtocol) return; - IRLAddress = address; - IRLCommand = command; - IRLProtocol = protocol; -} - -void decodeIR(const uint16_t duration){ - // add your own protocols here or create your own decoding function - // you can overwrite this function in your .ino file - decodeAll(duration); -}
--- a/start/IRLremote-1.7.3/examples/Demos/Receive_NoBlocking/IRLremote.h Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,778 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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 IRLREMOTE_H -#define IRLREMOTE_H - -#include <Arduino.h> - -//missing 1.0.6 definition workaround -#if ARDUINO == 106 -#define NOT_AN_INTERRUPT -1 -#endif - -// board type detection -#if defined(__MK20DX128__) || defined(__MK20DX256__) -#define IRLREMOTE_ARM -#define IRLREMOTE_TEENSY3 -#elif defined(__SAM3X8E__) -#define IRLREMOTE_ARM -#define IRLREMOTE_DUE -#else -// default to assuming everything else is avr for now -#define IRLREMOTE_AVR -#endif - -// delay_basic is only for avrs. with ARM sending is currently not possible -#ifdef IRLREMOTE_AVR -#include <util/delay_basic.h> -#endif - -//================================================================================ -// Definitions -//================================================================================ - -//NEC -//IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,-78,(16,-4,1,-173)*) -// Lead + Space logic -#define NEC_HZ 38400 -#define NEC_PULSE 564UL -#define NEC_BLOCKS 4 -#define NEC_ADDRESS_LENGTH 16 -#define NEC_COMMAND_LENGTH 16 -#define NEC_LENGTH 2 + NEC_BLOCKS*8*2 // 2 for lead + space, each block has 8bits: mark and space -#define NEC_TIMEOUT NEC_PULSE*173 -#define NEC_MARK_LEAD NEC_PULSE*16 -#define NEC_SPACE_LEAD NEC_PULSE*8 -#define NEC_SPACE_HOLDING NEC_PULSE*4 -#define NEC_MARK_ZERO NEC_PULSE*1 -#define NEC_MARK_ONE NEC_PULSE*1 -#define NEC_SPACE_ZERO NEC_PULSE*1 -#define NEC_SPACE_ONE NEC_PULSE*3 - -//PANASONIC -//IRP notation: {37k,432}<1,-1|1,-3>(8,-4,3:8,1:8,D:8,S:8,F:8,(D^S^F):8,1,-173)+ -// Lead + Space logic -#define PANASONIC_HZ 37000 -#define PANASONIC_PULSE 432UL -#define PANASONIC_BLOCKS 6 -#define PANASONIC_ADDRESS_LENGTH 16 -#define PANASONIC_COMMAND_LENGTH 32 -#define PANASONIC_LENGTH 2 + PANASONIC_BLOCKS*8*2 // 2 for lead + space, each block has 8bits: mark and space -#define PANASONIC_TIMEOUT PANASONIC_PULSE*173 -#define PANASONIC_MARK_LEAD PANASONIC_PULSE*8 -#define PANASONIC_SPACE_LEAD PANASONIC_PULSE*4 -#define PANASONIC_SPACE_HOLDING 0 // no holding function in this protocol -#define PANASONIC_MARK_ZERO PANASONIC_PULSE*1 -#define PANASONIC_MARK_ONE PANASONIC_PULSE*1 -#define PANASONIC_SPACE_ZERO PANASONIC_PULSE*1 -#define PANASONIC_SPACE_ONE PANASONIC_PULSE*3 - -/* -Panasonic pulse demonstration: - -*---------| |------------| |---------| |---| ... -| |--------- -* | | | | | | | ... | | -* | | | | | | | ... | | -* |------------------------| |---| |---| |- ... |---| -* | Lead Mark | Lead Space | Logical 1 | Log 0 | Data |End| - -*/ - -//SONY 8, 12, 15, 20 -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:8,^22200) -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m) + -// Lead + Mark logic -#define SONY_HZ 40000 -#define SONY_PULSE 600UL -#define SONY_BLOCKS_8 1 -#define SONY_BLOCKS_12 2 -#define SONY_BLOCKS_15 2 -#define SONY_BLOCKS_20 3 -#define SONY_ADDRESS_LENGTH_8 0 -#define SONY_ADDRESS_LENGTH_12 5 -#define SONY_ADDRESS_LENGTH_15 8 -#define SONY_ADDRESS_LENGTH_20 13 -#define SONY_COMMAND_LENGTH_8 8 -#define SONY_COMMAND_LENGTH_12 7 -#define SONY_COMMAND_LENGTH_15 7 -#define SONY_COMMAND_LENGTH_20 7 -#define SONY_LENGTH_8 2 + (8-1)*2 // 2 for lead + space, -1 for mark end, 8 bit -#define SONY_LENGTH_12 2 + (7+5-1)*2 // 2 for lead + space, -1 for mark end, 12 bit -#define SONY_LENGTH_15 2 + (7+8-1)*2 // 2 for lead + space, -1 for mark end, 15 bit -#define SONY_LENGTH_20 2 + (7+5+8-1)*2 // 2 for lead + space, -1 for mark end, 20 bit -#define SONY_TIMEOUT_8 22200 -#define SONY_TIMEOUT 45000 // 12, 15, 20 have the same timeout -#define SONY_MARK_LEAD SONY_PULSE*4 -#define SONY_SPACE_LEAD SONY_PULSE*1 -#define SONY_SPACE_HOLDING 0 // no holding function in this protocol -#define SONY_MARK_ZERO SONY_PULSE*1 -#define SONY_MARK_ONE SONY_PULSE*2 -#define SONY_SPACE_ZERO SONY_PULSE*1 -#define SONY_SPACE_ONE SONY_PULSE*1 - -typedef enum IRType{ - IR_NO_PROTOCOL, // 0 - IR_USER, // 1 - IR_ALL, // 2 - IR_NEC, // ... - IR_PANASONIC, - IR_SONY8, - IR_SONY12, - IR_SONY15, - IR_SONY20, - // add new protocols here - IR_RAW, -}; - -// definitions to use decoding functions with extra accuracy -#define IR_EXTRA_ACCURACY true -#define IR_NO_EXTRA_ACCURACY false - -// definition for sending to determine what should be send first -#define IR_ADDRESS_FIRST true -#define IR_COMMAND_FIRST false - -// definition to convert an uint8_t array to an uint16_t/uint32_t at any position (thx timeage!) -#define UINT16_AT_OFFSET(p_to_8, offset) ((uint16_t)*((const uint16_t *)((p_to_8)+(offset)))) -#define UINT32_AT_OFFSET(p_to_8, offset) ((uint32_t)*((const uint32_t *)((p_to_8)+(offset)))) - -// definition to get the higher value -#define MAX(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) - -// definition to get the lower value -#define MIN(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) - -//================================================================================ -// Prototypes -//================================================================================ - -// attach the interrupt function -template <IRType irType> -inline void IRLbegin(const uint8_t interrupt) __attribute__((always_inline)); - -// dettach the interrupt function -inline void IRLend(const uint8_t interrupt) __attribute__((always_inline)); - -// variables for IR processing if no user function was set -extern uint8_t IRLProtocol; -extern uint16_t IRLAddress; -extern uint32_t IRLCommand; - -// functions to use if no user function was set -inline bool IRLavailable(void) __attribute__((always_inline)); -inline void IRLreset(void) __attribute__((always_inline)); -inline uint8_t IRLgetProtocol(void) __attribute__((always_inline)); -inline uint16_t IRLgetAddress(void) __attribute__((always_inline)); -inline uint32_t IRLgetCommand(void) __attribute__((always_inline)); - -// function called on a valid IR event, must be overwritten by the user -void __attribute__((weak)) IREvent(uint8_t protocol, uint16_t address, uint32_t command); - -// optinal user function called when the user wants to implement its own decoding function -void __attribute__((weak)) decodeIR(const uint16_t duration); - -// called by interrupt CHANGE -template <IRType irType> -inline void IRLinterrupt(void) __attribute__((always_inline)); - -// special decode function for each protocol -inline void decodeAll(const uint16_t duration) __attribute__((always_inline)); -template <bool extraAccuracy> inline void decodeNec(const uint16_t duration); -template <bool extraAccuracy> inline void decodePanasonic(const uint16_t duration) __attribute__((always_inline)); -template <bool extraAccuracy> inline void decodeSony8(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony12(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony15(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony20(const uint16_t duration); -inline void decodeRaw(const uint16_t duration) __attribute__((always_inline)); - -// functions to check if the received data is valid with the protocol checksums -inline bool IRLcheckInverse0(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckInverse1(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckHolding(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckXOR0(uint8_t data[]) __attribute__((always_inline)); - -// default decoder helper function -template <uint8_t irLength, uint16_t timeoutThreshold, uint16_t markLeadThreshold, uint16_t spaceLeadThreshold, - uint16_t spaceLeadHoldingThreshold, uint16_t markThreshold, uint16_t spaceThreshold, - uint16_t markTimeout, uint16_t spaceTimeout> - inline bool IRLdecode(uint16_t duration, uint8_t data[]) __attribute__((always_inline)); - -// functions to send the protocol -template <IRType irType> -inline void IRLwrite(const uint8_t pin, uint16_t address, uint32_t command) __attribute__((always_inline)); - -template <uint8_t addressLength, uint8_t commandLength, - uint16_t Hz, bool addressFirst, - uint16_t markLead, uint16_t spaceLead, - uint16_t markZero, uint16_t markOne, - uint16_t spaceZero, uint16_t spaceOne> - inline void IRLsend(volatile uint8_t * outPort, uint8_t bitmask, uint16_t address, uint32_t command) __attribute__((always_inline)); - -// functions to set the pin high or low (with bitbang pwm) -inline void IRLmark(const uint16_t Hz, volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) __attribute__((always_inline)); -inline void IRLspace(volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) __attribute__((always_inline)); - -//================================================================================ -// Inline Implementations (receive) -//================================================================================ - -template <IRType irType> -void IRLbegin(const uint8_t interrupt){ - // attach the function that decodes the signals - attachInterrupt(interrupt, IRLinterrupt<irType>, CHANGE); -} - -void IRLend(const uint8_t interrupt){ - // release the interrupt, if its NOT_AN_INTERRUPT the detach function does nothing - detachInterrupt(interrupt); - // also make sure to call reset() after end() if you use the intern reading functions -} - -bool IRLavailable(void){ - return IRLProtocol; -} - -void IRLreset(void){ - IRLProtocol = 0; -} - -uint8_t IRLgetProtocol(void){ - return IRLProtocol; -} - -uint16_t IRLgetAddress(void){ - return IRLAddress; -} - -uint32_t IRLgetCommand(void){ - return IRLCommand; -} - -template <IRType irType> -void IRLinterrupt(void){ - //save the duration between the last reading - static uint32_t lastTime = 0; - uint32_t time = micros(); - uint32_t duration_32 = time - lastTime; - lastTime = time; - - // calculate 16 bit duration. On overflow set duration to a clear timeout - uint16_t duration = 0xFFFF; - if (duration_32 <= 0xFFFF) - duration = duration_32; - - // determinate which decode function must be called - switch (irType){ - case IR_USER: - // userfunction that can be overwritten - decodeIR(duration); - break; - case IR_ALL: - decodeAll(duration); - break; - case IR_NEC: - decodeNec<IR_NO_EXTRA_ACCURACY>(duration); - break; - case IR_PANASONIC: - decodePanasonic<IR_NO_EXTRA_ACCURACY>(duration); - break; - //case IR_SONY8: - // decodeSony8<IR_NO_EXTRA_ACCURACY>(duration); - // break; - case IR_SONY12: - decodeSony12<IR_NO_EXTRA_ACCURACY>(duration); - break; - //case IR_SONY15: - // decodeSony15<IR_NO_EXTRA_ACCURACY>(duration); - // break; - //case IR_SONY20: - // decodeSony20<IR_NO_EXTRA_ACCURACY>(duration); - // break; - case IR_RAW: - decodeRaw(duration); - break; - } -} - -void decodeAll(const uint16_t duration){ - // go through all known protocols and decode with more (resource unfriendly) accuration - decodeNec<IR_EXTRA_ACCURACY>(duration); - decodePanasonic<IR_EXTRA_ACCURACY>(duration); - decodeSony12<IR_EXTRA_ACCURACY>(duration); -} - -template <bool extraAccuracy> void decodeNec(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[NEC_BLOCKS]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) // no accuracy set at the moment, no conflict detected yet - newInput = IRLdecode <NEC_LENGTH, (NEC_TIMEOUT + NEC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (NEC_MARK_LEAD + NEC_SPACE_ONE) / 2, (NEC_SPACE_LEAD + NEC_SPACE_HOLDING) / 2, // markLeadThreshold, spaceLeadThreshold - (NEC_SPACE_HOLDING + NEC_SPACE_ONE) / 2, 0, // spaceLeadHoldingThreshold, markThreshold - (NEC_SPACE_ONE + NEC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <NEC_LENGTH, (NEC_TIMEOUT + NEC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (NEC_MARK_LEAD + NEC_SPACE_ONE) / 2, (NEC_SPACE_LEAD + NEC_SPACE_HOLDING) / 2, // markLeadThreshold, spaceLeadThreshold - (NEC_SPACE_HOLDING + NEC_SPACE_ONE) / 2, 0, // spaceLeadHoldingThreshold, markThreshold - (NEC_SPACE_ONE + NEC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // Check if the protcol's checksum is correct - bool holding; - if (IRLcheckInverse1(data) || (holding = IRLcheckHolding(data))){ - // normally NEC also check for the inverse of the address. - // newer remotes dont have this because of the wide used protocol all addresses were already used - // to make it less complicated its left out and the user can check the command inverse himself if needed - //if (!holding && !extended && !IRLcheckInverse0(data)) - // return; - - // save address + command and trigger event - uint16_t address = UINT16_AT_OFFSET(data, 0); - uint32_t command = UINT16_AT_OFFSET(data, 2); - IREvent(IR_NEC, address, command); - } - } -} - -template <bool extraAccuracy> void decodePanasonic(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[PANASONIC_BLOCKS]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) // no accuracy set at the moment, no conflict detected yet - newInput = IRLdecode <PANASONIC_LENGTH, (PANASONIC_TIMEOUT + PANASONIC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (PANASONIC_MARK_LEAD + PANASONIC_SPACE_ONE) / 2, (PANASONIC_SPACE_LEAD + PANASONIC_SPACE_ONE) / 2, // markLeadThreshold, spaceLeadThreshold - 0, 0, // spaceLeadHoldingThreshold, markThreshold - (PANASONIC_SPACE_ONE + PANASONIC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <PANASONIC_LENGTH, (PANASONIC_TIMEOUT + PANASONIC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (PANASONIC_MARK_LEAD + PANASONIC_SPACE_ONE) / 2, (PANASONIC_SPACE_LEAD + PANASONIC_SPACE_ONE) / 2, // markLeadThreshold, spaceLeadThreshold - 0, 0, // spaceLeadHoldingThreshold, markThreshold - (PANASONIC_SPACE_ONE + PANASONIC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // Check if the protcol's checksum is correct - if (IRLcheckXOR0(data)){ - uint16_t address = UINT16_AT_OFFSET(data, 0); - uint32_t command = UINT32_AT_OFFSET(data, 2); IREvent(IR_PANASONIC, address, command); - return; - } - } -} - -template <bool extraAccuracy> void decodeSony12(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[SONY_BLOCKS_12]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) - newInput = IRLdecode <SONY_LENGTH_12, (SONY_TIMEOUT + SONY_MARK_LEAD) / 2, // irLength, timeoutThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, 0, // markLeadThreshold, spaceLeadThreshold - 0, (SONY_MARK_ONE + SONY_MARK_ZERO) / 2, // spaceLeadHoldingThreshold, markThreshold - 0, // spaceThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, SONY_MARK_ONE>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <SONY_LENGTH_12, (SONY_TIMEOUT + SONY_MARK_LEAD) / 2, // irLength, timeoutThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, 0, // markLeadThreshold, spaceLeadThreshold - 0, (SONY_MARK_ONE + SONY_MARK_ZERO) / 2, // spaceLeadHoldingThreshold, markThreshold - 0, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // protocol has no checksum - uint16_t address = UINT16_AT_OFFSET(data, 0) >> 7; - uint32_t command = data[0] & 0x7F; - IREvent(IR_SONY12, address, command); - return; - } -} - -void decodeRaw(const uint16_t duration){ - //TODO, use advanced raw example instead -} - -bool IRLcheckInverse0(uint8_t data[]){ - // check if byte 2 and is the inverse of byte 3 - if (uint8_t((data[0] ^ (~data[1]))) == 0) - return true; - else return false; -} - -bool IRLcheckInverse1(uint8_t data[]){ - // check if byte 0 and is the inverse of byte 1 - if (uint8_t((data[2] ^ (~data[3]))) == 0) - return true; - else return false; -} - -bool IRLcheckHolding(uint8_t data[]){ - // check if at least the command is always 1 - if (data[2] == 0xFF && data[3] == 0xFF) - return true; - else return false; -} - -bool IRLcheckXOR0(uint8_t data[]){ - // this function is used for panasonic checksum - if (uint8_t(data[2] ^ data[3] ^ data[4]) == data[5]) - return true; - else return false; -} - -// multifunctional template for receiving -template <uint8_t irLength, uint16_t timeoutThreshold, uint16_t markLeadThreshold, uint16_t spaceLeadThreshold, - uint16_t spaceLeadHoldingThreshold, uint16_t markThreshold, uint16_t spaceThreshold, - uint16_t markTimeout, uint16_t spaceTimeout> - bool IRLdecode(uint16_t duration, uint8_t data[]){ - - // variables for ir processing - static uint8_t count = 0; - - // if timeout always start next possible reading and abort any pending readings - if (duration >= timeoutThreshold) - count = 1; - - // on a reset (error in decoding) we are waiting for a timeout to start a new reading again - // this is to not conflict with other protocols while they are sending 0/1 which might be similar to a lead in another protocol - else if (count == 0) - return false; - - // check pulses for mark/space and lead + logical 0/1 seperate - else{ - // Mark pulses (odd numbers) - if (count % 2 == 1){ - // check Mark Lead (needs a timeout or a correct signal) - if (markLeadThreshold && count == 1){ - // lead is okay// wrong lead - if (duration <= markLeadThreshold){ - count = 0; - return false; - } - } - - else{ - // check for timeout if needed (might be a different protocol) - if (markTimeout && duration > markTimeout){ - count = 0; - return false; - } - - // only check values if the protocol has different logical space pulses - else if (markThreshold){ - - // get number of the Mark Bits (starting from zero) - uint8_t length; - // only save every 2nd value, substract the first two lead pulses - if (!spaceThreshold) - length = (count / 2) - 1; - // special case: spaces and marks both have data in the pulse - else length = count - 2; - - // move bits and write 1 or 0 depending on the duration - // 1.7: changed from MSB to LSB. somehow takes a bit more flash but is correct and easier to handle. - data[length / 8] >>= 1; - if (duration > markThreshold) - data[length / 8] |= 0x80; - //else // normally not needed through the bitshift - // data[length / 8] &= ~0x80; - } - - // check last input (always a mark) - if (count > irLength){ - count = 0; - return true; - } - } - } - - // Space pulses (even numbers) - else{ - //check Space Lead/Space Holding - if (spaceLeadThreshold && count == 2){ - // normal Space, next reading - if (duration > spaceLeadThreshold); - - // Button holding (if supported by protocol) - else if (spaceLeadHoldingThreshold && duration > spaceLeadHoldingThreshold){ - // set command to 0xFF if button is held down - if (irLength == (4 * 8 * 2 + 2)){ - data[0] = data[1] = 0x00; - data[2] = data[3] = 0xFF; - } - count = 0; - return true; - } - // wrong space - else { - count = 0; - return false; - } - } - else{ - // check for timeout if needed (might be a different protocol) - if (spaceTimeout && duration > spaceTimeout){ - count = 0; - return false; - } - - // only check values if the protocol has different logical space pulses - else if (spaceThreshold){ - - // get number of the Space Bits (starting from zero) - uint8_t length; - // only save every 2nd value, substract the first two lead pulses - if (!markThreshold) - length = (count / 2) - 2; - // special case: spaces and marks both have data in the pulse - else length = count - 2; - - // move bits and write 1 or 0 depending on the duration - // 1.7: changed from MSB to LSB. somehow takes a bit more flash but is correct and easier to handle. - data[length / 8] >>= 1; - if (duration > spaceThreshold) - data[length / 8] |= 0x80; - //else // normally not needed through the bitshift - // data[length / 8] &= ~0x80; - } - } - } - - // next reading, no errors - count++; - } - - // no valid input (yet) - return false; -} - -//================================================================================ -// Inline Implementations (send) -//================================================================================ - -template <IRType irType> -void IRLwrite(const uint8_t pin, uint16_t address, uint32_t command) -{ - // get the port mask and the pointers to the out/mode registers for faster access - uint8_t bitMask = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - volatile uint8_t * outPort = portOutputRegister(port); - volatile uint8_t * modePort = portModeRegister(port); - - // set pin to OUTPUT and LOW - *modePort |= bitMask; - *outPort &= ~bitMask; - - // disable interrupts - uint8_t oldSREG = SREG; - cli(); - - switch (irType){ - - case IR_NEC: - // NEC only sends the data once - if (command == 0xFFF) - // send holding indicator - IRLsend<0, 0, NEC_HZ, 0, NEC_MARK_LEAD, NEC_SPACE_HOLDING, - 0, 0, 0, 0> - (outPort, bitMask, address, command); - else - // send data - IRLsend<NEC_ADDRESS_LENGTH, NEC_COMMAND_LENGTH, NEC_HZ, IR_ADDRESS_FIRST, NEC_MARK_LEAD, NEC_SPACE_LEAD, - NEC_MARK_ZERO, NEC_MARK_ONE, NEC_SPACE_ZERO, NEC_SPACE_ONE> - (outPort, bitMask, address, command); - break; - - case IR_PANASONIC: //TODO test - // send data - IRLsend<PANASONIC_ADDRESS_LENGTH, PANASONIC_COMMAND_LENGTH, PANASONIC_HZ, IR_ADDRESS_FIRST, PANASONIC_MARK_LEAD, PANASONIC_SPACE_LEAD, - PANASONIC_MARK_ZERO, PANASONIC_MARK_ONE, PANASONIC_SPACE_ZERO, PANASONIC_SPACE_ONE> - (outPort, bitMask, address, command); - break; - - case IR_SONY12: //TODO test, address -1? - // repeat 3 times - for (uint8_t i = 0; i < 3; i++) - // send data - IRLsend<SONY_ADDRESS_LENGTH_12, SONY_COMMAND_LENGTH_12, SONY_HZ, IR_COMMAND_FIRST, SONY_MARK_LEAD, SONY_SPACE_LEAD, - SONY_MARK_ZERO, SONY_MARK_ONE, SONY_SPACE_ZERO, SONY_SPACE_ONE> - (outPort, bitMask, address, command); - break; - } - - // enable interrupts - SREG = oldSREG; - - // set pin to INPUT again to be save - *modePort &= ~bitMask; -} - -// multifunctional template for sending -template <uint8_t addressLength, uint8_t commandLength, - uint16_t Hz, bool addressFirst, - uint16_t markLead, uint16_t spaceLead, - uint16_t markZero, uint16_t markOne, - uint16_t spaceZero, uint16_t spaceOne> - void IRLsend(volatile uint8_t * outPort, uint8_t bitmask, uint16_t address, uint32_t command){ - - // send lead mark - if (markLead) - IRLmark(Hz, outPort, bitmask, markLead); - - // send lead space - if (spaceLead) - IRLspace(outPort, bitmask, spaceLead); - - // abort if input values are both the same (sending a holding signal for example) - if (markOne != markZero || spaceOne != spaceZero) - { - // go through all bits - for (uint8_t i = 0; i < (addressLength + commandLength); i++){ - // determine if its a logical one or zero, starting with address or command - bool bitToSend; - if (addressFirst && i < addressLength || !addressFirst && i >= commandLength){ - bitToSend = address & 0x01; - address >>= 1; - } - else{ - bitToSend = command & 0x01; - command >>= 1; - } - - // send logic mark bits if needed - if (markOne != markZero){ - // modulate if spaces dont have logic, else only every even number - if (spaceOne == spaceZero || spaceOne != spaceZero && i % 2 == 0) - { - if (bitToSend) - IRLmark(Hz, outPort, bitmask, markOne); - else - IRLmark(Hz, outPort, bitmask, markZero); - } - } - else - IRLmark(Hz, outPort, bitmask, markOne); - - // send logic space bits if needed - if (spaceOne != spaceZero){ - // modulate if marks dont have logic, else only every odd number - if (markOne == markZero || markOne != markZero && i % 2 == 1){ - if (bitToSend) - IRLspace(outPort, bitmask, spaceOne); - else - IRLspace(outPort, bitmask, spaceZero); - } - } - else - IRLspace(outPort, bitmask, spaceOne); - } - } - - // finish mark - IRLmark(Hz, outPort, bitmask, markZero); //TODO zero or one for sony? - IRLspace(outPort, bitmask, 0); -} - -void IRLmark(const uint16_t Hz, volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) { - /* - Bitbangs PWM in the given Hz number for the given time - ________________________________________________________________________________ - Delay calculation: - F_CPU/1.000.000 to get number of cycles/uS - /3 to get the number of loops needed for 1ms (1loop = 3 cycles) - - Multiply with the number of ms delay: - 1/kHz to get the seconds - * 1.000.000 to get it in uS - /2 to get half of a full pulse - - Substract the while, portmanipulation, loop overhead /3 loop cycles - - F_CPU(16.000.000) 1 * 1.000.000(pulse in uS) 12(overhead) - ========================== * ========================== - ============== - 1.000.000 * 3(loop cycles) Hz * 2(half of a pulse) 3(loop cycles) - - <==> - - F_CPU(16.000.000) - (12(overhead) * Hz * 2(half of a pulse)) - =========================================================== - Hz * 2(half of a on/off pulse) * 3(loop cycles) - - ________________________________________________________________________________ - Iterations calculation: - Devide time with cycles in while loop - Multiply this with the cycles per uS - cycles per while loop: 3(loop cycles) * delay + overhead - - time * (F_CPU(16.000.000) / 1.000.000) - ====================================== - delay*3(loop cycles) + overhead - */ - - const uint32_t loopCycles = 3; - const uint32_t overHead = 12; // just a guess from try + error - uint8_t delay = (F_CPU - (overHead * Hz * 2UL)) / (Hz * 2UL * loopCycles); - uint16_t iterations = (time*(F_CPU / 1000000UL)) / (delay * loopCycles + overHead); - - while (iterations--){ - // flip pin state and wait for the calculated time - *outPort ^= bitMask; -#ifdef IRLREMOTE_AVR - _delay_loop_1(delay); -#else - // ARM TODO? -#endif - } -} - -void IRLspace(volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) { - // Sends an IRLspace for the specified number of microseconds. - // A IRLspace is no output, so the PWM output is disabled. - *outPort &= ~bitMask; // write pin LOW - delayMicroseconds(time); - //_delay_loop_2(time*(F_CPU/1000000UL)/4UL); -} - -#endif \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Demos/Receive_NoBlocking/Receive_NoBlocking.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive_NoBlocking - Receives IR signals and instantly calls an attached interrupt function. - This may fire more than one time if you press a button too long, add a debounce. - Dont use Serial inside the interrupt! - */ - -#include "IRLremote.h" - -// see readme to choose the right pin (with an interrupt!) for your Arduino board -const int interruptIR = 0; // digitalPinToInterrupt(2); - -// temporary variables to save latest IR input -uint8_t IRProtocol = 0; -uint16_t IRAddress = 0; -uint32_t IRCommand = 0; - -void setup() { - // start serial debug output - Serial.begin(115200); - Serial.println("Startup"); - - // choose your protocol here to reduce flash/ram/performance - // see readme for more information - IRLbegin<IR_NEC>(interruptIR); -} - -void loop() { - // temporary disable interrupts and print newest input - uint8_t oldSREG = SREG; - cli(); - if (IRProtocol) { - // print as much as you want in this function - // see source to terminate what number is for each protocol - Serial.println(); - Serial.print("Protocol:"); - Serial.println(IRProtocol); - Serial.print("Address:"); - Serial.println(IRAddress, HEX); - Serial.print("Command:"); - Serial.println(IRCommand, HEX); - - // reset variable to not read the same value twice - IRProtocol = 0; - } - SREG = oldSREG; -} - -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // called when directly received an interrupt CHANGE. - // do not use Serial inside, it can crash your program! - - // update the values to the newest valid input - IRProtocol = protocol; - IRAddress = address; - IRCommand = command; -}
--- a/start/IRLremote-1.7.3/examples/Demos/Receive_PinChangeInterrupt_Basic/Receive_PinChangeInterrupt_Basic.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Receive_PinChangeInterrupt_Basic - Receives IR signals with custom Pin Change Interrupt function (blocking). - - This is the very basic PCINT version to use almost any pin for the IRLremote. - PCINT is usefull if you are running out of normal INTs or if you are using HoodLoader2. - Keep in mind that this PCINT is not compatible with SoftSerial (at the moment). - - On Arduino Uno you can use any pin for receiving. - On Arduino Mega you can use 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69). - On Arduino Leonardo you can use 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). - With HoodLoader you can use pin 1-7 and some other pins which are normally not connected. - - */ - -#include "IRLremote.h" - -//================================================================================ -// PCINT functions -//================================================================================ - -// PCINT definitions, edit and see data sheets for more information -#define PCINT_PIN 11 - -#define PCMSK *digitalPinToPCMSK(PCINT_PIN) -#define PCINT digitalPinToPCMSKbit(PCINT_PIN) -#define PCIE digitalPinToPCICRbit(PCINT_PIN) -#define PCPIN *portInputRegister(digitalPinToPort(PCINT_PIN)) - -#if (PCIE == 0) -#define PCINT_vect PCINT0_vect -#elif (PCIE == 1) -#define PCINT_vect PCINT1_vect -#elif (PCIE == 2) -#define PCINT_vect PCINT2_vect -#else -#error This board doesnt support PCINT ? -#endif - -#define PCINT_FUNCTION IRLinterrupt<IR_ALL> - -// variable to save the last register state -volatile static uint8_t lastRegister; - -void attachPinChangeInterrupt(void) { - // save the current state first - lastRegister = PCPIN; - - // pin change mask registers decide which pins are enabled as triggers - PCMSK |= (1 << PCINT); - - // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors - PCICR |= (1 << PCIE); -} - -void detachPinChangeInterrupt(void) { - // disable the mask. - PCMSK &= ~(1 << PCINT); - - // if that's the last one, disable the interrupt. - if (PCMSK == 0) - PCICR &= ~(0x01 << PCIE); -} - -ISR(PCINT_vect) { - // get the new pin states for port, compare with the old state and save new state - // this is not needed if you only use a single PCINT pin - // to be complete i've added it anyways. The smaller version would be just to call PCINT_FUNCTION(); - uint8_t currRegister = PCPIN; - uint8_t changedPinMask = currRegister ^ lastRegister; - lastRegister = currRegister; - - // if our needed pin has changed, call the IRL interrupt function - if (changedPinMask & (1 << PCINT)) - PCINT_FUNCTION(); -} - -//================================================================================ -// Main sketch -//================================================================================ - -void setup() -{ - // start serial debug output - Serial.begin(115200); - Serial.println(F("Startup")); - - // attach the new PinChangeInterrupt function above - attachPinChangeInterrupt(); -} - -void loop() { - // this will get the first valid input, and blocks until you reset below - if (IRLavailable()) { - // print as much as you want in this function - // see source to terminate what number is for each protocol - Serial.println(); - Serial.print(F("Protocol:")); - Serial.println(IRLgetProtocol()); - Serial.print(F("Address:")); - Serial.println(IRLgetAddress(), HEX); - Serial.print(F("Command:")); - Serial.println(IRLgetCommand(), HEX); - - // resume reading to get new values - IRLreset(); - } -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Demos/Send_Button/Send_Button.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Send Button - Sends IR signals on any pin. This uses Bitbanging. - - Press the button to send data. - Turn interrupts off to get a better result if needed - */ - -#include "IRLremote.h" - -// choose any pin to send IR signals -const int pinSendIR = 3; - -// choose any pin to trigger IR sending -const int pinButton = 8; - -void setup() { - // setup for the button - pinMode(pinButton, INPUT_PULLUP); -} - -void loop() { - if (!digitalRead(pinButton)) { - // send the data, no pin setting to OUTPUT needed - uint16_t address = 0x6361; - uint32_t command = 0xFE01; - IRLwrite<IR_NEC>(pinSendIR, address, command); - - // simple debounce - delay(300); - } -}
--- a/start/IRLremote-1.7.3/examples/Demos/Send_Serial/Send_Serial.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Send Serial - Sends IR signals on any pin. This uses Bitbanging. - - Write anything to the Serial port and hit enter to send Data. - Turn interrupts off to get a better result if needed - */ - -#include "IRLremote.h" - -// choose any pin to send IR signals -const int pinSendIR = 3; - -void setup() { - // start serial debug in/output - Serial.begin(115200); - Serial.println("Startup"); -} - -void loop() { - if (Serial.available()) { - // discard all Serial bytes to avoid multiple sendings - delay(10); - while (Serial.available()) - Serial.read(); - - // send the data, no pin setting to OUTPUT needed - Serial.println("Sending..."); - uint16_t address = 0x6361; - uint32_t command = 0xFE01; - - IRLwrite<IR_NEC>(pinSendIR, address, command); - } -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/examples/Demos/Transceive/Transceive.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - Copyright (c) 2014 NicoHood - See the readme for credit to other people. - - IRL Transceive - Receives IR signals and blocks until the data is read. - On receiving a specific IR input it will send another IR signal out. - */ - -#include "IRLremote.h" - -// see readme to choose the right pin (with an interrupt!) for your Arduino board -const int pinReceiveIR = digitalPinToInterrupt(2); - -// choose any pin to send IR signals -const int pinSendIR = 3; - -void setup() { - // start serial debug output - Serial.begin(115200); - Serial.println("Startup"); - - // choose your protocol here to reduce flash/ram/performance - // see readme for more information - IRLbegin<IR_ALL>(pinReceiveIR); -} - -void loop() { - // this will get the first valid input, and blocks until you reset below - if (IRLavailable()) { - // print as much as you want in this function - // see source to terminate what number is for each protocol - Serial.println(); - Serial.print("Protocol:"); - Serial.println(IRLgetProtocol()); - Serial.print("Address:"); - Serial.println(IRLgetAddress(), HEX); - Serial.print("Command:"); - Serial.println(IRLgetCommand(), HEX); - - // check if the input was a specific signal and send another signal out - if (IRLgetProtocol() == IR_PANASONIC && IRLgetAddress() == 0x2002 && IRLgetCommand() == 0x813D1CA0) { - // send the data, no pin setting to OUTPUT needed - Serial.println(); - Serial.println("Sending..."); - uint16_t address = 0x6361; - uint32_t command = 0xFE01; - - IRLwrite<IR_NEC>(pinSendIR, address, command); - } - - // resume reading to get new values - IRLreset(); - } -} \ No newline at end of file
--- a/start/IRLremote-1.7.3/keywords.txt Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -####################################### -# Syntax Coloring Map For IRLremote -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -IRLbegin KEYWORD2 -IRLend KEYWORD2 - -IRLavailable KEYWORD2 -IRLreset KEYWORD2 -IRLgetProtocol KEYWORD2 -IRLgetAddress KEYWORD2 -IRLgetCommand KEYWORD2 - -IREvent KEYWORD2 -IRLinterrupt KEYWORD2 - -IRLcheckInverse0 KEYWORD2 -IRLcheckInverse1 KEYWORD2 -IRLcheckHolding KEYWORD2 -IRLcheckXOR0 KEYWORD2 -IRLdecode KEYWORD2 - -decodeIR KEYWORD2 -decodeALL KEYWORD2 -decodeNec KEYWORD2 -decodePanasonic KEYWORD2 -decodeSony8 KEYWORD2 -decodeSony12 KEYWORD2 -decodeSony15 KEYWORD2 -decodeSony20 KEYWORD2 - -IRLwrite KEYWORD2 - -IRLmark KEYWORD2 -IRLspace KEYWORD2 - -####################################### -# Instances (KEYWORD2) -####################################### - -####################################### -# Constants (LITERAL1) -####################################### - -IR_NO_PROTOCOL LITERAL1 -IR_USER LITERAL1 -IR_ALL LITERAL1 -IR_NEC LITERAL1 -IR_PANASONIC LITERAL1 -IR_SONY8 LITERAL1 -IR_SONY12 LITERAL1 -IR_SONY15 LITERAL1 -IR_SONY20 LITERAL1 -IR_RAW LITERAL1 - -IR_EXTRA_ACCURACY LITERAL1 -IR_NO_EXTRA_ACCURACY LITERAL1 - -IR_ADDRESS_FIRST LITERAL1 -IR_COMMAND_FIRST LITERAL1
--- a/start/IRLremote.cpp Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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. -*/ - -#include "IRLremote.h" - -//================================================================================ -// User function helper -//================================================================================ - -// ensure available() returns false -uint8_t IRLProtocol = 0; -uint16_t IRLAddress = 0; -uint32_t IRLCommand = 0; - -// Called when directly received correct IR Signal -// Do not use Serial inside, it can crash your Arduino! -void IREvent(uint8_t protocol, uint16_t address, uint32_t command) { - // For no user function set we need to pause IR - // to not overwrite the actual values until they are read. - if (IRLProtocol) return; - IRLAddress = address; - IRLCommand = command; - IRLProtocol = protocol; -} - -void decodeIR(const uint16_t duration){ - // add your own protocols here or create your own decoding function - // you can overwrite this function in your .ino file - decodeAll(duration); -}
--- a/start/IRLremote.h Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,778 +0,0 @@ -/* -Copyright (c) 2014 NicoHood -See the readme for credit to other people. - -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 IRLREMOTE_H -#define IRLREMOTE_H - -#include <Arduino.h> - -//missing 1.0.6 definition workaround -#if ARDUINO == 106 -#define NOT_AN_INTERRUPT -1 -#endif - -// board type detection -#if defined(__MK20DX128__) || defined(__MK20DX256__) -#define IRLREMOTE_ARM -#define IRLREMOTE_TEENSY3 -#elif defined(__SAM3X8E__) -#define IRLREMOTE_ARM -#define IRLREMOTE_DUE -#else -// default to assuming everything else is avr for now -#define IRLREMOTE_AVR -#endif - -// delay_basic is only for avrs. with ARM sending is currently not possible -#ifdef IRLREMOTE_AVR -#include <util/delay_basic.h> -#endif - -//================================================================================ -// Definitions -//================================================================================ - -//NEC -//IRP notation: {38.4k,564}<1,-1|1,-3>(16,-8,D:8,S:8,F:8,~F:8,1,-78,(16,-4,1,-173)*) -// Lead + Space logic -#define NEC_HZ 38400 -#define NEC_PULSE 564UL -#define NEC_BLOCKS 4 -#define NEC_ADDRESS_LENGTH 16 -#define NEC_COMMAND_LENGTH 16 -#define NEC_LENGTH 2 + NEC_BLOCKS*8*2 // 2 for lead + space, each block has 8bits: mark and space -#define NEC_TIMEOUT NEC_PULSE*173 -#define NEC_MARK_LEAD NEC_PULSE*16 -#define NEC_SPACE_LEAD NEC_PULSE*8 -#define NEC_SPACE_HOLDING NEC_PULSE*4 -#define NEC_MARK_ZERO NEC_PULSE*1 -#define NEC_MARK_ONE NEC_PULSE*1 -#define NEC_SPACE_ZERO NEC_PULSE*1 -#define NEC_SPACE_ONE NEC_PULSE*3 - -//PANASONIC -//IRP notation: {37k,432}<1,-1|1,-3>(8,-4,3:8,1:8,D:8,S:8,F:8,(D^S^F):8,1,-173)+ -// Lead + Space logic -#define PANASONIC_HZ 37000 -#define PANASONIC_PULSE 432UL -#define PANASONIC_BLOCKS 6 -#define PANASONIC_ADDRESS_LENGTH 16 -#define PANASONIC_COMMAND_LENGTH 32 -#define PANASONIC_LENGTH 2 + PANASONIC_BLOCKS*8*2 // 2 for lead + space, each block has 8bits: mark and space -#define PANASONIC_TIMEOUT PANASONIC_PULSE*173 -#define PANASONIC_MARK_LEAD PANASONIC_PULSE*8 -#define PANASONIC_SPACE_LEAD PANASONIC_PULSE*4 -#define PANASONIC_SPACE_HOLDING 0 // no holding function in this protocol -#define PANASONIC_MARK_ZERO PANASONIC_PULSE*1 -#define PANASONIC_MARK_ONE PANASONIC_PULSE*1 -#define PANASONIC_SPACE_ZERO PANASONIC_PULSE*1 -#define PANASONIC_SPACE_ONE PANASONIC_PULSE*3 - -/* -Panasonic pulse demonstration: - -*---------| |------------| |---------| |---| ... -| |--------- -* | | | | | | | ... | | -* | | | | | | | ... | | -* |------------------------| |---| |---| |- ... |---| -* | Lead Mark | Lead Space | Logical 1 | Log 0 | Data |End| - -*/ - -//SONY 8, 12, 15, 20 -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:8,^22200) -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ -//IRP notation: {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m) + -// Lead + Mark logic -#define SONY_HZ 40000 -#define SONY_PULSE 600UL -#define SONY_BLOCKS_8 1 -#define SONY_BLOCKS_12 2 -#define SONY_BLOCKS_15 2 -#define SONY_BLOCKS_20 3 -#define SONY_ADDRESS_LENGTH_8 0 -#define SONY_ADDRESS_LENGTH_12 5 -#define SONY_ADDRESS_LENGTH_15 8 -#define SONY_ADDRESS_LENGTH_20 13 -#define SONY_COMMAND_LENGTH_8 8 -#define SONY_COMMAND_LENGTH_12 7 -#define SONY_COMMAND_LENGTH_15 7 -#define SONY_COMMAND_LENGTH_20 7 -#define SONY_LENGTH_8 2 + (8-1)*2 // 2 for lead + space, -1 for mark end, 8 bit -#define SONY_LENGTH_12 2 + (7+5-1)*2 // 2 for lead + space, -1 for mark end, 12 bit -#define SONY_LENGTH_15 2 + (7+8-1)*2 // 2 for lead + space, -1 for mark end, 15 bit -#define SONY_LENGTH_20 2 + (7+5+8-1)*2 // 2 for lead + space, -1 for mark end, 20 bit -#define SONY_TIMEOUT_8 22200 -#define SONY_TIMEOUT 45000 // 12, 15, 20 have the same timeout -#define SONY_MARK_LEAD SONY_PULSE*4 -#define SONY_SPACE_LEAD SONY_PULSE*1 -#define SONY_SPACE_HOLDING 0 // no holding function in this protocol -#define SONY_MARK_ZERO SONY_PULSE*1 -#define SONY_MARK_ONE SONY_PULSE*2 -#define SONY_SPACE_ZERO SONY_PULSE*1 -#define SONY_SPACE_ONE SONY_PULSE*1 - -typedef enum IRType{ - IR_NO_PROTOCOL, // 0 - IR_USER, // 1 - IR_ALL, // 2 - IR_NEC, // ... - IR_PANASONIC, - IR_SONY8, - IR_SONY12, - IR_SONY15, - IR_SONY20, - // add new protocols here - IR_RAW, -}; - -// definitions to use decoding functions with extra accuracy -#define IR_EXTRA_ACCURACY true -#define IR_NO_EXTRA_ACCURACY false - -// definition for sending to determine what should be send first -#define IR_ADDRESS_FIRST true -#define IR_COMMAND_FIRST false - -// definition to convert an uint8_t array to an uint16_t/uint32_t at any position (thx timeage!) -#define UINT16_AT_OFFSET(p_to_8, offset) ((uint16_t)*((const uint16_t *)((p_to_8)+(offset)))) -#define UINT32_AT_OFFSET(p_to_8, offset) ((uint32_t)*((const uint32_t *)((p_to_8)+(offset)))) - -// definition to get the higher value -#define MAX(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) - -// definition to get the lower value -#define MIN(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) - -//================================================================================ -// Prototypes -//================================================================================ - -// attach the interrupt function -template <IRType irType> -inline void IRLbegin(const uint8_t interrupt) __attribute__((always_inline)); - -// dettach the interrupt function -inline void IRLend(const uint8_t interrupt) __attribute__((always_inline)); - -// variables for IR processing if no user function was set -extern uint8_t IRLProtocol; -extern uint16_t IRLAddress; -extern uint32_t IRLCommand; - -// functions to use if no user function was set -inline bool IRLavailable(void) __attribute__((always_inline)); -inline void IRLreset(void) __attribute__((always_inline)); -inline uint8_t IRLgetProtocol(void) __attribute__((always_inline)); -inline uint16_t IRLgetAddress(void) __attribute__((always_inline)); -inline uint32_t IRLgetCommand(void) __attribute__((always_inline)); - -// function called on a valid IR event, must be overwritten by the user -void __attribute__((weak)) IREvent(uint8_t protocol, uint16_t address, uint32_t command); - -// optinal user function called when the user wants to implement its own decoding function -void __attribute__((weak)) decodeIR(const uint16_t duration); - -// called by interrupt CHANGE -template <IRType irType> -inline void IRLinterrupt(void) __attribute__((always_inline)); - -// special decode function for each protocol -inline void decodeAll(const uint16_t duration) __attribute__((always_inline)); -template <bool extraAccuracy> inline void decodeNec(const uint16_t duration); -template <bool extraAccuracy> inline void decodePanasonic(const uint16_t duration) __attribute__((always_inline)); -template <bool extraAccuracy> inline void decodeSony8(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony12(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony15(const uint16_t duration); -template <bool extraAccuracy> inline void decodeSony20(const uint16_t duration); -inline void decodeRaw(const uint16_t duration) __attribute__((always_inline)); - -// functions to check if the received data is valid with the protocol checksums -inline bool IRLcheckInverse0(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckInverse1(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckHolding(uint8_t data[]) __attribute__((always_inline)); -inline bool IRLcheckXOR0(uint8_t data[]) __attribute__((always_inline)); - -// default decoder helper function -template <uint8_t irLength, uint16_t timeoutThreshold, uint16_t markLeadThreshold, uint16_t spaceLeadThreshold, - uint16_t spaceLeadHoldingThreshold, uint16_t markThreshold, uint16_t spaceThreshold, - uint16_t markTimeout, uint16_t spaceTimeout> - inline bool IRLdecode(uint16_t duration, uint8_t data[]) __attribute__((always_inline)); - -// functions to send the protocol -template <IRType irType> -inline void IRLwrite(const uint8_t pin, uint16_t address, uint32_t command) __attribute__((always_inline)); - -template <uint8_t addressLength, uint8_t commandLength, - uint16_t Hz, bool addressFirst, - uint16_t markLead, uint16_t spaceLead, - uint16_t markZero, uint16_t markOne, - uint16_t spaceZero, uint16_t spaceOne> - inline void IRLsend(volatile uint8_t * outPort, uint8_t bitmask, uint16_t address, uint32_t command) __attribute__((always_inline)); - -// functions to set the pin high or low (with bitbang pwm) -inline void IRLmark(const uint16_t Hz, volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) __attribute__((always_inline)); -inline void IRLspace(volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) __attribute__((always_inline)); - -//================================================================================ -// Inline Implementations (receive) -//================================================================================ - -template <IRType irType> -void IRLbegin(const uint8_t interrupt){ - // attach the function that decodes the signals - attachInterrupt(interrupt, IRLinterrupt<irType>, CHANGE); -} - -void IRLend(const uint8_t interrupt){ - // release the interrupt, if its NOT_AN_INTERRUPT the detach function does nothing - detachInterrupt(interrupt); - // also make sure to call reset() after end() if you use the intern reading functions -} - -bool IRLavailable(void){ - return IRLProtocol; -} - -void IRLreset(void){ - IRLProtocol = 0; -} - -uint8_t IRLgetProtocol(void){ - return IRLProtocol; -} - -uint16_t IRLgetAddress(void){ - return IRLAddress; -} - -uint32_t IRLgetCommand(void){ - return IRLCommand; -} - -template <IRType irType> -void IRLinterrupt(void){ - //save the duration between the last reading - static uint32_t lastTime = 0; - uint32_t time = micros(); - uint32_t duration_32 = time - lastTime; - lastTime = time; - - // calculate 16 bit duration. On overflow set duration to a clear timeout - uint16_t duration = 0xFFFF; - if (duration_32 <= 0xFFFF) - duration = duration_32; - - // determinate which decode function must be called - switch (irType){ - case IR_USER: - // userfunction that can be overwritten - decodeIR(duration); - break; - case IR_ALL: - decodeAll(duration); - break; - case IR_NEC: - decodeNec<IR_NO_EXTRA_ACCURACY>(duration); - break; - case IR_PANASONIC: - decodePanasonic<IR_NO_EXTRA_ACCURACY>(duration); - break; - //case IR_SONY8: - // decodeSony8<IR_NO_EXTRA_ACCURACY>(duration); - // break; - case IR_SONY12: - decodeSony12<IR_NO_EXTRA_ACCURACY>(duration); - break; - //case IR_SONY15: - // decodeSony15<IR_NO_EXTRA_ACCURACY>(duration); - // break; - //case IR_SONY20: - // decodeSony20<IR_NO_EXTRA_ACCURACY>(duration); - // break; - case IR_RAW: - decodeRaw(duration); - break; - } -} - -void decodeAll(const uint16_t duration){ - // go through all known protocols and decode with more (resource unfriendly) accuration - decodeNec<IR_EXTRA_ACCURACY>(duration); - decodePanasonic<IR_EXTRA_ACCURACY>(duration); - decodeSony12<IR_EXTRA_ACCURACY>(duration); -} - -template <bool extraAccuracy> void decodeNec(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[NEC_BLOCKS]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) // no accuracy set at the moment, no conflict detected yet - newInput = IRLdecode <NEC_LENGTH, (NEC_TIMEOUT + NEC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (NEC_MARK_LEAD + NEC_SPACE_ONE) / 2, (NEC_SPACE_LEAD + NEC_SPACE_HOLDING) / 2, // markLeadThreshold, spaceLeadThreshold - (NEC_SPACE_HOLDING + NEC_SPACE_ONE) / 2, 0, // spaceLeadHoldingThreshold, markThreshold - (NEC_SPACE_ONE + NEC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <NEC_LENGTH, (NEC_TIMEOUT + NEC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (NEC_MARK_LEAD + NEC_SPACE_ONE) / 2, (NEC_SPACE_LEAD + NEC_SPACE_HOLDING) / 2, // markLeadThreshold, spaceLeadThreshold - (NEC_SPACE_HOLDING + NEC_SPACE_ONE) / 2, 0, // spaceLeadHoldingThreshold, markThreshold - (NEC_SPACE_ONE + NEC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // Check if the protcol's checksum is correct - bool holding; - if (IRLcheckInverse1(data) || (holding = IRLcheckHolding(data))){ - // normally NEC also check for the inverse of the address. - // newer remotes dont have this because of the wide used protocol all addresses were already used - // to make it less complicated its left out and the user can check the command inverse himself if needed - //if (!holding && !extended && !IRLcheckInverse0(data)) - // return; - - // save address + command and trigger event - uint16_t address = UINT16_AT_OFFSET(data, 0); - uint32_t command = UINT16_AT_OFFSET(data, 2); - IREvent(IR_NEC, address, command); - } - } -} - -template <bool extraAccuracy> void decodePanasonic(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[PANASONIC_BLOCKS]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) // no accuracy set at the moment, no conflict detected yet - newInput = IRLdecode <PANASONIC_LENGTH, (PANASONIC_TIMEOUT + PANASONIC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (PANASONIC_MARK_LEAD + PANASONIC_SPACE_ONE) / 2, (PANASONIC_SPACE_LEAD + PANASONIC_SPACE_ONE) / 2, // markLeadThreshold, spaceLeadThreshold - 0, 0, // spaceLeadHoldingThreshold, markThreshold - (PANASONIC_SPACE_ONE + PANASONIC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <PANASONIC_LENGTH, (PANASONIC_TIMEOUT + PANASONIC_MARK_LEAD) / 2, // irLength, timeoutThreshold - (PANASONIC_MARK_LEAD + PANASONIC_SPACE_ONE) / 2, (PANASONIC_SPACE_LEAD + PANASONIC_SPACE_ONE) / 2, // markLeadThreshold, spaceLeadThreshold - 0, 0, // spaceLeadHoldingThreshold, markThreshold - (PANASONIC_SPACE_ONE + PANASONIC_SPACE_ZERO) / 2, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // Check if the protcol's checksum is correct - if (IRLcheckXOR0(data)){ - uint16_t address = UINT16_AT_OFFSET(data, 0); - uint32_t command = UINT32_AT_OFFSET(data, 2); IREvent(IR_PANASONIC, address, command); - return; - } - } -} - -template <bool extraAccuracy> void decodeSony12(const uint16_t duration){ - // temporary buffer to hold bytes for decoding this protocol - static uint8_t data[SONY_BLOCKS_12]; - - // pass the duration to the decoding function - bool newInput; - if (extraAccuracy) - newInput = IRLdecode <SONY_LENGTH_12, (SONY_TIMEOUT + SONY_MARK_LEAD) / 2, // irLength, timeoutThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, 0, // markLeadThreshold, spaceLeadThreshold - 0, (SONY_MARK_ONE + SONY_MARK_ZERO) / 2, // spaceLeadHoldingThreshold, markThreshold - 0, // spaceThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, SONY_MARK_ONE>// markTimeout, spaceTimeout - (duration, data); - else - newInput = IRLdecode <SONY_LENGTH_12, (SONY_TIMEOUT + SONY_MARK_LEAD) / 2, // irLength, timeoutThreshold - (SONY_MARK_LEAD + SONY_MARK_ONE) / 2, 0, // markLeadThreshold, spaceLeadThreshold - 0, (SONY_MARK_ONE + SONY_MARK_ZERO) / 2, // spaceLeadHoldingThreshold, markThreshold - 0, // spaceThreshold - 0, 0>// markTimeout, spaceTimeout - (duration, data); - - if (newInput){ - // protocol has no checksum - uint16_t address = UINT16_AT_OFFSET(data, 0) >> 7; - uint32_t command = data[0] & 0x7F; - IREvent(IR_SONY12, address, command); - return; - } -} - -void decodeRaw(const uint16_t duration){ - //TODO, use advanced raw example instead -} - -bool IRLcheckInverse0(uint8_t data[]){ - // check if byte 2 and is the inverse of byte 3 - if (uint8_t((data[0] ^ (~data[1]))) == 0) - return true; - else return false; -} - -bool IRLcheckInverse1(uint8_t data[]){ - // check if byte 0 and is the inverse of byte 1 - if (uint8_t((data[2] ^ (~data[3]))) == 0) - return true; - else return false; -} - -bool IRLcheckHolding(uint8_t data[]){ - // check if at least the command is always 1 - if (data[2] == 0xFF && data[3] == 0xFF) - return true; - else return false; -} - -bool IRLcheckXOR0(uint8_t data[]){ - // this function is used for panasonic checksum - if (uint8_t(data[2] ^ data[3] ^ data[4]) == data[5]) - return true; - else return false; -} - -// multifunctional template for receiving -template <uint8_t irLength, uint16_t timeoutThreshold, uint16_t markLeadThreshold, uint16_t spaceLeadThreshold, - uint16_t spaceLeadHoldingThreshold, uint16_t markThreshold, uint16_t spaceThreshold, - uint16_t markTimeout, uint16_t spaceTimeout> - bool IRLdecode(uint16_t duration, uint8_t data[]){ - - // variables for ir processing - static uint8_t count = 0; - - // if timeout always start next possible reading and abort any pending readings - if (duration >= timeoutThreshold) - count = 1; - - // on a reset (error in decoding) we are waiting for a timeout to start a new reading again - // this is to not conflict with other protocols while they are sending 0/1 which might be similar to a lead in another protocol - else if (count == 0) - return false; - - // check pulses for mark/space and lead + logical 0/1 seperate - else{ - // Mark pulses (odd numbers) - if (count % 2 == 1){ - // check Mark Lead (needs a timeout or a correct signal) - if (markLeadThreshold && count == 1){ - // lead is okay// wrong lead - if (duration <= markLeadThreshold){ - count = 0; - return false; - } - } - - else{ - // check for timeout if needed (might be a different protocol) - if (markTimeout && duration > markTimeout){ - count = 0; - return false; - } - - // only check values if the protocol has different logical space pulses - else if (markThreshold){ - - // get number of the Mark Bits (starting from zero) - uint8_t length; - // only save every 2nd value, substract the first two lead pulses - if (!spaceThreshold) - length = (count / 2) - 1; - // special case: spaces and marks both have data in the pulse - else length = count - 2; - - // move bits and write 1 or 0 depending on the duration - // 1.7: changed from MSB to LSB. somehow takes a bit more flash but is correct and easier to handle. - data[length / 8] >>= 1; - if (duration > markThreshold) - data[length / 8] |= 0x80; - //else // normally not needed through the bitshift - // data[length / 8] &= ~0x80; - } - - // check last input (always a mark) - if (count > irLength){ - count = 0; - return true; - } - } - } - - // Space pulses (even numbers) - else{ - //check Space Lead/Space Holding - if (spaceLeadThreshold && count == 2){ - // normal Space, next reading - if (duration > spaceLeadThreshold); - - // Button holding (if supported by protocol) - else if (spaceLeadHoldingThreshold && duration > spaceLeadHoldingThreshold){ - // set command to 0xFF if button is held down - if (irLength == (4 * 8 * 2 + 2)){ - data[0] = data[1] = 0x00; - data[2] = data[3] = 0xFF; - } - count = 0; - return true; - } - // wrong space - else { - count = 0; - return false; - } - } - else{ - // check for timeout if needed (might be a different protocol) - if (spaceTimeout && duration > spaceTimeout){ - count = 0; - return false; - } - - // only check values if the protocol has different logical space pulses - else if (spaceThreshold){ - - // get number of the Space Bits (starting from zero) - uint8_t length; - // only save every 2nd value, substract the first two lead pulses - if (!markThreshold) - length = (count / 2) - 2; - // special case: spaces and marks both have data in the pulse - else length = count - 2; - - // move bits and write 1 or 0 depending on the duration - // 1.7: changed from MSB to LSB. somehow takes a bit more flash but is correct and easier to handle. - data[length / 8] >>= 1; - if (duration > spaceThreshold) - data[length / 8] |= 0x80; - //else // normally not needed through the bitshift - // data[length / 8] &= ~0x80; - } - } - } - - // next reading, no errors - count++; - } - - // no valid input (yet) - return false; -} - -//================================================================================ -// Inline Implementations (send) -//================================================================================ - -template <IRType irType> -void IRLwrite(const uint8_t pin, uint16_t address, uint32_t command) -{ - // get the port mask and the pointers to the out/mode registers for faster access - uint8_t bitMask = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - volatile uint8_t * outPort = portOutputRegister(port); - volatile uint8_t * modePort = portModeRegister(port); - - // set pin to OUTPUT and LOW - *modePort |= bitMask; - *outPort &= ~bitMask; - - // disable interrupts - uint8_t oldSREG = SREG; - cli(); - - switch (irType){ - - case IR_NEC: - // NEC only sends the data once - if (command == 0xFFF) - // send holding indicator - IRLsend<0, 0, NEC_HZ, 0, NEC_MARK_LEAD, NEC_SPACE_HOLDING, - 0, 0, 0, 0> - (outPort, bitMask, address, command); - else - // send data - IRLsend<NEC_ADDRESS_LENGTH, NEC_COMMAND_LENGTH, NEC_HZ, IR_ADDRESS_FIRST, NEC_MARK_LEAD, NEC_SPACE_LEAD, - NEC_MARK_ZERO, NEC_MARK_ONE, NEC_SPACE_ZERO, NEC_SPACE_ONE> - (outPort, bitMask, address, command); - break; - - case IR_PANASONIC: //TODO test - // send data - IRLsend<PANASONIC_ADDRESS_LENGTH, PANASONIC_COMMAND_LENGTH, PANASONIC_HZ, IR_ADDRESS_FIRST, PANASONIC_MARK_LEAD, PANASONIC_SPACE_LEAD, - PANASONIC_MARK_ZERO, PANASONIC_MARK_ONE, PANASONIC_SPACE_ZERO, PANASONIC_SPACE_ONE> - (outPort, bitMask, address, command); - break; - - case IR_SONY12: //TODO test, address -1? - // repeat 3 times - for (uint8_t i = 0; i < 3; i++) - // send data - IRLsend<SONY_ADDRESS_LENGTH_12, SONY_COMMAND_LENGTH_12, SONY_HZ, IR_COMMAND_FIRST, SONY_MARK_LEAD, SONY_SPACE_LEAD, - SONY_MARK_ZERO, SONY_MARK_ONE, SONY_SPACE_ZERO, SONY_SPACE_ONE> - (outPort, bitMask, address, command); - break; - } - - // enable interrupts - SREG = oldSREG; - - // set pin to INPUT again to be save - *modePort &= ~bitMask; -} - -// multifunctional template for sending -template <uint8_t addressLength, uint8_t commandLength, - uint16_t Hz, bool addressFirst, - uint16_t markLead, uint16_t spaceLead, - uint16_t markZero, uint16_t markOne, - uint16_t spaceZero, uint16_t spaceOne> - void IRLsend(volatile uint8_t * outPort, uint8_t bitmask, uint16_t address, uint32_t command){ - - // send lead mark - if (markLead) - IRLmark(Hz, outPort, bitmask, markLead); - - // send lead space - if (spaceLead) - IRLspace(outPort, bitmask, spaceLead); - - // abort if input values are both the same (sending a holding signal for example) - if (markOne != markZero || spaceOne != spaceZero) - { - // go through all bits - for (uint8_t i = 0; i < (addressLength + commandLength); i++){ - // determine if its a logical one or zero, starting with address or command - bool bitToSend; - if (addressFirst && i < addressLength || !addressFirst && i >= commandLength){ - bitToSend = address & 0x01; - address >>= 1; - } - else{ - bitToSend = command & 0x01; - command >>= 1; - } - - // send logic mark bits if needed - if (markOne != markZero){ - // modulate if spaces dont have logic, else only every even number - if (spaceOne == spaceZero || spaceOne != spaceZero && i % 2 == 0) - { - if (bitToSend) - IRLmark(Hz, outPort, bitmask, markOne); - else - IRLmark(Hz, outPort, bitmask, markZero); - } - } - else - IRLmark(Hz, outPort, bitmask, markOne); - - // send logic space bits if needed - if (spaceOne != spaceZero){ - // modulate if marks dont have logic, else only every odd number - if (markOne == markZero || markOne != markZero && i % 2 == 1){ - if (bitToSend) - IRLspace(outPort, bitmask, spaceOne); - else - IRLspace(outPort, bitmask, spaceZero); - } - } - else - IRLspace(outPort, bitmask, spaceOne); - } - } - - // finish mark - IRLmark(Hz, outPort, bitmask, markZero); //TODO zero or one for sony? - IRLspace(outPort, bitmask, 0); -} - -void IRLmark(const uint16_t Hz, volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) { - /* - Bitbangs PWM in the given Hz number for the given time - ________________________________________________________________________________ - Delay calculation: - F_CPU/1.000.000 to get number of cycles/uS - /3 to get the number of loops needed for 1ms (1loop = 3 cycles) - - Multiply with the number of ms delay: - 1/kHz to get the seconds - * 1.000.000 to get it in uS - /2 to get half of a full pulse - - Substract the while, portmanipulation, loop overhead /3 loop cycles - - F_CPU(16.000.000) 1 * 1.000.000(pulse in uS) 12(overhead) - ========================== * ========================== - ============== - 1.000.000 * 3(loop cycles) Hz * 2(half of a pulse) 3(loop cycles) - - <==> - - F_CPU(16.000.000) - (12(overhead) * Hz * 2(half of a pulse)) - =========================================================== - Hz * 2(half of a on/off pulse) * 3(loop cycles) - - ________________________________________________________________________________ - Iterations calculation: - Devide time with cycles in while loop - Multiply this with the cycles per uS - cycles per while loop: 3(loop cycles) * delay + overhead - - time * (F_CPU(16.000.000) / 1.000.000) - ====================================== - delay*3(loop cycles) + overhead - */ - - const uint32_t loopCycles = 3; - const uint32_t overHead = 12; // just a guess from try + error - uint8_t delay = (F_CPU - (overHead * Hz * 2UL)) / (Hz * 2UL * loopCycles); - uint16_t iterations = (time*(F_CPU / 1000000UL)) / (delay * loopCycles + overHead); - - while (iterations--){ - // flip pin state and wait for the calculated time - *outPort ^= bitMask; -#ifdef IRLREMOTE_AVR - _delay_loop_1(delay); -#else - // ARM TODO? -#endif - } -} - -void IRLspace(volatile uint8_t * outPort, uint8_t bitMask, uint16_t time) { - // Sends an IRLspace for the specified number of microseconds. - // A IRLspace is no output, so the PWM output is disabled. - *outPort &= ~bitMask; // write pin LOW - delayMicroseconds(time); - //_delay_loop_2(time*(F_CPU/1000000UL)/4UL); -} - -#endif \ No newline at end of file
--- a/start/battery.h Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#ifndef BATTERY_H -#define BATTERY_H - -void battery_setup(void); -int get_battery(void); -void battery_loop(void); - -#endif
--- a/start/battery.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -#include "beep.h" - -#define BATTERY_PIN A3 -#define MIN_BATTERY 557 // About 3.59V. - -extern int robot_mode; - -void battery_setup() { - pinMode(BATTERY_PIN, INPUT); -} - -int get_battery() { - return analogRead(BATTERY_PIN); -} - -void battery_loop() { - static int battery_fail = 0; - int reading = get_battery(); - - if (reading < MIN_BATTERY) { - battery_fail += 1; - beep(reading, 200); - } else { - battery_fail = 0; - } - if (battery_fail > 40) { - /* If it stays bad for 4s, shut down. */ - robot_mode = 0; - } -}
--- a/start/beep.h Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#ifndef BEEP_H -#define BEEP_H - -extern bool beep_mute; - -void beep_setup(void); -void beep(int frequency, int duration); - -#endif
--- a/start/beep.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#define BEEP_PIN 3 - -bool beep_mute = true; - - -void beep_setup() { - pinMode(BEEP_PIN, OUTPUT); - beep(1760, 50); - delay(100); - beep(1975, 50); - delay(50); - beep(1760, 50); -} - -void beep(int frequency, int duration) { - if (beep_mute) { - return; - } - tone(BEEP_PIN, frequency, duration); -}
--- a/start/clock.ino Fri Jun 26 14:54:07 2015 +0200 +++ b/start/clock.ino Sun Jun 28 23:02:02 2015 +0200 @@ -4,7 +4,7 @@ // Wait remaining time to delay ms milliseconds since last call. static unsigned long last = 0; unsigned long now = millis(); - long wait = last + ms - now; + long wait = last - now + ms; if (wait > 0) { delay(wait); } else {
--- a/start/creep.ino Fri Jun 26 14:54:07 2015 +0200 +++ b/start/creep.ino Sun Jun 28 23:02:02 2015 +0200 @@ -2,13 +2,9 @@ #include "misc.h" #include "leg.h" #include "clock.h" -#include "beep.h" -const unsigned int tones[4] = {880, 988, 1318, 1175}; - /* Creep gait parameters. */ -#ifdef TOTE2 #define SPEED 1 /* How far forward to move them when making a step? */ #define STRIDE 14.0 @@ -20,19 +16,6 @@ #define RAISE 10.0 /* In how many steps. */ #define RAISE_STEPS 3 -#else -#define SPEED 0.5 -/* How far forward to move them when making a step? */ -#define STRIDE 12.0 -/* How much to shift the body? */ -#define SHIFT 8.0 -/* In how many steps should the body be shifted? */ -#define SHIFT_STEPS 4 -/* How fast to raise the leg. */ -#define RAISE 10.0 -/* In how many steps. */ -#define RAISE_STEPS 3 -#endif /* Given current leg, which leg to move next? */ const unsigned char _NEXT_LEG[6][4] = { @@ -106,12 +89,10 @@ void _creep_step(unsigned char leg) { _shift_body(leg); _on_ground[leg] = false; - beep(440, 5); for (unsigned char step = 0; step < RAISE_STEPS; ++step) { move_leg_by(leg, 0, 0, RAISE); _creep_tick(); } - beep(tones[leg], 25); move_leg( leg, HOME + (_shift_x + creep_dx * STRIDE) * LEG_X[leg] + creep_spread, @@ -120,7 +101,6 @@ ); _creep_tick(); _creep_tick(); - beep(1865, 5); for (unsigned char step = 0; step < RAISE_STEPS - 1; ++step) { move_leg_by(leg, 0, 0, -RAISE); _creep_tick();
--- a/start/ir.h Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -#ifndef IR_H -#define IR_H - -void ir_setup(); -void ir_loop(); - -#endif
--- a/start/ir.ino Fri Jun 26 14:54:07 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -#include "creep.h" -#include "leg.h" -#include "servos.h" -#include "misc.h" -#include "beep.h" -#include "IRLremote.h" - - -#define LED_PIN 13 -#define IR_INTERRUPT 0 // Sensor on PIN 2 -#define IR_PROTOCOL IR_NEC -#define IR_ADDRESS 0xFF00 - -#define KEY_UP 0xBF40 // Up arrow. -#define KEY_DOWN 0xE619 // Down arrow. -#define KEY_LEFT 0xF807 // Left arrow. -#define KEY_RIGHT 0xF609 // Right arrow. -#define KEY_REV 0xF30C // Rewind. -#define KEY_PLAY 0xE718 // Play/pause. -#define KEY_FF 0xA15E // Fast forward. -#define KEY_CHMINUS 0xF708 // Channel minus. -#define KEY_CHPLUS 0xA55A // Channel plus. -#define KEY_CHLEVEL 0xE31C -#define KEY_VOLDOWN 0xBD42 // Volume down. -#define KEY_MUTE 0xAD52 // Mute. -#define KEY_VOLUP 0xB54A // Volume up. -#define KEY_POWER 0xBA45 // Power. -#define KEY_POWER2 0xAF50 // Power. -#define KEY_SEARCH 0xBB44 // Search. -#define KEY_HOME 0xB847 // Home. -#define KEY_OK 0xEA15 // OK. - - -extern int robot_mode; - - -void ir_setup() { - IRLbegin<IR_ALL>(IR_INTERRUPT); - pinMode(LED_PIN, OUTPUT); - digitalWrite(LED_PIN, LOW); - Serial.begin(115200); -} - -void ir_loop() { - static uint32_t last=0; - uint32_t IRcommand = 0; - bool led = true; - - if (!IRLavailable()) { - if (led) { - digitalWrite(LED_PIN, LOW); - led = false; - } - return; - } - - IRcommand = IRLgetCommand(); - - if (IRcommand == 0xFFFF) { - IRcommand = last; - } else if (IRLgetAddress() != IR_ADDRESS) { - IRLreset(); - return; // React only to my remote. - } - last = IRcommand; - - beep(1319, 50); - digitalWrite(LED_PIN, HIGH); - - switch (IRcommand) { - case KEY_UP: // Up arrow. - creep_dy = min(3, creep_dy + 0.25); - break; - case KEY_DOWN: // Down arrow. - creep_dy = max(-3, creep_dy - 0.25); - break; - case KEY_LEFT: // Left arrow. - creep_rotation = min(PI/90, creep_rotation + PI/360); - break; - case KEY_RIGHT: // Right arrow. - creep_rotation = max(-PI/90, creep_rotation - PI/360); - break; - case KEY_REV: // Rewind. - creep_spread = max(-10.0, creep_spread - 1); - break; - case KEY_PLAY: // Play/pause. - creep_spread = 0.0; - break; - case KEY_FF: // Fast forward. - creep_spread = min(10.0, creep_spread + 1); - break; - case KEY_CHMINUS: // Channel minus. - creep_height = max(TIBIA * 0.25, creep_height - 1); - break; - case KEY_CHPLUS: // Channel plus. - creep_height = min(TIBIA * 1.25, creep_height + 1); - break; - case KEY_CHLEVEL: - creep_height = TIBIA * 0.75; - break; - case KEY_VOLDOWN: // Volume down. - creep_dx = max(-1.0, creep_dx - 0.25); - break; - case KEY_MUTE: // Mute. - beep_mute = !beep_mute; - break; - case KEY_VOLUP: // Volume up. - creep_dx = min(1.0, creep_dx + 0.25); - break; - case KEY_POWER: // Power. - case KEY_POWER2: // Power. - digitalWrite(LED_PIN, LOW); - robot_mode = 0; - break; - case KEY_SEARCH: // Search. - switch (robot_mode) { - case 1: - robot_mode = 2; - break; - case 2: - robot_mode = 1; - break; - } - break; - case KEY_HOME: // Home. - for (unsigned char leg=0; leg < 4; ++leg) { - move_leg(leg, HOME, HOME, TIBIA); - } - break; - case KEY_OK: // OK. - creep_dx = 0.0; - creep_dy = 0.0; - creep_rotation = 0.0; - break; - default: - Serial.println(IRcommand); - } - IRLreset(); -}
--- a/start/leg.h Fri Jun 26 14:54:07 2015 +0200 +++ b/start/leg.h Sun Jun 28 23:02:02 2015 +0200 @@ -1,19 +1,10 @@ #ifndef LEG_H #define LEG_H -#ifdef TOTE2 -// For version 2: -#define COXA 12.0 -#define FEMUR 42.0 -#define TIBIA 38.5 -#define BASE 21.0 -#else -// For version 1: -#define COXA 8.0 -#define FEMUR 20.5 -#define TIBIA 28.5 -#define BASE 18.5 -#endif +const double COXA = 12.0; +const double FEMUR = 42.0; +const double TIBIA = 38.5; +const double BASE = 21.0; const char LEG_X[4] = {-1, -1, 1, 1}; const char LEG_Y[4] = {1, -1, -1, 1};
--- a/start/leg.ino Fri Jun 26 14:54:07 2015 +0200 +++ b/start/leg.ino Sun Jun 28 23:02:02 2015 +0200 @@ -36,7 +36,8 @@ // Return true on success, and false if x and y are out of range. double f = _norm(x, y) - COXA; double d = _norm(f, z); - if (d > FEMUR + TIBIA) { return false; } + // if (d > FEMUR + TIBIA) { return false; } + d = min(d, FEMUR + TIBIA); *hip = atan2(y, x); if (isnan(*hip)) { return false; } *knee = _solve_triangle(FEMUR, d, TIBIA) - atan2(-z, f);
--- a/start/servos.ino Fri Jun 26 14:54:07 2015 +0200 +++ b/start/servos.ino Sun Jun 28 23:02:02 2015 +0200 @@ -8,16 +8,15 @@ static const unsigned char SERVO_PINS[SERVOS] = { // ankle, knee, hip - -/* For Pro Micro - 14, 16, 10, // front left - A0, A1, A2, // hind left -*/ - 12, 11, 10, // front left 14, 15, 16, // hind left 6, 5, 4, // hind right 7, 8, 9 // front right + +// 16, 15, 14, // front left +// 17, 18, 19, // hind left +// 9, 8, 7, // hind right +// 10, 11, 12 // front right }; static const char SERVO_REVERSE[SERVOS] = { // ankle, knee, hip @@ -28,10 +27,10 @@ }; static const char SERVO_TRIM[SERVOS] = { // ankle, knee, hip - -10, -5, -10, // front left - 10, -5, -10, // hind left - 0, 0, 10, // hind right - 0, 0, 10 // front right + 0, 0, 0, // front left + 0, 0, 0, // hind left + 0, 0, 0, // hind right + 0, 0, 0 // front right }; static Servo servos[SERVOS]; @@ -53,6 +52,8 @@ void servo_move(unsigned char servo, double rads) { // Move a servo to a position in radians between -PI/2 and PI/2. + long int freq; + if (servo >= SERVOS) { return; } @@ -63,11 +64,9 @@ while (rads < 0) { rads += TAU; } - int freq = (SERVO_FREQ_MAX - - SERVO_FREQ_MIN) * rads / PI + SERVO_FREQ_MIN; + freq = (SERVO_FREQ_MAX - SERVO_FREQ_MIN) * rads / PI + SERVO_FREQ_MIN; freq = min(SERVO_FREQ_MAX, - max(SERVO_FREQ_MIN, - freq + SERVO_TRIM[servo] * 10)); + max(SERVO_FREQ_MIN, freq + SERVO_TRIM[servo] * 10)); servos[servo].writeMicroseconds(freq); } @@ -75,6 +74,7 @@ // Initialize all servos. // Start with hips. for (unsigned char servo = 2; servo < SERVOS; servo += 3) { + pinMode(SERVO_PINS[servo], OUTPUT); servos[servo].attach(SERVO_PINS[servo], SERVO_FREQ_MIN, SERVO_FREQ_MAX); servo_move(servo, HOME_POSITION[servo]); @@ -82,6 +82,7 @@ } // Then ankles. for (unsigned char servo = 0; servo < SERVOS; servo += 3) { + pinMode(SERVO_PINS[servo], OUTPUT); servos[servo].attach(SERVO_PINS[servo], SERVO_FREQ_MIN, SERVO_FREQ_MAX); servo_move(servo, HOME_POSITION[servo]); @@ -89,6 +90,7 @@ } // Finally knees. for (unsigned char servo = 1; servo < SERVOS; servo += 3) { + pinMode(SERVO_PINS[servo], OUTPUT); servos[servo].attach(SERVO_PINS[servo], SERVO_FREQ_MIN, SERVO_FREQ_MAX); servo_move(servo, HOME_POSITION[servo]);
--- a/start/start.ino Fri Jun 26 14:54:07 2015 +0200 +++ b/start/start.ino Sun Jun 28 23:02:02 2015 +0200 @@ -1,11 +1,8 @@ #include "misc.h" #include "servos.h" -#include "beep.h" -#include "battery.h" #include "creep.h" #include "leg.h" -#include <avr/sleep.h> // 0 -- Power off // 1 -- Walk @@ -14,19 +11,15 @@ void setup() { - battery_setup(); servo_setup(); - beep_setup(); - ir_setup(); + pinMode(13, OUTPUT); + digitalWrite(13, HIGH); } void loop() { switch (robot_mode) { case 0: // Power off servo_shutdown(); - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_enable(); - sleep_mode(); while (1) { delay(100); } @@ -38,6 +31,5 @@ delay(100); break; } - ir_loop(); - battery_loop(); + digitalWrite(13, LOW); }
