Revert "Merge pull request #9121 from Jason2866/rc_switch"

This reverts commit b827b6ca20, reversing
changes made to 39ca0d6c72.
This commit is contained in:
Theo Arends 2020-08-19 16:40:07 +02:00
parent 3308b7a995
commit f6128bdae3
21 changed files with 135 additions and 498 deletions

View File

@ -0,0 +1,69 @@
language: c
python:
- "2.7"
# Cache PlatformIO packages using Travis CI container-based infrastructure
cache:
pip: true
directories:
- "~/.platformio"
env:
- >
PLATFORMIO_CI_SRC=$PWD/examples/Webserver
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/Webserver.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01"
- >
PLATFORMIO_CI_SRC=$PWD/examples/ReceiveDemo_Simple
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/ReceiveDemo_Simple.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01"
- >
PLATFORMIO_CI_SRC=$PWD/examples/TypeC_Intertechno
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/TypeC_Intertechno.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01 --board=attiny25 --board=attiny24"
- >
PLATFORMIO_CI_SRC=$PWD/examples/TypeD_REV
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/TypeD_REV.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01 --board=attiny25 --board=attiny24"
- >
PLATFORMIO_CI_SRC=$PWD/examples/TypeA_WithDIPSwitches
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/TypeA_WithDIPSwitches.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01 --board=attiny25 --board=attiny24"
- >
PLATFORMIO_CI_SRC=$PWD/examples/TypeA_WithDIPSwitches_Lightweight
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/TypeA_WithDIPSwitches_Lightweight.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01 --board=attiny25 --board=attiny24"
- >
PLATFORMIO_CI_SRC=$PWD/examples/TypeB_WithRotaryOrSlidingSwitches
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/TypeB_WithRotaryOrSlidingSwitches.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01 --board=attiny25 --board=attiny24"
- >
PLATFORMIO_CI_SRC=$PWD/examples/SendDemo
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/SendDemo.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01"
- >
PLATFORMIO_CI_SRC=$PWD/examples/ReceiveDemo_Advanced
ARDUINOIDE_CI_SRC=$PLATFORMIO_CI_SRC/ReceiveDemo_Advanced.ino
BOARDS="--board=diecimilaatmega328 --board=uno --board=esp01"
before_install:
# Arduino IDE
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
- sleep 3
- export DISPLAY=:1.0
- wget http://downloads.arduino.cc/arduino-1.6.9-linux64.tar.xz
- tar xf arduino-1.6.9-linux64.tar.xz
- sudo mv arduino-1.6.9 /usr/local/share/arduino
- sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
install:
# Arduino IDE
- ln -s $PWD /usr/local/share/arduino/libraries/rc-switch
# PlatformIO
- sudo pip install -U platformio
script:
# Arduino IDE
- arduino --verify --board arduino:avr:uno ${ARDUINOIDE_CI_SRC}
# PlatformIO
- platformio ci --lib="." ${BOARDS}

View File

@ -13,6 +13,7 @@
- Robert ter Vehn / <first name>.<last name>(at)gmail(dot)com - Robert ter Vehn / <first name>.<last name>(at)gmail(dot)com
- Johann Richard / <first name>.<last name>(at)gmail(dot)com - Johann Richard / <first name>.<last name>(at)gmail(dot)com
- Vlad Gheorghe / <first name>.<last name>(at)gmail(dot)com https://github.com/vgheo - Vlad Gheorghe / <first name>.<last name>(at)gmail(dot)com https://github.com/vgheo
- Matias Cuenca-Acuna
Project home: https://github.com/sui77/rc-switch/ Project home: https://github.com/sui77/rc-switch/
@ -31,8 +32,6 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#define KeeLoq_NLF 0x3A5C742EUL
#include "RCSwitch.h" #include "RCSwitch.h"
#ifdef RaspberryPi #ifdef RaspberryPi
@ -56,77 +55,42 @@
#endif #endif
/* Protocol description format /* Format for protocol definitions:
* {pulselength, Sync bit, "0" bit, "1" bit, invertedSignal}
* *
* {Pulse length, Preamble, Sync bit, "0" bit, "1" bit, Inverted Signal, Guard time} * pulselength: pulse length in microseconds, e.g. 350
* * Sync bit: {1, 31} means 1 high pulse and 31 low pulses
* Pulse length: pulse duration Te in microseconds, * (perceived as a 31*pulselength long pulse, total length of sync bit is
* example 350 * 32*pulselength microseconds), i.e:
* Preamble: Alternating high and low levels
* {20, 1} means 20 alternations of 1 Te duration
* _ _ _ _ _ _ _ _ _ _
* | |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
* Sync bit: Header and clock
* {1, 31} means 1 pulse long Te high and 31 low
* _ * _
* | |_______________________________ (don't count the vertical bars) * | |_______________________________ (don't count the vertical bars)
* "0" bit: pulse shape defining a data bit, which is a logical "0" * "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse
* {1, 3} means 1 pulse duration Te high level and 3 low * and 3 low pulses, total length (1+3)*pulselength, i.e:
* _ * _
* | |___ * | |___
* "1" bit: pulse shape that defines the data bit, which is a logical "1" * "1" bit: waveform for a data bit of value "1", e.g. {3,1}:
* {3, 1} means 3 pulses with a duration of Te high level and 1 low
* ___ * ___
* | |_ * | |_
* *
* (note: to form the state bit Z (Tri-State bit), these two codes are combined) * These are combined to form Tri-State bits when sending or receiving codes.
* Inverted Signal: Signal inversion - if true the signal is inverted
* replacing high to low in a transmitted / received packet
* Guard time: Safety time, followed by the next preamble of the next packet
* for example 39 pulses of low duration Te
*/ */
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
static const VAR_ISR_ATTR RCSwitch::Protocol proto[] = { static const VAR_ISR_ATTR RCSwitch::Protocol proto[] = {
#else #else
static const RCSwitch::Protocol PROGMEM proto[] = { static const RCSwitch::Protocol PROGMEM proto[] = {
#endif #endif
{ 350, 0, { 0, 0 }, 1, { 1, 31 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 01 (Princeton, PT-2240) { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1
{ 650, 0, { 0, 0 }, 1, { 1, 10 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 02 { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2
{ 100, 0, { 0, 0 }, 1, { 30, 71 }, { 4, 11 }, { 9, 6 }, false, 0 }, // 03 { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3
{ 380, 0, { 0, 0 }, 1, { 1, 6 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 04 { 380, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4
{ 500, 0, { 0, 0 }, 1, { 6, 14 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 05 { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5
{ 450, 0, { 0, 0 }, 1, { 23, 1 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 06 (HT6P20B) { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 6 (HT6P20B)
{ 150, 0, { 0, 0 }, 1, { 2, 62 }, { 1, 6 }, { 6, 1 }, false, 0 }, // 07 (HS2303-PT, i. e. used in AUKEY Remote) { 150, { 2, 62 }, { 1, 6 }, { 6, 1 }, false }, // protocol 7 (HS2303-PT, i. e. used in AUKEY Remote)
{ 320, 0, { 0, 0 }, 1, { 36, 1 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 08 (Came 12bit, HT12E) { 200, { 3, 130}, { 7, 16 }, { 3, 16}, false}, // protocol 8 Conrad RS-200 RX
{ 700, 0, { 0, 0 }, 1, { 32, 1 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 09 (Nice_Flo 12bit) { 200, { 130, 7 }, { 16, 7 }, { 16, 3 }, true}, // protocol 9 Conrad RS-200 TX
{ 420, 0, { 0, 0 }, 1, { 60, 6 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 10 (V2 phoenix) { 365, { 18, 1 }, { 3, 1 }, { 1, 3 }, true }, // protocol 10 (1ByOne Doorbell)
{ 500, 2, { 3, 3 }, 0, { 0, 0 }, { 1, 2 }, { 2, 1 }, false, 37 }, // 11 (Nice_FloR-S 52bit) { 270, { 36, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 11 (HT12E)
{ 400, 23, { 1, 1 }, 1, { 0, 9 }, { 2, 1 }, { 1, 2 }, false, 39 }, // 12 (Keeloq 64/66) { 320, { 36, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 12 (SM5212)
{ 300, 6, { 2, 2 }, 3, { 8, 3 }, { 2, 2 }, { 3, 3 }, false, 0 }, // 13 test (CFM)
{ 250, 12, { 4, 4 }, 0, { 0, 0 }, { 1, 1 }, { 2, 2 }, false, 0 }, // 14 test (StarLine)
{ 500, 0, { 0, 0 }, 0, { 100, 1 }, { 1, 2 }, { 2, 1 }, false, 35 }, // 15
{ 361, 0, { 0, 0 }, 1, { 52, 1 }, { 1, 3 }, { 3, 1 }, true, 0 }, // 16 (Einhell)
{ 500, 0, { 0, 0 }, 1, { 1, 23 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 17 (InterTechno PAR-1000)
{ 180, 0, { 0, 0 }, 1, { 1, 15 }, { 1, 1 }, { 1, 8 }, false, 0 }, // 18 (Intertechno ITT-1500)
{ 350, 0, { 0, 0 }, 1, { 1, 2 }, { 0, 2 }, { 3, 2 }, false, 0 }, // 19 (Murcury)
{ 150, 0, { 0, 0 }, 1, { 34, 3 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 20 (AC114)
{ 360, 0, { 0, 0 }, 1, { 13, 4 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 21 (DC250)
{ 650, 0, { 0, 0 }, 1, { 1, 10 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 22 (Mandolyn/Lidl TR-502MSV/RC-402/RC-402DX)
{ 641, 0, { 0, 0 }, 1, { 115, 1 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 23 (Lidl TR-502MSV/RC-402 - Flavien)
{ 620, 0, { 0, 0 }, 1, { 0, 64 }, { 0, 1 }, { 1, 0 }, false, 0 }, // 24 (Lidl TR-502MSV/RC701)
{ 560, 0, { 0, 0 }, 1, { 16, 8 }, { 1, 1 }, { 1, 3 }, false, 0 }, // 25 (NEC)
{ 385, 0, { 0, 0 }, 1, { 1, 17 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 26 (Arlec RC210)
{ 188, 0, { 0, 0 }, 1, { 1, 31 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 27 (Zap, FHT-7901)
{ 700, 1, { 0, 1 }, 1, { 116, 0 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 28 (Quigg GT-7000) from @Tho85 https://github.com/sui77/rc-switch/pull/115
{ 220, 0, { 0, 0 }, 1, { 1, 46 }, { 1, 6 }, { 1, 1 }, false, 2 }, // 29 (NEXA)
{ 260, 0, { 0, 0 }, 1, { 1, 8 }, { 1, 4 }, { 4, 1 }, true, 0 }, // 30 (Anima)
{ 400, 0, { 0, 0 }, 1, { 1, 1 }, { 1, 2 }, { 2, 1 }, false, 43 }, // 31 (Mertik Maxitrol G6R-H4T1)
{ 365, 0, { 0, 0 }, 1, { 18, 1 }, { 3, 1 }, { 1, 3 }, true, 0 }, // 32 (1ByOne Doorbell) from @Fatbeard https://github.com/sui77/rc-switch/pull/277
{ 340, 0, { 0, 0 }, 1, { 14, 4 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 33 (Dooya Control DC2708L)
{ 120, 0, { 0, 0 }, 1, { 1, 28 }, { 1, 3 }, { 3, 1 }, false, 0 } // 34 DIGOO SD10
}; };
enum { enum {
@ -134,23 +98,21 @@ enum {
}; };
#if not defined( RCSwitchDisableReceiving ) #if not defined( RCSwitchDisableReceiving )
volatile unsigned long long RCSwitch::nReceivedValue = 0; volatile unsigned long RCSwitch::nReceivedValue = 0;
volatile unsigned int RCSwitch::nReceivedBitlength = 0; volatile unsigned int RCSwitch::nReceivedBitlength = 0;
volatile unsigned int RCSwitch::nReceivedDelay = 0; volatile unsigned int RCSwitch::nReceivedDelay = 0;
volatile unsigned int RCSwitch::nReceivedProtocol = 0; volatile unsigned int RCSwitch::nReceivedProtocol = 0;
int RCSwitch::nReceiveTolerance = 60; int RCSwitch::nReceiveTolerance = 60;
const unsigned int RCSwitch::nSeparationLimit = 2600; // 4300 default const unsigned int RCSwitch::nSeparationLimit = 4300;
// separationLimit: minimum microseconds between received codes, closer codes are ignored. // separationLimit: minimum microseconds between received codes, closer codes are ignored.
// according to discussion on issue #14 it might be more suitable to set the separation // according to discussion on issue #14 it might be more suitable to set the separation
// limit to the same time as the 'low' part of the sync signal for the current protocol. // limit to the same time as the 'low' part of the sync signal for the current protocol.
// should be set to the minimum value of pulselength * the sync signal
unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES];
unsigned int RCSwitch::buftimings[4];
#endif #endif
RCSwitch::RCSwitch() { RCSwitch::RCSwitch() {
this->nTransmitterPin = -1; this->nTransmitterPin = -1;
this->setRepeatTransmit(5); this->setRepeatTransmit(10);
this->setProtocol(1); this->setProtocol(1);
#if not defined( RCSwitchDisableReceiving ) #if not defined( RCSwitchDisableReceiving )
this->nReceiverInterrupt = -1; this->nReceiverInterrupt = -1;
@ -490,7 +452,7 @@ char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) {
*/ */
void RCSwitch::sendTriState(const char* sCodeWord) { void RCSwitch::sendTriState(const char* sCodeWord) {
// turn the tristate code word into the corresponding bit pattern, then send it // turn the tristate code word into the corresponding bit pattern, then send it
unsigned long long code = 0; unsigned long code = 0;
unsigned int length = 0; unsigned int length = 0;
for (const char* p = sCodeWord; *p; p++) { for (const char* p = sCodeWord; *p; p++) {
code <<= 2L; code <<= 2L;
@ -500,11 +462,11 @@ void RCSwitch::sendTriState(const char* sCodeWord) {
break; break;
case 'F': case 'F':
// bit pattern 01 // bit pattern 01
code |= 1ULL; code |= 1L;
break; break;
case '1': case '1':
// bit pattern 11 // bit pattern 11
code |= 3ULL; code |= 3L;
break; break;
} }
length += 2; length += 2;
@ -512,37 +474,17 @@ void RCSwitch::sendTriState(const char* sCodeWord) {
this->send(code, length); this->send(code, length);
} }
/**
* @param duration no. of microseconds to delay
*/
static inline void safeDelayMicroseconds(unsigned long duration) {
#if defined(ESP8266) || defined(ESP32)
if (duration > 10000) {
// if delay > 10 milliseconds, use yield() to avoid wdt reset
unsigned long start = micros();
while ((micros() - start) < duration) {
yield();
}
}
else {
delayMicroseconds(duration);
}
#else
delayMicroseconds(duration);
#endif
}
/** /**
* @param sCodeWord a binary code word consisting of the letter 0, 1 * @param sCodeWord a binary code word consisting of the letter 0, 1
*/ */
void RCSwitch::send(const char* sCodeWord) { void RCSwitch::send(const char* sCodeWord) {
// turn the tristate code word into the corresponding bit pattern, then send it // turn the tristate code word into the corresponding bit pattern, then send it
unsigned long long code = 0; unsigned long code = 0;
unsigned int length = 0; unsigned int length = 0;
for (const char* p = sCodeWord; *p; p++) { for (const char* p = sCodeWord; *p; p++) {
code <<= 1ULL; code <<= 1L;
if (*p != '0') if (*p != '0')
code |= 1ULL; code |= 1L;
length++; length++;
} }
this->send(code, length); this->send(code, length);
@ -553,7 +495,7 @@ void RCSwitch::send(const char* sCodeWord) {
* bits are sent from MSB to LSB, i.e., first the bit at position length-1, * bits are sent from MSB to LSB, i.e., first the bit at position length-1,
* then the bit at position length-2, and so on, till finally the bit at position 0. * then the bit at position length-2, and so on, till finally the bit at position 0.
*/ */
void RCSwitch::send(unsigned long long code, unsigned int length) { void RCSwitch::send(unsigned long code, unsigned int length) {
if (this->nTransmitterPin == -1) if (this->nTransmitterPin == -1)
return; return;
@ -565,41 +507,14 @@ void RCSwitch::send(unsigned long long code, unsigned int length) {
} }
#endif #endif
// repeat sending the packet nRepeatTransmit times
for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) { for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) {
// send the preamble for (int i = length-1; i >= 0; i--) {
for (int i = 0; i < ((protocol.PreambleFactor / 2) + (protocol.PreambleFactor %2 )); i++) { if (code & (1L << i))
this->transmit({protocol.Preamble.high, protocol.Preamble.low});
}
// send the header
if (protocol.HeaderFactor > 0) {
for (int i = 0; i < protocol.HeaderFactor; i++) {
this->transmit(protocol.Header);
}
}
// send the code
for (int i = length - 1; i >= 0; i--) {
if (code & (1ULL << i))
this->transmit(protocol.one); this->transmit(protocol.one);
else else
this->transmit(protocol.zero); this->transmit(protocol.zero);
} }
// for kilok, there should be a duration of 66, and 64 significant data codes are stored this->transmit(protocol.syncFactor);
// send two more bits for even count
if (length == 64) {
if (nRepeat == 0) {
this->transmit(protocol.zero);
this->transmit(protocol.zero);
} else {
this->transmit(protocol.one);
this->transmit(protocol.one);
}
}
// Set the guard Time
if (protocol.Guard > 0) {
digitalWrite(this->nTransmitterPin, LOW);
safeDelayMicroseconds(this->protocol.pulseLength * protocol.Guard);
}
} }
// Disable transmit after sending (i.e., for inverted protocols) // Disable transmit after sending (i.e., for inverted protocols)
@ -620,14 +535,10 @@ void RCSwitch::transmit(HighLow pulses) {
uint8_t firstLogicLevel = (this->protocol.invertedSignal) ? LOW : HIGH; uint8_t firstLogicLevel = (this->protocol.invertedSignal) ? LOW : HIGH;
uint8_t secondLogicLevel = (this->protocol.invertedSignal) ? HIGH : LOW; uint8_t secondLogicLevel = (this->protocol.invertedSignal) ? HIGH : LOW;
if (pulses.high > 0) {
digitalWrite(this->nTransmitterPin, firstLogicLevel); digitalWrite(this->nTransmitterPin, firstLogicLevel);
delayMicroseconds( this->protocol.pulseLength * pulses.high); delayMicroseconds( this->protocol.pulseLength * pulses.high);
}
if (pulses.low > 0) {
digitalWrite(this->nTransmitterPin, secondLogicLevel); digitalWrite(this->nTransmitterPin, secondLogicLevel);
delayMicroseconds( this->protocol.pulseLength * pulses.low); delayMicroseconds( this->protocol.pulseLength * pulses.low);
}
} }
@ -670,7 +581,7 @@ void RCSwitch::resetAvailable() {
RCSwitch::nReceivedValue = 0; RCSwitch::nReceivedValue = 0;
} }
unsigned long long RCSwitch::getReceivedValue() { unsigned long RCSwitch::getReceivedValue() {
return RCSwitch::nReceivedValue; return RCSwitch::nReceivedValue;
} }
@ -706,41 +617,12 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
memcpy_P(&pro, &proto[p-1], sizeof(Protocol)); memcpy_P(&pro, &proto[p-1], sizeof(Protocol));
#endif #endif
unsigned long long code = 0; unsigned long code = 0;
unsigned int FirstTiming = 0; //Assuming the longer pulse length is the pulse captured in timings[0]
if (pro.PreambleFactor > 0) { const unsigned int syncLengthInPulses = ((pro.syncFactor.low) > (pro.syncFactor.high)) ? (pro.syncFactor.low) : (pro.syncFactor.high);
FirstTiming = pro.PreambleFactor + 1; const unsigned int delay = RCSwitch::timings[0] / syncLengthInPulses;
}
unsigned int BeginData = 0;
if (pro.HeaderFactor > 0) {
BeginData = (pro.invertedSignal) ? (2) : (1);
// Header pulse count correction for more than one
if (pro.HeaderFactor > 1) {
BeginData += (pro.HeaderFactor - 1) * 2;
}
}
//Assuming the longer pulse length is the pulse captured in timings[FirstTiming]
// берем наибольшее значение из Header
const unsigned int syncLengthInPulses = ((pro.Header.low) > (pro.Header.high)) ? (pro.Header.low) : (pro.Header.high);
// определяем длительность Te как длительность первого импульса header деленную на количество импульсов в нем
// или как длительность импульса preamble деленную на количество Te в нем
unsigned int sdelay = 0;
if (syncLengthInPulses > 0) {
sdelay = RCSwitch::timings[FirstTiming] / syncLengthInPulses;
} else {
sdelay = RCSwitch::timings[FirstTiming-2] / pro.PreambleFactor;
}
const unsigned int delay = sdelay;
// nReceiveTolerance = 60
// допустимое отклонение длительностей импульсов на 60 %
const unsigned int delayTolerance = delay * RCSwitch::nReceiveTolerance / 100; const unsigned int delayTolerance = delay * RCSwitch::nReceiveTolerance / 100;
// 0 - sync перед preamble или data
// BeginData - сдвиг на 1 или 2 от sync к preamble/data
// FirstTiming - сдвиг на preamble к header
// firstDataTiming первый импульс data
// bitChangeCount - количество импульсов в data
/* For protocols that start low, the sync period looks like /* For protocols that start low, the sync period looks like
* _________ * _________
* _____________| |XXXXXXXXXXXX| * _____________| |XXXXXXXXXXXX|
@ -758,16 +640,9 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
* *
* The 2nd saved duration starts the data * The 2nd saved duration starts the data
*/ */
// если invertedSignal=false, то сигнал начинается с 1 элемента массива (высокий уровень) const unsigned int firstDataTiming = (pro.invertedSignal) ? (2) : (1);
// если invertedSignal=true, то сигнал начинается со 2 элемента массива (низкий уровень)
// добавляем поправку на Преамбулу и Хедер
const unsigned int firstDataTiming = BeginData + FirstTiming;
unsigned int bitChangeCount = changeCount - firstDataTiming - 1 + pro.invertedSignal;
if (bitChangeCount > 128) {
bitChangeCount = 128;
}
for (unsigned int i = firstDataTiming; i < firstDataTiming + bitChangeCount; i += 2) { for (unsigned int i = firstDataTiming; i < changeCount - 1; i += 2) {
code <<= 1; code <<= 1;
if (diff(RCSwitch::timings[i], delay * pro.zero.high) < delayTolerance && if (diff(RCSwitch::timings[i], delay * pro.zero.high) < delayTolerance &&
diff(RCSwitch::timings[i + 1], delay * pro.zero.low) < delayTolerance) { diff(RCSwitch::timings[i + 1], delay * pro.zero.low) < delayTolerance) {
@ -782,9 +657,9 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
} }
} }
if (bitChangeCount > 14) { // ignore very short transmissions: no device sends them, so this must be noise if (changeCount > 7) { // ignore very short transmissions: no device sends them, so this must be noise
RCSwitch::nReceivedValue = code; RCSwitch::nReceivedValue = code;
RCSwitch::nReceivedBitlength = bitChangeCount / 2; RCSwitch::nReceivedBitlength = (changeCount - 1) / 2;
RCSwitch::nReceivedDelay = delay; RCSwitch::nReceivedDelay = delay;
RCSwitch::nReceivedProtocol = p; RCSwitch::nReceivedProtocol = p;
return true; return true;
@ -797,63 +672,32 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() {
static unsigned int changeCount = 0; static unsigned int changeCount = 0;
static unsigned long lastTime = 0; static unsigned long lastTime = 0;
static byte repeatCount = 0; static unsigned int repeatCount = 0;
const long time = micros(); const long time = micros();
const unsigned int duration = time - lastTime; const unsigned int duration = time - lastTime;
RCSwitch::buftimings[3]=RCSwitch::buftimings[2]; if (duration > RCSwitch::nSeparationLimit) {
RCSwitch::buftimings[2]=RCSwitch::buftimings[1];
RCSwitch::buftimings[1]=RCSwitch::buftimings[0];
RCSwitch::buftimings[0]=duration;
if (duration > RCSwitch::nSeparationLimit ||
changeCount == 156 ||
(diff(RCSwitch::buftimings[3], RCSwitch::buftimings[2]) < 50 &&
diff(RCSwitch::buftimings[2], RCSwitch::buftimings[1]) < 50 &&
changeCount > 25)) {
// принят длинный импульс продолжительностью более nSeparationLimit (4300)
// A long stretch without signal level change occurred. This could // A long stretch without signal level change occurred. This could
// be the gap between two transmission. // be the gap between two transmission.
if (diff(duration, RCSwitch::timings[0]) < 400 || if ((repeatCount==0) || (diff(duration, RCSwitch::timings[0]) < 200)) {
changeCount == 156 ||
(diff(RCSwitch::buftimings[3], RCSwitch::timings[1]) < 50 &&
diff(RCSwitch::buftimings[2], RCSwitch::timings[2]) < 50 &&
diff(RCSwitch::buftimings[1], RCSwitch::timings[3]) < 50 &&
changeCount > 25)) {
// если его длительность отличается от первого импульса,
// который приняли раньше, менее чем на +-200 (исходно 200)
// то считаем это повторным пакетом и игнорируем его
// This long signal is close in length to the long signal which // This long signal is close in length to the long signal which
// started the previously recorded timings; this suggests that // started the previously recorded timings; this suggests that
// it may indeed by a a gap between two transmissions (we assume // it may indeed by a a gap between two transmissions (we assume
// here that a sender will send the signal multiple times, // here that a sender will send the signal multiple times,
// with roughly the same gap between them). // with roughly the same gap between them).
// количество повторных пакетов
repeatCount++; repeatCount++;
// при приеме второго повторного начинаем анализ принятого первым if (repeatCount == 2) {
if (repeatCount == 1) {
for(unsigned int i = 1; i <= numProto; i++) { for(unsigned int i = 1; i <= numProto; i++) {
if (receiveProtocol(i, changeCount)) { if (receiveProtocol(i, changeCount)) {
// receive succeeded for protocol i // receive succeeded for protocol i
break; break;
} }
} }
// очищаем количество повторных пакетов
repeatCount = 0; repeatCount = 0;
} }
} }
// дительность отличается более чем на +-200 от первого
// принятого ранее, очищаем счетчик для приема нового пакета
changeCount = 0; changeCount = 0;
if (diff(RCSwitch::buftimings[3], RCSwitch::buftimings[2]) < 50 &&
diff(RCSwitch::buftimings[2], RCSwitch::buftimings[1]) < 50) {
RCSwitch::timings[1]=RCSwitch::buftimings[3];
RCSwitch::timings[2]=RCSwitch::buftimings[2];
RCSwitch::timings[3]=RCSwitch::buftimings[1];
changeCount = 4;
}
} }
// detect overflow // detect overflow
@ -862,118 +706,7 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() {
repeatCount = 0; repeatCount = 0;
} }
// заносим в массив длительность очередного принятого импульса
if (changeCount > 0 && duration < 100) { // игнорируем шумовые всплески менее 100 мкс
RCSwitch::timings[changeCount-1] += duration;
} else {
RCSwitch::timings[changeCount++] = duration; RCSwitch::timings[changeCount++] = duration;
}
lastTime = time; lastTime = time;
} }
#endif #endif
/**
* Initilize Keeloq
*/
Keeloq::Keeloq() {
_keyHigh = 0;
_keyLow = 0;
}
/**
* Set Keeloq 64 bit cypher key
*/
void Keeloq::SetKey(unsigned long keyHigh, unsigned long keyLow) {
_keyHigh = keyHigh;
_keyLow = keyLow;
}
/**
* Get Key data
*/
unsigned long Keeloq::GetKey(bool HighLow) {
if (HighLow) {
return _keyHigh;
}
return _keyLow;
}
/**
* Encrypt Keeloq 32 bit data
*/
unsigned long Keeloq::Encrypt(unsigned long data) {
unsigned long x = data;
unsigned long r;
int keyBitNo, index;
unsigned long keyBitVal,bitVal;
for (r = 0; r < 528; r++) {
keyBitNo = r & 63;
if (keyBitNo < 32) {
keyBitVal = bitRead(_keyLow,keyBitNo);
} else {
keyBitVal = bitRead(_keyHigh, keyBitNo - 32);
}
index = 1 * bitRead(x, 1) + 2 * bitRead(x, 9) + 4 * bitRead(x, 20) + 8 * bitRead(x, 26) + 16 * bitRead(x, 31);
bitVal = bitRead(x, 0) ^ bitRead(x, 16) ^ bitRead(KeeLoq_NLF, index) ^ keyBitVal;
x = (x >> 1) ^ bitVal << 31;
}
return x;
}
/**
* Decrypt Keeloq 32 bit data
*/
unsigned long Keeloq::Decrypt(unsigned long data) {
unsigned long x = data;
unsigned long r;
int keyBitNo, index;
unsigned long keyBitVal,bitVal;
for (r = 0; r < 528; r++) {
keyBitNo = (15-r) & 63;
if(keyBitNo < 32) {
keyBitVal = bitRead(_keyLow,keyBitNo);
} else {
keyBitVal = bitRead(_keyHigh, keyBitNo - 32);
}
index = 1 * bitRead(x, 0) + 2 * bitRead(x, 8) + 4 * bitRead(x, 19) + 8 * bitRead(x, 25) + 16 * bitRead(x, 30);
bitVal = bitRead(x, 31) ^ bitRead(x, 15) ^ bitRead(KeeLoq_NLF, index) ^ keyBitVal;
x = (x << 1) ^ bitVal;
}
return x;
}
/**
* Set Normal Learning Keeloq key
*/
void Keeloq::NormLearn(unsigned long FixSN) {
unsigned long tmpFixSN;
// заготовки для формируемого ключа
unsigned long NewkeyHigh;
unsigned long NewkeyLow;
tmpFixSN = FixSN & 0x0FFFFFFF;
tmpFixSN |= 0x20000000;
NewkeyLow = Decrypt(tmpFixSN);
tmpFixSN = FixSN & 0x0FFFFFFF;
tmpFixSN |= 0x60000000;
NewkeyHigh = Decrypt(tmpFixSN);
_keyHigh = NewkeyHigh;
_keyLow = NewkeyLow;
}
/**
* Reflect a 32 bit package
*/
unsigned long Keeloq::ReflectPack(unsigned long PackSrc) {
unsigned long long PackOut = 0;
for (byte i = 0; i < 32; i++) {
PackOut = PackOut << 1;
if (PackSrc & 1) {
PackOut = PackOut | 1;
}
PackSrc = PackSrc >> 1;
}
return PackOut;
}

View File

@ -58,8 +58,7 @@
// Number of maximum high/Low changes per packet. // 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 // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync
// Для keeloq нужно увеличить RCSWITCH_MAX_CHANGES до 23+1+66*2+1=157 #define RCSWITCH_MAX_CHANGES 67
#define RCSWITCH_MAX_CHANGES 67 // default 67
class RCSwitch { class RCSwitch {
@ -78,7 +77,7 @@ class RCSwitch {
void switchOff(char sGroup, int nDevice); void switchOff(char sGroup, int nDevice);
void sendTriState(const char* sCodeWord); void sendTriState(const char* sCodeWord);
void send(unsigned long long code, unsigned int length); void send(unsigned long code, unsigned int length);
void send(const char* sCodeWord); void send(const char* sCodeWord);
#if not defined( RCSwitchDisableReceiving ) #if not defined( RCSwitchDisableReceiving )
@ -88,7 +87,7 @@ class RCSwitch {
bool available(); bool available();
void resetAvailable(); void resetAvailable();
unsigned long long getReceivedValue(); unsigned long getReceivedValue();
unsigned int getReceivedBitlength(); unsigned int getReceivedBitlength();
unsigned int getReceivedDelay(); unsigned int getReceivedDelay();
unsigned int getReceivedProtocol(); unsigned int getReceivedProtocol();
@ -121,11 +120,8 @@ class RCSwitch {
struct Protocol { struct Protocol {
/** base pulse length in microseconds, e.g. 350 */ /** base pulse length in microseconds, e.g. 350 */
uint16_t pulseLength; uint16_t pulseLength;
uint8_t PreambleFactor;
HighLow Preamble;
uint8_t HeaderFactor;
HighLow Header;
HighLow syncFactor;
HighLow zero; HighLow zero;
HighLow one; HighLow one;
@ -146,7 +142,6 @@ class RCSwitch {
* FOO.low*pulseLength microseconds. * FOO.low*pulseLength microseconds.
*/ */
bool invertedSignal; bool invertedSignal;
uint16_t Guard;
}; };
void setProtocol(Protocol protocol); void setProtocol(Protocol protocol);
@ -172,7 +167,7 @@ class RCSwitch {
#if not defined( RCSwitchDisableReceiving ) #if not defined( RCSwitchDisableReceiving )
static int nReceiveTolerance; static int nReceiveTolerance;
volatile static unsigned long long nReceivedValue; volatile static unsigned long nReceivedValue;
volatile static unsigned int nReceivedBitlength; volatile static unsigned int nReceivedBitlength;
volatile static unsigned int nReceivedDelay; volatile static unsigned int nReceivedDelay;
volatile static unsigned int nReceivedProtocol; volatile static unsigned int nReceivedProtocol;
@ -181,25 +176,9 @@ class RCSwitch {
* timings[0] contains sync timing, followed by a number of bits * timings[0] contains sync timing, followed by a number of bits
*/ */
static unsigned int timings[RCSWITCH_MAX_CHANGES]; static unsigned int timings[RCSWITCH_MAX_CHANGES];
// буфер длительностей последних четырех пакетов, [0] - последний
static unsigned int buftimings[4];
#endif #endif
}; };
class Keeloq {
public:
Keeloq();
void SetKey(unsigned long keyHigh, unsigned long keyLow);
unsigned long GetKey(bool HighLow);
unsigned long Encrypt(unsigned long data);
unsigned long Decrypt(unsigned long data);
void NormLearn(unsigned long FixSN);
unsigned long ReflectPack(unsigned long PackSrc);
private:
unsigned long _keyHigh;
unsigned long _keyLow;
};
#endif #endif

View File

@ -1,17 +1,15 @@
**Fork of RC-SWITCH by @sui77**
# rc-switch # rc-switch
[![Build Status](https://travis-ci.org/1technophile/rc-switch.svg?branch=master)](https://travis-ci.org/1technophile/rc-switch) [![Build Status](https://travis-ci.org/sui77/rc-switch.svg?branch=master)](https://travis-ci.org/sui77/rc-switch)
Use your Arduino or Raspberry Pi to operate remote radio controlled devices Use your Arduino or Raspberry Pi to operate remote radio controlled devices
## Download ## Download
https://github.com/1technophile/rc-switch/releases/latest https://github.com/sui77/rc-switch/releases/latest
rc-switch is also listed in the arduino library manager. rc-switch is also listed in the arduino library manager.
## Wiki ## Wiki
https://github.com/1technophile/rc-switch/wiki https://github.com/sui77/rc-switch/wiki
## Info ## Info
### Send RC codes ### Send RC codes

View File

@ -1,39 +0,0 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < https://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < https://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choose one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#
#
# Template #1: General project. Test it using existing `platformio.ini`.
#
matrix:
include:
- language: python
python: 2.7
sudo: false
cache:
directories:
- "~/.platformio"
install:
- pip install -U platformio
- platformio update
script:
- platformio run

View File

@ -1,103 +0,0 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
src_dir = examples/ReceiveDemo_Advanced
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ENVIRONMENT CHOICE ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Uncomment the env line corresponding to your board and modules required, ;
;you can also adapt the modules by removing the corresponding lines in the env detail ;
; if you go to the build flag section of your env you will see that some user_config.h ;
; parameters can be overwritten here, for example the gateway name. ;
; If you want to avoid the lost of your environments at each update you can put them ;
; into a separate file called prod_env.ini, it will be automatically read by pio ;
; an example (prod_env.ini.example) is available into the same folder as this file. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;default_envs = sonoff-basic-rfr3
;default_envs = esp32dev-rf
;default_envs = nodemcuv2-rf
;default_envs = rf-wifi-gateway
;default_envs = uno-rf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ENVIRONMENTS PARAMETERS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Libraries and parameters shared accross environements ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[env]
lib_extra_dirs = .
framework = arduino
build_flags =
-w ; supress all warnings
monitor_speed = 115200
[com]
esp8266_platform = espressif8266@2.2.3
esp32_platform = espressif32@1.11.1
atmelavr_platform = atmelavr@1.13.0
[com-esp]
build_flags =
${env.build_flags}
[com-arduino]
build_flags =
${env.build_flags}
[com-arduino-low-memory]
build_flags =
${env.build_flags}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ENVIRONMENTS LIST ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;List of environments that can be build ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[env:esp32dev-rf]
platform = ${com.esp32_platform}
board = esp32dev
build_flags =
${com-esp.build_flags}
[env:nodemcuv2-rf]
platform = ${com.esp8266_platform}
board = nodemcuv2
build_flags =
${com-esp.build_flags}
board_build.flash_mode = dout
[env:rf-wifi-gateway]
platform = ${com.esp8266_platform}
board = nodemcuv2
build_flags =
${com-esp.build_flags}
board_build.flash_mode = dout
[env:sonoff-basic-rfr3]
platform = ${com.esp8266_platform}
board = esp8285
build_flags =
${com-esp.build_flags}
board_build.flash_mode = dout
[env:uno-rf]
platform = ${com.atmelavr_platform}
board = uno
build_flags =
${com-arduino-low-memory.build_flags}

View File

@ -710,7 +710,7 @@
//#define USE_WINDMETER // Add support for analog anemometer (+2k2 code) //#define USE_WINDMETER // Add support for analog anemometer (+2k2 code)
//#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+3k2 code, 460 iram) //#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram)
//#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) //#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
// #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code)