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,26 +13,25 @@
- 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/
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
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}
* *
* Pulse length: pulse duration Te in microseconds, * pulselength: pulse length in microseconds, e.g. 350
* example 350 * Sync bit: {1, 31} means 1 high pulse and 31 low pulses
* Preamble: Alternating high and low levels * (perceived as a 31*pulselength long pulse, total length of sync bit is
* {20, 1} means 20 alternations of 1 Te duration * 32*pulselength microseconds), i.e:
* _ _ _ _ _ _ _ _ _ _
* | |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
* 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); digitalWrite(this->nTransmitterPin, secondLogicLevel);
} delayMicroseconds( this->protocol.pulseLength * pulses.low);
if (pulses.low > 0) {
digitalWrite(this->nTransmitterPin, secondLogicLevel);
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;
} }
// заносим в массив длительность очередного принятого импульса RCSwitch::timings[changeCount++] = duration;
if (changeCount > 0 && duration < 100) { // игнорируем шумовые всплески менее 100 мкс
RCSwitch::timings[changeCount-1] += duration;
} else {
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)