diff --git a/lib/rc-switch-2.6.2.13/.travis.yml b/lib/rc-switch-2.6.2.13/.travis.yml deleted file mode 100644 index 16cadf8a2..000000000 --- a/lib/rc-switch-2.6.2.13/.travis.yml +++ /dev/null @@ -1,69 +0,0 @@ -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} diff --git a/lib/rc-switch-2.6.2.13/.gitignore b/lib/rc-switch/.gitignore similarity index 100% rename from lib/rc-switch-2.6.2.13/.gitignore rename to lib/rc-switch/.gitignore diff --git a/lib/rc-switch/.travis.yml b/lib/rc-switch/.travis.yml new file mode 100644 index 000000000..e885c1118 --- /dev/null +++ b/lib/rc-switch/.travis.yml @@ -0,0 +1,39 @@ +# 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 + diff --git a/lib/rc-switch-2.6.2.13/README.md b/lib/rc-switch/README.md similarity index 80% rename from lib/rc-switch-2.6.2.13/README.md rename to lib/rc-switch/README.md index bf12543be..f323c6388 100644 --- a/lib/rc-switch-2.6.2.13/README.md +++ b/lib/rc-switch/README.md @@ -1,15 +1,17 @@ +**Fork of RC-SWITCH by @sui77** + # rc-switch -[![Build Status](https://travis-ci.org/sui77/rc-switch.svg?branch=master)](https://travis-ci.org/sui77/rc-switch) +[![Build Status](https://travis-ci.org/1technophile/rc-switch.svg?branch=master)](https://travis-ci.org/1technophile/rc-switch) Use your Arduino or Raspberry Pi to operate remote radio controlled devices ## Download -https://github.com/sui77/rc-switch/releases/latest +https://github.com/1technophile/rc-switch/releases/latest rc-switch is also listed in the arduino library manager. ## Wiki -https://github.com/sui77/rc-switch/wiki +https://github.com/1technophile/rc-switch/wiki ## Info ### Send RC codes diff --git a/lib/rc-switch-2.6.2.13/examples/ReceiveDemo_Advanced/ReceiveDemo_Advanced.ino b/lib/rc-switch/examples/ReceiveDemo_Advanced/ReceiveDemo_Advanced.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/ReceiveDemo_Advanced/ReceiveDemo_Advanced.ino rename to lib/rc-switch/examples/ReceiveDemo_Advanced/ReceiveDemo_Advanced.ino diff --git a/lib/rc-switch-2.6.2.13/examples/ReceiveDemo_Advanced/output.ino b/lib/rc-switch/examples/ReceiveDemo_Advanced/output.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/ReceiveDemo_Advanced/output.ino rename to lib/rc-switch/examples/ReceiveDemo_Advanced/output.ino diff --git a/lib/rc-switch-2.6.2.13/examples/ReceiveDemo_Simple/ReceiveDemo_Simple.ino b/lib/rc-switch/examples/ReceiveDemo_Simple/ReceiveDemo_Simple.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/ReceiveDemo_Simple/ReceiveDemo_Simple.ino rename to lib/rc-switch/examples/ReceiveDemo_Simple/ReceiveDemo_Simple.ino diff --git a/lib/rc-switch-2.6.2.13/examples/SendDemo/SendDemo.ino b/lib/rc-switch/examples/SendDemo/SendDemo.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/SendDemo/SendDemo.ino rename to lib/rc-switch/examples/SendDemo/SendDemo.ino diff --git a/lib/rc-switch-2.6.2.13/examples/TypeA_WithDIPSwitches/TypeA_WithDIPSwitches.ino b/lib/rc-switch/examples/TypeA_WithDIPSwitches/TypeA_WithDIPSwitches.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/TypeA_WithDIPSwitches/TypeA_WithDIPSwitches.ino rename to lib/rc-switch/examples/TypeA_WithDIPSwitches/TypeA_WithDIPSwitches.ino diff --git a/lib/rc-switch-2.6.2.13/examples/TypeA_WithDIPSwitches_Lightweight/TypeA_WithDIPSwitches_Lightweight.ino b/lib/rc-switch/examples/TypeA_WithDIPSwitches_Lightweight/TypeA_WithDIPSwitches_Lightweight.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/TypeA_WithDIPSwitches_Lightweight/TypeA_WithDIPSwitches_Lightweight.ino rename to lib/rc-switch/examples/TypeA_WithDIPSwitches_Lightweight/TypeA_WithDIPSwitches_Lightweight.ino diff --git a/lib/rc-switch-2.6.2.13/examples/TypeB_WithRotaryOrSlidingSwitches/TypeB_WithRotaryOrSlidingSwitches.ino b/lib/rc-switch/examples/TypeB_WithRotaryOrSlidingSwitches/TypeB_WithRotaryOrSlidingSwitches.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/TypeB_WithRotaryOrSlidingSwitches/TypeB_WithRotaryOrSlidingSwitches.ino rename to lib/rc-switch/examples/TypeB_WithRotaryOrSlidingSwitches/TypeB_WithRotaryOrSlidingSwitches.ino diff --git a/lib/rc-switch-2.6.2.13/examples/TypeC_Intertechno/TypeC_Intertechno.ino b/lib/rc-switch/examples/TypeC_Intertechno/TypeC_Intertechno.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/TypeC_Intertechno/TypeC_Intertechno.ino rename to lib/rc-switch/examples/TypeC_Intertechno/TypeC_Intertechno.ino diff --git a/lib/rc-switch-2.6.2.13/examples/TypeD_REV/TypeD_REV.ino b/lib/rc-switch/examples/TypeD_REV/TypeD_REV.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/TypeD_REV/TypeD_REV.ino rename to lib/rc-switch/examples/TypeD_REV/TypeD_REV.ino diff --git a/lib/rc-switch-2.6.2.13/examples/Webserver/Webserver.ino b/lib/rc-switch/examples/Webserver/Webserver.ino similarity index 100% rename from lib/rc-switch-2.6.2.13/examples/Webserver/Webserver.ino rename to lib/rc-switch/examples/Webserver/Webserver.ino diff --git a/lib/rc-switch-2.6.2.13/keywords.txt b/lib/rc-switch/keywords.txt similarity index 100% rename from lib/rc-switch-2.6.2.13/keywords.txt rename to lib/rc-switch/keywords.txt diff --git a/lib/rc-switch-2.6.2.13/library.json b/lib/rc-switch/library.json similarity index 100% rename from lib/rc-switch-2.6.2.13/library.json rename to lib/rc-switch/library.json diff --git a/lib/rc-switch-2.6.2.13/library.properties b/lib/rc-switch/library.properties similarity index 100% rename from lib/rc-switch-2.6.2.13/library.properties rename to lib/rc-switch/library.properties diff --git a/lib/rc-switch/platformio.ini b/lib/rc-switch/platformio.ini new file mode 100644 index 000000000..74999c992 --- /dev/null +++ b/lib/rc-switch/platformio.ini @@ -0,0 +1,103 @@ +; 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} diff --git a/lib/rc-switch-2.6.2.13/RCSwitch.cpp b/lib/rc-switch/src/RCSwitch.cpp similarity index 58% rename from lib/rc-switch-2.6.2.13/RCSwitch.cpp rename to lib/rc-switch/src/RCSwitch.cpp index ced09ceff..876bc2f5b 100644 --- a/lib/rc-switch-2.6.2.13/RCSwitch.cpp +++ b/lib/rc-switch/src/RCSwitch.cpp @@ -13,25 +13,26 @@ - Robert ter Vehn / .(at)gmail(dot)com - Johann Richard / .(at)gmail(dot)com - Vlad Gheorghe / .(at)gmail(dot)com https://github.com/vgheo - - Matias Cuenca-Acuna Project home: https://github.com/sui77/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 */ +#define KeeLoq_NLF 0x3A5C742EUL + #include "RCSwitch.h" #ifdef RaspberryPi @@ -55,42 +56,77 @@ #endif -/* Format for protocol definitions: - * {pulselength, Sync bit, "0" bit, "1" bit, invertedSignal} +/* Protocol description format + * + * {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 - * (perceived as a 31*pulselength long pulse, total length of sync bit is - * 32*pulselength microseconds), i.e: + * Pulse length: pulse duration Te in microseconds, + * example 350 + * 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) - * "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse - * and 3 low pulses, total length (1+3)*pulselength, i.e: + * "0" bit: pulse shape defining a data bit, which is a logical "0" + * {1, 3} means 1 pulse duration Te high level and 3 low * _ * | |___ - * "1" bit: waveform for a data bit of value "1", e.g. {3,1}: + * "1" bit: pulse shape that defines the data bit, which is a logical "1" + * {3, 1} means 3 pulses with a duration of Te high level and 1 low * ___ * | |_ * - * These are combined to form Tri-State bits when sending or receiving codes. + * (note: to form the state bit Z (Tri-State bit), these two codes are combined) + * 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) static const VAR_ISR_ATTR RCSwitch::Protocol proto[] = { #else static const RCSwitch::Protocol PROGMEM proto[] = { #endif - { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1 - { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2 - { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3 - { 380, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4 - { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5 - { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 6 (HT6P20B) - { 150, { 2, 62 }, { 1, 6 }, { 6, 1 }, false }, // protocol 7 (HS2303-PT, i. e. used in AUKEY Remote) - { 200, { 3, 130}, { 7, 16 }, { 3, 16}, false}, // protocol 8 Conrad RS-200 RX - { 200, { 130, 7 }, { 16, 7 }, { 16, 3 }, true}, // protocol 9 Conrad RS-200 TX - { 365, { 18, 1 }, { 3, 1 }, { 1, 3 }, true }, // protocol 10 (1ByOne Doorbell) - { 270, { 36, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 11 (HT12E) - { 320, { 36, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 12 (SM5212) + { 350, 0, { 0, 0 }, 1, { 1, 31 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 01 (Princeton, PT-2240) + { 650, 0, { 0, 0 }, 1, { 1, 10 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 02 + { 100, 0, { 0, 0 }, 1, { 30, 71 }, { 4, 11 }, { 9, 6 }, false, 0 }, // 03 + { 380, 0, { 0, 0 }, 1, { 1, 6 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 04 + { 500, 0, { 0, 0 }, 1, { 6, 14 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 05 + { 450, 0, { 0, 0 }, 1, { 23, 1 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 06 (HT6P20B) + { 150, 0, { 0, 0 }, 1, { 2, 62 }, { 1, 6 }, { 6, 1 }, false, 0 }, // 07 (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) + { 700, 0, { 0, 0 }, 1, { 32, 1 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 09 (Nice_Flo 12bit) + { 420, 0, { 0, 0 }, 1, { 60, 6 }, { 1, 2 }, { 2, 1 }, true, 0 }, // 10 (V2 phoenix) + { 500, 2, { 3, 3 }, 0, { 0, 0 }, { 1, 2 }, { 2, 1 }, false, 37 }, // 11 (Nice_FloR-S 52bit) + { 400, 23, { 1, 1 }, 1, { 0, 9 }, { 2, 1 }, { 1, 2 }, false, 39 }, // 12 (Keeloq 64/66) + { 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 { @@ -98,21 +134,23 @@ enum { }; #if not defined( RCSwitchDisableReceiving ) -volatile unsigned long RCSwitch::nReceivedValue = 0; +volatile unsigned long long RCSwitch::nReceivedValue = 0; volatile unsigned int RCSwitch::nReceivedBitlength = 0; volatile unsigned int RCSwitch::nReceivedDelay = 0; volatile unsigned int RCSwitch::nReceivedProtocol = 0; int RCSwitch::nReceiveTolerance = 60; -const unsigned int RCSwitch::nSeparationLimit = 4300; +const unsigned int RCSwitch::nSeparationLimit = 2600; // 4300 default // 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 // 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::buftimings[4]; #endif RCSwitch::RCSwitch() { this->nTransmitterPin = -1; - this->setRepeatTransmit(10); + this->setRepeatTransmit(5); this->setProtocol(1); #if not defined( RCSwitchDisableReceiving ) this->nReceiverInterrupt = -1; @@ -452,7 +490,7 @@ char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) { */ void RCSwitch::sendTriState(const char* sCodeWord) { // turn the tristate code word into the corresponding bit pattern, then send it - unsigned long code = 0; + unsigned long long code = 0; unsigned int length = 0; for (const char* p = sCodeWord; *p; p++) { code <<= 2L; @@ -462,11 +500,11 @@ void RCSwitch::sendTriState(const char* sCodeWord) { break; case 'F': // bit pattern 01 - code |= 1L; + code |= 1ULL; break; case '1': // bit pattern 11 - code |= 3L; + code |= 3ULL; break; } length += 2; @@ -474,17 +512,37 @@ void RCSwitch::sendTriState(const char* sCodeWord) { 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 */ void RCSwitch::send(const char* sCodeWord) { // turn the tristate code word into the corresponding bit pattern, then send it - unsigned long code = 0; + unsigned long long code = 0; unsigned int length = 0; for (const char* p = sCodeWord; *p; p++) { - code <<= 1L; + code <<= 1ULL; if (*p != '0') - code |= 1L; + code |= 1ULL; length++; } this->send(code, length); @@ -495,7 +553,7 @@ void RCSwitch::send(const char* sCodeWord) { * 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. */ -void RCSwitch::send(unsigned long code, unsigned int length) { +void RCSwitch::send(unsigned long long code, unsigned int length) { if (this->nTransmitterPin == -1) return; @@ -507,14 +565,41 @@ void RCSwitch::send(unsigned long code, unsigned int length) { } #endif + // repeat sending the packet nRepeatTransmit times for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) { - for (int i = length-1; i >= 0; i--) { - if (code & (1L << i)) + // send the preamble + for (int i = 0; i < ((protocol.PreambleFactor / 2) + (protocol.PreambleFactor %2 )); 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); else this->transmit(protocol.zero); } - this->transmit(protocol.syncFactor); + // for kilok, there should be a duration of 66, and 64 significant data codes are stored + // 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) @@ -535,10 +620,14 @@ void RCSwitch::transmit(HighLow pulses) { uint8_t firstLogicLevel = (this->protocol.invertedSignal) ? LOW : HIGH; uint8_t secondLogicLevel = (this->protocol.invertedSignal) ? HIGH : LOW; - digitalWrite(this->nTransmitterPin, firstLogicLevel); - delayMicroseconds( this->protocol.pulseLength * pulses.high); - digitalWrite(this->nTransmitterPin, secondLogicLevel); - delayMicroseconds( this->protocol.pulseLength * pulses.low); + if (pulses.high > 0) { + digitalWrite(this->nTransmitterPin, firstLogicLevel); + delayMicroseconds( this->protocol.pulseLength * pulses.high); + } + if (pulses.low > 0) { + digitalWrite(this->nTransmitterPin, secondLogicLevel); + delayMicroseconds( this->protocol.pulseLength * pulses.low); + } } @@ -581,7 +670,7 @@ void RCSwitch::resetAvailable() { RCSwitch::nReceivedValue = 0; } -unsigned long RCSwitch::getReceivedValue() { +unsigned long long RCSwitch::getReceivedValue() { return RCSwitch::nReceivedValue; } @@ -617,12 +706,41 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun memcpy_P(&pro, &proto[p-1], sizeof(Protocol)); #endif - unsigned long code = 0; - //Assuming the longer pulse length is the pulse captured in timings[0] - const unsigned int syncLengthInPulses = ((pro.syncFactor.low) > (pro.syncFactor.high)) ? (pro.syncFactor.low) : (pro.syncFactor.high); - const unsigned int delay = RCSwitch::timings[0] / syncLengthInPulses; + unsigned long long code = 0; + unsigned int FirstTiming = 0; + if (pro.PreambleFactor > 0) { + FirstTiming = pro.PreambleFactor + 1; + } + 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; + // 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 * _________ * _____________| |XXXXXXXXXXXX| @@ -640,9 +758,16 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun * * The 2nd saved duration starts the data */ - const unsigned int firstDataTiming = (pro.invertedSignal) ? (2) : (1); + // если invertedSignal=false, то сигнал начинается с 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 < changeCount - 1; i += 2) { + for (unsigned int i = firstDataTiming; i < firstDataTiming + bitChangeCount; i += 2) { code <<= 1; if (diff(RCSwitch::timings[i], delay * pro.zero.high) < delayTolerance && diff(RCSwitch::timings[i + 1], delay * pro.zero.low) < delayTolerance) { @@ -657,9 +782,9 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun } } - if (changeCount > 7) { // ignore very short transmissions: no device sends them, so this must be noise + if (bitChangeCount > 14) { // ignore very short transmissions: no device sends them, so this must be noise RCSwitch::nReceivedValue = code; - RCSwitch::nReceivedBitlength = (changeCount - 1) / 2; + RCSwitch::nReceivedBitlength = bitChangeCount / 2; RCSwitch::nReceivedDelay = delay; RCSwitch::nReceivedProtocol = p; return true; @@ -672,32 +797,63 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() { static unsigned int changeCount = 0; static unsigned long lastTime = 0; - static unsigned int repeatCount = 0; + static byte repeatCount = 0; const long time = micros(); const unsigned int duration = time - lastTime; - if (duration > RCSwitch::nSeparationLimit) { + RCSwitch::buftimings[3]=RCSwitch::buftimings[2]; + 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 // be the gap between two transmission. - if ((repeatCount==0) || (diff(duration, RCSwitch::timings[0]) < 200)) { + if (diff(duration, RCSwitch::timings[0]) < 400 || + 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 // started the previously recorded timings; this suggests that // it may indeed by a a gap between two transmissions (we assume // here that a sender will send the signal multiple times, // with roughly the same gap between them). + + // количество повторных пакетов repeatCount++; - if (repeatCount == 2) { + // при приеме второго повторного начинаем анализ принятого первым + if (repeatCount == 1) { for(unsigned int i = 1; i <= numProto; i++) { if (receiveProtocol(i, changeCount)) { // receive succeeded for protocol i break; } } + // очищаем количество повторных пакетов repeatCount = 0; } } + // дительность отличается более чем на +-200 от первого + // принятого ранее, очищаем счетчик для приема нового пакета 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 @@ -706,7 +862,118 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() { repeatCount = 0; } - RCSwitch::timings[changeCount++] = duration; + // заносим в массив длительность очередного принятого импульса + if (changeCount > 0 && duration < 100) { // игнорируем шумовые всплески менее 100 мкс + RCSwitch::timings[changeCount-1] += duration; + } else { + RCSwitch::timings[changeCount++] = duration; + } lastTime = time; } #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; +} diff --git a/lib/rc-switch-2.6.2.13/RCSwitch.h b/lib/rc-switch/src/RCSwitch.h similarity index 86% rename from lib/rc-switch-2.6.2.13/RCSwitch.h rename to lib/rc-switch/src/RCSwitch.h index b7755e0b4..3199bf81d 100644 --- a/lib/rc-switch-2.6.2.13/RCSwitch.h +++ b/lib/rc-switch/src/RCSwitch.h @@ -58,7 +58,8 @@ // 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 +// Для keeloq нужно увеличить RCSWITCH_MAX_CHANGES до 23+1+66*2+1=157 +#define RCSWITCH_MAX_CHANGES 67 // default 67 class RCSwitch { @@ -77,7 +78,7 @@ class RCSwitch { void switchOff(char sGroup, int nDevice); void sendTriState(const char* sCodeWord); - void send(unsigned long code, unsigned int length); + void send(unsigned long long code, unsigned int length); void send(const char* sCodeWord); #if not defined( RCSwitchDisableReceiving ) @@ -87,7 +88,7 @@ class RCSwitch { bool available(); void resetAvailable(); - unsigned long getReceivedValue(); + unsigned long long getReceivedValue(); unsigned int getReceivedBitlength(); unsigned int getReceivedDelay(); unsigned int getReceivedProtocol(); @@ -120,8 +121,11 @@ class RCSwitch { struct Protocol { /** base pulse length in microseconds, e.g. 350 */ uint16_t pulseLength; + uint8_t PreambleFactor; + HighLow Preamble; + uint8_t HeaderFactor; + HighLow Header; - HighLow syncFactor; HighLow zero; HighLow one; @@ -142,6 +146,7 @@ class RCSwitch { * FOO.low*pulseLength microseconds. */ bool invertedSignal; + uint16_t Guard; }; void setProtocol(Protocol protocol); @@ -167,7 +172,7 @@ class RCSwitch { #if not defined( RCSwitchDisableReceiving ) static int nReceiveTolerance; - volatile static unsigned long nReceivedValue; + volatile static unsigned long long nReceivedValue; volatile static unsigned int nReceivedBitlength; volatile static unsigned int nReceivedDelay; volatile static unsigned int nReceivedProtocol; @@ -176,9 +181,25 @@ class RCSwitch { * timings[0] contains sync timing, followed by a number of bits */ static unsigned int timings[RCSWITCH_MAX_CHANGES]; + // буфер длительностей последних четырех пакетов, [0] - последний + static unsigned int buftimings[4]; #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 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index ec7ae2911..c1bdcdb79 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -710,7 +710,7 @@ //#define USE_WINDMETER // Add support for analog anemometer (+2k2 code) -//#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) +//#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+3k2 code, 460 iram) //#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)