* More code comments

* Added retransmitter example for NewRemoteSwitch
This commit is contained in:
randy
2012-04-21 22:12:50 +02:00
parent 1b67ccd25e
commit fb36e9e5c2
6 changed files with 151 additions and 57 deletions
@@ -175,10 +175,10 @@ void NewRemoteReceiver::interruptHandler() {
// States 106 - 109 are group bit states.
switch (receivedBit & B1111) {
case B0001: // Bit "0" received.
receivedCode.groupMode = false;
receivedCode.groupBit = false;
break;
case B0100: // Bit "1" received.
receivedCode.groupMode = true;
receivedCode.groupBit = true;
break;
default: // Bit was invalid. Abort.
_state = -1;
@@ -259,7 +259,7 @@ void NewRemoteReceiver::interruptHandler() {
receivedCode.address != previousCode.address ||
receivedCode.unit != previousCode.unit ||
receivedCode.dimLevel != previousCode.dimLevel ||
receivedCode.groupMode != previousCode.groupMode ||
receivedCode.groupBit != previousCode.groupBit ||
receivedCode.switchType != previousCode.switchType
) { // memcmp isn't deemed safe
repeats=0;
@@ -10,12 +10,12 @@
#include <Arduino.h>
struct NewRemoteCode {
unsigned int period;
unsigned long address;
boolean groupMode;
unsigned short switchType;
unsigned short unit;
unsigned short dimLevel;
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
unsigned short switchType; // 0: swich off; 1: switch on; 2: set dim level
unsigned short unit; // Unit code of received code [0..15]
unsigned short dimLevel; // Dim level [0..15] iff switchType == 2
};
typedef void (*NewRemoteReceiverCallBack)(NewRemoteCode);
@@ -28,63 +28,66 @@ typedef void (*NewRemoteReceiverCallBack)(NewRemoteCode);
* 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 b finished before NewRemoteReceiver will call the callback function again, thus
* 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 RemoteSwich, disable() the receiver first.
* 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)(unsigned long, bool, unsigned short, unsigned short, unsigned short)
*/
static void init(short interrupt, unsigned short minRepeats, NewRemoteReceiverCallBack callback);
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(short interrupt, unsigned short minRepeats, NewRemoteReceiverCallBack callback);
/**
* Enable decoding. No need to call enable() after init().
*/
static void enable();
/**
* 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();
/**
* Disable decoding. You can re-enable decoding by calling enable();
*/
static void disable();
/**
* 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);
/**
* 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);
static void interruptHandler();
/**
* Called every time the signal level changes (high to low or vice versa). Usually called by interrupt.
*/
static void interruptHandler();
private:
private:
static unsigned short _interrupt; // Radio input interrupt
volatile static unsigned short _state; // State of decoding process. There are 49 states, 1 for "waiting for signal" and 48 for decoding the 48 edges in a valid code.
static unsigned short _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.
static unsigned short _interrupt; // Radio input interrupt
volatile static unsigned short _state; // State of decoding process. There are 49 states, 1 for "waiting for signal" and 48 for decoding the 48 edges in a valid code.
static unsigned short _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.
};
@@ -42,10 +42,27 @@ class NewRemoteTransmitter {
*/
NewRemoteTransmitter(unsigned long address, unsigned short pin, unsigned int periodusec = 260, unsigned short 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(unsigned short 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(unsigned short unit, unsigned short dimLevel);
protected:
@@ -54,14 +71,33 @@ class NewRemoteTransmitter {
unsigned int _periodusec; // Oscillator period in microseconds
unsigned short _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(unsigned short 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
@@ -0,0 +1,52 @@
/*
* Demo for RF remote switch receiver.
* For details, see NewRemoteReceiver.h!
*
* Connect the transmitter to digital pin 11, and the receiver to digital pin 2.
*
* When run, this sketch waits for a valid code from a new-style the receiver,
* decodes it, and retransmits it after 5 seconds.
*/
#include <NewRemoteReceiver.h>
#include <NewRemoteTransmitter.h>
void setup() {
// See example ShowReceivedCode for info on this
NewRemoteReceiver::init(0, 2, retransmitter);
}
void loop() {
}
void retransmitter(NewRemoteCode receivedCode) {
// Disable the receiver; otherwise it might pick up the retransmit as well.
NewRemoteReceiver::disable();
// Need interrupts for delay()
interrupts();
// Wait 5 seconds before sending.
delay(5000);
// Create a new transmitter with the received address and period, use digital pin 11 as output pin, and repeat the signal 2^3=8 times.
NewRemoteTransmitter transmitter(receivedCode.address, 11, receivedCode.period, 3);
// Switch type 0 = switch off, type 1 = switch on, type 2 = set dim level.
if (receivedCode.switchType == 2) {
// Dimmer signal received
transmitter.sendDim(receivedCode.unit, receivedCode.dimLevel);
} else {
// On/Off signal received
if (receivedCode.groupBit) {
// Send to the group
transmitter.sendGroup(receivedCode.switchType);
} else {
// Send to a single unit
transmitter.sendUnit(receivedCode.unit, receivedCode.switchType);
}
}
NewRemoteReceiver::enable();
}
@@ -33,7 +33,7 @@ void showCode(NewRemoteCode receivedCode) {
Serial.print("Addr ");
Serial.print(receivedCode.address);
if (receivedCode.groupMode) {
if (receivedCode.groupBit) {
Serial.print(" group");
} else {
Serial.print(" unit ");
@@ -1,7 +1,10 @@
NewRemoteReceiver KEYWORD1
NewRemoteTransmitter KEYWORD1
NewRemoteCode KEYWORD1
isReceiving KEYWORD2
init KEYWORD2
enable KEYWORD2
disable KEYWORD2
isReceiving KEYWORD2
NewRemoteCode KEYWORD1
NewRemoteTransmitter KEYWORD1
sendGroup KEYWORD2
sendUnit KEYWORD2
sendDim KEYWORD2