IRremote
ir_Sony.hpp
Go to the documentation of this file.
1 /*
2  * ir_Sony.hpp
3  *
4  * Contains functions for receiving and sending SIRCS/Sony IR Protocol in "raw" and standard format with 5 bit address 7 bit command
5  *
6  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
7  *
8  ************************************************************************************
9  * MIT License
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is furnished
16  * to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in all
19  * copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
22  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
26  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  *
28  ************************************************************************************
29  */
30 #ifndef _IR_SONY_HPP
31 #define _IR_SONY_HPP
32 
33 #if defined(DEBUG) && !defined(LOCAL_DEBUG)
34 #define LOCAL_DEBUG
35 #else
36 //#define LOCAL_DEBUG // This enables debug output only for this file
37 #endif
38 
42 //==============================================================================
43 // SSSS OOO N N Y Y
44 // S O O NN N Y Y
45 // SSS O O N N N Y
46 // S O O N NN Y
47 // SSSS OOO N N Y
48 //==============================================================================
49 /*
50  * Protocol=Sony Address=0x4B9 Command=0x7 Raw-Data=0x25C87 20 bits LSB first
51  +2550,- 400
52  // 7 command bits
53  +1300,- 450 +1350,- 450 +1300,- 450 + 700,- 450
54  + 700,- 450 + 750,- 450 + 700,- 400
55  // (5,8,) 13 address bits and NO stop bit!
56  +1300,- 500
57  + 700,- 450 + 700,- 450 +1300,- 500 +1300,- 450
58  +1300,- 450 + 700,- 450 +1350,- 400 + 750,- 450
59  + 700,- 450 +1300,- 450 + 700,- 450 + 700
60  Sum: 31100
61  */
62 /*
63  * Sony is the only protocol using the pulse width encoding, which requires no stop bit
64  */
65 // see https://www.sbprojects.net/knowledge/ir/sirc.php
66 // https://www.mikrocontroller.net/articles/IRMP_-_english#SIRCS
67 // Frames are repeated every 45ms (measured from start to start) for as long as the key on the remote control is held down.
68 // This leads to a 15 ms gap for a Sony20 protocol!
69 // Here http://picprojects.org.uk/projects/sirc/ it is claimed, that many Sony remotes send each frame a minimum of 3 times. But 1 repeat (2 sends) has also been seen in real life.
70 // LSB first, start bit + 7 command + 5 to 13 address, no stop bit
71 // IRP: Sony12 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,^45m)+ ==> 40 kHz, Unit is 600, LSB, One mark is 2 units, Start bit is 4 units, 7 bit Function, 5 bit Device, no Stop bit, every 45 milliseconds
72 // IRP: Sony15 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ ==> 8 bit Device
73 // IRP: Sony20 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m)+ ==> 5 bit Device, 8 bit Subdevice
74 //
75 #define SONY_ADDRESS_BITS 5
76 #define SONY_COMMAND_BITS 7
77 #define SONY_EXTRA_BITS 8
78 #define SONY_BITS_MIN (SONY_COMMAND_BITS + SONY_ADDRESS_BITS) // 12 bits
79 #define SONY_BITS_15 (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + 3) // 15 bits
80 #define SONY_BITS_MAX (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + SONY_EXTRA_BITS) // 20 bits == SIRCS_20_PROTOCOL
81 #define SONY_UNIT 600 // 24 periods of 40kHz
82 
83 #define SONY_HEADER_MARK (4 * SONY_UNIT) // 2400
84 #define SONY_ONE_MARK (2 * SONY_UNIT) // 1200
85 #define SONY_ZERO_MARK SONY_UNIT
86 #define SONY_SPACE SONY_UNIT
87 
88 #define SONY_AVERAGE_DURATION_MIN 21000 // SONY_HEADER_MARK + SONY_SPACE + 12 * 2,5 * SONY_UNIT // 2.5 because we assume more zeros than ones
89 #define SONY_AVERAGE_DURATION_MAX 33000 // SONY_HEADER_MARK + SONY_SPACE + 20 * 2,5 * SONY_UNIT // 2.5 because we assume more zeros than ones
90 #define SONY_REPEAT_PERIOD 45000 // Commands are repeated every 45 ms (measured from start to start) for as long as the key on the remote control is held down.
91 #define SONY_MAXIMUM_REPEAT_DISTANCE (SONY_REPEAT_PERIOD - SONY_AVERAGE_DURATION_MIN) // 24 ms
92 
95 
96 /************************************
97  * Start of send and decode functions
98  ************************************/
99 
103 void IRsend::sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint8_t numberOfBits) {
104  uint32_t tData = (uint32_t) aAddress << 7 | (aCommand & 0x7F);
105  // send 5, 8, 13 address bits LSB first
107 }
108 
110 
112  return false;
113  }
114 
115  // Check we have enough data. +2 for initial gap and start bit mark and space minus the last/MSB space. NO stop bit! 26, 32, 42
116  if (decodedIRData.rawlen != (2 * SONY_BITS_MIN) + 2 && decodedIRData.rawlen != (2 * SONY_BITS_MAX) + 2
117  && decodedIRData.rawlen != (2 * SONY_BITS_15) + 2) {
118  IR_DEBUG_PRINT(F("Sony: "));
119  IR_DEBUG_PRINT(F("Data length="));
121  IR_DEBUG_PRINTLN(F(" is not 12, 15 or 20"));
122  return false;
123  }
124 
126 #if defined(LOCAL_DEBUG)
127  Serial.print(F("Sony: "));
128  Serial.println(F("Decode failed"));
129 #endif
130  return false;
131  }
132 
133  // Success
134 // decodedIRData.flags = IRDATA_FLAGS_IS_LSB_FIRST; // Not required, since this is the start value
135  decodedIRData.command = decodedIRData.decodedRawData & 0x7F; // first 7 bits
136  decodedIRData.address = decodedIRData.decodedRawData >> 7; // next 5 or 8 or 13 bits
139 
140  //Check for repeat
142 
143  return true;
144 }
145 
146 /*********************************************************************************
147  * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials
148  *********************************************************************************/
149 
150 /*
151  * Old version with MSB first data
152  */
153 #define SONY_DOUBLE_SPACE_USECS 500 // usually see 713 - not using ticks as get number wrap around
155  long data = 0;
156  uint8_t bits = 0;
157  unsigned int offset = 0; // Dont skip first space, check its size
158 
159  if (aResults->rawlen < (2 * SONY_BITS_MIN) + 2) {
160  return false;
161  }
162 
163  // Some Sony's deliver repeats fast after first
164  // unfortunately can't spot difference from of repeat from two fast clicks
165  if (aResults->rawbuf[0] < (SONY_DOUBLE_SPACE_USECS / MICROS_PER_TICK)) {
166 #if defined(LOCAL_DEBUG)
167  Serial.println(F("IR Gap found"));
168 #endif
169  aResults->bits = 0;
170  aResults->value = 0xFFFFFFFF;
173  return true;
174  }
175  offset++;
176 
177  // Check header "mark"
178  if (!matchMark(aResults->rawbuf[offset], SONY_HEADER_MARK)) {
179  return false;
180  }
181  offset++;
182 
183  // MSB first - Not compatible to standard, which says LSB first :-(
184  while (offset + 1 < aResults->rawlen) {
185 
186  // First check for the constant space length, we do not have a space at the end of raw data
187  // we are lucky, since the start space is equal the data space.
188  if (!matchSpace(aResults->rawbuf[offset], SONY_SPACE)) {
189  return false;
190  }
191  offset++;
192 
193  // bit value is determined by length of the mark
194  if (matchMark(aResults->rawbuf[offset], SONY_ONE_MARK)) {
195  data = (data << 1) | 1;
196  } else if (matchMark(aResults->rawbuf[offset], SONY_ZERO_MARK)) {
197  data = (data << 1) | 0;
198  } else {
199  return false;
200  }
201  offset++;
202  bits++;
203 
204  }
205 
206  aResults->bits = bits;
207  aResults->value = data;
208  aResults->decode_type = SONY;
210  return true;
211 }
212 
216 void IRsend::sendSonyMSB(unsigned long data, int nbits) {
217  // Set IR carrier frequency
219 
220  // Header
222  space(SONY_SPACE);
223 
224  // Old version with MSB first Data
226 }
227 void IRsend::sendSony(unsigned long data, int nbits) {
228  sendSonyMSB(data, nbits);
229 }
230 
232 #if defined(LOCAL_DEBUG)
233 #undef LOCAL_DEBUG
234 #endif
235 #endif // _IR_SONY_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRProtocol.h:110
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:250
decode_results
Results returned from old decoders !!!deprecated!!!
Definition: IRremoteInt.h:183
decode_results::rawbuf
uint16_t * rawbuf
Definition: IRremoteInt.h:194
PROTOCOL_IS_MSB_FIRST
#define PROTOCOL_IS_MSB_FIRST
Definition: IRProtocol.h:147
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRProtocol.h:119
IRsend::aNumberOfRepeats
void int_fast8_t aNumberOfRepeats
Definition: IRremoteInt.h:547
MICROS_IN_ONE_MILLI
#define MICROS_IN_ONE_MILLI
Definition: IRremote.hpp:255
IRsend::sendSony
void sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint8_t numberOfBits=12)
Definition: ir_Sony.hpp:103
IRsend::mark
void mark(uint16_t aMarkMicros)
Sends an IR mark for the specified number of microseconds.
Definition: IRSend.hpp:947
SONY
@ SONY
Definition: IRProtocol.h:64
SONY_HEADER_MARK
#define SONY_HEADER_MARK
Definition: ir_Sony.hpp:83
SONY_MAXIMUM_REPEAT_DISTANCE
#define SONY_MAXIMUM_REPEAT_DISTANCE
Definition: ir_Sony.hpp:91
SONY_DOUBLE_SPACE_USECS
#define SONY_DOUBLE_SPACE_USECS
Definition: ir_Sony.hpp:153
IRDATA_FLAGS_IS_REPEAT
#define IRDATA_FLAGS_IS_REPEAT
The gap between the preceding frame is as smaller than the maximum gap expected for a repeat....
Definition: IRProtocol.h:92
IRsend::sendPulseDistanceWidth
void sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats)
Sends PulseDistance frames and repeats.
Definition: IRSend.hpp:691
decode_results::bits
uint8_t bits
Definition: IRremoteInt.h:189
decode_results::decode_type
decode_type_t decode_type
Definition: IRremoteInt.h:186
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:113
IRrecv::checkForRepeatSpaceTicksAndSetFlag
void checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks)
Definition: IRReceive.hpp:1150
IR_DEBUG_PRINT
#define IR_DEBUG_PRINT(...)
If DEBUG, print the arguments, otherwise do nothing.
Definition: IRremoteInt.h:161
IRrecv::decodeSonyMSB
bool decodeSonyMSB(decode_results *aResults)
Definition: ir_Sony.hpp:154
SONY_BITS_MIN
#define SONY_BITS_MIN
Definition: ir_Sony.hpp:78
IRrecv::decodeSony
bool decodeSony()
Definition: ir_Sony.hpp:109
matchSpace
bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1227
decode_results::value
uint32_t value
Definition: IRremoteInt.h:188
PulseDistanceWidthProtocolConstants
Definition: IRProtocol.h:134
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:358
IRData::flags
uint8_t flags
IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:120
PROTOCOL_IS_LSB_FIRST
#define PROTOCOL_IS_LSB_FIRST
Definition: IRProtocol.h:148
IRrecv::checkHeader
bool checkHeader(PulseDistanceWidthProtocolConstants *aProtocolConstants)
Definition: IRReceive.hpp:1126
IRrecv::decodePulseDistanceWidthData
bool decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset=3)
Decode pulse distance protocols for PulseDistanceWidthProtocolConstants.
Definition: IRReceive.hpp:954
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRProtocol.h:111
matchMark
bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1193
SONY_BITS_MAX
#define SONY_BITS_MAX
Definition: ir_Sony.hpp:80
SonyProtocolConstants
struct PulseDistanceWidthProtocolConstants SonyProtocolConstants
Definition: ir_Sony.hpp:93
IRsend::sendSonyMSB
void sendSonyMSB(unsigned long data, int nbits)
Old version with MSB first data.
Definition: ir_Sony.hpp:216
SONY_KHZ
#define SONY_KHZ
Definition: IRProtocol.h:156
IRsend::space
static void space(uint16_t aSpaceMicros)
Sends an IR space for the specified number of microseconds.
Definition: IRSend.hpp:1148
SONY_ZERO_MARK
#define SONY_ZERO_MARK
Definition: ir_Sony.hpp:85
IRData::rawlen
IRRawlenType rawlen
counter of entries in rawbuf of last received frame.
Definition: IRProtocol.h:128
SONY_REPEAT_PERIOD
#define SONY_REPEAT_PERIOD
Definition: ir_Sony.hpp:90
SONY_ONE_MARK
#define SONY_ONE_MARK
Definition: ir_Sony.hpp:84
IRsend::sendPulseDistanceWidthData
void sendPulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, uint_fast8_t aNumberOfBits)
Sends PulseDistance from data contained in parameter using ProtocolConstants structure for timing etc...
Definition: IRSend.hpp:812
IR_DEBUG_PRINTLN
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
Definition: IRremoteInt.h:165
decode_results::rawlen
uint_fast8_t rawlen
Definition: IRremoteInt.h:195
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:109
SONY_BITS_15
#define SONY_BITS_15
Definition: ir_Sony.hpp:79
SONY_SPACE
#define SONY_SPACE
Definition: ir_Sony.hpp:86
IRsend::aCommand
void aCommand
Definition: IRremoteInt.h:610
IRsend::enableIROut
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.
Definition: IRSend.hpp:1188