diff --git a/RCSwitch.cpp b/RCSwitch.cpp index 4ce4df9..5e2a3a8 100644 --- a/RCSwitch.cpp +++ b/RCSwitch.cpp @@ -1,12 +1,12 @@ /* RCSwitch - Arduino libary for remote control outlet switches - Copyright (c) 2011 Suat Özgür. All right reserved. - + 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 @@ -90,7 +90,7 @@ void RCSwitch::setRepeatTransmit(int nRepeatTransmit) { void RCSwitch::setReceiveTolerance(int nPercent) { RCSwitch::nReceiveTolerance = nPercent; } - + /** * Enable transmissions @@ -190,8 +190,8 @@ void RCSwitch::switchOff(char* sGroup, int nChannel) { char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) { int nReturnPos = 0; static char sReturn[13]; - - char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; + + const char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { return '\0'; } @@ -202,19 +202,19 @@ char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus 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; } @@ -226,12 +226,12 @@ 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" }; + 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'; @@ -241,11 +241,11 @@ char* RCSwitch::getCodeWordA(char* sGroup, int nChannelCode, boolean bStatus) { return '\0'; } } - + for (int i = 0; i<5; i++) { sReturn[nReturnPos++] = code[ nChannelCode ][i]; } - + if (bStatus) { sReturn[nReturnPos++] = '0'; sReturn[nReturnPos++] = 'F'; @@ -264,11 +264,11 @@ char* RCSwitch::getCodeWordA(char* sGroup, int nChannelCode, boolean bStatus) { 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++) { @@ -310,7 +310,7 @@ void RCSwitch::sendTriState(char* sCodeWord) { } i++; } - this->sendSync(); + this->sendSync(); } } @@ -355,9 +355,9 @@ void RCSwitch::transmit(int nHighPulses, int nLowPulses) { } /** * Sends a "0" Bit - * _ + * _ * Waveform Protocol 1: | |___ - * _ + * _ * Waveform Protocol 2: | |__ */ void RCSwitch::send0() { @@ -371,9 +371,9 @@ void RCSwitch::send0() { /** * Sends a "1" Bit - * ___ + * ___ * Waveform Protocol 1: | |_ - * __ + * __ * Waveform Protocol 2: | |_ */ void RCSwitch::send1() { @@ -445,6 +445,7 @@ void RCSwitch::enableReceive() { if (this->nReceiverInterrupt != -1) { RCSwitch::nReceivedValue = NULL; RCSwitch::nReceivedBitlength = NULL; + wiringPiISR(this->nReceiverInterrupt, INT_EDGE_BOTH, &handleInterrupt); } } @@ -487,13 +488,13 @@ unsigned int* RCSwitch::getReceivedRawdata() { * */ 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; + 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) { @@ -504,7 +505,7 @@ bool RCSwitch::receiveProtocol1(unsigned int changeCount){ 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; @@ -518,18 +519,18 @@ bool RCSwitch::receiveProtocol1(unsigned int changeCount){ }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; + 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) { @@ -540,7 +541,7 @@ bool RCSwitch::receiveProtocol2(unsigned int changeCount){ 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; @@ -557,6 +558,41 @@ bool RCSwitch::receiveProtocol2(unsigned int changeCount){ } +void RCSwitch::handleInterrupt() { + + static unsigned int duration; + static unsigned int changeCount; + static unsigned long lastTime; + static unsigned int repeatCount; + + long time = micros(); + duration = time - lastTime; + + if (duration > 5000 && duration > RCSwitch::timings[0] - 200 && duration < RCSwitch::timings[0] + 200) { + repeatCount++; + changeCount--; + + if (repeatCount == 2) { + if (receiveProtocol1(changeCount) == false){ + if (receiveProtocol2(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 */ @@ -577,7 +613,6 @@ char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ } } bin[bitLength] = '\0'; - + return bin; } -