fixed crlf for project

This commit is contained in:
Henrik Ekblad
2014-03-07 21:17:56 +01:00
parent 586a4d6239
commit c1441dca4a
62 changed files with 6964 additions and 6964 deletions
+318 -318
View File
@@ -1,318 +1,318 @@
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
* See NewRemoteReceiver.h for details.
*
* License: GPLv3. See license.txt
*/
#include "NewRemoteReceiver.h"
/************
* NewRemoteReceiver
Protocol. (Copied from Wieltje, http://www.circuitsonline.net/forum/view/message/1181410#1181410,
but with slightly different timings, as measured on my device.)
_ _
'0': | |_| |_____ (T,T,T,5T)
_ _
'1': | |_____| |_ (T,5T,T,T)
_ _
dim: | |_| |_ (T,T,T,T)
T = short period of ~260µs. However, this code tries
to figure out the correct period
A full frame looks like this:
- start pulse: 1T high, 10.44T low
- 26 bit: Address
- 1 bit: group bit
- 1 bit: on/off/[dim]
- 4 bit: unit
- [4 bit: dim level. Only present of [dim] is chosen]
- stop pulse: 1T high, 40T low
************/
int8_t NewRemoteReceiver::_interrupt;
volatile short NewRemoteReceiver::_state;
byte NewRemoteReceiver::_minRepeats;
NewRemoteReceiverCallBack NewRemoteReceiver::_callback;
boolean NewRemoteReceiver::_inCallback = false;
boolean NewRemoteReceiver::_enabled = false;
void NewRemoteReceiver::init(int8_t interrupt, byte minRepeats, NewRemoteReceiverCallBack callback) {
_interrupt = interrupt;
_minRepeats = minRepeats;
_callback = callback;
enable();
if (_interrupt >= 0) {
attachInterrupt(_interrupt, interruptHandler, CHANGE);
}
}
void NewRemoteReceiver::enable() {
_state = -1;
_enabled = true;
}
void NewRemoteReceiver::disable() {
_enabled = false;
}
void NewRemoteReceiver::deinit() {
_enabled = false;
if (_interrupt >= 0) {
detachInterrupt(_interrupt);
}
}
void NewRemoteReceiver::interruptHandler() {
// This method is written as compact code to keep it fast. While breaking up this method into more
// methods would certainly increase the readability, it would also be much slower to execute.
// Making calls to other methods is quite expensive on AVR. As These interrupt handlers are called
// many times a second, calling other methods should be kept to a minimum.
if (!_enabled) {
return;
}
static byte receivedBit; // Contains "bit" currently receiving
static NewRemoteCode receivedCode; // Contains received code
static NewRemoteCode previousCode; // Contains previous received code
static byte repeats = 0; // The number of times the an identical code is received in a row.
static unsigned long edgeTimeStamp[3] = {0, }; // Timestamp of edges
static unsigned int min1Period, max1Period, min5Period, max5Period;
static bool skip;
// Filter out too short pulses. This method works as a low pass filter.
edgeTimeStamp[1] = edgeTimeStamp[2];
edgeTimeStamp[2] = micros();
if (skip) {
skip = false;
return;
}
if (_state >= 0 && edgeTimeStamp[2]-edgeTimeStamp[1] < min1Period) {
// Last edge was too short.
// Skip this edge, and the next too.
skip = true;
return;
}
unsigned int duration = edgeTimeStamp[1] - edgeTimeStamp[0];
edgeTimeStamp[0] = edgeTimeStamp[1];
// Note that if state>=0, duration is always >= 1 period.
if (_state == -1) {
// wait for the long low part of a stop bit.
// Stopbit: 1T high, 40T low
// By default 1T is 260µs, but for maximum compatibility go as low as 120µs
if (duration > 4800) { // =40*120µs, minimal time between two edges before decoding starts.
// Sync signal received.. Preparing for decoding
repeats = 0;
receivedCode.period = duration / 40; // Measured signal is 40T, so 1T (period) is measured signal / 40.
// Allow for large error-margin. ElCheapo-hardware :(
min1Period = receivedCode.period * 3 / 10; // Lower limit for 1 period is 0.3 times measured period; high signals can "linger" a bit sometimes, making low signals quite short.
max1Period = receivedCode.period * 3; // Upper limit for 1 period is 3 times measured period
min5Period = receivedCode.period * 3; // Lower limit for 5 periods is 3 times measured period
max5Period = receivedCode.period * 8; // Upper limit for 5 periods is 8 times measured period
}
else {
return;
}
} else if (_state == 0) { // Verify start bit part 1 of 2
// Duration must be ~1T
if (duration > max1Period) {
_state = -1;
return;
}
// Start-bit passed. Do some clean-up.
receivedCode.address = receivedCode.unit = receivedCode.dimLevel = 0;
} else if (_state == 1) { // Verify start bit part 2 of 2
// Duration must be ~10.44T
if (duration < 7 * receivedCode.period || duration > 15 * receivedCode.period) {
_state = -1;
return;
}
} else if (_state < 148) { // state 146 is first edge of stop-sequence. All bits before that adhere to default protocol, with exception of dim-bit
receivedBit <<= 1;
// One bit consists out of 4 bit parts.
// bit part durations can ONLY be 1 or 5 periods.
if (duration <= max1Period) {
receivedBit &= B1110; // Clear LSB of receivedBit
} else if (duration >= min5Period && duration <= max5Period) {
receivedBit |= B1; // Set LSB of receivedBit
} else if (
// Check if duration matches the second part of stopbit (duration must be ~40T), and ...
(duration >= 20 * receivedCode.period && duration <= 80 * receivedCode.period) &&
// if first part op stopbit was a short signal (short signal yielded a 0 as second bit in receivedBit), and ...
((receivedBit & B10) == B00) &&
// we are in a state in which a stopbit is actually valid, only then ...
(_state == 147 || _state == 131) ) {
// If a dim-level was present...
if (_state == 147) {
// ... test if it was an "on" signal ...
if (receivedCode.switchType == NewRemoteCode::on) {
// ... set the appropriate switch type
receivedCode.switchType = NewRemoteCode::on_with_dim;
} else {
// ... otherwise it was wrong (e.g. off-signal with dim)
_state = -1;
return;
}
}
// a valid signal was found!
if (
receivedCode.address != previousCode.address ||
receivedCode.unit != previousCode.unit ||
receivedCode.dimLevel != previousCode.dimLevel ||
receivedCode.groupBit != previousCode.groupBit ||
receivedCode.switchType != previousCode.switchType
) { // memcmp isn't deemed safe
repeats=0;
previousCode = receivedCode;
}
repeats++;
if (repeats>=_minRepeats) {
if (!_inCallback) {
_inCallback = true;
(_callback)(receivedCode);
_inCallback = false;
}
// Reset after callback.
_state=-1;
return;
}
// Reset for next round
_state=0; // no need to wait for another sync-bit!
return;
}
else { // Otherwise the entire sequence is invalid
_state = -1;
return;
}
if (_state % 4 == 1) { // Last bit part? Note: this is the short version of "if ( (_state-2) % 4 == 3 )"
// There are 3 valid options for receivedBit:
// 0, indicated by short short short long == B0001.
// 1, short long shot short == B0100.
// dim, short shot short shot == B0000.
// Everything else: inconsistent data, trash the whole sequence.
if (_state < 106) {
// States 2 - 105 are address bit states
receivedCode.address <<= 1;
// Decode bit. Only 4 LSB's of receivedBit are used; trim the rest.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
// receivedCode.address |= 0; But let's not do that, as it is wasteful.
break;
case B0100: // Bit "1" received.
receivedCode.address |= 1;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 110) {
// States 106 - 109 are group bit states.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
receivedCode.groupBit = false;
break;
case B0100: // Bit "1" received.
receivedCode.groupBit = true;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 114) {
// States 110 - 113 are switch bit states.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
receivedCode.switchType = NewRemoteCode::off;
break;
case B0100: // Bit "1" received. Note: this might turn out to be a on_with_dim signal.
receivedCode.switchType = NewRemoteCode::on;
break;
case B0000: // Bit "dim" received.
receivedCode.switchType = NewRemoteCode::dim;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 130){
// States 114 - 129 are unit bit states.
receivedCode.unit <<= 1;
// Decode bit.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
// receivedCode.unit |= 0; But let's not do that, as it is wasteful.
break;
case B0100: // Bit "1" received.
receivedCode.unit |= 1;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 146) {
// States 130 - 145 are dim bit states.
// If switchType == 0 these are never present.
// If switchType == 2 these are always present.
// If switchType == 1 these are or are not present, depending on the revision of the transmitter.
receivedCode.dimLevel <<= 1;
// Decode bit.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
// receivedCode.dimLevel |= 0; But let's not do that, as it is wasteful.
break;
case B0100: // Bit "1" received.
receivedCode.dimLevel |= 1;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
}
}
}
_state++;
return;
}
boolean NewRemoteReceiver::isReceiving(int waitMillis) {
unsigned long startTime=millis();
int waited; // Signed int!
do {
if (_state >= 34) { // Abort if a significant part of a code (start pulse + 8 bits) has been received
return true;
}
waited = (millis()-startTime);
} while(waited>=0 && waited <= waitMillis); // Yes, clock wraps every 50 days. And then you'd have to wait for a looooong time.
return false;
}
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
* See NewRemoteReceiver.h for details.
*
* License: GPLv3. See license.txt
*/
#include "NewRemoteReceiver.h"
/************
* NewRemoteReceiver
Protocol. (Copied from Wieltje, http://www.circuitsonline.net/forum/view/message/1181410#1181410,
but with slightly different timings, as measured on my device.)
_ _
'0': | |_| |_____ (T,T,T,5T)
_ _
'1': | |_____| |_ (T,5T,T,T)
_ _
dim: | |_| |_ (T,T,T,T)
T = short period of ~260µs. However, this code tries
to figure out the correct period
A full frame looks like this:
- start pulse: 1T high, 10.44T low
- 26 bit: Address
- 1 bit: group bit
- 1 bit: on/off/[dim]
- 4 bit: unit
- [4 bit: dim level. Only present of [dim] is chosen]
- stop pulse: 1T high, 40T low
************/
int8_t NewRemoteReceiver::_interrupt;
volatile short NewRemoteReceiver::_state;
byte NewRemoteReceiver::_minRepeats;
NewRemoteReceiverCallBack NewRemoteReceiver::_callback;
boolean NewRemoteReceiver::_inCallback = false;
boolean NewRemoteReceiver::_enabled = false;
void NewRemoteReceiver::init(int8_t interrupt, byte minRepeats, NewRemoteReceiverCallBack callback) {
_interrupt = interrupt;
_minRepeats = minRepeats;
_callback = callback;
enable();
if (_interrupt >= 0) {
attachInterrupt(_interrupt, interruptHandler, CHANGE);
}
}
void NewRemoteReceiver::enable() {
_state = -1;
_enabled = true;
}
void NewRemoteReceiver::disable() {
_enabled = false;
}
void NewRemoteReceiver::deinit() {
_enabled = false;
if (_interrupt >= 0) {
detachInterrupt(_interrupt);
}
}
void NewRemoteReceiver::interruptHandler() {
// This method is written as compact code to keep it fast. While breaking up this method into more
// methods would certainly increase the readability, it would also be much slower to execute.
// Making calls to other methods is quite expensive on AVR. As These interrupt handlers are called
// many times a second, calling other methods should be kept to a minimum.
if (!_enabled) {
return;
}
static byte receivedBit; // Contains "bit" currently receiving
static NewRemoteCode receivedCode; // Contains received code
static NewRemoteCode previousCode; // Contains previous received code
static byte repeats = 0; // The number of times the an identical code is received in a row.
static unsigned long edgeTimeStamp[3] = {0, }; // Timestamp of edges
static unsigned int min1Period, max1Period, min5Period, max5Period;
static bool skip;
// Filter out too short pulses. This method works as a low pass filter.
edgeTimeStamp[1] = edgeTimeStamp[2];
edgeTimeStamp[2] = micros();
if (skip) {
skip = false;
return;
}
if (_state >= 0 && edgeTimeStamp[2]-edgeTimeStamp[1] < min1Period) {
// Last edge was too short.
// Skip this edge, and the next too.
skip = true;
return;
}
unsigned int duration = edgeTimeStamp[1] - edgeTimeStamp[0];
edgeTimeStamp[0] = edgeTimeStamp[1];
// Note that if state>=0, duration is always >= 1 period.
if (_state == -1) {
// wait for the long low part of a stop bit.
// Stopbit: 1T high, 40T low
// By default 1T is 260µs, but for maximum compatibility go as low as 120µs
if (duration > 4800) { // =40*120µs, minimal time between two edges before decoding starts.
// Sync signal received.. Preparing for decoding
repeats = 0;
receivedCode.period = duration / 40; // Measured signal is 40T, so 1T (period) is measured signal / 40.
// Allow for large error-margin. ElCheapo-hardware :(
min1Period = receivedCode.period * 3 / 10; // Lower limit for 1 period is 0.3 times measured period; high signals can "linger" a bit sometimes, making low signals quite short.
max1Period = receivedCode.period * 3; // Upper limit for 1 period is 3 times measured period
min5Period = receivedCode.period * 3; // Lower limit for 5 periods is 3 times measured period
max5Period = receivedCode.period * 8; // Upper limit for 5 periods is 8 times measured period
}
else {
return;
}
} else if (_state == 0) { // Verify start bit part 1 of 2
// Duration must be ~1T
if (duration > max1Period) {
_state = -1;
return;
}
// Start-bit passed. Do some clean-up.
receivedCode.address = receivedCode.unit = receivedCode.dimLevel = 0;
} else if (_state == 1) { // Verify start bit part 2 of 2
// Duration must be ~10.44T
if (duration < 7 * receivedCode.period || duration > 15 * receivedCode.period) {
_state = -1;
return;
}
} else if (_state < 148) { // state 146 is first edge of stop-sequence. All bits before that adhere to default protocol, with exception of dim-bit
receivedBit <<= 1;
// One bit consists out of 4 bit parts.
// bit part durations can ONLY be 1 or 5 periods.
if (duration <= max1Period) {
receivedBit &= B1110; // Clear LSB of receivedBit
} else if (duration >= min5Period && duration <= max5Period) {
receivedBit |= B1; // Set LSB of receivedBit
} else if (
// Check if duration matches the second part of stopbit (duration must be ~40T), and ...
(duration >= 20 * receivedCode.period && duration <= 80 * receivedCode.period) &&
// if first part op stopbit was a short signal (short signal yielded a 0 as second bit in receivedBit), and ...
((receivedBit & B10) == B00) &&
// we are in a state in which a stopbit is actually valid, only then ...
(_state == 147 || _state == 131) ) {
// If a dim-level was present...
if (_state == 147) {
// ... test if it was an "on" signal ...
if (receivedCode.switchType == NewRemoteCode::on) {
// ... set the appropriate switch type
receivedCode.switchType = NewRemoteCode::on_with_dim;
} else {
// ... otherwise it was wrong (e.g. off-signal with dim)
_state = -1;
return;
}
}
// a valid signal was found!
if (
receivedCode.address != previousCode.address ||
receivedCode.unit != previousCode.unit ||
receivedCode.dimLevel != previousCode.dimLevel ||
receivedCode.groupBit != previousCode.groupBit ||
receivedCode.switchType != previousCode.switchType
) { // memcmp isn't deemed safe
repeats=0;
previousCode = receivedCode;
}
repeats++;
if (repeats>=_minRepeats) {
if (!_inCallback) {
_inCallback = true;
(_callback)(receivedCode);
_inCallback = false;
}
// Reset after callback.
_state=-1;
return;
}
// Reset for next round
_state=0; // no need to wait for another sync-bit!
return;
}
else { // Otherwise the entire sequence is invalid
_state = -1;
return;
}
if (_state % 4 == 1) { // Last bit part? Note: this is the short version of "if ( (_state-2) % 4 == 3 )"
// There are 3 valid options for receivedBit:
// 0, indicated by short short short long == B0001.
// 1, short long shot short == B0100.
// dim, short shot short shot == B0000.
// Everything else: inconsistent data, trash the whole sequence.
if (_state < 106) {
// States 2 - 105 are address bit states
receivedCode.address <<= 1;
// Decode bit. Only 4 LSB's of receivedBit are used; trim the rest.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
// receivedCode.address |= 0; But let's not do that, as it is wasteful.
break;
case B0100: // Bit "1" received.
receivedCode.address |= 1;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 110) {
// States 106 - 109 are group bit states.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
receivedCode.groupBit = false;
break;
case B0100: // Bit "1" received.
receivedCode.groupBit = true;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 114) {
// States 110 - 113 are switch bit states.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
receivedCode.switchType = NewRemoteCode::off;
break;
case B0100: // Bit "1" received. Note: this might turn out to be a on_with_dim signal.
receivedCode.switchType = NewRemoteCode::on;
break;
case B0000: // Bit "dim" received.
receivedCode.switchType = NewRemoteCode::dim;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 130){
// States 114 - 129 are unit bit states.
receivedCode.unit <<= 1;
// Decode bit.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
// receivedCode.unit |= 0; But let's not do that, as it is wasteful.
break;
case B0100: // Bit "1" received.
receivedCode.unit |= 1;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
} else if (_state < 146) {
// States 130 - 145 are dim bit states.
// If switchType == 0 these are never present.
// If switchType == 2 these are always present.
// If switchType == 1 these are or are not present, depending on the revision of the transmitter.
receivedCode.dimLevel <<= 1;
// Decode bit.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
// receivedCode.dimLevel |= 0; But let's not do that, as it is wasteful.
break;
case B0100: // Bit "1" received.
receivedCode.dimLevel |= 1;
break;
default: // Bit was invalid. Abort.
_state = -1;
return;
}
}
}
}
_state++;
return;
}
boolean NewRemoteReceiver::isReceiving(int waitMillis) {
unsigned long startTime=millis();
int waited; // Signed int!
do {
if (_state >= 34) { // Abort if a significant part of a code (start pulse + 8 bits) has been received
return true;
}
waited = (millis()-startTime);
} while(waited>=0 && waited <= waitMillis); // Yes, clock wraps every 50 days. And then you'd have to wait for a looooong time.
return false;
}
+107 -107
View File
@@ -1,107 +1,107 @@
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
*
* License: GPLv3. See license.txt
*/
#ifndef NewRemoteReceiver_h
#define NewRemoteReceiver_h
#include <Arduino.h>
struct NewRemoteCode {
enum SwitchType {
off = 0,
on = 1,
dim = 2,
on_with_dim = 3
};
unsigned int period; // Detected duration in microseconds of 1T in the received signal
unsigned long address; // Address of received code. [0..2^26-1]
boolean groupBit; // Group bit set or not
SwitchType switchType; // off, on, dim, on_with_dim.
byte unit; // Unit code of received code [0..15]
byte dimLevel; // Dim level [0..15] iff switchType == 2
};
typedef void (*NewRemoteReceiverCallBack)(NewRemoteCode);
/**
* See RemoteSwitch for introduction.
*
* NewRemoteReceiver decodes the signal received from a 433MHz-receiver, like the "KlikAanKlikUit"-system
* as well as the signal sent by the RemoteSwtich class. When a correct signal is received,
* a user-defined callback function is called.
*
* Note that in the callback function, the interrupts are still disabled. You can enabled them, if needed.
* A call to the callback must be finished before NewRemoteReceiver will call the callback function again, thus
* there is no re-entrant problem.
*
* When sending your own code using NewRemoteSwich, disable() the receiver first.
*
* This is a pure static class, for simplicity and to limit memory-use.
*/
class NewRemoteReceiver {
public:
/**
* Initializes the decoder.
*
* If interrupt >= 0, init will register pin <interrupt> to this library.
* If interrupt < 0, no interrupt is registered. In that case, you have to call interruptHandler()
* yourself whenever the output of the receiver changes, or you can use InterruptChain.
*
* @param interrupt The interrupt as is used by Arduino's attachInterrupt function. See attachInterrupt for details.
If < 0, you must call interruptHandler() yourself.
* @param minRepeats The number of times the same code must be received in a row before the callback is calles
* @param callback Pointer to a callback function, with signature void (*func)(NewRemoteCode)
*/
static void init(int8_t interrupt, byte minRepeats, NewRemoteReceiverCallBack callback);
/**
* Enable decoding. No need to call enable() after init().
*/
static void enable();
/**
* Disable decoding. You can re-enable decoding by calling enable();
*/
static void disable();
/**
* Deinitializes the decoder. Disables decoding and detaches the interrupt handler. If you want to
* re-enable decoding, call init() again.
*/
static void deinit();
/**
* Tells wether a signal is being received. If a compatible signal is detected within the time out, isReceiving returns true.
* Since it makes no sense to transmit while another transmitter is active, it's best to wait for isReceiving() to false.
* By default it waits for 150ms, in which a (relative slow) KaKu signal can be broadcasted three times.
*
* Note: isReceiving() depends on interrupts enabled. Thus, when disabled()'ed, or when interrupts are disabled (as is
* the case in the callback), isReceiving() will not work properly.
*
* @param waitMillis number of milliseconds to monitor for signal.
* @return boolean If after waitMillis no signal was being processed, returns false. If before expiration a signal was being processed, returns true.
*/
static boolean isReceiving(int waitMillis = 150);
/**
* Called every time the signal level changes (high to low or vice versa). Usually called by interrupt.
*/
static void interruptHandler();
private:
static int8_t _interrupt; // Radio input interrupt
volatile static short _state; // State of decoding process.
static byte _minRepeats;
static NewRemoteReceiverCallBack _callback;
static boolean _inCallback; // When true, the callback function is being executed; prevents re-entrance.
static boolean _enabled; // If true, monitoring and decoding is enabled. If false, interruptHandler will return immediately.
};
#endif
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
*
* License: GPLv3. See license.txt
*/
#ifndef NewRemoteReceiver_h
#define NewRemoteReceiver_h
#include <Arduino.h>
struct NewRemoteCode {
enum SwitchType {
off = 0,
on = 1,
dim = 2,
on_with_dim = 3
};
unsigned int period; // Detected duration in microseconds of 1T in the received signal
unsigned long address; // Address of received code. [0..2^26-1]
boolean groupBit; // Group bit set or not
SwitchType switchType; // off, on, dim, on_with_dim.
byte unit; // Unit code of received code [0..15]
byte dimLevel; // Dim level [0..15] iff switchType == 2
};
typedef void (*NewRemoteReceiverCallBack)(NewRemoteCode);
/**
* See RemoteSwitch for introduction.
*
* NewRemoteReceiver decodes the signal received from a 433MHz-receiver, like the "KlikAanKlikUit"-system
* as well as the signal sent by the RemoteSwtich class. When a correct signal is received,
* a user-defined callback function is called.
*
* Note that in the callback function, the interrupts are still disabled. You can enabled them, if needed.
* A call to the callback must be finished before NewRemoteReceiver will call the callback function again, thus
* there is no re-entrant problem.
*
* When sending your own code using NewRemoteSwich, disable() the receiver first.
*
* This is a pure static class, for simplicity and to limit memory-use.
*/
class NewRemoteReceiver {
public:
/**
* Initializes the decoder.
*
* If interrupt >= 0, init will register pin <interrupt> to this library.
* If interrupt < 0, no interrupt is registered. In that case, you have to call interruptHandler()
* yourself whenever the output of the receiver changes, or you can use InterruptChain.
*
* @param interrupt The interrupt as is used by Arduino's attachInterrupt function. See attachInterrupt for details.
If < 0, you must call interruptHandler() yourself.
* @param minRepeats The number of times the same code must be received in a row before the callback is calles
* @param callback Pointer to a callback function, with signature void (*func)(NewRemoteCode)
*/
static void init(int8_t interrupt, byte minRepeats, NewRemoteReceiverCallBack callback);
/**
* Enable decoding. No need to call enable() after init().
*/
static void enable();
/**
* Disable decoding. You can re-enable decoding by calling enable();
*/
static void disable();
/**
* Deinitializes the decoder. Disables decoding and detaches the interrupt handler. If you want to
* re-enable decoding, call init() again.
*/
static void deinit();
/**
* Tells wether a signal is being received. If a compatible signal is detected within the time out, isReceiving returns true.
* Since it makes no sense to transmit while another transmitter is active, it's best to wait for isReceiving() to false.
* By default it waits for 150ms, in which a (relative slow) KaKu signal can be broadcasted three times.
*
* Note: isReceiving() depends on interrupts enabled. Thus, when disabled()'ed, or when interrupts are disabled (as is
* the case in the callback), isReceiving() will not work properly.
*
* @param waitMillis number of milliseconds to monitor for signal.
* @return boolean If after waitMillis no signal was being processed, returns false. If before expiration a signal was being processed, returns true.
*/
static boolean isReceiving(int waitMillis = 150);
/**
* Called every time the signal level changes (high to low or vice versa). Usually called by interrupt.
*/
static void interruptHandler();
private:
static int8_t _interrupt; // Radio input interrupt
volatile static short _state; // State of decoding process.
static byte _minRepeats;
static NewRemoteReceiverCallBack _callback;
static boolean _inCallback; // When true, the callback function is being executed; prevents re-entrance.
static boolean _enabled; // If true, monitoring and decoding is enabled. If false, interruptHandler will return immediately.
};
#endif
+134 -134
View File
@@ -1,134 +1,134 @@
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
* See NewRemoteTransmitter.h for details.
*
* License: GPLv3. See license.txt
*/
#include "NewRemoteTransmitter.h"
NewRemoteTransmitter::NewRemoteTransmitter(unsigned long address, byte pin, unsigned int periodusec, byte repeats) {
_address = address;
_pin = pin;
_periodusec = periodusec;
_repeats = (1 << repeats) - 1; // I.e. _repeats = 2^repeats - 1
pinMode(_pin, OUTPUT);
}
void NewRemoteTransmitter::sendGroup(boolean switchOn) {
for (int8_t i = _repeats; i >= 0; i--) {
_sendStartPulse();
_sendAddress();
// Do send group bit
_sendBit(true);
// Switch on | off
_sendBit(switchOn);
// No unit. Is this actually ignored?..
_sendUnit(0);
_sendStopPulse();
}
}
void NewRemoteTransmitter::sendUnit(byte unit, boolean switchOn) {
for (int8_t i = _repeats; i >= 0; i--) {
_sendStartPulse();
_sendAddress();
// No group bit
_sendBit(false);
// Switch on | off
_sendBit(switchOn);
_sendUnit(unit);
_sendStopPulse();
}
}
void NewRemoteTransmitter::sendDim(byte unit, byte dimLevel) {
for (int8_t i = _repeats; i >= 0; i--) {
_sendStartPulse();
_sendAddress();
// No group bit
_sendBit(false);
// Switch type 'dim'
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
_sendUnit(unit);
for (int8_t j=3; j>=0; j--) {
_sendBit(dimLevel & 1<<j);
}
_sendStopPulse();
}
}
void NewRemoteTransmitter::_sendStartPulse(){
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 10 + (_periodusec >> 1)); // Actually 10.5T insteat of 10.44T. Close enough.
}
void NewRemoteTransmitter::_sendAddress() {
for (int8_t i=25; i>=0; i--) {
_sendBit((_address >> i) & 1);
}
}
void NewRemoteTransmitter::_sendUnit(byte unit) {
for (int8_t i=3; i>=0; i--) {
_sendBit(unit & 1<<i);
}
}
void NewRemoteTransmitter::_sendStopPulse() {
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 40);
}
void NewRemoteTransmitter::_sendBit(boolean isBitOne) {
if (isBitOne) {
// Send '1'
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 5);
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
} else {
// Send '0'
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 5);
}
}
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
* See NewRemoteTransmitter.h for details.
*
* License: GPLv3. See license.txt
*/
#include "NewRemoteTransmitter.h"
NewRemoteTransmitter::NewRemoteTransmitter(unsigned long address, byte pin, unsigned int periodusec, byte repeats) {
_address = address;
_pin = pin;
_periodusec = periodusec;
_repeats = (1 << repeats) - 1; // I.e. _repeats = 2^repeats - 1
pinMode(_pin, OUTPUT);
}
void NewRemoteTransmitter::sendGroup(boolean switchOn) {
for (int8_t i = _repeats; i >= 0; i--) {
_sendStartPulse();
_sendAddress();
// Do send group bit
_sendBit(true);
// Switch on | off
_sendBit(switchOn);
// No unit. Is this actually ignored?..
_sendUnit(0);
_sendStopPulse();
}
}
void NewRemoteTransmitter::sendUnit(byte unit, boolean switchOn) {
for (int8_t i = _repeats; i >= 0; i--) {
_sendStartPulse();
_sendAddress();
// No group bit
_sendBit(false);
// Switch on | off
_sendBit(switchOn);
_sendUnit(unit);
_sendStopPulse();
}
}
void NewRemoteTransmitter::sendDim(byte unit, byte dimLevel) {
for (int8_t i = _repeats; i >= 0; i--) {
_sendStartPulse();
_sendAddress();
// No group bit
_sendBit(false);
// Switch type 'dim'
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
_sendUnit(unit);
for (int8_t j=3; j>=0; j--) {
_sendBit(dimLevel & 1<<j);
}
_sendStopPulse();
}
}
void NewRemoteTransmitter::_sendStartPulse(){
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 10 + (_periodusec >> 1)); // Actually 10.5T insteat of 10.44T. Close enough.
}
void NewRemoteTransmitter::_sendAddress() {
for (int8_t i=25; i>=0; i--) {
_sendBit((_address >> i) & 1);
}
}
void NewRemoteTransmitter::_sendUnit(byte unit) {
for (int8_t i=3; i>=0; i--) {
_sendBit(unit & 1<<i);
}
}
void NewRemoteTransmitter::_sendStopPulse() {
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 40);
}
void NewRemoteTransmitter::_sendBit(boolean isBitOne) {
if (isBitOne) {
// Send '1'
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 5);
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
} else {
// Send '0'
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec);
digitalWrite(_pin, HIGH);
delayMicroseconds(_periodusec);
digitalWrite(_pin, LOW);
delayMicroseconds(_periodusec * 5);
}
}
+103 -103
View File
@@ -1,103 +1,103 @@
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
*
* License: GPLv3. See license.txt
*/
#ifndef NewRemoteTransmitter_h
#define NewRemoteTransmitter_h
#include <Arduino.h>
/**
* NewRemoteTransmitter provides a generic class for simulation of common RF remote controls, like the A-series
* 'Klik aan Klik uit'-system (http://www.klikaanklikuit.nl/), used to remotely switch lights etc.
*
* This class is meant for new-style remotes, usually accompanied by receivers with "code learning"
* capabilities. For other remotes, use the RemoteTransmitter class.
*
* Hardware required for this library: a 433MHz/434MHz SAW oscillator transmitter, e.g.
* http://www.sparkfun.com/products/10534
* http://www.conrad.nl/goto/?product=130428
*
* Notes:
* - I measured the period length with an oscilloscope, using a A-series KAKU transmitter. Other devices
* or manufacturers may use other period length. Use the ShowReceivedCodeNewRemote example to find the
* period length for your devices.
* - You can copy the address of your "real" remotes, so you won't have to learn new codes into the receivers.
* In effect this duplicates a remote. But you can also pick a random number in the range 0..2^26-1.
*/
class NewRemoteTransmitter {
public:
/**
* Constructor.
*
* To obtain the correct period length, use the ShowReceivedCodeNewRemote example, or you
* can use an oscilloscope.
*
* @param address Address of this transmitter [0..2^26-1] Duplicate the address of your hardware, or choose a random number.
* @param pin Output pin on Arduino to which the transmitter is connected
* @param periodusec Duration of one period, in microseconds. One bit takes 8 periods (but only 4 for 'dim' signal).
* @param repeats [0..8] The 2log-Number of times the signal is repeated. The actual number of repeats will be 2^repeats. 2 would be bare minimum, 4 seems robust, 8 is maximum (and overkill).
*/
NewRemoteTransmitter(unsigned long address, byte pin, unsigned int periodusec = 260, byte repeats = 4);
/**
* Send on/off command to the address group.
*
* @param switchOn True to send "on" signal, false to send "off" signal.
*/
void sendGroup(boolean switchOn);
/**
* Send on/off command to an unit on the current address.
*
* @param unit [0..15] target unit.
* @param switchOn True to send "on" signal, false to send "off" signal.
*/
void sendUnit(byte unit, boolean switchOn);
/**
* Send dim value to an unit on the current address.
*
* @param unit [0..15] target unit.
* @param dimLevel [0..15] Dim level. 0 for off, 15 for brightest level.
*/
void sendDim(byte unit, byte dimLevel);
protected:
unsigned long _address; // Address of this transmitter.
byte _pin; // Transmitter output pin
unsigned int _periodusec; // Oscillator period in microseconds
byte _repeats; // Number over repetitions of one telegram
/**
* Transmits start-pulse
*/
void _sendStartPulse();
/**
* Transmits address part
*/
void _sendAddress();
/**
* Transmits unit part.
*
* @param unit [0-15] target unit.
*/
void _sendUnit(byte unit);
/**
* Transmits stop pulse.
*/
void _sendStopPulse();
/**
* Transmits a single bit.
*
* @param isBitOne True, to send '1', false to send '0'.
*/
void _sendBit(boolean isBitOne);
};
#endif
/*
* NewRemoteSwitch library v1.1.0 (20130601) made by Randy Simons http://randysimons.nl/
*
* License: GPLv3. See license.txt
*/
#ifndef NewRemoteTransmitter_h
#define NewRemoteTransmitter_h
#include <Arduino.h>
/**
* NewRemoteTransmitter provides a generic class for simulation of common RF remote controls, like the A-series
* 'Klik aan Klik uit'-system (http://www.klikaanklikuit.nl/), used to remotely switch lights etc.
*
* This class is meant for new-style remotes, usually accompanied by receivers with "code learning"
* capabilities. For other remotes, use the RemoteTransmitter class.
*
* Hardware required for this library: a 433MHz/434MHz SAW oscillator transmitter, e.g.
* http://www.sparkfun.com/products/10534
* http://www.conrad.nl/goto/?product=130428
*
* Notes:
* - I measured the period length with an oscilloscope, using a A-series KAKU transmitter. Other devices
* or manufacturers may use other period length. Use the ShowReceivedCodeNewRemote example to find the
* period length for your devices.
* - You can copy the address of your "real" remotes, so you won't have to learn new codes into the receivers.
* In effect this duplicates a remote. But you can also pick a random number in the range 0..2^26-1.
*/
class NewRemoteTransmitter {
public:
/**
* Constructor.
*
* To obtain the correct period length, use the ShowReceivedCodeNewRemote example, or you
* can use an oscilloscope.
*
* @param address Address of this transmitter [0..2^26-1] Duplicate the address of your hardware, or choose a random number.
* @param pin Output pin on Arduino to which the transmitter is connected
* @param periodusec Duration of one period, in microseconds. One bit takes 8 periods (but only 4 for 'dim' signal).
* @param repeats [0..8] The 2log-Number of times the signal is repeated. The actual number of repeats will be 2^repeats. 2 would be bare minimum, 4 seems robust, 8 is maximum (and overkill).
*/
NewRemoteTransmitter(unsigned long address, byte pin, unsigned int periodusec = 260, byte repeats = 4);
/**
* Send on/off command to the address group.
*
* @param switchOn True to send "on" signal, false to send "off" signal.
*/
void sendGroup(boolean switchOn);
/**
* Send on/off command to an unit on the current address.
*
* @param unit [0..15] target unit.
* @param switchOn True to send "on" signal, false to send "off" signal.
*/
void sendUnit(byte unit, boolean switchOn);
/**
* Send dim value to an unit on the current address.
*
* @param unit [0..15] target unit.
* @param dimLevel [0..15] Dim level. 0 for off, 15 for brightest level.
*/
void sendDim(byte unit, byte dimLevel);
protected:
unsigned long _address; // Address of this transmitter.
byte _pin; // Transmitter output pin
unsigned int _periodusec; // Oscillator period in microseconds
byte _repeats; // Number over repetitions of one telegram
/**
* Transmits start-pulse
*/
void _sendStartPulse();
/**
* Transmits address part
*/
void _sendAddress();
/**
* Transmits unit part.
*
* @param unit [0-15] target unit.
*/
void _sendUnit(byte unit);
/**
* Transmits stop pulse.
*/
void _sendStopPulse();
/**
* Transmits a single bit.
*
* @param isBitOne True, to send '1', false to send '0'.
*/
void _sendBit(boolean isBitOne);
};
#endif
+48 -48
View File
@@ -1,48 +1,48 @@
NewRemoteSwitch library v1.1.0 (BETA) for Arduino 1.0
Made by Randy Simons http://randysimons.nl/
This library provides an easy class for Arduino, to send and receive signals
used by some common "new style" 433MHz remote control switches.
There are two styles of remote:
- "old style", which uses switches or a dial to set the house code. Use the
RemoteSwitch library instead.
- "new style", which use a button on the receivers to "learn" a signal. Use
this library.
License: GPLv3. See ./NewRemoteSwitch/license.txt
Latest source and wiki: https://bitbucket.org/fuzzillogic/433mhzforarduino
Installation of library:
- Make sure Arduino is closed
- Copy the directory NewRemoteSwitch to the Arduino library directory (usually
<Sketchbook directory>/libraries/)
See http://arduino.cc/en/Guide/Libraries for detailed instructions.
Default installation demo:
- Connect the data-out-pin of a 433MHz receiver to digital pin 2. See photo.
(Note: your hardware may have a different pin configuration!)
- Start Arduino, and open the example: File -> Examples -> NewRemoteSwitch ->
ShowReceivedCode or ShowReceivedCodeNewRemote.
- Compile, upload and run
- Open serial monitor in Arduino (115200 baud)
- Press buttons on a 433MHz-remote, and watch the serial monitor
Changelog:
NewRemoteSwitch library v1.1.0 (20130601) for Arduino 1.0
- BUGFIX: in many occasions, when receiving a dim-level, the code was rejected
even if the signal was correct.
- Support decoding A-series transmitters which transmit a dim-level in
combination with an on-signal, instead of a dim-signal.
- Uses NewRemodeCode::on, ::off, ::dim, ::on_with_dim instead of 0, 1, 2 and 3,
for better readability. This change is backwards compatible.
- Updated examples to use the new NewRemodeCode::on, ::off, ::dim and
::on_with_dim notation.
- Reduced memory usage (Flash, RAM)
NewRemoteSwitch library v1.0.0 (20121229) for Arduino 1.0
- Support for receiving A-series Klik-aan-klik-uit remote. (NewRemoteReceiver)
- With examples to test and demonstrate.
NewRemoteSwitch library v1.1.0 (BETA) for Arduino 1.0
Made by Randy Simons http://randysimons.nl/
This library provides an easy class for Arduino, to send and receive signals
used by some common "new style" 433MHz remote control switches.
There are two styles of remote:
- "old style", which uses switches or a dial to set the house code. Use the
RemoteSwitch library instead.
- "new style", which use a button on the receivers to "learn" a signal. Use
this library.
License: GPLv3. See ./NewRemoteSwitch/license.txt
Latest source and wiki: https://bitbucket.org/fuzzillogic/433mhzforarduino
Installation of library:
- Make sure Arduino is closed
- Copy the directory NewRemoteSwitch to the Arduino library directory (usually
<Sketchbook directory>/libraries/)
See http://arduino.cc/en/Guide/Libraries for detailed instructions.
Default installation demo:
- Connect the data-out-pin of a 433MHz receiver to digital pin 2. See photo.
(Note: your hardware may have a different pin configuration!)
- Start Arduino, and open the example: File -> Examples -> NewRemoteSwitch ->
ShowReceivedCode or ShowReceivedCodeNewRemote.
- Compile, upload and run
- Open serial monitor in Arduino (115200 baud)
- Press buttons on a 433MHz-remote, and watch the serial monitor
Changelog:
NewRemoteSwitch library v1.1.0 (20130601) for Arduino 1.0
- BUGFIX: in many occasions, when receiving a dim-level, the code was rejected
even if the signal was correct.
- Support decoding A-series transmitters which transmit a dim-level in
combination with an on-signal, instead of a dim-signal.
- Uses NewRemodeCode::on, ::off, ::dim, ::on_with_dim instead of 0, 1, 2 and 3,
for better readability. This change is backwards compatible.
- Updated examples to use the new NewRemodeCode::on, ::off, ::dim and
::on_with_dim notation.
- Reduced memory usage (Flash, RAM)
NewRemoteSwitch library v1.0.0 (20121229) for Arduino 1.0
- Support for receiving A-series Klik-aan-klik-uit remote. (NewRemoteReceiver)
- With examples to test and demonstrate.
@@ -1,23 +1,23 @@
= Protocol of klikaanklikuit A-series devices =
Copied from Wieltje, http://www.circuitsonline.net/forum/view/message/1181410#1181410,
but with slightly different timings, as measured on my device.
_ _
'0': | |_| |_____ (T,T,T,5T)
_ _
'1': | |_____| |_ (T,5T,T,T)
_ _
'dim': | |_| |_ (T,T,T,T)
T = short period of ~260µs. Use the ShowReceivedCodeNewRemote example to find the
actual period length for your devices.
A full frame looks like this:
- start pulse: 1T high, 10.44T low
- 26 bit: Address
- 1 bit: group bit
- 1 bit: on/off/[dim]
- 4 bit: unit
- [4 bit: dim level. Only present of [dim] is chosen]
= Protocol of klikaanklikuit A-series devices =
Copied from Wieltje, http://www.circuitsonline.net/forum/view/message/1181410#1181410,
but with slightly different timings, as measured on my device.
_ _
'0': | |_| |_____ (T,T,T,5T)
_ _
'1': | |_____| |_ (T,5T,T,T)
_ _
'dim': | |_| |_ (T,T,T,T)
T = short period of ~260µs. Use the ShowReceivedCodeNewRemote example to find the
actual period length for your devices.
A full frame looks like this:
- start pulse: 1T high, 10.44T low
- 26 bit: Address
- 1 bit: group bit
- 1 bit: on/off/[dim]
- 4 bit: unit
- [4 bit: dim level. Only present of [dim] is chosen]
- stop pulse: 1T high, 40T low
@@ -1,55 +1,55 @@
/**
* Demo for RF remote switch receiver.
* For details, see NewRemoteReceiver.h!
*
* Connect the transmitter to digital pin 11.
*
* This sketch demonstrates the use of the NewRemoteTransmitter class.
*
* When run, this sketch switches some pre-defined devices on and off in a loop.
*
* NOTE: the actual receivers have the address and group numbers in this example
* are only for demonstration! If you want to duplicate an existing remote, please
* try the "retransmitter"-example instead.
*
* To use this actual example, you'd need to "learn" the used code in the receivers
* This sketch is unsuited for that.
*
*/
#include <NewRemoteTransmitter.h>
// Create a transmitter on address 123, using digital pin 11 to transmit,
// with a period duration of 260ms (default), repeating the transmitted
// code 2^3=8 times.
NewRemoteTransmitter transmitter(123, 11, 260, 3);
void setup() {
}
void loop() {
// Switch unit 2 off
transmitter.sendUnit(2, false);
// Switch all devices in the group off
transmitter.sendGroup(false);
// Set unit 1 to dim-level 3 (range 0-15)
transmitter.sendDim(1, 3);
// Wait 5 seconds
delay(5000);
// Switch unit 2 on
transmitter.sendUnit(2, true);
// Switch all devices in the group on
transmitter.sendGroup(true);
// Set unit 1 to dim-level 15, full brightness.
transmitter.sendDim(1, 15);
// Wait 5 seconds
delay(5000);
}
/**
* Demo for RF remote switch receiver.
* For details, see NewRemoteReceiver.h!
*
* Connect the transmitter to digital pin 11.
*
* This sketch demonstrates the use of the NewRemoteTransmitter class.
*
* When run, this sketch switches some pre-defined devices on and off in a loop.
*
* NOTE: the actual receivers have the address and group numbers in this example
* are only for demonstration! If you want to duplicate an existing remote, please
* try the "retransmitter"-example instead.
*
* To use this actual example, you'd need to "learn" the used code in the receivers
* This sketch is unsuited for that.
*
*/
#include <NewRemoteTransmitter.h>
// Create a transmitter on address 123, using digital pin 11 to transmit,
// with a period duration of 260ms (default), repeating the transmitted
// code 2^3=8 times.
NewRemoteTransmitter transmitter(123, 11, 260, 3);
void setup() {
}
void loop() {
// Switch unit 2 off
transmitter.sendUnit(2, false);
// Switch all devices in the group off
transmitter.sendGroup(false);
// Set unit 1 to dim-level 3 (range 0-15)
transmitter.sendDim(1, 3);
// Wait 5 seconds
delay(5000);
// Switch unit 2 on
transmitter.sendUnit(2, true);
// Switch all devices in the group on
transmitter.sendGroup(true);
// Set unit 1 to dim-level 15, full brightness.
transmitter.sendDim(1, 15);
// Wait 5 seconds
delay(5000);
}
+10 -10
View File
@@ -1,11 +1,11 @@
NewRemoteReceiver KEYWORD1
NewRemoteCode KEYWORD1
isReceiving KEYWORD2
init KEYWORD2
enable KEYWORD2
disable KEYWORD2
deinit KEYWORD2
NewRemoteTransmitter KEYWORD1
sendGroup KEYWORD2
sendUnit KEYWORD2
NewRemoteReceiver KEYWORD1
NewRemoteCode KEYWORD1
isReceiving KEYWORD2
init KEYWORD2
enable KEYWORD2
disable KEYWORD2
deinit KEYWORD2
NewRemoteTransmitter KEYWORD1
sendGroup KEYWORD2
sendUnit KEYWORD2
sendDim KEYWORD2