IRremote
TinyIR.h
Go to the documentation of this file.
1 /*
2  * TinyIR.h
3  *
4  *
5  * Copyright (C) 2021-2023 Armin Joachimsmeyer
6  * armin.joachimsmeyer@gmail.com
7  *
8  * This file is part of IRMP https://github.com/IRMP-org/IRMP.
9  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
10  *
11  * TinyIRReceiver is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
23  *
24  */
25 
26 #ifndef _TINY_IR_H
27 #define _TINY_IR_H
28 
29 #include <Arduino.h>
30 
31 #include "LongUnion.h"
32 
37 #define VERSION_TINYIR "2.1.0"
38 #define VERSION_TINYIR_MAJOR 2
39 #define VERSION_TINYIR_MINOR 1
40 #define VERSION_TINYIR_PATCH 0
41 // The change log is at the bottom of the file
42 
49 #if !defined(NEC_ADDRESS_BITS)
50 #define NEC_ADDRESS_BITS 16 // 16 bit address or 8 bit address and 8 bit inverted address
51 #define NEC_COMMAND_BITS 16 // Command and inverted command
52 #define NEC_BITS (NEC_ADDRESS_BITS + NEC_COMMAND_BITS)
53 
54 #define NEC_UNIT 560
55 
56 #define NEC_HEADER_MARK (16 * NEC_UNIT) // 9000
57 #define NEC_HEADER_SPACE (8 * NEC_UNIT) // 4500
58 
59 #define NEC_BIT_MARK NEC_UNIT
60 #define NEC_ONE_SPACE (3 * NEC_UNIT) // 1690
61 #define NEC_ZERO_SPACE NEC_UNIT
62 
63 #define NEC_REPEAT_HEADER_SPACE (4 * NEC_UNIT) // 2250
64 
65 #define NEC_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down.
66 #define NEC_MINIMAL_DURATION 49900 // NEC_HEADER_MARK + NEC_HEADER_SPACE + 32 * 2 * NEC_UNIT + NEC_UNIT // 2.5 because we assume more zeros than ones
67 #define NEC_MAXIMUM_REPEAT_DISTANCE (NEC_REPEAT_PERIOD - NEC_MINIMAL_DURATION + 10000) // 70 ms
68 #endif
69 
79 /*
80  Protocol=FAST Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first
81  +2100,-1050
82  + 550,- 500 + 550,-1550 + 550,-1550 + 550,- 500
83  + 550,-1550 + 550,-1550 + 550,-1550 + 550,- 500
84  + 550,-1550 + 550,- 500 + 550,- 500 + 550,-1550
85  + 550,- 500 + 550,- 500 + 550,- 500 + 550,-1550
86  + 550
87  Sum: 28900
88  */
89 #define FAST_KHZ 38
90 #define FAST_ADDRESS_BITS 0 // No address
91 #define FAST_COMMAND_BITS 16 // Command and inverted command (parity)
92 #define FAST_BITS (FAST_ADDRESS_BITS + FAST_COMMAND_BITS)
93 
94 #define FAST_UNIT 526 // 20 periods of 38 kHz (526.315789)
95 
96 #define FAST_BIT_MARK FAST_UNIT
97 #define FAST_ONE_SPACE (3 * FAST_UNIT) // 1578 -> bit period = 2104
98 #define FAST_ZERO_SPACE FAST_UNIT // 526 -> bit period = 1052
99 
100 #define FAST_HEADER_MARK (4 * FAST_UNIT) // 2104
101 #define FAST_HEADER_SPACE (2 * FAST_UNIT) // 1052
102 
103 #define FAST_REPEAT_PERIOD 50000 // Commands are repeated every 50 ms (measured from start to start) for as long as the key on the remote control is held down.
104 #define FAST_REPEAT_DISTANCE (FAST_REPEAT_PERIOD - (55 * FAST_UNIT)) // 19 ms
105 #define FAST_MAXIMUM_REPEAT_DISTANCE (FAST_REPEAT_DISTANCE + 10000) // 29 ms
106 
107 /*
108  * Definitions to switch between FAST and NEC/ONKYO timing with the same code.
109  */
110 #if defined(USE_FAST_PROTOCOL)
111 #define ENABLE_NEC2_REPEATS // Disables detection of special short frame NEC repeats. Saves 40 bytes program memory.
112 
113 #define TINY_RECEIVER_ADDRESS_BITS FAST_ADDRESS_BITS
114 #define TINY_RECEIVER_COMMAND_BITS FAST_COMMAND_BITS
115 #if !defined(TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY)
116 #define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY true // 8 bit and 8 bit parity
117 //#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY false // 16 bit command without parity - not tested
118 #endif
119 
120 #define TINY_RECEIVER_BITS FAST_BITS
121 #define TINY_RECEIVER_UNIT FAST_UNIT
122 
123 #define TINY_RECEIVER_HEADER_MARK FAST_HEADER_MARK
124 #define TINY_RECEIVER_HEADER_SPACE FAST_HEADER_SPACE
125 
126 #define TINY_RECEIVER_BIT_MARK FAST_BIT_MARK
127 #define TINY_RECEIVER_ONE_SPACE FAST_ONE_SPACE
128 #define TINY_RECEIVER_ZERO_SPACE FAST_ZERO_SPACE
129 
130 #define TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE FAST_MAXIMUM_REPEAT_DISTANCE // for repeat detection
131 
132 #else
133 
134 #define TINY_RECEIVER_ADDRESS_BITS NEC_ADDRESS_BITS // the address bits + parity
135 # if defined(USE_ONKYO_PROTOCOL)
136 #define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY false // 16 bit address without parity
137 # elif defined(USE_EXTENDED_NEC_PROTOCOL)
138 #define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY false // 16 bit address without parity
139 # else
140 #define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY true // 8 bit and 8 bit parity
141 # endif
142 
143 #define TINY_RECEIVER_COMMAND_BITS NEC_COMMAND_BITS // the command bits + parity
144 # if defined(USE_ONKYO_PROTOCOL)
145 #define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY false // 16 bit command without parity
146 # else
147 #define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY true // 8 bit and 8 bit parity
148 # endif
149 
150 #define TINY_RECEIVER_BITS NEC_BITS
151 #define TINY_RECEIVER_UNIT NEC_UNIT
152 
153 #define TINY_RECEIVER_HEADER_MARK NEC_HEADER_MARK
154 #define TINY_RECEIVER_HEADER_SPACE NEC_HEADER_SPACE
155 
156 #define TINY_RECEIVER_BIT_MARK NEC_BIT_MARK
157 #define TINY_RECEIVER_ONE_SPACE NEC_ONE_SPACE
158 #define TINY_RECEIVER_ZERO_SPACE NEC_ZERO_SPACE
159 
160 #define TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE NEC_MAXIMUM_REPEAT_DISTANCE
161 #endif
162 
163 #if defined(USE_CALLBACK_FOR_TINY_RECEIVER)
164 /*
165  * This function is called, if a complete command was received and must be implemented in the file (user code)
166  * which includes this library if USE_CALLBACK_FOR_TINY_RECEIVER is activated.
167  */
168 extern void handleReceivedTinyIRData();
169 #endif
170 
171 #if !defined(MICROS_IN_ONE_SECOND)
172 #define MICROS_IN_ONE_SECOND 1000000L
173 #endif
174 
175 #if !defined(MICROS_IN_ONE_MILLI)
176 #define MICROS_IN_ONE_MILLI 1000L
177 #endif
178 
179 /*
180  * Macros for comparing timing values
181  */
182 #define lowerValue25Percent(aDuration) (aDuration - (aDuration / 4))
183 #define upperValue25Percent(aDuration) (aDuration + (aDuration / 4))
184 #define lowerValue50Percent(aDuration) (aDuration / 2) // (aDuration - (aDuration / 2))
185 #define upperValue50Percent(aDuration) (aDuration + (aDuration / 2))
186 
187 /*
188  * The states for the state machine
189  */
190 #define IR_RECEIVER_STATE_WAITING_FOR_START_MARK 0
191 #define IR_RECEIVER_STATE_WAITING_FOR_START_SPACE 1
192 #define IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK 2
193 #define IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE 3
194 #define IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK 4
195 #define IR_RECEIVER_STATE_WAITING_FOR_STOP_MARK 5
196 
200  /*
201  * State machine
202  */
203  uint32_t LastChangeMicros;
204  uint8_t IRReceiverState;
206  /*
207  * Data
208  */
209 #if (TINY_RECEIVER_BITS > 16)
210  uint32_t IRRawDataMask;
212 #else
213  uint16_t IRRawDataMask;
215 #endif
216  uint8_t Flags;
217 };
218 
219 /*
220  * Definitions for member TinyIRReceiverCallbackDataStruct.Flags
221  * From IRremoteInt.h
222  */
223 #define IRDATA_FLAGS_EMPTY 0x00
224 #define IRDATA_FLAGS_IS_REPEAT 0x01
225 #define IRDATA_FLAGS_IS_AUTO_REPEAT 0x02 // not used here, overwritten with _IRDATA_FLAGS_IS_SHORT_REPEAT
226 #define IRDATA_FLAGS_PARITY_FAILED 0x04
227 
228 
232 #if (TINY_RECEIVER_ADDRESS_BITS > 0)
233 # if (TINY_RECEIVER_ADDRESS_BITS == 16) && !TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY
234  uint16_t Address;
235 # else
236  uint8_t Address;
237 # endif
238 #endif
239 
240 # if (TINY_RECEIVER_COMMAND_BITS == 16) && !TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY
241  uint16_t Command;
242 #else
243  uint8_t Command;
244 #endif
245  uint8_t Flags; // Bit coded flags. Can contain one of the bits: IRDATA_FLAGS_IS_REPEAT and IRDATA_FLAGS_PARITY_FAILED
246  bool justWritten;
247 };
249 
254 bool isTinyReceiverIdle();
255 void printTinyReceiverResultMinimal(Print *aSerial);
256 
257 void sendFAST(uint8_t aSendPin, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0);
258 void sendFast8BitAndParity(uint8_t aSendPin, uint8_t aCommand, uint_fast8_t aNumberOfRepeats = 0);
259 void sendONKYO(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0, bool aSendNEC2Repeats = false); // Send NEC with 16 bit command, even if aCommand < 0x100
260 void sendNECMinimal(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0)
261  __attribute__ ((deprecated ("Renamed to sendNEC().")));
262 void sendNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0, bool aSendNEC2Repeats = false);
263 void sendExtendedNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0, bool aSendNEC2Repeats = false);
264 
265 /*
266  * Version 2.1.0 - 2/2024
267  * - New sendExtendedNEC() function and new parameter aSendNEC2Repeats.
268  *
269  * Version 2.0.0 - 10/2023
270  * - New TinyIRReceiverData which is filled with address, command and flags.
271  * - Removed parameters address, command and flags from callback handleReceivedTinyIRData() and printTinyReceiverResultMinimal().
272  * - Callback function now only enabled if USE_CALLBACK_FOR_TINY_RECEIVER is activated.
273  *
274  * Version 1.2.0 - 01/2023
275  * - Added ONKYO protocol, NEC with 16 bit address and command, instead of 8 bit + 8 bit parity address and command.
276  * - Renamed functions and macros.
277  *
278  * Version 1.1.0 - 01/2023
279  * - FAST protocol added.
280  */
283 #endif // _TINY_IR_H
LongUnion
Union to specify parts / manifestations of a 32 bit Long without casts and shifts.
Definition: LongUnion.h:59
TinyIRReceiverStruct::IRReceiverState
uint8_t IRReceiverState
The state of the state machine.
Definition: TinyIR.h:204
sendNECMinimal
void sendNECMinimal(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats=0) __attribute__((deprecated("Renamed to sendNEC().")))
Definition: TinyIRSender.hpp:165
TinyIRReceiverCallbackDataStruct::Flags
uint8_t Flags
Definition: TinyIR.h:245
WordUnion
Union to specify parts / manifestations of a 16 bit Word without casts and shifts.
Definition: LongUnion.h:36
TinyIRReceiverStruct
Control and data variables of the state machine for TinyReceiver.
Definition: TinyIR.h:199
TinyIRReceiverStruct::Flags
uint8_t Flags
One of IRDATA_FLAGS_EMPTY, IRDATA_FLAGS_IS_REPEAT, and IRDATA_FLAGS_PARITY_FAILED.
Definition: TinyIR.h:216
enablePCIInterruptForTinyReceiver
bool enablePCIInterruptForTinyReceiver()
Initializes hardware interrupt generation according to IR_RECEIVE_PIN or use attachInterrupt() functi...
Definition: TinyIRReceiver.hpp:551
TinyIRReceiverData
volatile TinyIRReceiverCallbackDataStruct TinyIRReceiverData
Definition: TinyIRReceiver.hpp:106
isTinyReceiverIdle
bool isTinyReceiverIdle()
Definition: TinyIRReceiver.hpp:422
disablePCIInterruptForTinyReceiver
void disablePCIInterruptForTinyReceiver()
Definition: TinyIRReceiver.hpp:617
TinyIRReceiverCallbackDataStruct::Address
uint16_t Address
Definition: TinyIR.h:234
TinyIRReceiverCallbackDataStruct::justWritten
bool justWritten
Is set true if new data is available. Used by the main loop, to avoid multiple evaluations of the sam...
Definition: TinyIR.h:246
TinyIRReceiverStruct::LastChangeMicros
uint32_t LastChangeMicros
Microseconds of last Pin Change Interrupt.
Definition: TinyIR.h:203
TinyIRReceiverStruct::IRRawDataMask
uint32_t IRRawDataMask
The corresponding bit mask for IRRawDataBitCounter.
Definition: TinyIR.h:210
TinyIRReceiverCallbackDataStruct
Is filled before calling the user callback to transfer received data to main loop for further process...
Definition: TinyIR.h:231
sendNEC
void sendNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats=0, bool aSendNEC2Repeats=false)
Definition: TinyIRSender.hpp:168
LongUnion.h
TinyIRReceiverCallbackDataStruct::Command
uint16_t Command
Definition: TinyIR.h:241
printTinyReceiverResultMinimal
void printTinyReceiverResultMinimal(Print *aSerial)
Definition: TinyIRReceiver.hpp:450
TinyIRReceiverStruct::IRRawDataBitCounter
uint8_t IRRawDataBitCounter
How many bits are currently contained in raw data.
Definition: TinyIR.h:205
sendFast8BitAndParity
void sendFast8BitAndParity(uint8_t aSendPin, uint8_t aCommand, uint_fast8_t aNumberOfRepeats=0)
Definition: TinyIRSender.hpp:287
sendONKYO
void sendONKYO(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats=0, bool aSendNEC2Repeats=false)
Definition: TinyIRSender.hpp:114
isIRReceiverAttachedForTinyReceiver
bool isIRReceiverAttachedForTinyReceiver()
Definition: TinyIRReceiver.hpp:430
sendExtendedNEC
void sendExtendedNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats=0, bool aSendNEC2Repeats=false)
Definition: TinyIRSender.hpp:234
sendFAST
void sendFAST(uint8_t aSendPin, uint16_t aCommand, uint_fast8_t aNumberOfRepeats=0)
Definition: TinyIRSender.hpp:294
TinyIRReceiverStruct::IRRawData
LongUnion IRRawData
The current raw data. LongUnion helps with decoding of address and command.
Definition: TinyIR.h:211
initPCIInterruptForTinyReceiver
bool initPCIInterruptForTinyReceiver()
Sets IR_RECEIVE_PIN mode to INPUT, and if IR_FEEDBACK_LED_PIN is defined, sets feedback LED output mo...
Definition: TinyIRReceiver.hpp:441