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
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 // see https://www.sbprojects.net/knowledge/ir/sirc.php
63 // Frames are repeated every 45ms (measured from start to start) for as long as the key on the remote control is held down.
64 // This leads to a 15 ms gap for a Sony20 protocol!
65 // 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.
66 // LSB first, start bit + 7 command + 5 to 13 address, no stop bit
67 // 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
68 // IRP: Sony15 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:8,^45m)+ ==> 8 bit Device
69 // IRP: Sony20 {40k,600}<1,-1|2,-1>(4,-1,F:7,D:5,S:8,^45m)+ ==> 5 bit Device, 8 bit Subdevice
70 //
71 #define SONY_ADDRESS_BITS 5
72 #define SONY_COMMAND_BITS 7
73 #define SONY_EXTRA_BITS 8
74 #define SONY_BITS_MIN (SONY_COMMAND_BITS + SONY_ADDRESS_BITS) // 12 bits
75 #define SONY_BITS_15 (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + 3) // 15 bits
76 #define SONY_BITS_MAX (SONY_COMMAND_BITS + SONY_ADDRESS_BITS + SONY_EXTRA_BITS) // 20 bits == SIRCS_20_PROTOCOL
77 #define SONY_UNIT 600 // 24 periods of 40kHz
78 
79 #define SONY_HEADER_MARK (4 * SONY_UNIT) // 2400
80 #define SONY_ONE_MARK (2 * SONY_UNIT) // 1200
81 #define SONY_ZERO_MARK SONY_UNIT
82 #define SONY_SPACE SONY_UNIT
83 
84 #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
85 #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
86 #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.
87 #define SONY_MAXIMUM_REPEAT_DISTANCE (SONY_REPEAT_PERIOD - SONY_AVERAGE_DURATION_MIN) // 24 ms
88 
89 #define SIRCS_12_PROTOCOL 12
90 #define SIRCS_15_PROTOCOL 15
91 #define SIRCS_20_PROTOCOL 20
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
117  && decodedIRData.rawDataPtr->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::sendSony(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
227 #if !defined(DISABLE_CODE_FOR_RECEIVER)
229 #endif
230 }
231 
233 #if defined(LOCAL_DEBUG)
234 #undef LOCAL_DEBUG
235 #endif
236 #endif // _IR_SONY_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRProtocol.h:117
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:258
decode_results
Results returned from old decoders !!!deprecated!!!
Definition: IRremoteInt.h:155
PROTOCOL_IS_MSB_FIRST
#define PROTOCOL_IS_MSB_FIRST
Definition: IRProtocol.h:130
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRProtocol.h:120
IRsend::aNumberOfRepeats
void uint8_t int_fast8_t aNumberOfRepeats
Definition: IRremoteInt.h:474
MICROS_IN_ONE_MILLI
#define MICROS_IN_ONE_MILLI
Definition: IRremote.hpp:263
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(unsigned int aMarkMicros)
Sends an IR mark for the specified number of microseconds.
Definition: IRSend.hpp:757
SONY
@ SONY
Definition: IRProtocol.h:64
SONY_HEADER_MARK
#define SONY_HEADER_MARK
Definition: ir_Sony.hpp:79
SONY_MAXIMUM_REPEAT_DISTANCE
#define SONY_MAXIMUM_REPEAT_DISTANCE
Definition: ir_Sony.hpp:87
SONY_DOUBLE_SPACE_USECS
#define SONY_DOUBLE_SPACE_USECS
Definition: ir_Sony.hpp:153
IRDATA_FLAGS_IS_REPEAT
#define IRDATA_FLAGS_IS_REPEAT
Definition: IRProtocol.h:94
IRrecv::restartAfterSend
void restartAfterSend()
Restarts receiver after send.
Definition: IRReceive.hpp:346
IRsend::sendPulseDistanceWidth
void sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats)
Sends PulseDistance frames and repeats.
Definition: IRSend.hpp:532
decode_results::rawbuf
unsigned int * rawbuf
Definition: IRremoteInt.h:166
IRData::rawDataPtr
irparams_struct * rawDataPtr
Pointer of the raw timing data to be decoded. Mainly the OverflowFlag and the data buffer filled by r...
Definition: IRProtocol.h:126
decode_results::bits
uint8_t bits
Definition: IRremoteInt.h:161
decode_results::decode_type
decode_type_t decode_type
Definition: IRremoteInt.h:158
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:122
IR_DEBUG_PRINT
#define IR_DEBUG_PRINT(...)
If DEBUG, print the arguments, otherwise do nothing.
Definition: IRremoteInt.h:133
IRrecv::decodeSonyMSB
bool decodeSonyMSB(decode_results *aResults)
Definition: ir_Sony.hpp:154
SONY_BITS_MIN
#define SONY_BITS_MIN
Definition: ir_Sony.hpp:74
IRrecv::decodeSony
bool decodeSony()
Definition: ir_Sony.hpp:109
irparams_struct::rawlen
uint_fast8_t rawlen
counter of entries in rawbuf
Definition: IRremoteInt.h:109
IRrecv::decodePulseDistanceWidthData
bool decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset=3)
Decode pulse distance protocols for PulseDistanceWidthProtocolConstants.
Definition: IRReceive.hpp:768
decode_results::value
uint32_t value
Definition: IRremoteInt.h:160
PulseDistanceWidthProtocolConstants
Definition: IRProtocol.h:74
SEND_NO_STOP_BIT
#define SEND_NO_STOP_BIT
Definition: IRremoteInt.h:394
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:305
matchSpace
bool matchSpace(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1033
IRData::flags
uint8_t flags
See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:121
PROTOCOL_IS_LSB_FIRST
#define PROTOCOL_IS_LSB_FIRST
Definition: IRProtocol.h:129
IRrecv::checkForRepeatSpaceAndSetFlag
void checkForRepeatSpaceAndSetFlag(unsigned int aMediumRepeatSpaceMicros)
Definition: IRReceive.hpp:962
IRrecv::checkHeader
bool checkHeader(PulseDistanceWidthProtocolConstants *aProtocolConstants)
Definition: IRReceive.hpp:943
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRProtocol.h:118
IRsend::space
static void space(unsigned int aSpaceMicros)
Sends an IR space for the specified number of microseconds.
Definition: IRSend.hpp:927
SONY_BITS_MAX
#define SONY_BITS_MAX
Definition: ir_Sony.hpp:76
SonyProtocolConstants
struct PulseDistanceWidthProtocolConstants SonyProtocolConstants
Definition: ir_Sony.hpp:93
SONY_KHZ
#define SONY_KHZ
Definition: IRProtocol.h:138
SONY_ZERO_MARK
#define SONY_ZERO_MARK
Definition: ir_Sony.hpp:81
SONY_REPEAT_PERIOD
#define SONY_REPEAT_PERIOD
Definition: ir_Sony.hpp:86
SONY_ONE_MARK
#define SONY_ONE_MARK
Definition: ir_Sony.hpp:80
IRsend::sendPulseDistanceWidthData
void sendPulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, uint_fast8_t aNumberOfBits)
Sends PulseDistance data The output always ends with a space Each additional call costs 16 bytes prog...
Definition: IRSend.hpp:643
IR_DEBUG_PRINTLN
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
Definition: IRremoteInt.h:137
matchMark
bool matchMark(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1000
decode_results::rawlen
uint_fast8_t rawlen
Definition: IRremoteInt.h:167
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:116
SONY_BITS_15
#define SONY_BITS_15
Definition: ir_Sony.hpp:75
SONY_SPACE
#define SONY_SPACE
Definition: ir_Sony.hpp:82
IRsend::aCommand
void uint8_t aCommand
Definition: IRremoteInt.h:474
IrReceiver
IRrecv IrReceiver
The receiver instance.
Definition: IRReceive.hpp:59
IRsend::enableIROut
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.
Definition: IRSend.hpp:961