diff --git a/RCSwitch.cpp b/RCSwitch.cpp index 4ce4df9..ec6b6a0 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -1,583 +1,647 @@ -/* - RCSwitch - Arduino libary for remote control outlet switches - Copyright (c) 2011 Suat Özgür. All right reserved. - - Contributors: - - Andre Koehler / info(at)tomate-online(dot)de - - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com - - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=48 - - Project home: http://code.google.com/p/rc-switch/ - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "RCSwitch.h" - -unsigned long RCSwitch::nReceivedValue = NULL; -unsigned int RCSwitch::nReceivedBitlength = 0; -unsigned int RCSwitch::nReceivedDelay = 0; -unsigned int RCSwitch::nReceivedProtocol = 0; -unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; -int RCSwitch::nReceiveTolerance = 60; - -RCSwitch::RCSwitch() { - this->nReceiverInterrupt = -1; - this->nTransmitterPin = -1; - RCSwitch::nReceivedValue = NULL; - this->setPulseLength(350); - this->setRepeatTransmit(10); - this->setReceiveTolerance(60); - this->setProtocol(1); -} - -/** - * 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); - } -} - -/** - * Sets the protocol to send with pulse length in microseconds. - */ -void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { - this->nProtocol = nProtocol; - if (nProtocol == 1){ - this->setPulseLength(nPulseLength); - } - else if (nProtocol == 2) { - this->setPulseLength(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; -} - -/** - * Set Receiving Tolerance - */ -void RCSwitch::setReceiveTolerance(int nPercent) { - RCSwitch::nReceiveTolerance = nPercent; -} - - -/** - * Enable transmissions - * - * @param nTransmitterPin Arduino Pin to which the sender is connected to - */ -void RCSwitch::enableTransmit(int nTransmitterPin) { - this->nTransmitterPin = nTransmitterPin; - pinMode(this->nTransmitterPin, OUTPUT); -} - -/** - * Disable transmissions - */ -void RCSwitch::disableTransmit() { - this->nTransmitterPin = -1; -} - -/** - * Switch a remote switch on (Type C Intertechno) - * - * @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) ); -} - -/** - * Switch a remote switch off (Type C Intertechno) - * - * @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) ); -} - -/** - * Switch a remote switch on (Type B with two rotary/sliding switches) - * - * @param nAddressCode Number of the switch group (1..4) - * @param nChannelCode Number of the switch itself (1..4) - */ -void RCSwitch::switchOn(int nAddressCode, int nChannelCode) { - this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) ); -} - -/** - * Switch a remote switch off (Type B with two rotary/sliding switches) - * - * @param nAddressCode Number of the switch group (1..4) - * @param nChannelCode Number of the switch itself (1..4) - */ -void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { - this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) ); -} - -/** - * Switch a remote switch on (Type A with 10 pole DIP switches) - * - * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") - * @param nChannelCode Number of the switch itself (1..4) - */ -void RCSwitch::switchOn(char* sGroup, int nChannel) { - this->sendTriState( this->getCodeWordA(sGroup, nChannel, true) ); -} - -/** - * Switch a remote switch off (Type A with 10 pole DIP switches) - * - * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") - * @param nChannelCode Number of the switch itself (1..4) - */ -void RCSwitch::switchOff(char* sGroup, int nChannel) { - this->sendTriState( this->getCodeWordA(sGroup, nChannel, false) ); -} - -/** - * Returns a char[13], representing the Code Word to be send. - * 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) - * - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit | - * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S | - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * - * @param nAddressCode Number of the switch group (1..4) - * @param nChannelCode Number of the switch itself (1..4) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[13] - */ -char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) { - 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]; - } - - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = code[nChannelCode][i]; - } - - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - - if (bStatus) { - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = '0'; - } - - sReturn[nReturnPos] = '\0'; - - return sReturn; -} - - -/** - * Like getCodeWord (Type A) - */ -char* RCSwitch::getCodeWordA(char* sGroup, int nChannelCode, boolean bStatus) { - int nReturnPos = 0; - static char sReturn[13]; - - char* code[6] = { "FFFFF", "0FFFF", "F0FFF", "FF0FF", "FFF0F", "FFFF0" }; - - if (nChannelCode < 1 || nChannelCode > 5) { - return '\0'; - } - - for (int i = 0; i<5; i++) { - if (sGroup[i] == '0') { - sReturn[nReturnPos++] = 'F'; - } else if (sGroup[i] == '1') { - sReturn[nReturnPos++] = '0'; - } else { - return '\0'; - } - } - - for (int i = 0; i<5; i++) { - sReturn[nReturnPos++] = code[ nChannelCode ][i]; - } - - if (bStatus) { - sReturn[nReturnPos++] = '0'; - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = '0'; - } - sReturn[nReturnPos] = '\0'; - - return sReturn; -} - -/** - * 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; -} - -/** - * Sends a Code Word - * @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(); - } -} - -void RCSwitch::send(unsigned long Code, unsigned int 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(); - } -} - -void RCSwitch::transmit(int nHighPulses, int nLowPulses) { - boolean disabled_Receive = false; - int nReceiverInterrupt_backup = nReceiverInterrupt; - if (this->nTransmitterPin != -1) { - if (this->nReceiverInterrupt != -1) { - this->disableReceive(); - disabled_Receive = true; - } - digitalWrite(this->nTransmitterPin, HIGH); - delayMicroseconds( this->nPulseLength * nHighPulses); - digitalWrite(this->nTransmitterPin, LOW); - delayMicroseconds( this->nPulseLength * nLowPulses); - if(disabled_Receive){ - this->enableReceive(nReceiverInterrupt_backup); - } - } -} -/** - * Sends a "0" Bit - * _ - * Waveform Protocol 1: | |___ - * _ - * Waveform Protocol 2: | |__ - */ -void RCSwitch::send0() { - if (this->nProtocol == 1){ - this->transmit(1,3); - } - else if (this->nProtocol == 2) { - this->transmit(1,2); - } -} - -/** - * Sends a "1" Bit - * ___ - * Waveform Protocol 1: | |_ - * __ - * Waveform Protocol 2: | |_ - */ -void RCSwitch::send1() { - if (this->nProtocol == 1){ - this->transmit(3,1); - } - else if (this->nProtocol == 2) { - this->transmit(2,1); - } -} - - -/** - * Sends a Tri-State "0" Bit - * _ _ - * Waveform: | |___| |___ - */ -void RCSwitch::sendT0() { - this->transmit(1,3); - this->transmit(1,3); -} - -/** - * Sends a Tri-State "1" Bit - * ___ ___ - * Waveform: | |_| |_ - */ -void RCSwitch::sendT1() { - this->transmit(3,1); - this->transmit(3,1); -} - -/** - * Sends a Tri-State "F" Bit - * _ ___ - * Waveform: | |___| |_ - */ -void RCSwitch::sendTF() { - this->transmit(1,3); - this->transmit(3,1); -} - -/** - * Sends a "Sync" Bit - * _ - * Waveform Protocol 1: | |_______________________________ - * _ - * Waveform Protocol 2: | |__________ - */ -void RCSwitch::sendSync() { - - if (this->nProtocol == 1){ - this->transmit(1,31); - } - else if (this->nProtocol == 2) { - this->transmit(1,10); - } -} - -/** - * 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; - } -} - -/** - * Disable receiving data - */ -void RCSwitch::disableReceive() { - this->nReceiverInterrupt = -1; -} - -bool RCSwitch::available() { - return RCSwitch::nReceivedValue != NULL; -} - -void RCSwitch::resetAvailable() { - RCSwitch::nReceivedValue = NULL; -} - -unsigned long RCSwitch::getReceivedValue() { - return RCSwitch::nReceivedValue; -} - -unsigned int RCSwitch::getReceivedBitlength() { - return RCSwitch::nReceivedBitlength; -} - -unsigned int RCSwitch::getReceivedDelay() { - return RCSwitch::nReceivedDelay; -} - -unsigned int RCSwitch::getReceivedProtocol() { - return RCSwitch::nReceivedProtocol; -} - -unsigned int* RCSwitch::getReceivedRawdata() { - return RCSwitch::timings; -} - -/** - * - */ -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; - } - -} - -/** - * Turns a decimal value to its binary representation - */ -char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ - static char bin[64]; - unsigned int i=0; - - while (Dec > 0) { - bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0'; - 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] = '0'; - } - } - bin[bitLength] = '\0'; - - return bin; -} - +/* + RCSwitch - Arduino libary for remote control outlet switches + Copyright (c) 2011 Suat Özgür. All right reserved. + + Contributors: + - Andre Koehler / info(at)tomate-online(dot)de + - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com + - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=48 + - Dominik Fischer / dom_fischer(at)web(dot)de + + Project home: http://code.google.com/p/rc-switch/ + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "RCSwitch.h" + +unsigned long RCSwitch::nReceivedValue = NULL; +unsigned int RCSwitch::nReceivedBitlength = 0; +unsigned int RCSwitch::nReceivedDelay = 0; +unsigned int RCSwitch::nReceivedProtocol = 0; +unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; +int RCSwitch::nReceiveTolerance = 60; + +RCSwitch::RCSwitch() { + this->nReceiverInterrupt = -1; + this->nTransmitterPin = -1; + RCSwitch::nReceivedValue = NULL; + this->setPulseLength(350); + this->setRepeatTransmit(10); + this->setReceiveTolerance(60); + this->setProtocol(1); +} + +/** + * 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); + } +} + +/** + * Sets the protocol to send with pulse length in microseconds. + */ +void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { + this->nProtocol = nProtocol; + if (nProtocol == 1){ + this->setPulseLength(nPulseLength); + } + else if (nProtocol == 2) { + this->setPulseLength(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; +} + +/** + * Set Receiving Tolerance + */ +void RCSwitch::setReceiveTolerance(int nPercent) { + RCSwitch::nReceiveTolerance = nPercent; +} + + +/** + * Enable transmissions + * + * @param nTransmitterPin Arduino Pin to which the sender is connected to + */ +void RCSwitch::enableTransmit(int nTransmitterPin) { + this->nTransmitterPin = nTransmitterPin; + pinMode(this->nTransmitterPin, OUTPUT); +} + +/** + * Disable transmissions + */ +void RCSwitch::disableTransmit() { + this->nTransmitterPin = -1; +} + +/** + * Switch a remote switch on (Type C Intertechno) + * + * @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) ); +} + +/** + * Switch a remote switch off (Type C Intertechno) + * + * @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) ); +} + +/** + * Switch a remote switch on (Type B with two rotary/sliding switches) + * + * @param nAddressCode Number of the switch group (1..4) + * @param nChannelCode Number of the switch itself (1..4) + */ +void RCSwitch::switchOn(int nAddressCode, int nChannelCode) { + this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) ); +} + +/** + * Switch a remote switch off (Type B with two rotary/sliding switches) + * + * @param nAddressCode Number of the switch group (1..4) + * @param nChannelCode Number of the switch itself (1..4) + */ +void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { + this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) ); +} + +/** + * Switch a remote switch on (Type A with 10 pole DIP switches) + * + * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") + * @param nChannelCode Number of the switch itself (1..4) + */ +void RCSwitch::switchOn(char* sGroup, int nChannel) { + this->sendTriState( this->getCodeWordA(sGroup, nChannel, true) ); +} + +/** + * Switch a remote switch off (Type A with 10 pole DIP switches) + * + * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") + * @param nChannelCode Number of the switch itself (1..4) + */ +void RCSwitch::switchOff(char* sGroup, int nChannel) { + this->sendTriState( this->getCodeWordA(sGroup, nChannel, false) ); +} + +/** + * Switch a remote switch on (Type A with 10 pole DIP switches) + * + * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") + * @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) ); +} + +/** + * Switch a remote switch off (Type A with 10 pole DIP switches) + * + * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") + * @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) ); +} + + +/** + * Returns a char[13], representing the Code Word to be send. + * 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) + * + * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ + * | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit | + * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S | + * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ + * + * @param nAddressCode Number of the switch group (1..4) + * @param nChannelCode Number of the switch itself (1..4) + * @param bStatus Wether to switch on (true) or off (false) + * + * @return char[13] + */ +char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) { + int nReturnPos = 0; + static char sReturn[13]; + + const 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]; + } + + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + + if (bStatus) { + sReturn[nReturnPos++] = 'F'; + } else { + sReturn[nReturnPos++] = '0'; + } + + sReturn[nReturnPos] = '\0'; + + return sReturn; +} + + +/** + * Like getCodeWord (Type A) + */ +char* RCSwitch::getCodeWordA(char* sGroup, int nChannelCode, boolean bStatus) { + int nReturnPos = 0; + static char sReturn[13]; + + const char* code[6] = { "FFFFF", "0FFFF", "F0FFF", "FF0FF", "FFF0F", "FFFF0" }; + + if (nChannelCode < 1 || nChannelCode > 5) { + return '\0'; + } + + for (int i = 0; i<5; i++) { + if (sGroup[i] == '0') { + sReturn[nReturnPos++] = 'F'; + } else if (sGroup[i] == '1') { + sReturn[nReturnPos++] = '1'; + } else { + return '\0'; + } + } + + for (int i = 0; i<5; i++) { + sReturn[nReturnPos++] = code[ nChannelCode ][i]; + } + + if (bStatus) { + sReturn[nReturnPos++] = '0'; + sReturn[nReturnPos++] = 'F'; + } else { + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = '0'; + } + sReturn[nReturnPos] = '\0'; + + return sReturn; +} +/** + * Like getCodeWord (Type A) + * + * @param sGroup String representing the dipswich setting for the group (switches 1-5) + * @param sDevice String representing the dipswich setting for the device (switches A-E) + * (any combinations are allowed -> 2^5 Devices, not only 5!) + * + */ +char* RCSwitch::getCodeWordA(char* sGroup, char* sDevice, boolean bOn) { + 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 (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'; + } + + sDipSwitches[j] = '\0'; + + 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; +} + +/** + * Sends a Code Word + * @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(); + } +} + +void RCSwitch::send(unsigned long Code, unsigned int 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(); + } +} + +void RCSwitch::transmit(int nHighPulses, int nLowPulses) { + boolean disabled_Receive = false; + int nReceiverInterrupt_backup = nReceiverInterrupt; + if (this->nTransmitterPin != -1) { + if (this->nReceiverInterrupt != -1) { + this->disableReceive(); + disabled_Receive = true; + } + digitalWrite(this->nTransmitterPin, HIGH); + delayMicroseconds( this->nPulseLength * nHighPulses); + digitalWrite(this->nTransmitterPin, LOW); + delayMicroseconds( this->nPulseLength * nLowPulses); + if(disabled_Receive){ + this->enableReceive(nReceiverInterrupt_backup); + } + } +} +/** + * Sends a "0" Bit + * _ + * Waveform Protocol 1: | |___ + * _ + * Waveform Protocol 2: | |__ + */ +void RCSwitch::send0() { + if (this->nProtocol == 1){ + this->transmit(1,3); + } + else if (this->nProtocol == 2) { + this->transmit(1,2); + } +} + +/** + * Sends a "1" Bit + * ___ + * Waveform Protocol 1: | |_ + * __ + * Waveform Protocol 2: | |_ + */ +void RCSwitch::send1() { + if (this->nProtocol == 1){ + this->transmit(3,1); + } + else if (this->nProtocol == 2) { + this->transmit(2,1); + } +} + + +/** + * Sends a Tri-State "0" Bit + * _ _ + * Waveform: | |___| |___ + */ +void RCSwitch::sendT0() { + this->transmit(1,3); + this->transmit(1,3); +} + +/** + * Sends a Tri-State "1" Bit + * ___ ___ + * Waveform: | |_| |_ + */ +void RCSwitch::sendT1() { + this->transmit(3,1); + this->transmit(3,1); +} + +/** + * Sends a Tri-State "F" Bit + * _ ___ + * Waveform: | |___| |_ + */ +void RCSwitch::sendTF() { + this->transmit(1,3); + this->transmit(3,1); +} + +/** + * Sends a "Sync" Bit + * _ + * Waveform Protocol 1: | |_______________________________ + * _ + * Waveform Protocol 2: | |__________ + */ +void RCSwitch::sendSync() { + + if (this->nProtocol == 1){ + this->transmit(1,31); + } + else if (this->nProtocol == 2) { + this->transmit(1,10); + } +} + +/** + * 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; + } +} + +/** + * Disable receiving data + */ +void RCSwitch::disableReceive() { + this->nReceiverInterrupt = -1; +} + +bool RCSwitch::available() { + return RCSwitch::nReceivedValue != NULL; +} + +void RCSwitch::resetAvailable() { + RCSwitch::nReceivedValue = NULL; +} + +unsigned long RCSwitch::getReceivedValue() { + return RCSwitch::nReceivedValue; +} + +unsigned int RCSwitch::getReceivedBitlength() { + return RCSwitch::nReceivedBitlength; +} + +unsigned int RCSwitch::getReceivedDelay() { + return RCSwitch::nReceivedDelay; +} + +unsigned int RCSwitch::getReceivedProtocol() { + return RCSwitch::nReceivedProtocol; +} + +unsigned int* RCSwitch::getReceivedRawdata() { + return RCSwitch::timings; +} + +/** + * + */ +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; + } + +} + +/** + * Turns a decimal value to its binary representation + */ +char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ + static char bin[64]; + unsigned int i=0; + + while (Dec > 0) { + bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0'; + 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] = '0'; + } + } + bin[bitLength] = '\0'; + + return bin; +} + diff --git a/RCSwitch.h b/RCSwitch.h index f762ebc..f011df1 100644 --- a/RCSwitch.h +++ b/RCSwitch.h @@ -1,123 +1,127 @@ -/* - RCSwitch - Arduino libary for remote control outlet switches - Copyright (c) 2011 Suat Özgür. All right reserved. - - Contributors: - - Andre Koehler / info(at)tomate-online(dot)de - - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com - - Project home: http://code.google.com/p/rc-switch/ - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef _RCSwitch_h -#define _RCSwitch_h - -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" -#else - #include - #include - #define NULL 0 - #define CHANGE 1 -#ifdef __cplusplus -extern "C"{ -#endif -typedef uint8_t boolean; -typedef uint8_t byte; - -#if !defined(NULL) -#endif -#ifdef __cplusplus -} -#endif -#endif - - -// 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 - - -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 sendTriState(char* Code); - void send(unsigned long Code, unsigned int length); - void send(char* Code); - - 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(); - - void enableTransmit(int nTransmitterPin); - void disableTransmit(); - void setPulseLength(int nPulseLength); - void setRepeatTransmit(int nRepeatTransmit); - void setReceiveTolerance(int nPercent); - void setProtocol(int nProtocol); - void setProtocol(int nProtocol, int nPulseLength); - - private: - char* getCodeWordB(int nGroupNumber, int nSwitchNumber, boolean bStatus); - char* getCodeWordA(char* sGroup, int nSwitchNumber, boolean bStatus); - char* getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus); - void sendT0(); - void sendT1(); - void sendTF(); - void send0(); - void send1(); - void sendSync(); - void transmit(int nHighPulses, int nLowPulses); - - static char* dec2binWzerofill(unsigned long dec, unsigned int length); - - static void handleInterrupt(); - static bool receiveProtocol1(unsigned int changeCount); - static bool receiveProtocol2(unsigned int changeCount); - int nReceiverInterrupt; - int nTransmitterPin; - int nPulseLength; - int nRepeatTransmit; - char nProtocol; - - static int nReceiveTolerance; - static unsigned long nReceivedValue; - static unsigned int nReceivedBitlength; - static unsigned int nReceivedDelay; - static unsigned int nReceivedProtocol; - static unsigned int timings[RCSWITCH_MAX_CHANGES]; - - -}; - -#endif +/* + RCSwitch - Arduino libary for remote control outlet switches + Copyright (c) 2011 Suat Özgür. All right reserved. + + Contributors: + - Andre Koehler / info(at)tomate-online(dot)de + - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com + - Dominik Fischer / dom_fischer(at)web(dot)de + + Project home: http://code.google.com/p/rc-switch/ + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef _RCSwitch_h +#define _RCSwitch_h + +#if defined(ARDUINO) && ARDUINO >= 100 + #include "Arduino.h" +#else + #include + #include + #define NULL 0 + #define CHANGE 1 +#ifdef __cplusplus +extern "C"{ +#endif +typedef uint8_t boolean; +typedef uint8_t byte; + +#if !defined(NULL) +#endif +#ifdef __cplusplus +} +#endif +#endif + + +// 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 + + +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 sendTriState(char* Code); + void send(unsigned long Code, unsigned int length); + void send(char* Code); + + 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(); + + void enableTransmit(int nTransmitterPin); + void disableTransmit(); + void setPulseLength(int nPulseLength); + void setRepeatTransmit(int nRepeatTransmit); + void setReceiveTolerance(int nPercent); + void setProtocol(int nProtocol); + void setProtocol(int nProtocol, int nPulseLength); + + 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); + void sendT0(); + void sendT1(); + void sendTF(); + void send0(); + void send1(); + void sendSync(); + void transmit(int nHighPulses, int nLowPulses); + + static char* dec2binWzerofill(unsigned long dec, unsigned int length); + + static void handleInterrupt(); + static bool receiveProtocol1(unsigned int changeCount); + static bool receiveProtocol2(unsigned int changeCount); + int nReceiverInterrupt; + int nTransmitterPin; + int nPulseLength; + int nRepeatTransmit; + char nProtocol; + + static int nReceiveTolerance; + static unsigned long nReceivedValue; + static unsigned int nReceivedBitlength; + static unsigned int nReceivedDelay; + static unsigned int nReceivedProtocol; + static unsigned int timings[RCSWITCH_MAX_CHANGES]; + + +}; + +#endif diff --git a/send.cpp b/send.cpp index 076e77c..c93d5c8 100644 --- a/send.cpp +++ b/send.cpp @@ -1,11 +1,28 @@ /* - Usage: ./send - Command is 0 for OFF and 1 for ON + Usage: see printUsage() */ #include "RCSwitch.h" #include #include +#include +#include + +void printUsage() +{ + std::cout << " Usage: sudo ./send \n"; + std::cout << " e.g. sudo ./send 01011 3 1\n"; + std::cout << " sudo ./send \n"; + std::cout << " e.g. sudo ./send 4 3 0\n"; + std::cout << " sudo ./send \n"; + std::cout << " e.g. sudo ./send c 2 3 1\n"; + std::cout << " sudo ./send \n"; + std::cout << " e.g. sudo ./send 11100 00001 1\n"; + std::cout << "\n"; + std::cout << " Command is 0 for OFF and 1 for ON\n"; + std::cout << "\n"; + std::cout << " See http://code.google.com/p/rc-switch/wiki/HowTo_OperateLowCostOutlets for more information about supported switches\n"; +} int main(int argc, char *argv[]) { @@ -15,25 +32,91 @@ int main(int argc, char *argv[]) { for pin mapping of the raspberry pi GPIO connector */ int PIN = 0; - char* systemCode = argv[1]; - int unitCode = atoi(argv[2]); - int command = atoi(argv[3]); - - if (wiringPiSetup () == -1) return 1; - printf("sending systemCode[%s] unitCode[%i] command[%i]\n", systemCode, unitCode, command); + if (wiringPiSetup () == -1) return 1; RCSwitch mySwitch = RCSwitch(); mySwitch.enableTransmit(PIN); + + if(argc == 4) + { + char* sGroup = argv[1]; + char* sSwitch = argv[2]; + int nSwitchNumber = atoi(argv[2]); + + int command = atoi(argv[3]); + + if(strlen(sGroup) > 2) + { + //Type A: 10 pole DIP switches + printf("sending [Type A] groupCode[%s] switchNumber[%s] command[%i]\n", sGroup, sSwitch, command); + + switch(command) { + case 1: + if (strlen(sSwitch) > 2) { + mySwitch.switchOn(sGroup, sSwitch); + } else { + mySwitch.switchOn(sGroup, nSwitchNumber); + } + break; + case 0: + if (strlen(sSwitch) > 2) { + mySwitch.switchOff(sGroup, sSwitch); + } else { + mySwitch.switchOff(sGroup, nSwitchNumber); + } + break; + default: + printf("command[%i] is unsupported\n", command); + printUsage(); + return -1; + } + return 0; + } else { + //Type B: Two rotary/sliding switches + int nGroupNumber = atoi(sGroup); + printf("sending [Type B] groupNumber[%i] switchNumber[%i] command[%i]\n", nGroupNumber, nSwitchNumber, command); + switch(command) { + case 1: + mySwitch.switchOn(nGroupNumber, nSwitchNumber); + break; + case 0: + mySwitch.switchOff(nGroupNumber, nSwitchNumber); + break; + default: + printf("command[%i] is unsupported\n", command); + printUsage(); + return -1; + } + return 0; + } + } + else if(argc == 5) + { + //Type C: Intertechno + char* sFamily = argv[1]; + int nGroup = atoi(argv[2]); + int nDevice = atoi(argv[3]); + + int command = atoi(argv[4]); - switch(command) { - case 1: - mySwitch.switchOn(systemCode, unitCode); - break; - case 0: - mySwitch.switchOff(systemCode, unitCode); - break; - default: - printf("command[%i] is unsupported\n", command); - return -1; - } - return 0; + printf("sending [Type C] family[%s] groupNumber[%i] switchNumber[%i] command[%i]\n", sFamily, nGroup, nDevice, command); + + switch(command) { + case 1: + mySwitch.switchOn(sFamily[0], nGroup, nDevice); + break; + case 0: + mySwitch.switchOff(sFamily[0], nGroup, nDevice); + break; + default: + printf("command[%i] is unsupported\n", command); + printUsage(); + return -1; + } + return 0; + } + else + { + printUsage(); + } + return 1; }