Documentation

This commit is contained in:
Armin 2022-12-29 18:46:09 +01:00
parent 83387a8493
commit cc13de99f3
16 changed files with 158 additions and 107 deletions

View File

@ -10,12 +10,16 @@ If you want to contribute to this project:
## Guidelines
The following are some guidelines to observe when creating discussions / PRs:
- Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and **it is okay for people to have different ideas**.
- Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile:.
- Use the style; we use the original [C Style by Kerninghan / Ritchie](https://en.wikipedia.org/wiki/Indentation_style#K&R_style) in [variant: 1TBS (OTBS)](https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)).
In short: 4 spaces indentation, no tabs, opening braces on the same line, braces are mandatory on all if/while/do, no hard line length limit.
To beautify your code, you may use the online formatter [here](https://www.freecodeformat.com/c-format.php).
- Cover **all** occurences of the problem / addition you address with your PR. Do not forget the documentation like it is done for existing code. Code changes without proper documentation will be rejected!
#### Be friendly
It is important that we can all enjoy a safe space as we are all working on the same project and **it is okay for people to have different ideas**.
#### Use reasonable titles
Refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile:.
#### Use the formatting style
We use the original [C Style by Kerninghan / Ritchie](https://en.wikipedia.org/wiki/Indentation_style#K&R_style) in [variant: 1TBS (OTBS)](https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)).<br/>
In short: 4 spaces indentation, no tabs, opening braces on the same line, braces are mandatory on all if/while/do, no hard line length limit.<br/>
To beautify your code, you may use the online formatter [here](https://www.freecodeformat.com/c-format.php).
#### Cover **all** occurences of the problem / addition you address with your PR
Do not forget the documentation like it is done for existing code. Code changes without proper documentation will be rejected!
## Adding new protocols
To add a new protocol is quite straightforward. Best is too look at the existing protocols to find a similar one and modify it.<br/>

View File

@ -99,7 +99,7 @@ Protocols can be switched off and on by defining macros before the line `#includ
## New features with version 4.x
- New universal **Pulse Distance / Pulse Width decoder** added, which covers many previous unknown protocols.
- Printout of code how to send received command by `IrReceiver.printIRSendUsage(&Serial)`.
- RawData type is now 64 bit for 32 bit platforms and therefore contains complete frame information for more protocols.
- RawData type is now 64 bit for 32 bit platforms and therefore `decodedIRData.decodedRawData` can contain complete frame information for more protocols than with 32 bit as before.
- Callback after receiving a command - call your own code if a message was received.
# Converting your 3.x program to the 4.x version
@ -289,7 +289,7 @@ struct IRData {
uint16_t extra; // Used for Kaseikyo unknown vendor ID. Ticks used for decoding Distance protocol.
uint16_t numberOfBits; // Number of bits received for data (address + command + parity) - to determine protocol length if different length are possible.
uint8_t flags; // See IRDATA_FLAGS_* definitions
uint32_t decodedRawData; // Up to 32 bit decoded raw data, used for sendRaw functions.
IRRawDataType decodedRawData; // Up to 32 (64 bit for 32 bit CPU architectures) bit decoded raw data, used for sendRaw functions.
uint32_t decodedRawDataArray[RAW_DATA_ARRAY_SIZE]; // 32 bit decoded raw data, to be used for send function.
irparams_struct *rawDataPtr; // Pointer of the raw timing data to be decoded. Mainly the data buffer filled by receiving ISR.
};
@ -297,7 +297,7 @@ struct IRData {
#### To access the **RAW data**, use:
```c++
uint32_t myRawdata= IrReceiver.decodedIRData.decodedRawData;
auto myRawdata= IrReceiver.decodedIRData.decodedRawData;
```
The definitions for the `IrReceiver.decodedIRData.flags` are described [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremoteInt.h#L128-L140).
@ -311,14 +311,12 @@ IrReceiver.printIRResultShort(&Serial);
```c++
IrReceiver.printIRResultRawFormatted(&Serial, true);`
```
The raw data depends on the internal state of the Arduino timer in relation to the received signal and might therefore be slightly different each time. (resolution problem). The decoded values are the interpreted ones which are tolerant to such slight differences!
<br/>
# Tiny NEC receiver
For applications only requiring NEC protocol, there is a special receiver included,<br/>
which has very **small code size of 500 bytes and does NOT require any timer**.
Check out the [TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote#tinyreceiver--tinysender) and [IRDispatcherDemo](https://github.com/Arduino-IRremote/Arduino-IRremote#irdispatcherdemo) examples.
#### Print how to send the received data:
```c++
IrReceiver.printIRSendUsage(&Serial);
```
<br/>
@ -342,17 +340,30 @@ If you handle the sending of repeat frames by your own, you must insert sensible
The old send*Raw() functions for sending like e.g. `IrSender.sendNECRaw(0xE61957A8,2)` are kept for backward compatibility to **(old)** tutorials and unsupported as well as error prone.
## Send pin
Any pin can be choosen as send pin, because the PWM signal is generated by default with software bit banging, since `SEND_PWM_BY_TIMER` is not active.
If `IR_SEND_PIN` is specified (as constant), it reduces program size and improves send timing for AVR. If you want to use a variable to specify send pin e.g. with `setSendPin(uint8_t aSendPinNumber)`, you must disable this macro. Then you can change send pin at any time before sending an IR frame. See also [Compile options / macros for this library](https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library).
### List of public IR code databases
http://www.harctoolbox.org/IR-resources.html
<br/>
# Tiny NEC receiver and sender
For applications only requiring NEC protocol, there is a special receiver / sender included,<br/>
which has very **small code size of 500 bytes and does NOT require any timer**.
Check out the [TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote#tinyreceiver--tinysender) and [IRDispatcherDemo](https://github.com/Arduino-IRremote/Arduino-IRremote#irdispatcherdemo) examples.
<br/>
# FAQ and hints
## Problems with Neopixels, FastLed etc.
IRremote will not work right when you use **Neopixels** (aka WS2811/WS2812/WS2812B) or other libraries blocking interrupts for a longer time (> 50 &micro;s).<br/>
Whether you use the Adafruit Neopixel lib, or FastLED, interrupts get disabled on many lower end CPUs like the basic Arduinos for longer than 50 &micro;s.
In turn, this stops the IR interrupt handler from running when it needs to.
In turn, this stops the IR interrupt handler from running when it needs to. See also this [video](https://www.youtube.com/watch?v=62-nEJtm070).
One **workaround** is to wait for the IR receiver to be idle before you send the Neopixel data with `if (IrReceiver.isIdle()) { strip.show();}`.<br/>
This **prevents at least breaking a running IR transmission** and -depending of the update rate of the Neopixel- may work quite well.<br/>
@ -416,7 +427,7 @@ If this does not suit you for further research, you can change it [here](https:/
## Protocol=UNKNOWN
If you see something like `Protocol=UNKNOWN Hash=0x13BD886C 35 bits received` as output of e.g. the ReceiveDemo example, you either have a problem with decoding a protocol, or an unsupported protocol.
- If you have an **odd number of bits** received, it is likely, that your receiver circuit has problems. Maybe because the IR signal is too weak.
- If you have an **odd number of bits** received, your receiver circuit probably has problems. Maybe because the IR signal is too weak.
- If you see timings like `+ 600,- 600 + 550,- 150 + 200,- 100 + 750,- 550` then one 450 &micro;s space was split into two 150 and 100 &micro;s spaces with a spike / error signal of 200 &micro;s between. Maybe because of a defective receiver or a weak signal in conjunction with another light emitting source nearby.
- If you see timings like `+ 500,- 550 + 450,- 550 + 500,- 500 + 500,-1550`, then marks are generally shorter than spaces and therefore `MARK_EXCESS_MICROS` (specified in your ino file) should be **negative** to compensate for this at decoding.
- If you see `Protocol=UNKNOWN Hash=0x0 1 bits received` it may be that the space after the initial mark is longer than [`RECORD_GAP_MICROS`](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremote.h#L124).
@ -537,7 +548,7 @@ Modify them by enabling / disabling them, or change the values if applicable.
| `MARK_EXCESS_MICROS` | 20 | MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, to compensate for the signal forming of different IR receiver modules. |
| `RECORD_GAP_MICROS` | 5000 | Minimum gap between IR transmissions, to detect the end of a protocol.<br/>Must be greater than any space of a protocol e.g. the NEC header space of 4500 &micro;s.<br/>Must be smaller than any gap between a command and a repeat; e.g. the retransmission gap for Sony is around 24 ms.<br/>Keep in mind, that this is the delay between the end of the received command and the start of decoding. |
| `IR_INPUT_IS_ACTIVE_HIGH` | disabled | Enable it if you use a RF receiver, which has an active HIGH output signal. |
| `IR_SEND_PIN` | disabled | If specified (as constant), reduces program size and improves send timing for AVR. If you want to use a runtime variable send pin e.g. with `setSendPin(uint8_t aSendPinNumber)` , you must disable this macro. |
| `IR_SEND_PIN` | disabled | If specified (as constant), it reduces program size and improves send timing for AVR. If you want to use a variable to specify send pin e.g. with `setSendPin(uint8_t aSendPinNumber)`, you must disable this macro. |
| `SEND_PWM_BY_TIMER` | disabled | Disables carrier PWM generation in software and use hardware PWM (by timer). Has the advantage of more exact PWM generation, especially the duty cycle (which is not very relevant for most IR receiver circuits), and the disadvantage of using a hardware timer, which in turn is not available for other libraries and to fix the send pin (but not the receive pin) at the [dedicated timer output pin(s)](https://github.com/Arduino-IRremote/Arduino-IRremote#timer-and-pin-usage). Is enabled for ESP32 and RP2040 in all examples, since they support PWM gereration for each pin without using a shared resource (timer). |
| `USE_NO_SEND_PWM` | disabled | Uses no carrier PWM, just simulate an **active low** receiver signal. Overrides `SEND_PWM_BY_TIMER` definition. |
| `IR_SEND_DUTY_CYCLE_PERCENT` | 30 | Duty cycle of IR send signal. |
@ -584,7 +595,7 @@ If you are using [Sloeber](https://eclipse.baeyens.it) as your IDE, you can easi
<br/>
ATtiny and Digispark boards are only tested with the recommended [ATTinyCore](https://github.com/SpenceKonde/ATTinyCore) using `New Style` pin mapping for the pro board.
- Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc.
- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC - but [limited support](https://forum.pjrc.com/threads/65912-Enable-Continuous-Integration-with-arduino-cli-for-3-party-libraries); Credits: PaulStoffregen (Teensy Team)
- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / 3.2 / Teensy-LC - but [limited support](https://forum.pjrc.com/threads/65912-Enable-Continuous-Integration-with-arduino-cli-for-3-party-libraries); Credits: PaulStoffregen (Teensy Team)
- Sanguino
- ATmega8, 48, 88, 168, 328
- ATmega8535, 16, 32, 164, 324, 644, 1284,

View File

@ -32,7 +32,7 @@ See also the commit log at github: https://github.com/Arduino-IRremote/Arduino-I
- Fixed SEND_PWM_BY_TIMER for ATtiny167 thanks to freskpe.
- Improved SHARP repeat decoding.
- Replaced macros TIMER_EN/DISABLE_RECEIVE_INTR and EN/DISABLE_SEND_PWM_BY_TIMER by functions.
- Added SAMSUNG48 protocol and sendSamsung48().
- Added SAMSUNG48 protocol and sendSamsung48() function.
## 3.9.0
- Improved documentation with the help of [ElectronicsArchiver}(https://github.com/ElectronicsArchiver).

View File

@ -85,7 +85,7 @@ void setup() {
Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed"));
Serial.print(MARK_EXCESS_MICROS);
Serial.println();
Serial.println(F("Because of the verbose output, repeats are likely not dumped correctly!"));
Serial.println(F("Because of the verbose output, repeats are probably not dumped correctly!"));
Serial.println();
}

View File

@ -71,36 +71,6 @@ typedef enum {
} decode_type_t;
const char string_Unknown[] PROGMEM = "UNKNOWN";
const char string_PulseWidth[] PROGMEM = "PulseWidth";
const char string_PulseDistance[] PROGMEM = "PulseDistance";
const char string_Apple[] PROGMEM = "Apple";
const char string_Denon[] PROGMEM = "Denon";
const char string_JVC[] PROGMEM = "JVC";
const char string_LG[] PROGMEM = "LG";
const char string_LG2[] PROGMEM = "LG2";
const char string_NEC[] PROGMEM = "NEC";
const char string_NEC2[] PROGMEM = "NEC2";
const char string_Onkyo[] PROGMEM = "Onkyo";
const char string_Panasonic[] PROGMEM = "Panasonic";
const char string_Kaseikyo[] PROGMEM = "Kaseikyo";
const char string_Kaseikyo_Denon[] PROGMEM = "Kaseikyo_Denon";
const char string_Kaseikyo_Sharp[] PROGMEM = "Kaseikyo_Sharp";
const char string_Kaseikyo_JVC[] PROGMEM = "Kaseikyo_JVC";
const char string_Kaseikyo_Mitsubishi[] PROGMEM = "Kaseikyo_Mitsubishi";
const char string_RC5[] PROGMEM = "RC5";
const char string_RC6[] PROGMEM = "RC6";
const char string_Samsung[] PROGMEM = "Samsung";
const char string_Samsung48[] PROGMEM = "Samsung48";
const char string_SamsungLG[] PROGMEM = "SamsungLG";
const char string_Sharp[] PROGMEM = "Sharp";
const char string_Sony[] PROGMEM = "Sony";
const char string_BangOlufsen[] PROGMEM = "Bang&Olufsen";
const char string_BoseWave[] PROGMEM = "BoseWave";
const char string_Lego[] PROGMEM = "Lego";
const char string_MagiQuest[] PROGMEM = "MagiQuest";
const char string_Whynter[] PROGMEM = "Whynter";
struct PulseDistanceWidthProtocolConstants {
decode_type_t ProtocolIndex;
uint_fast8_t FrequencyKHz;

View File

@ -48,6 +48,36 @@
* @{
*/
const char string_Unknown[] PROGMEM = "UNKNOWN";
const char string_PulseWidth[] PROGMEM = "PulseWidth";
const char string_PulseDistance[] PROGMEM = "PulseDistance";
const char string_Apple[] PROGMEM = "Apple";
const char string_Denon[] PROGMEM = "Denon";
const char string_JVC[] PROGMEM = "JVC";
const char string_LG[] PROGMEM = "LG";
const char string_LG2[] PROGMEM = "LG2";
const char string_NEC[] PROGMEM = "NEC";
const char string_NEC2[] PROGMEM = "NEC2";
const char string_Onkyo[] PROGMEM = "Onkyo";
const char string_Panasonic[] PROGMEM = "Panasonic";
const char string_Kaseikyo[] PROGMEM = "Kaseikyo";
const char string_Kaseikyo_Denon[] PROGMEM = "Kaseikyo_Denon";
const char string_Kaseikyo_Sharp[] PROGMEM = "Kaseikyo_Sharp";
const char string_Kaseikyo_JVC[] PROGMEM = "Kaseikyo_JVC";
const char string_Kaseikyo_Mitsubishi[] PROGMEM = "Kaseikyo_Mitsubishi";
const char string_RC5[] PROGMEM = "RC5";
const char string_RC6[] PROGMEM = "RC6";
const char string_Samsung[] PROGMEM = "Samsung";
const char string_Samsung48[] PROGMEM = "Samsung48";
const char string_SamsungLG[] PROGMEM = "SamsungLG";
const char string_Sharp[] PROGMEM = "Sharp";
const char string_Sony[] PROGMEM = "Sony";
const char string_BangOlufsen[] PROGMEM = "Bang&Olufsen";
const char string_BoseWave[] PROGMEM = "BoseWave";
const char string_Lego[] PROGMEM = "Lego";
const char string_MagiQuest[] PROGMEM = "MagiQuest";
const char string_Whynter[] PROGMEM = "Whynter";
/*
* !!Must be the same order as in decode_type_t in IRProtocol.h!!!
*/
@ -131,9 +161,6 @@ namespace PrintULL {
* @param aSerial The Print object on which to write, for Arduino you can use &Serial.
* @param aIRDataPtr Pointer to the data to be printed.
* @param aPrintRepeatGap If true also print the gap before repeats.
* @param aCheckForRecordGapsMicros If true, call CheckForRecordGapsMicros() which may do a long printout,
* which in turn may block the proper detection of repeats.
* @return true, if CheckForRecordGapsMicros() has printed a message, i.e. gap <
*
*/
void printIRResultShort(Print *aSerial, IRData *aIRDataPtr, bool aPrintRepeatGap) {

View File

@ -301,7 +301,9 @@ void IRrecv::registerReceiveCompleteCallback(void (*aReceiveCompleteCallbackFunc
}
/**
* Configures the timer and the state machine for IR reception.
* Start the receiving process.
* This configures the timer and the state machine for IR reception
* and enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
*/
void IRrecv::start() {
@ -312,7 +314,7 @@ void IRrecv::start() {
resume();
// Timer interrupt is enabled after state machine reset
timerEnableReceiveInterrupt();
timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
#ifdef _IR_MEASURE_TIMING
pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
#endif
@ -375,8 +377,7 @@ bool IRrecv::isIdle() {
}
/**
* Restart the ISR (Interrupt Service Routine) state machine
* Enable receiving of the next value
* Restart the ISR (Interrupt Service Routine) state machine, to enable receiving of the next IR frame
*/
void IRrecv::resume() {
// check allows to call resume at arbitrary places or more than once
@ -444,7 +445,8 @@ IRData* IRrecv::read() {
/**
* The main decode function, attempts to decode the recently receive IR signal.
* The set of decoders used is determined by active definitions of the DECODE_<PROTOCOL> macros.
* @return false if no IR receiver data available, true if data available. Results of decoding are stored in IrReceiver.decodedIRData.
* Results of decoding are stored in IrReceiver.decodedIRData.* like e.g. IrReceiver.decodedIRData.command.
* @return false if no IR receiver data available, true if data available.
*/
bool IRrecv::decode() {
if (irparams.StateForISR != IR_REC_STATE_STOP) {
@ -608,11 +610,13 @@ bool IRrecv::decode() {
*
* Assume pulse distance if aOneMarkMicros == aZeroMarkMicros
*
* @param aStartOffset Must point to a mark
* @param aNumberOfBits Number of bits to decode from decodedIRData.rawDataPtr->rawbuf[] array.
* @param aStartOffset Offset in decodedIRData.rawDataPtr->rawbuf[] to start decoding. Must point to a mark.
* @param aOneMarkMicros Taken as constant BitMarkMicros for pulse distance.
* @param aZeroMarkMicros Not required if DECODE_STRICT_CHECKS is not defined.
* @param aOneSpaceMicros Taken as (constant) BitSpaceMicros for pulse width.
* @param aZeroSpaceMicros Not required if DECODE_STRICT_CHECKS is not defined.
* @param aMSBfirst If true send Most Significant Bit first, else send Least Significant Bit (lowest bit) first.
* @return true If decoding was successful
*/
bool IRrecv::decodePulseDistanceWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, unsigned int aOneMarkMicros,
@ -1158,8 +1162,11 @@ void printActiveIRProtocols(Print *aSerial) {
* Function to print values and flags of IrReceiver.decodedIRData in one line.
* Ends with println().
*
* @param aSerial The Print object on which to write, for Arduino you can use &Serial.
* @return true, if CheckForRecordGapsMicros() has printed a message, i.e. gap < 15ms (RECORD_GAP_MICROS_WARNING_THRESHOLD)
* @param aSerial The Print object on which to write, for Arduino you can use &Serial.
* @param aPrintRepeatGap If true also print the gap before repeats.
* @param aCheckForRecordGapsMicros If true, call CheckForRecordGapsMicros() which may do a long printout,
* which in turn may block the proper detection of repeats.*
* @return true, if CheckForRecordGapsMicros() has printed a message, i.e. gap < 15ms (RECORD_GAP_MICROS_WARNING_THRESHOLD).
*/
bool IRrecv::printIRResultShort(Print *aSerial, bool aPrintRepeatGap, bool aCheckForRecordGapsMicros) {
// call no class function with same name

View File

@ -520,10 +520,14 @@ void IRsend::sendPulseDistanceWidthFromArray(PulseDistanceWidthProtocolConstants
IrReceiver.restartAfterSend();
#endif
}
/**
* Sends PulseDistance frames and repeats
* @param aProtocolConstants The constants to use for sending this protocol.
* @param aData uint32 or uint64 holding the bits to be sent.
* @param aNumberOfBits Number of bits from aData to be actually sent.
* @param aNumberOfRepeats If < 0 and a aProtocolConstants->SpecialSendRepeatFunction() is specified
* then it is called without leading and trailing space
* then it is called without leading and trailing space.
*/
void IRsend::sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData,
uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats) {
@ -574,7 +578,13 @@ void IRsend::sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtoc
}
/**
* Sends PulseDistance frames and repeats
* Sends PulseDistance frames and repeats.
* @param aFrequencyKHz, aHeaderMarkMicros, aHeaderSpaceMicros, aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aMSBFirst, aSendStopBit, aRepeatPeriodMillis Values to use for sending this protocol, also contained in the PulseDistanceWidthProtocolConstants of this protocol.
* @param aData uint32 or uint64 holding the bits to be sent.
* @param aNumberOfBits Number of bits from aData to be actually sent.
* @param aNumberOfRepeats If < 0 and a aProtocolConstants->SpecialSendRepeatFunction() is specified
* then it is called without leading and trailing space.
* @param aSpecialSendRepeatFunction If NULL, the first frame is repeated completely, otherwise this function is used for sending the repeat frame.
*/
void IRsend::sendPulseDistanceWidth(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros, unsigned int aHeaderSpaceMicros,
unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros, unsigned int aZeroSpaceMicros,

View File

@ -409,9 +409,9 @@ public:
void begin(bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin = USE_DEFAULT_FEEDBACK_LED_PIN);
// The next function is a dummy to avoid acceptance of pre 4.0 calls to begin(IR_SEND_PIN, DISABLE_LED_FEEDBACK);
void begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback)
#if !defined (DOXYGEN)
# if !defined (DOXYGEN)
__attribute__ ((deprecated ("You must use begin(ENABLE_LED_FEEDBACK) or begin(DISABLE_LED_FEEDBACK) since version 4.0.")));
#endif
# endif
#else
IRsend(uint_fast8_t aSendPin);
void begin(uint_fast8_t aSendPin);

View File

@ -30,7 +30,7 @@
#include "LongUnion.h"
/** \addtogroup TinyReceiver Minimal receiver for NEC protocol
/** \addtogroup TinyReceiver Minimal receiver for NEC and FAST protocol
* @{
*/

View File

@ -49,7 +49,7 @@
// 1. The carrier frequency is 455 kHz
// You can build your own receiver as Bang & Olufsen did (check old schematics) or use a TSOP7000
// Vishay stopped producing TSOP7000 since 2009 so you will likely only find counterfeits:
// Vishay stopped producing TSOP7000 since 2009 so you will probably only find counterfeits:
// https://www.vishay.com/files/whatsnew/doc/ff_FastFacts_CounterfeitTSOP7000_Dec72018.pdf
// It is also likely that you will need an oscilloscope to debug a counterfeit TSOP7000
// The specimen used to test this code was very noisy and had a very low output current

View File

@ -62,6 +62,7 @@ Sum: 40350
// IRP: {38k,525}<1,-1|1,-3>(16,-8,(D:8,F:8,1,-45)+)
// LSB first, 1 start bit + 8 bit address + 8 bit command + 1 stop bit.
// The JVC protocol repeats by skipping the header mark and space -> this leads to a poor repeat detection for JVC protocol.
// Some JVC devices require to send 3 repeats. https://github.com/Arduino-IRremote/Arduino-IRremote/issues/21
#define JVC_ADDRESS_BITS 8 // 8 bit address
#define JVC_COMMAND_BITS 8 // Command

View File

@ -287,8 +287,9 @@ bool IRrecv::decodeLG() {
*********************************************************************************/
/**
* Here you can put your raw data, even one with "wrong" checksum
* @param aNumberOfRepeats If < 0 then only a special repeat frame will be sent
* Here you can put your raw data, even one with "wrong" checksum.
* @param aRawData The lowest 28 (LG_BITS) bit of this value are sent MSB first.
* @param aNumberOfRepeats If < 0 then only a special repeat frame will be sent.
*/
void IRsend::sendLGRaw(uint32_t aRawData, int_fast8_t aNumberOfRepeats) {
sendPulseDistanceWidth(&LGProtocolConstants, aRawData, LG_BITS, aNumberOfRepeats);

View File

@ -105,7 +105,7 @@ struct PulseDistanceWidthProtocolConstants NECProtocolConstants = { NEC, NEC_KHZ
NEC_ONE_SPACE, NEC_BIT_MARK, NEC_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, SEND_STOP_BIT, (NEC_REPEAT_PERIOD / MICROS_IN_ONE_MILLI),
&sendNECSpecialRepeat };
// Like NEC but repeat are full frames instead of special NEC repeats
// Like NEC but repeats are full frames instead of special NEC repeats
struct PulseDistanceWidthProtocolConstants NEC2ProtocolConstants = { NEC2, NEC_KHZ, NEC_HEADER_MARK, NEC_HEADER_SPACE, NEC_BIT_MARK,
NEC_ONE_SPACE, NEC_BIT_MARK, NEC_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST, SEND_STOP_BIT, (NEC_REPEAT_PERIOD / MICROS_IN_ONE_MILLI), NULL };

View File

@ -96,7 +96,8 @@ uint8_t sLastSendToggleValue = 1; // To start first command with toggle 0
************************************/
/**
* @param aCommand If aCommand is >=0x40 then we switch automatically to RC5X
* @param aCommand If aCommand is >=0x40 then we switch automatically to RC5X.
* @param aEnableAutomaticToggle Send toggle bit according to the state of the static sLastSendToggleValue variable.
*/
void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) {
// Set IR carrier frequency
@ -244,8 +245,8 @@ bool IRrecv::decodeRC5() {
+ 450
Sum: 23150
*/
// Frame RC6: 1 start bit + 1 Bit "1" + 3 mode bits (000) + 1 toggle bit + 8 address + 8 command bits + 2666µs pause
// Frame RC6A: 1 start bit + 1 Bit "1" + 3 mode bits (110) + 1 toggle bit + "1" + 14 customer bits + 8 system bits + 8 command bits (=31bits) + 2666µs pause
// Frame RC6: 1 start bit + 1 Bit "1" + 3 mode bits (000) + 1 toggle bit + 8 address + 8 command bits + 2666us pause
// Frame RC6A: 1 start bit + 1 Bit "1" + 3 mode bits (110) + 1 toggle bit + "1" + 14 customer bits + 8 system bits + 8 command bits (=31bits) + 2666us pause
// !!! toggle bit has another timing :-( !!!
// mark->space => 1
// space->mark => 0

View File

@ -92,6 +92,50 @@ void timerConfigForSend(uint8_t aFrequencyKHz);
*/
#define IR_SEND_PIN
/**
* Configures the timer to be able to generate the receive sample interrupt,
* which consumes a small amount of CPU every 50 (MICROS_PER_TICK) us.
* The actual interrupt generation is controlled by timerEnableReceiveInterrupt() and timerDisableReceiveInterrupt().
* timerConfigForReceive() is used exclusively by IRrecv::start()
*/
void timerConfigForReceive() {
}
/**
* Enables the receive sample timer interrupt, which consumes a small amount of CPU every 50 us.
*/
void timerEnableReceiveInterrupt() {
}
/**
* Disables the receive sample timer interrupt. This must be done before using the timer for e.g. tone().
* Is a synonym for calling end() or stop().
*/
void timerDisableReceiveInterrupt() {
}
/**
* IF PWM should be generated not by software, but by a timer, this function sets output pin mode,
* configures the timer for generating a PWM with duty cycle of IR_SEND_DUTY_CYCLE_PERCENT
* and disables the receive interrupt if it uses the same resource.
* For most architectures, the pin number(s) which can be used for output is determined by the timer used!
* The output of the PWM signal is controlled by enableSendPWMByTimer() and disableSendPWMByTimer().
* timerConfigForSend() is used exclusively by IRsend::enableIROut().
* @param aFrequencyKHz Frequency of the sent PWM signal in kHz. There is no practical reason to have a sub kHz resolution for sending frequency :-).
*/
void timerConfigForSend(uint8_t aFrequencyKHz) {
}
/**
* Enables output of the PWM signal of the timer at the timer pin.
*/
void enableSendPWMByTimer() {
}
/**
* Disables output of the PWM signal of the timer at the timer pin and set it to inactive.
*/
void disableSendPWMByTimer() {
}
#elif defined(__AVR__)
/**********************************************************************************************************************
* Mapping of AVR boards to AVR timers
@ -431,10 +475,7 @@ void timerDisableReceiveInterrupt() {
#define TIMER_INTR_NAME TIMER2_COMPB_vect // We use TIMER2_COMPB_vect to be compatible with tone() library
#define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
/*
* timerConfigForReceive() is used exclusively by IRrecv::start()
* It generates an interrupt each 50 (MICROS_PER_TICK) us.
*/
void timerConfigForReceive() {
# if (TIMER_COUNT_TOP < 256)
TCCR2A = _BV(WGM21);
@ -760,6 +801,7 @@ void timerDisableReceiveInterrupt() {
#define TIMER_INTR_NAME TIMER0_COMPA_vect
#define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
void timerConfigForReceive() {
# if (TIMER_COUNT_TOP < 256)
TCCR0A = _BV(WGM01); // CTC, Top is OCR0A
@ -818,6 +860,7 @@ void timerDisableReceiveInterrupt() {
#define TIMER_INTR_NAME TIMER1_COMPB_vect
#define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
void timerConfigForReceive() {
# if (TIMER_COUNT_TOP < 256)
TCCR1 = _BV(CTC1) | _BV(CS10); // Clear Timer/Counter on Compare Match, Top is OCR1C, No prescaling
@ -1041,12 +1084,12 @@ void timerConfigForSend(uint8_t aFrequencyKHz) {
* End of AVR timers
**********************************************************************************************************************/
/***************************************
* Teensy 3.0 / Teensy 3.1 boards
***************************************/
/**********************************************
* Teensy 3.0 / Teensy 3.1 / Teensy 3.2 boards
**********************************************/
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
// Special carrier modulator timer for Teensy 3.0 / Teensy 3.1
// Special carrier modulator timer for Teensy 3.0 / Teensy 3.1 / Teensy 3.2
#define TIMER_REQUIRES_RESET_INTR_PENDING
void timerResetInterruptPending() {
uint8_t tmp __attribute__((unused)) = CMT_MSC;
@ -1303,9 +1346,6 @@ void timerDisableReceiveInterrupt() {
timer1_detachInterrupt(); // disables interrupt too }
}
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
timer1_isr_init();
/*
@ -1356,10 +1396,6 @@ void timerDisableReceiveInterrupt() {
#define ISR() IRAM_ATTR void IRTimerInterruptHandler()
IRAM_ATTR void IRTimerInterruptHandler();
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
// ESP32 has a proper API to setup timers, no weird chip macros needed
// simply call the readable API versions :)
@ -1436,9 +1472,6 @@ void IRTimerInterruptHandler();
* GCLK4 = 12 MHz
* GCLK3 = XOSC32K
*/
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
@ -1545,9 +1578,6 @@ void timerDisableReceiveInterrupt() {
s50usTimer.detach();
}
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
s50usTimer.attach(IRTimerInterruptHandler, std::chrono::microseconds(MICROS_PER_TICK));
}
@ -1681,9 +1711,6 @@ void timerDisableReceiveInterrupt() {
#define ISR(f) void IRTimerInterruptHandler(void)
void IRTimerInterruptHandler();
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Timer Mode
NRF_TIMER2->TASKS_CLEAR = 1; // clear the task first to be usable for later
@ -1748,9 +1775,6 @@ void timerDisableReceiveInterrupt() {
#define ISR() void IRTimerInterruptHandler(void)
void IRTimerInterruptHandler();
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
s50usTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
s50usTimer.setPrescaleFactor(1);
@ -1795,9 +1819,6 @@ void timerDisableReceiveInterrupt() {
#define ISR() void IRTimerInterruptHandler(void)
void IRTimerInterruptHandler();
/*
* Set timer for interrupts every MICROS_PER_TICK (50 us)
*/
void timerConfigForReceive() {
s50usTimer.setOverflow(MICROS_PER_TICK, MICROSEC_FORMAT); // 50 uS
s50usTimer.attachInterrupt(IRTimerInterruptHandler);
@ -1882,8 +1903,6 @@ void timerDisableReceiveInterrupt() {};
# endif
#define ISR() void notImplemented(void)
void timerConfigForReceive() {
}