From 1f9fc948a51afa051a8a2ec3f31a97e3a94b6eaa Mon Sep 17 00:00:00 2001 From: Ernest Gu Date: Thu, 7 Jul 2016 13:22:16 -0700 Subject: [PATCH 1/3] Rewrote library to allow for multiple RX pins WARNING: This breaks the current API (although a fix is simple enough). Rewrote example (`ReceiveDemo_Advanced.ino`) to use the new API. The number of RX pins must be defined at compile-time with #define RCSWITCH_MAX_RX_PINS. --- firmware/RCSwitch.cpp | 1032 +++++++++++--------- firmware/RCSwitch.h | 214 ++-- firmware/examples/ReceiveDemo_Advanced.ino | 3 +- 3 files changed, 694 insertions(+), 555 deletions(-) diff --git a/firmware/RCSwitch.cpp b/firmware/RCSwitch.cpp index d842459..3f47514 100644 --- a/firmware/RCSwitch.cpp +++ b/firmware/RCSwitch.cpp @@ -33,72 +33,65 @@ #include "spark_wiring_usbserial.h" #if not defined( RCSwitchDisableReceiving ) -unsigned long RCSwitch::nReceivedValue = NULL; -unsigned int RCSwitch::nReceivedBitlength = 0; -unsigned int RCSwitch::nReceivedDelay = 0; -unsigned int RCSwitch::nReceivedProtocol = 0; +RCSwitch::InterruptData RCSwitch::receiverInterrupts[RCSWITCH_MAX_RX_PINS]; +int RCSwitch::nInterruptSourcePin = -1; int RCSwitch::nReceiveTolerance = 60; #endif -unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; +unsigned int RCSwitch::timings[RCSWITCH_MAX_RX_PINS][RCSWITCH_MAX_CHANGES]; RCSwitch::RCSwitch() { - this->nTransmitterPin = -1; - this->setPulseLength(350); - this->setRepeatTransmit(10); - this->setProtocol(1); - #if not defined( RCSwitchDisableReceiving ) - this->nReceiverInterrupt = -1; - this->setReceiveTolerance(60); - RCSwitch::nReceivedValue = NULL; - #endif + this->nTransmitterPin = -1; + this->setPulseLength(350); + this->setRepeatTransmit(10); + this->setProtocol(1); + #if not defined( RCSwitchDisableReceiving ) + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + this->receiverInterrupts[i] = RCSwitch::InterruptData(); + } + this->nInterruptSourcePin = -1; + this->setReceiveTolerance(60); + #endif } /** - * Sets the protocol to send. - */ + * Sets the protocol to send. + */ void RCSwitch::setProtocol(int nProtocol) { - this->nProtocol = nProtocol; - if (nProtocol == 1){ - this->setPulseLength(350); - } - else if (nProtocol == 2) { - this->setPulseLength(650); - } - else if (nProtocol == 3) { - this->setPulseLength(100); - } + this->nProtocol = nProtocol; + switch (nProtocol) { + case 1 : this->setPulseLength(350); break; + case 2 : this->setPulseLength(650); break; + case 3 : this->setPulseLength(100); break; + } } /** - * Sets the protocol to send with pulse length in microseconds. - */ + * Sets the protocol to send with pulse length in microseconds. + */ void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { - this->nProtocol = nProtocol; - this->setPulseLength(nPulseLength); + this->nProtocol = nProtocol; + this->setPulseLength(nPulseLength); } /** - * Sets pulse length in microseconds - */ -void RCSwitch::setPulseLength(int nPulseLength) { - this->nPulseLength = nPulseLength; -} + * Sets pulse length in microseconds + */ +void RCSwitch::setPulseLength(int nPulseLength) + { this->nPulseLength = nPulseLength; } /** * Sets Repeat Transmits */ -void RCSwitch::setRepeatTransmit(int nRepeatTransmit) { - this->nRepeatTransmit = nRepeatTransmit; -} +void RCSwitch::setRepeatTransmit(int nRepeatTransmit) + { this->nRepeatTransmit = nRepeatTransmit; } /** * Set Receiving Tolerance */ #if not defined( RCSwitchDisableReceiving ) -void RCSwitch::setReceiveTolerance(int nPercent) { - RCSwitch::nReceiveTolerance = nPercent; -} +void RCSwitch::setReceiveTolerance(int nPercent) + { this->nReceiveTolerance = nPercent; } #endif @@ -108,15 +101,15 @@ void RCSwitch::setReceiveTolerance(int nPercent) { * @param nTransmitterPin Arduino Pin to which the sender is connected to */ void RCSwitch::enableTransmit(int nTransmitterPin) { - this->nTransmitterPin = nTransmitterPin; - pinMode(this->nTransmitterPin, OUTPUT); + this->nTransmitterPin = nTransmitterPin; + pinMode(this->nTransmitterPin, OUTPUT); } /** - * Disable transmissions - */ + * Disable transmissions + */ void RCSwitch::disableTransmit() { - this->nTransmitterPin = -1; + this->nTransmitterPin = -1; } /** @@ -126,7 +119,7 @@ void RCSwitch::disableTransmit() { * @param nDevice Number of the switch itself (1..3) */ void RCSwitch::switchOn(char sGroup, int nDevice) { - this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) ); + this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) ); } /** @@ -136,29 +129,29 @@ void RCSwitch::switchOn(char sGroup, int nDevice) { * @param nDevice Number of the switch itself (1..3) */ void RCSwitch::switchOff(char sGroup, int nDevice) { - this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) ); + this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) ); } /** * Switch a remote switch on (Type C Intertechno) * - * @param sFamily Familycode (a..p) + * @param sFamily Familycode (a..f) * @param nGroup Number of group (1..4) * @param nDevice Number of device (1..4) - */ + */ void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) { - this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) ); + this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) ); } /** * Switch a remote switch off (Type C Intertechno) * - * @param sFamily Familycode (a..p) + * @param sFamily Familycode (a..f) * @param nGroup Number of group (1..4) * @param nDevice Number of device (1..4) */ void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) { - this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) ); + this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) ); } /** @@ -168,7 +161,7 @@ void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) { * @param nChannelCode Number of the switch itself (1..4) */ void RCSwitch::switchOn(int nAddressCode, int nChannelCode) { - this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) ); + this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) ); } /** @@ -178,7 +171,7 @@ void RCSwitch::switchOn(int nAddressCode, int nChannelCode) { * @param nChannelCode Number of the switch itself (1..4) */ void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { - this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) ); + this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) ); } /** @@ -189,8 +182,8 @@ void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { * @param nChannelCode Number of the switch itself (1..5) */ void RCSwitch::switchOn(char* sGroup, int nChannel) { - char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; - this->switchOn(sGroup, code[nChannel]); + char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; + this->switchOn(sGroup, code[nChannel]); } /** @@ -201,8 +194,8 @@ void RCSwitch::switchOn(char* sGroup, int nChannel) { * @param nChannelCode Number of the switch itself (1..5) */ void RCSwitch::switchOff(char* sGroup, int nChannel) { - char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; - this->switchOff(sGroup, code[nChannel]); + char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; + this->switchOff(sGroup, code[nChannel]); } /** @@ -212,7 +205,7 @@ void RCSwitch::switchOff(char* sGroup, int nChannel) { * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") */ void RCSwitch::switchOn(char* sGroup, char* sDevice) { - this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) ); + this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) ); } /** @@ -222,11 +215,11 @@ void RCSwitch::switchOn(char* sGroup, char* sDevice) { * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") */ void RCSwitch::switchOff(char* sGroup, char* sDevice) { - this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) ); + this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) ); } /** - * Returns a char[13], representing the Code Word to be send. + * Returns a char[13], representing the Code Word to be sent. * A Code Word consists of 9 address bits, 3 data bits and one sync bit but in our case only the first 8 address bits and the last 2 data bits were used. * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit) * @@ -242,105 +235,105 @@ void RCSwitch::switchOff(char* sGroup, char* sDevice) { * @return char[13] */ char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) { - int nReturnPos = 0; - static char sReturn[13]; + int nReturnPos = 0; + static char sReturn[13]; - char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; - if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { - return '\0'; - } - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = code[nAddressCode][i]; - } + char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; + if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { + return '\0'; + } + for (int i = 0; i<4; i++) { + sReturn[nReturnPos++] = code[nAddressCode][i]; + } - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = code[nChannelCode][i]; - } + for (int i = 0; i<4; i++) { + sReturn[nReturnPos++] = code[nChannelCode][i]; + } - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; - if (bStatus) { - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = '0'; - } + if (bStatus) { + sReturn[nReturnPos++] = 'F'; + } else { + sReturn[nReturnPos++] = '0'; + } - sReturn[nReturnPos] = '\0'; + sReturn[nReturnPos] = '\0'; - return sReturn; + return sReturn; } /** - * Returns a char[13], representing the Code Word to be send. + * Returns a char[13], representing the Code Word to be sent. * * getCodeWordA(char*, char*) * */ char* RCSwitch::getCodeWordA(char* sGroup, char* sDevice, boolean bOn) { - static char sDipSwitches[13]; - int i = 0; - int j = 0; + static char sDipSwitches[13]; + int i = 0; + int j = 0; - for (i=0; i < 5; i++) { - if (sGroup[i] == '0') { - sDipSwitches[j++] = 'F'; - } else { - sDipSwitches[j++] = '0'; - } - } + for (i=0; i < 5; i++) { + if (sGroup[i] == '0') { + sDipSwitches[j++] = 'F'; + } else { + sDipSwitches[j++] = '0'; + } + } - for (i=0; i < 5; i++) { - if (sDevice[i] == '0') { - sDipSwitches[j++] = 'F'; - } else { - sDipSwitches[j++] = '0'; - } - } + for (i=0; i < 5; i++) { + if (sDevice[i] == '0') { + sDipSwitches[j++] = 'F'; + } else { + sDipSwitches[j++] = '0'; + } + } - if ( bOn ) { - sDipSwitches[j++] = '0'; - sDipSwitches[j++] = 'F'; - } else { - sDipSwitches[j++] = 'F'; - sDipSwitches[j++] = '0'; - } + if (bOn) { + sDipSwitches[j++] = '0'; + sDipSwitches[j++] = 'F'; + } else { + sDipSwitches[j++] = 'F'; + sDipSwitches[j++] = '0'; + } - sDipSwitches[j] = '\0'; + sDipSwitches[j] = '\0'; - return sDipSwitches; + return sDipSwitches; } /** * Like getCodeWord (Type C = Intertechno) */ char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus) { - static char sReturn[13]; - int nReturnPos = 0; - - if ( (byte)sFamily < 97 || (byte)sFamily > 112 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { - return '\0'; - } - - char* sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 ); - char familycode[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" }; - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = familycode[ (int)sFamily - 97 ][i]; - } - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0'); - } - sReturn[nReturnPos++] = '0'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - if (bStatus) { - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = '0'; - } - sReturn[nReturnPos] = '\0'; - return sReturn; + static char sReturn[13]; + int nReturnPos = 0; + + if ( (byte)sFamily < 97 || (byte)sFamily > 112 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { + return '\0'; + } + + char* sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 ); + char familycode[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" }; + for (int i = 0; i<4; i++) { + sReturn[nReturnPos++] = familycode[ (int)sFamily - 97 ][i]; + } + for (int i = 0; i<4; i++) { + sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0'); + } + sReturn[nReturnPos++] = '0'; + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + if (bStatus) { + sReturn[nReturnPos++] = 'F'; + } else { + sReturn[nReturnPos++] = '0'; + } + sReturn[nReturnPos] = '\0'; + return sReturn; } /** @@ -364,139 +357,139 @@ char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bSta * @return char[13] */ -char* RCSwitch::getCodeWordD(char sGroup, int nDevice, boolean bStatus){ - static char sReturn[13]; - int nReturnPos = 0; - - // Building 4 bits address - // (Potential problem if dec2binWcharfill not returning correct string) - char *sGroupCode; - switch(sGroup){ - case 'a': - case 'A': - sGroupCode = dec2binWcharfill(8, 4, 'F'); break; - case 'b': - case 'B': - sGroupCode = dec2binWcharfill(4, 4, 'F'); break; - case 'c': - case 'C': - sGroupCode = dec2binWcharfill(2, 4, 'F'); break; - case 'd': - case 'D': - sGroupCode = dec2binWcharfill(1, 4, 'F'); break; - default: - return '\0'; - } - - for (int i = 0; i<4; i++) - { - sReturn[nReturnPos++] = sGroupCode[i]; - } - - - // Building 3 bits address - // (Potential problem if dec2binWcharfill not returning correct string) - char *sDevice; - switch(nDevice) { - case 1: - sDevice = dec2binWcharfill(4, 3, 'F'); break; - case 2: - sDevice = dec2binWcharfill(2, 3, 'F'); break; - case 3: - sDevice = dec2binWcharfill(1, 3, 'F'); break; - default: - return '\0'; - } - - for (int i = 0; i<3; i++) - sReturn[nReturnPos++] = sDevice[i]; - - // fill up rest with zeros - for (int i = 0; i<5; i++) - sReturn[nReturnPos++] = '0'; +char* RCSwitch::getCodeWordD(char sGroup, int nDevice, boolean bStatus) { + static char sReturn[13]; + int nReturnPos = 0; + + // Building 4 bits address + // (Potential problem if dec2binWcharfill not returning correct string) + char *sGroupCode; + switch(sGroup) { + case 'a': + case 'A': + sGroupCode = dec2binWcharfill(8, 4, 'F'); break; + case 'b': + case 'B': + sGroupCode = dec2binWcharfill(4, 4, 'F'); break; + case 'c': + case 'C': + sGroupCode = dec2binWcharfill(2, 4, 'F'); break; + case 'd': + case 'D': + sGroupCode = dec2binWcharfill(1, 4, 'F'); break; + default: + return '\0'; + } + + for (int i = 0; i<4; i++) { + sReturn[nReturnPos++] = sGroupCode[i]; + } + + + // Building 3 bits address + // (Potential problem if dec2binWcharfill not returning correct string) + char *sDevice; + switch(nDevice) { + case 1: sDevice = dec2binWcharfill(4, 3, 'F'); break; + case 2: sDevice = dec2binWcharfill(2, 3, 'F'); break; + case 3: sDevice = dec2binWcharfill(1, 3, 'F'); break; + default: return '\0'; + } + + for (int i = 0; i<3; i++) { + sReturn[nReturnPos++] = sDevice[i]; + } + + // fill up rest with zeros + for (int i = 0; i<5; i++) { + sReturn[nReturnPos++] = '0'; + } // encode on or off - if (bStatus) - sReturn[10] = '1'; - else - sReturn[11] = '1'; - - // last position terminate string - sReturn[12] = '\0'; - return sReturn; + if (bStatus) { + sReturn[10] = '1'; + } else { + sReturn[11] = '1'; + } + // last position terminate string + sReturn[12] = '\0'; + return sReturn; } /** * @param sCodeWord /^[10FS]*$/ -> see getCodeWord */ void RCSwitch::sendTriState(char* sCodeWord) { - for (int nRepeat=0; nRepeatsendT0(); - break; - case 'F': - this->sendTF(); - break; - case '1': - this->sendT1(); - break; - } - i++; - } - this->sendSync(); - } + for (int nRepeat=0; nRepeatsendT0(); break; + case 'F': this->sendTF(); break; + case '1': this->sendT1(); break; + } + i++; + } + this->sendSync(); + } } void RCSwitch::send(unsigned long Code, unsigned int length) { - this->send( this->dec2binWzerofill(Code, length) ); + this->send( this->dec2binWzerofill(Code, length) ); } void RCSwitch::send(char* sCodeWord) { - for (int nRepeat=0; nRepeatsend0(); - break; - case '1': - this->send1(); - break; - } - i++; - } - this->sendSync(); - } + for (int nRepeat=0; nRepeatsend0(); break; + case '1': this->send1(); break; + } + i++; + } + this->sendSync(); + } } void RCSwitch::transmit(int nHighPulses, int nLowPulses) { - #if not defined ( RCSwitchDisableReceiving ) - boolean disabled_Receive = false; - int nReceiverInterrupt_backup = nReceiverInterrupt; - #endif - if (this->nTransmitterPin != -1) { - #if not defined( RCSwitchDisableReceiving ) - if (this->nReceiverInterrupt != -1) { - this->disableReceive(); - disabled_Receive = true; - } - #endif - digitalWrite(this->nTransmitterPin, HIGH); - delayMicroseconds( this->nPulseLength * nHighPulses); - digitalWrite(this->nTransmitterPin, LOW); - delayMicroseconds( this->nPulseLength * nLowPulses); - - #if not defined( RCSwitchDisableReceiving ) - if(disabled_Receive){ - this->enableReceive(nReceiverInterrupt_backup); - } - #endif - } + if (this->nTransmitterPin == -1) { + return; + } + + #if not defined ( RCSwitchDisableReceiving ) + boolean disabled_receive = false; + RCSwitch::InterruptData receiverInterrupts_backup[RCSWITCH_MAX_RX_PINS] = + this->receiverInterrupts; + // Arrays are copied by value -- i.e., a deep copy. + for (int i=0; ireceiverInterrupts[i].interrupt != -1) { + this->disableReceive(); + disabled_receive = true; + break; + } + } + #endif + + digitalWrite(this->nTransmitterPin, HIGH); + delayMicroseconds( this->nPulseLength * nHighPulses); + digitalWrite(this->nTransmitterPin, LOW); + delayMicroseconds( this->nPulseLength * nLowPulses); + + #if not defined( RCSwitchDisableReceiving ) + if (disabled_receive) { + for (int i=0; ienableReceive(receiverInterrupts_backup[i].interrupt); + this->receiverInterrupts[getInterruptIndex(receiverInterrupts_backup[i].interrupt)] = + receiverInterrupts_backup[i]; + // The default assignment operator does a member-wise, + // recursive assignment of each member. + } + } + #endif } + /** * Sends a "0" Bit * _ @@ -505,15 +498,13 @@ void RCSwitch::transmit(int nHighPulses, int nLowPulses) { * Waveform Protocol 2: | |__ */ void RCSwitch::send0() { - if (this->nProtocol == 1){ - this->transmit(1,3); - } - else if (this->nProtocol == 2) { - this->transmit(1,2); - } - else if (this->nProtocol == 3) { - this->transmit(4,11); - } + if (this->nProtocol == 1){ + this->transmit(1,3); + } else if (this->nProtocol == 2) { + this->transmit(1,2); + } else if (this->nProtocol == 3) { + this->transmit(4,11); + } } /** @@ -524,15 +515,13 @@ void RCSwitch::send0() { * Waveform Protocol 2: | |_ */ void RCSwitch::send1() { - if (this->nProtocol == 1){ - this->transmit(3,1); - } - else if (this->nProtocol == 2) { - this->transmit(2,1); - } - else if (this->nProtocol == 3) { - this->transmit(9,6); - } + if (this->nProtocol == 1){ + this->transmit(3,1); + } else if (this->nProtocol == 2) { + this->transmit(2,1); + } else if (this->nProtocol == 3) { + this->transmit(9,6); + } } @@ -552,8 +541,8 @@ void RCSwitch::sendT0() { * Waveform: | |_| |_ */ void RCSwitch::sendT1() { - this->transmit(3,1); - this->transmit(3,1); + this->transmit(3,1); + this->transmit(3,1); } /** @@ -562,8 +551,8 @@ void RCSwitch::sendT1() { * Waveform: | |___| |_ */ void RCSwitch::sendTF() { - this->transmit(1,3); - this->transmit(3,1); + this->transmit(1,3); + this->transmit(3,1); } /** @@ -575,15 +564,13 @@ void RCSwitch::sendTF() { */ void RCSwitch::sendSync() { - if (this->nProtocol == 1){ - this->transmit(1,31); - } - else if (this->nProtocol == 2) { - this->transmit(1,10); - } - else if (this->nProtocol == 3) { - this->transmit(1,71); - } + if (this->nProtocol == 1){ + this->transmit(1,31); + } else if (this->nProtocol == 2) { + this->transmit(1,10); + } else if (this->nProtocol == 3) { + this->transmit(1,71); + } } #if not defined( RCSwitchDisableReceiving ) @@ -591,232 +578,333 @@ void RCSwitch::sendSync() { * Enable receiving data */ void RCSwitch::enableReceive(int interrupt) { - this->nReceiverInterrupt = interrupt; - this->enableReceive(); -} - -void RCSwitch::enableReceive() { - if (this->nReceiverInterrupt != -1) { - RCSwitch::nReceivedValue = NULL; - RCSwitch::nReceivedBitlength = NULL; - attachInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE); - } + // check if interrupt is already enabled + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + if (interrupt == this->receiverInterrupts[i].interrupt) { + Serial.printlnf("Interrupt already enabled on pin %d -- skipping", interrupt); + return; + } + } + + Serial.printlnf("Searching for empty spot: interrupt on pin %d", interrupt); + int index = -1; + // find an unused element + // TODO: add a `isEnabled` member to the `InterruptData` struct; + // reset `nReceivedValue` and `nReceivedBitLength` only if previously not enabled + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + Serial.printlnf("element: %d | pin: %d", i, RCSwitch::receiverInterrupts[i].interrupt); + if (this->receiverInterrupts[i].interrupt == -1) { + this->receiverInterrupts[i].interrupt = interrupt; + index = i; + break; + } + } + Serial.println(""); + + attachInterrupt(interrupt, handleInterrupt, CHANGE); + + noInterrupts(); + Serial.printlnf("Attached interrupt: %d", interrupt); + Serial.printlnf(" interrupt index: %d", index); + Serial.printlnf(" fetched index: %d", getInterruptIndex(interrupt)); + Serial.println(""); + interrupts(); } /** * Disable receiving data */ +void RCSwitch::disableReceive(int interrupt) { + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + if (this->receiverInterrupts[i].interrupt == interrupt) { + detachInterrupt(RCSwitch::receiverInterrupts[i].interrupt); + this->receiverInterrupts[i].interrupt = -1; + } + } +} + void RCSwitch::disableReceive() { - detachInterrupt(this->nReceiverInterrupt); - this->nReceiverInterrupt = -1; + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + detachInterrupt(this->receiverInterrupts[i].interrupt); + this->receiverInterrupts[i].interrupt = -1; + } } bool RCSwitch::available() { - return RCSwitch::nReceivedValue != NULL; + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + if (this->receiverInterrupts[i].nReceivedValue != NULL) { + return true; + } + } + return false; } void RCSwitch::resetAvailable() { - RCSwitch::nReceivedValue = NULL; + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + this->receiverInterrupts[i].nReceivedValue = NULL; + } } -unsigned long RCSwitch::getReceivedValue() { - return RCSwitch::nReceivedValue; +int RCSwitch::getReceivedPin() { + return this->nInterruptSourcePin; } -unsigned int RCSwitch::getReceivedBitlength() { - return RCSwitch::nReceivedBitlength; +unsigned long RCSwitch::getReceivedValue(int interrupt) { + return this->receiverInterrupts[getInterruptIndex(interrupt)].nReceivedValue; } -unsigned int RCSwitch::getReceivedDelay() { - return RCSwitch::nReceivedDelay; +unsigned int RCSwitch::getReceivedBitlength(int interrupt) { + return this->receiverInterrupts[getInterruptIndex(interrupt)].nReceivedBitlength; } -unsigned int RCSwitch::getReceivedProtocol() { - return RCSwitch::nReceivedProtocol; +unsigned int RCSwitch::getReceivedDelay(int interrupt) { + return this->receiverInterrupts[getInterruptIndex(interrupt)].nReceivedDelay; } -unsigned int* RCSwitch::getReceivedRawdata() { - return RCSwitch::timings; +unsigned int RCSwitch::getReceivedProtocol(int interrupt) { + return this->receiverInterrupts[getInterruptIndex(interrupt)].nReceivedProtocol; +} + +unsigned int* RCSwitch::getReceivedRawdata(int interrupt) { + return this->timings[getInterruptIndex(interrupt)]; } /** * */ -bool RCSwitch::receiveProtocol1(unsigned int changeCount){ - - unsigned long code = 0; - unsigned long delay = RCSwitch::timings[0] / 31; - unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; - - for (int i = 1; i delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*3-delayTolerance && RCSwitch::timings[i+1] < delay*3+delayTolerance) { - code = code << 1; - } else if (RCSwitch::timings[i] > delay*3-delayTolerance && RCSwitch::timings[i] < delay*3+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) { - code+=1; - code = code << 1; - } else { - // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - RCSwitch::nReceivedValue = code; - RCSwitch::nReceivedBitlength = changeCount / 2; - RCSwitch::nReceivedDelay = delay; - RCSwitch::nReceivedProtocol = 1; - } - - if (code == 0){ - return false; - }else if (code != 0){ - return true; - } - - -} - -bool RCSwitch::receiveProtocol2(unsigned int changeCount){ - - unsigned long code = 0; - unsigned long delay = RCSwitch::timings[0] / 10; - unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; - - for (int i = 1; i delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*2-delayTolerance && RCSwitch::timings[i+1] < delay*2+delayTolerance) { - code = code << 1; - } else if (RCSwitch::timings[i] > delay*2-delayTolerance && RCSwitch::timings[i] < delay*2+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) { - code+=1; - code = code << 1; - } else { - // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - RCSwitch::nReceivedValue = code; - RCSwitch::nReceivedBitlength = changeCount / 2; - RCSwitch::nReceivedDelay = delay; - RCSwitch::nReceivedProtocol = 2; - } - - if (code == 0){ - return false; - }else if (code != 0){ - return true; - } - +bool RCSwitch::receiveProtocol1(int interrupt_i, unsigned int changeCount){ + Serial.println("Triggered: protocol 1"); + + unsigned long code = 0; + unsigned long delay = RCSwitch::timings[interrupt_i][0] / 31; + unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; + + for (int i = 1; i delay - delayTolerance && + RCSwitch::timings[interrupt_i][i] < delay + delayTolerance && + RCSwitch::timings[interrupt_i][i+1] > delay*3 - delayTolerance && + RCSwitch::timings[interrupt_i][i+1] < delay*3 + delayTolerance ) { + code = code << 1; + } else if ( RCSwitch::timings[interrupt_i][i] > delay*3 - delayTolerance && + RCSwitch::timings[interrupt_i][i] < delay*3 + delayTolerance && + RCSwitch::timings[interrupt_i][i+1] > delay - delayTolerance && + RCSwitch::timings[interrupt_i][i+1] < delay + delayTolerance ) { + code+=1; + code = code << 1; + } else { + // Failed + i = changeCount; + code = 0; + } + } + code = code >> 1; + + if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise + RCSwitch::receiverInterrupts[interrupt_i].nReceivedValue = code; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedBitlength = changeCount / 2; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedDelay = delay; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedProtocol = 1; + } + + if (code == 0) { + return false; + } else if (code != 0) { + nInterruptSourcePin = RCSwitch::receiverInterrupts[interrupt_i].interrupt; + //for (int j=1; j delay - delayTolerance && + RCSwitch::timings[interrupt_i][i] < delay + delayTolerance && + RCSwitch::timings[interrupt_i][i+1] > delay*2 - delayTolerance && + RCSwitch::timings[interrupt_i][i+1] < delay*2 + delayTolerance ) { + code = code << 1; + } else if ( RCSwitch::timings[interrupt_i][i] > delay*2 - delayTolerance && + RCSwitch::timings[interrupt_i][i] < delay*2 + delayTolerance && + RCSwitch::timings[interrupt_i][i+1] > delay - delayTolerance && + RCSwitch::timings[interrupt_i][i+1] < delay + delayTolerance ) { + code+=1; + code = code << 1; + } else { + // Failed + i = changeCount; + code = 0; + } + } + code = code >> 1; + + if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise + RCSwitch::receiverInterrupts[interrupt_i].nReceivedValue = code; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedBitlength = changeCount / 2; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedDelay = delay; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedProtocol = 2; + } + + if (code == 0) { + return false; + } else if (code != 0) { + nInterruptSourcePin = RCSwitch::receiverInterrupts[interrupt_i].interrupt; + //for (int j=1; j delay*PROTOCOL3_0_HIGH_CYCLES - delayTolerance - && RCSwitch::timings[i] < delay*PROTOCOL3_0_HIGH_CYCLES + delayTolerance - && RCSwitch::timings[i+1] > delay*PROTOCOL3_0_LOW_CYCLES - delayTolerance - && RCSwitch::timings[i+1] < delay*PROTOCOL3_0_LOW_CYCLES + delayTolerance) { - code = code << 1; - } else if (RCSwitch::timings[i] > delay*PROTOCOL3_1_HIGH_CYCLES - delayTolerance - && RCSwitch::timings[i] < delay*PROTOCOL3_1_HIGH_CYCLES + delayTolerance - && RCSwitch::timings[i+1] > delay*PROTOCOL3_1_LOW_CYCLES - delayTolerance - && RCSwitch::timings[i+1] < delay*PROTOCOL3_1_LOW_CYCLES + delayTolerance) { - code+=1; - code = code << 1; - } else { - // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - RCSwitch::nReceivedValue = code; - RCSwitch::nReceivedBitlength = changeCount / 2; - RCSwitch::nReceivedDelay = delay; - RCSwitch::nReceivedProtocol = 3; - } - - if (code == 0){ - return false; - }else if (code != 0){ - return true; - } +bool RCSwitch::receiveProtocol3(int interrupt_i, unsigned int changeCount){ + Serial.println("Triggered: protocol 3"); + + unsigned long code = 0; + unsigned long delay = RCSwitch::timings[interrupt_i][0] / PROTOCOL3_SYNC_FACTOR; + unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; + + for (int i = 1; i delay*PROTOCOL3_0_HIGH_CYCLES - delayTolerance && + RCSwitch::timings[interrupt_i][i] < delay*PROTOCOL3_0_HIGH_CYCLES + delayTolerance && + RCSwitch::timings[interrupt_i][i+1] > delay*PROTOCOL3_0_LOW_CYCLES - delayTolerance && + RCSwitch::timings[interrupt_i][i+1] < delay*PROTOCOL3_0_LOW_CYCLES + delayTolerance ) { + code = code << 1; + } else if ( RCSwitch::timings[interrupt_i][i] > delay*PROTOCOL3_1_HIGH_CYCLES - delayTolerance && + RCSwitch::timings[interrupt_i][i] < delay*PROTOCOL3_1_HIGH_CYCLES + delayTolerance && + RCSwitch::timings[interrupt_i][i+1] > delay*PROTOCOL3_1_LOW_CYCLES - delayTolerance && + RCSwitch::timings[interrupt_i][i+1] < delay*PROTOCOL3_1_LOW_CYCLES + delayTolerance ) { + code+=1; + code = code << 1; + } else { + // Failed + i = changeCount; + code = 0; + } + } + code = code >> 1; + + if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise + RCSwitch::receiverInterrupts[interrupt_i].nReceivedValue = code; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedBitlength = changeCount / 2; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedDelay = delay; + RCSwitch::receiverInterrupts[interrupt_i].nReceivedProtocol = 3; + } + + if (code == 0) { + return false; + } else if (code != 0) { + nInterruptSourcePin = RCSwitch::receiverInterrupts[interrupt_i].interrupt; + //for (int j=1; j 5000 && duration > RCSwitch::timings[0] - 200 && duration < RCSwitch::timings[0] + 200) { - repeatCount++; - changeCount--; - if (repeatCount == 2) { - if (receiveProtocol1(changeCount) == false){ - if (receiveProtocol2(changeCount) == false){ - if (receiveProtocol3(changeCount) == false){ - //failed - } - } - } - repeatCount = 0; - } - changeCount = 0; - } else if (duration > 5000) { - changeCount = 0; - } - - if (changeCount >= RCSWITCH_MAX_CHANGES) { - changeCount = 0; - repeatCount = 0; - } - RCSwitch::timings[changeCount++] = duration; - lastTime = time; -} - -/** - * Turns a decimal value to its binary representation - */ -char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ - return dec2binWcharfill(Dec, bitLength, '0'); -} - -char* RCSwitch::dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill){ - static char bin[64]; - unsigned int i=0; - - while (Dec > 0) { - bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill; - Dec = Dec >> 1; - } - - for (unsigned int j = 0; j< bitLength; j++) { - if (j >= bitLength - i) { - bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; - }else { - bin[j] = fill; - } - } - bin[bitLength] = '\0'; - - return bin; + bool doSwap = false; + unsigned long time = micros() * 0.983; // Spark Core micros() calibration + + for (int i = 0; i < RCSWITCH_MAX_RX_PINS; ++i) { + bool isCurrentHigh = (digitalRead(RCSwitch::receiverInterrupts[i].interrupt) == HIGH); + bool isCurrentLow = (digitalRead(RCSwitch::receiverInterrupts[i].interrupt) == LOW); + bool isPinPrevHigh_tmp = RCSwitch::receiverInterrupts[i].isPinPrevHigh; + + if ( (isCurrentHigh && isPinPrevHigh_tmp) || (isCurrentLow && !isPinPrevHigh_tmp) ) { + continue; + } + + RCSwitch::receiverInterrupts[i].duration = time - RCSwitch::receiverInterrupts[i].lastTime; + int duration_tmp = RCSwitch::receiverInterrupts[i].duration; + if (duration_tmp > 4600 && duration_tmp > RCSwitch::timings[i][0] - 200 && duration_tmp < RCSwitch::timings[i][0] + 200) { + RCSwitch::receiverInterrupts[i].repeatCount++; + RCSwitch::receiverInterrupts[i].changeCount--; + + if (RCSwitch::receiverInterrupts[i].repeatCount == 2) { + int sendInterruptIndex = getInterruptIndex(RCSwitch::receiverInterrupts[i].interrupt); + int sendChangeCount = RCSwitch::receiverInterrupts[i].changeCount; + if (receiveProtocol1(sendInterruptIndex, sendChangeCount) == false) { + if (receiveProtocol2(sendInterruptIndex, sendChangeCount) == false) { + if (receiveProtocol3(sendInterruptIndex, sendChangeCount) == false) { + // failed + } + } + } + RCSwitch::receiverInterrupts[i].repeatCount = 0; + } + RCSwitch::receiverInterrupts[i].changeCount = 0; + } else if (duration_tmp > 4600) { + RCSwitch::receiverInterrupts[i].changeCount = 0; + } + + if (RCSwitch::receiverInterrupts[i].changeCount >= RCSWITCH_MAX_CHANGES) { + RCSwitch::receiverInterrupts[i].changeCount = 0; + RCSwitch::receiverInterrupts[i].repeatCount = 0; + + //Serial.printf("dump(%d) -- ", i); + //for (int j=1; j 0) { + bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill; + Dec = Dec >> 1; + } + + for (unsigned int j = 0; j< bitLength; j++) { + if (j >= bitLength - i) { + bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; + } else { + bin[j] = fill; + } + } + bin[bitLength] = '\0'; + + return bin; } #endif diff --git a/firmware/RCSwitch.h b/firmware/RCSwitch.h index 17044e6..835903b 100644 --- a/firmware/RCSwitch.h +++ b/firmware/RCSwitch.h @@ -23,6 +23,9 @@ #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wreturn-type" +// Maximum number of supported RX pins. +// Setting this to 0 will #define RCSwitchDisableReceiving + // Number of maximum High/Low changes per packet. // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync #define RCSWITCH_MAX_CHANGES 67 @@ -33,90 +36,137 @@ #define PROTOCOL3_1_HIGH_CYCLES 9 #define PROTOCOL3_1_LOW_CYCLES 6 +// #define RCSwitchDisableReceiving if there are no supported RX pins. +#ifdef RCSWITCH_MAX_RX_PINS + #if (RCSWITCH_MAX_RX_PINS == 0) + // Two checks needed: preprocessor replaces undefined symbols with 0. + #define RCSwitchDisableReceiving + #endif +#endif + class RCSwitch { - public: - RCSwitch(); - - void switchOn(int nGroupNumber, int nSwitchNumber); - void switchOff(int nGroupNumber, int nSwitchNumber); - void switchOn(char* sGroup, int nSwitchNumber); - void switchOff(char* sGroup, int nSwitchNumber); - void switchOn(char sFamily, int nGroup, int nDevice); - void switchOff(char sFamily, int nGroup, int nDevice); - void switchOn(char* sGroup, char* sDevice); - void switchOff(char* sGroup, char* sDevice); - void switchOn(char sGroup, int nDevice); - void switchOff(char sGroup, int nDevice); - - void sendTriState(char* Code); - void send(unsigned long Code, unsigned int length); - void send(char* Code); - - #if not defined( RCSwitchDisableReceiving ) - void enableReceive(int interrupt); - void enableReceive(); - void disableReceive(); - bool available(); - void resetAvailable(); - - unsigned long getReceivedValue(); - unsigned int getReceivedBitlength(); - unsigned int getReceivedDelay(); - unsigned int getReceivedProtocol(); - unsigned int* getReceivedRawdata(); - #endif - - void enableTransmit(int nTransmitterPin); - void disableTransmit(); - void setPulseLength(int nPulseLength); - void setRepeatTransmit(int nRepeatTransmit); - #if not defined( RCSwitchDisableReceiving ) - void setReceiveTolerance(int nPercent); - #endif - void setProtocol(int nProtocol); - void setProtocol(int nProtocol, int nPulseLength); - - char* dec2binWzerofill(unsigned long dec, unsigned int length); - char* dec2binWcharfill(unsigned long dec, unsigned int length, char fill); - - private: - char* getCodeWordB(int nGroupNumber, int nSwitchNumber, boolean bStatus); - char* getCodeWordA(char* sGroup, int nSwitchNumber, boolean bStatus); - char* getCodeWordA(char* sGroup, char* sDevice, boolean bStatus); - char* getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus); - char* getCodeWordD(char group, int nDevice, boolean bStatus); - void sendT0(); - void sendT1(); - void sendTF(); - void send0(); - void send1(); - void sendSync(); - void transmit(int nHighPulses, int nLowPulses); - - #if not defined( RCSwitchDisableReceiving ) - static void handleInterrupt(); - static bool receiveProtocol1(unsigned int changeCount); - static bool receiveProtocol2(unsigned int changeCount); - static bool receiveProtocol3(unsigned int changeCount); - int nReceiverInterrupt; - #endif - int nTransmitterPin; - int nPulseLength; - int nRepeatTransmit; - char nProtocol; - - #if not defined( RCSwitchDisableReceiving ) - static int nReceiveTolerance; - static unsigned long nReceivedValue; - static unsigned int nReceivedBitlength; - static unsigned int nReceivedDelay; - static unsigned int nReceivedProtocol; - #endif - /* - * timings[0] contains sync timing, followed by a number of bits - */ - static unsigned int timings[RCSWITCH_MAX_CHANGES]; +public: + RCSwitch(); + + void switchOn(int nGroupNumber, int nSwitchNumber); + void switchOff(int nGroupNumber, int nSwitchNumber); + void switchOn(char* sGroup, int nSwitchNumber); + void switchOff(char* sGroup, int nSwitchNumber); + void switchOn(char sFamily, int nGroup, int nDevice); + void switchOff(char sFamily, int nGroup, int nDevice); + void switchOn(char* sGroup, char* sDevice); + void switchOff(char* sGroup, char* sDevice); + void switchOn(char sGroup, int nDevice); + void switchOff(char sGroup, int nDevice); + + void sendTriState(char* Code); + void send(unsigned long Code, unsigned int length); + void send(char* Code); + + #if not defined( RCSwitchDisableReceiving ) + void enableReceive(int interrupt); + // Enabling "all" is only useful if InterruptData.isDisabled exists. + //void enableReceive(); + void disableReceive(int interrupt); + void disableReceive(); + bool available(); + void resetAvailable(); + + int getReceivedPin(); + unsigned long getReceivedValue(int interrupt); + unsigned int getReceivedBitlength(int interrupt); + unsigned int getReceivedDelay(int interrupt); + unsigned int getReceivedProtocol(int interrupt); + unsigned int* getReceivedRawdata(int interrupt); + #endif + + void enableTransmit(int nTransmitterPin); + void disableTransmit(); + void setPulseLength(int nPulseLength); + void setRepeatTransmit(int nRepeatTransmit); + #if not defined( RCSwitchDisableReceiving ) + void setReceiveTolerance(int nPercent); + #endif + void setProtocol(int nProtocol); + void setProtocol(int nProtocol, int nPulseLength); + + char* dec2binWzerofill(unsigned long dec, unsigned int length); + char* dec2binWcharfill(unsigned long dec, unsigned int length, char fill); + +private: + char* getCodeWordB(int nGroupNumber, int nSwitchNumber, boolean bStatus); + char* getCodeWordA(char* sGroup, int nSwitchNumber, boolean bStatus); + char* getCodeWordA(char* sGroup, char* sDevice, boolean bStatus); + char* getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus); + char* getCodeWordD(char group, int nDevice, boolean bStatus); + void sendT0(); + void sendT1(); + void sendTF(); + void send0(); + void send1(); + void sendSync(); + void transmit(int nHighPulses, int nLowPulses); + + #if not defined ( RCSwitchDisableReceiving ) + static void handleInterrupt(); + static bool receiveProtocol1(int interrupt_i, unsigned int changeCount); + static bool receiveProtocol2(int interrupt_i, unsigned int changeCount); + static bool receiveProtocol3(int interrupt_i, unsigned int changeCount); + static int getInterruptIndex(int interrupt); + + // TODO: Possibly switch to using an explicit `bool is_disabled` (as opposed to -1) + // TODO: Possibly implement an interrupt-specific "isAvailable"? Such that the user + // can loop through all interrupts they are interested in. + struct InterruptData { + int interrupt; + //bool isDisabled; + //bool isAvailable; + + unsigned long nReceivedValue; + unsigned int nReceivedBitlength; + unsigned int nReceivedDelay; + unsigned int nReceivedProtocol; + + unsigned long lastTime; + unsigned int duration; + unsigned int changeCount, repeatCount; + bool isPinPrevHigh; + + InterruptData() { + interrupt = -1; + //isDisabled = true; + //isAvailable = false; + + nReceivedValue = NULL; + nReceivedBitlength = 0; + nReceivedDelay = 0; + nReceivedProtocol = 0; + + lastTime = 0; + duration = 0; + changeCount = 0; + repeatCount = 0; + isPinPrevHigh = false; + } + }; + + static InterruptData receiverInterrupts[RCSWITCH_MAX_RX_PINS]; + static int nInterruptSourcePin; + #endif + + int nTransmitterPin; + int nPulseLength; + int nRepeatTransmit; + char nProtocol; + #if not defined( RCSwitchDisableReceiving ) + static int nReceiveTolerance; + #endif + + /* + * timings[0] contains sync timing, followed by a number of bits + */ + static unsigned int timings[RCSWITCH_MAX_RX_PINS][RCSWITCH_MAX_CHANGES]; }; #endif diff --git a/firmware/examples/ReceiveDemo_Advanced.ino b/firmware/examples/ReceiveDemo_Advanced.ino index 2569b61..b0955a0 100644 --- a/firmware/examples/ReceiveDemo_Advanced.ino +++ b/firmware/examples/ReceiveDemo_Advanced.ino @@ -89,7 +89,8 @@ void loop() { digitalWrite(ledPin, inputPinState); if (mySwitch.available()) { - output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(), mySwitch.getReceivedProtocol()); + int receivedPin = mySwitch.getReceivedPin(); + output(mySwitch.getReceivedValue(receivedPin), mySwitch.getReceivedBitlength(receivedPin), mySwitch.getReceivedDelay(receivedPin), mySwitch.getReceivedRawdata(receivedPin), mySwitch.getReceivedProtocol(receivedPin)); mySwitch.resetAvailable(); } } From 77506cd74d5b53b5b42e64ddeecc8a0fe34dadd4 Mon Sep 17 00:00:00 2001 From: Ernest Gu Date: Thu, 7 Jul 2016 13:27:01 -0700 Subject: [PATCH 2/3] Set default RCSWITCH_MAX_RX_PINS to 1 --- firmware/RCSwitch.h | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/RCSwitch.h b/firmware/RCSwitch.h index 835903b..0aa56f1 100644 --- a/firmware/RCSwitch.h +++ b/firmware/RCSwitch.h @@ -25,6 +25,7 @@ // Maximum number of supported RX pins. // Setting this to 0 will #define RCSwitchDisableReceiving +#define RCSWITCH_MAX_RX_PINS 1 // Number of maximum High/Low changes per packet. // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync From 7284104df168fc56ef73a1e1eda8cf5bb0927ce1 Mon Sep 17 00:00:00 2001 From: Ernest Gu Date: Thu, 7 Jul 2016 13:27:57 -0700 Subject: [PATCH 3/3] Limited the line length in ReceiveDemo_Advanced.ino --- firmware/examples/ReceiveDemo_Advanced.ino | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/firmware/examples/ReceiveDemo_Advanced.ino b/firmware/examples/ReceiveDemo_Advanced.ino index b0955a0..50b4b3a 100644 --- a/firmware/examples/ReceiveDemo_Advanced.ino +++ b/firmware/examples/ReceiveDemo_Advanced.ino @@ -90,7 +90,13 @@ void loop() { if (mySwitch.available()) { int receivedPin = mySwitch.getReceivedPin(); - output(mySwitch.getReceivedValue(receivedPin), mySwitch.getReceivedBitlength(receivedPin), mySwitch.getReceivedDelay(receivedPin), mySwitch.getReceivedRawdata(receivedPin), mySwitch.getReceivedProtocol(receivedPin)); + output( + mySwitch.getReceivedValue(receivedPin), + mySwitch.getReceivedBitlength(receivedPin), + mySwitch.getReceivedDelay(receivedPin), + mySwitch.getReceivedRawdata(receivedPin), + mySwitch.getReceivedProtocol(receivedPin) + ); mySwitch.resetAvailable(); } }