fixed crlf for project
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user