Created
September 2, 2020 08:05
-
-
Save ArminJo/f5a5a93600a84ab1087c5daf7dedaab4 to your computer and use it in GitHub Desktop.
3 protocols for RF remote controls for Arduino. 2262 / 2272 + EIM-826 + Intertechno
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include <digitalWriteFast.h> | |
/* | |
* HX2262/2272 Stuff | |
*/ | |
// measured 33.91 kHz receiver clock => Data sheet says: Transmitter clock has to be 2.5 to 8 times slower | |
// https://cdn-shop.adafruit.com/datasheets/PT2262.pdf | |
//const int HX2272_FUNDAMENTAL_CLOCK_PERIOD_X4_MICROS = 118; | |
const int HX2272_FUNDAMENTAL_CLOCK_PERIOD_X4_MICROS = 440; | |
const int HX2272_DURATION4 = HX2272_FUNDAMENTAL_CLOCK_PERIOD_X4_MICROS; | |
const int HX2272_DURATION12 = HX2272_FUNDAMENTAL_CLOCK_PERIOD_X4_MICROS * 3; // 1320 | |
const int HX2272_DURATION128 = HX2272_FUNDAMENTAL_CLOCK_PERIOD_X4_MICROS * 32; | |
/* | |
* Sender IC HX2262 | |
* Receiver IC HX2272 | |
*/ | |
#define HX2272_0 0 // DIP switch on 0 | |
#define HX2272_1 1 | |
#define HX2272_FLOAT 3 // Code input pin floating - DIP switch on 0 | |
#define HX2272_SYNC 4 | |
#define HX2272_FLOAT_MASK 0x02 | |
void sendBitForHX2272(uint8_t aCode) { | |
switch (aCode) { | |
case HX2272_0: // Bit"0" 4 high + 12 low + 4 high + 12 low | |
case 2: | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION4); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION12); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION4); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION12); | |
break; | |
case HX2272_1: // Bit"1" 12 high + 4 low + 12 high + 4 low | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION12); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION4); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION12); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION4); | |
break; | |
case HX2272_FLOAT: // Bit"f" Floating 4 high + 12 low + 12 high + 4 low | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION4); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION12); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION12); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION4); | |
break; | |
case HX2272_SYNC: // Sync 4 high + 128 low | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(HX2272_DURATION4); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(HX2272_DURATION128); | |
break; | |
default: | |
break; | |
} | |
} | |
/* | |
* A Frame consists of 4 repeats of (address, data + sync) aka word | |
* a1MeansFloating true send floating code instead of code for a 1. | |
* This is required for DIP switches which left the pin float at position 1 | |
*/ | |
void sendFrameForHX2272(uint16_t aAddress, uint8_t aSwitchState, bool a1MeansFloating) { | |
// 4 words | |
for (uint8_t i = 0; i < 4; ++i) { | |
// 10 bit address | |
for (uint8_t j = 0; j < 10; ++j) { | |
uint8_t tValue = aAddress & 0x01; | |
aAddress = aAddress >> 1; | |
if (a1MeansFloating) { | |
sendBitForHX2272(tValue | HX2272_FLOAT_MASK); | |
} else { | |
sendBitForHX2272(tValue); | |
} | |
} | |
// 2 bit data | |
if (aSwitchState == HIGH) { | |
// Set both bits here. | |
sendBitForHX2272(HX2272_1); | |
sendBitForHX2272(HX2272_1); | |
} else { | |
sendBitForHX2272(HX2272_0); | |
sendBitForHX2272(HX2272_0); | |
} | |
// sync | |
sendBitForHX2272(HX2272_SYNC); | |
} | |
} | |
/* | |
* Unitec EIM-826 stuff | |
*/ | |
#define EIM826_FRAMEREPEAT 4 // >= 1 | |
/* | |
* Values measured at remote control with 13560 crystal | |
* ZERO 208.5 H + 625 L = 833.5; | |
* ONE 610,5 H + 223 L = 833.5; | |
* INTER FRAME 6287 (- 625 (low time of last Zero)) = 5662 | |
* 15 Frame repeats - But it works with 1 frame (if received correctly) | |
* | |
* https://forum.pimatic.org/topic/139/unitec-protocol-request | |
* https://github.com/pimatic/rfcontroljs/commit/ee2fe5997c393cb15facc849f3270f8890830fac | |
*/ | |
const int EIM826_SHORT_MICROS = 218; // 210 | |
const int EIM826_LONG_MICROS = 615; // 624 | |
const int EIM826_INTER_FRAME_MICROS = 5662; // 6280? | |
void sendBitForUnitec_EIM826(bool aSendaOne) { | |
if (aSendaOne) { | |
digitalWriteFast(OUT_433_SIGNAL_PIN, HIGH); | |
delayMicroseconds(579); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, LOW); | |
delayMicroseconds(EIM826_SHORT_MICROS); | |
} else { | |
digitalWriteFast(OUT_433_SIGNAL_PIN, HIGH); | |
delayMicroseconds(EIM826_SHORT_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, LOW); | |
delayMicroseconds(EIM826_LONG_MICROS); | |
} | |
} | |
/* | |
* aSwitchNumber from 0 to 3. 4 means ALL | |
* Frame: | |
* 00000000000000000000| 11 | 0 |0 | |
* ID |Unit|!All|State | |
*/ | |
void sendFrameForUnitec_EIM826(uint8_t aSwitchNumber, bool aSwitchToOn) { | |
uint8_t tSwitchNumber = aSwitchNumber ^ 0x03; // complement switch number bits | |
for (uint8_t i = 0; i < EIM826_FRAMEREPEAT; i++) { | |
noInterrupts(); | |
/* | |
* 20 preamble bits - always 0 | |
*/ | |
for (byte i = 0; i < 20; i++) { | |
sendBitForUnitec_EIM826(0); | |
} | |
/* | |
* Send switch number code. | |
*/ | |
if (tSwitchNumber & 0x01) { | |
sendBitForUnitec_EIM826(1); | |
} else { | |
sendBitForUnitec_EIM826(0); | |
} | |
if (tSwitchNumber & 0x02) { | |
sendBitForUnitec_EIM826(1); | |
} else { | |
sendBitForUnitec_EIM826(0); | |
} | |
// "All" switch pressed | |
if (aSwitchNumber == 4) { | |
sendBitForUnitec_EIM826(0); | |
} else { | |
sendBitForUnitec_EIM826(1); | |
} | |
/* | |
* ON/OFF | |
*/ | |
sendBitForUnitec_EIM826(aSwitchToOn); | |
/* | |
* Stopbit always 0 | |
*/ | |
sendBitForUnitec_EIM826(0); | |
interrupts(); | |
delayMicroseconds(EIM826_INTER_FRAME_MICROS); // interFrame delay | |
} | |
} | |
/* | |
* Intertechno stuff | |
*/ | |
const int INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS = 280; | |
const int INTERTECHNO_DURATION5 = INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS * 5; | |
const int INTERTECHNO_DURATION10 = INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS * 10; | |
#define INTERTECHNO_0 0 | |
#define INTERTECHNO_1 1 | |
#define INTERTECHNO_2 2 | |
#define INTERTECHNO_BEGIN 3 | |
#define INTERTECHNO_END 4 | |
void sendBitForINTERTECHNO(uint8_t aCode) { | |
switch (aCode) { | |
case INTERTECHNO_0: // Bit"0" | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_DURATION5); | |
break; | |
case INTERTECHNO_1: // Bit"1" | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_DURATION5); | |
break; | |
case INTERTECHNO_2: // Bit"F" | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_DURATION5); | |
break; | |
case INTERTECHNO_BEGIN: // | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_DURATION10); | |
break; | |
case INTERTECHNO_END: // Sync 4 high | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 1); | |
delayMicroseconds(INTERTECHNO_FUNDAMENTAL_CLOCK_PERIOD_MICROS); | |
digitalWriteFast(OUT_433_SIGNAL_PIN, 0); | |
delayMicroseconds(INTERTECHNO_DURATION5); | |
break; | |
default: | |
break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment