mirror of https://github.com/arendst/Tasmota.git
add support for nexus protocol to rc-switch library (#21886)
* add support for nexus protocol to RCSwitch library Nexus protocol is used by temperature and humidity sensor that operate at 433 MHz. It is used by various brands. * calc separation limit for RCSwitch library automatically
This commit is contained in:
parent
d1bd31b341
commit
caa501b1af
|
@ -151,8 +151,9 @@ static const RCSwitch::Protocol PROGMEM proto[] = {
|
||||||
{ 340, 0, { 0, 0 }, 1, { 14, 4 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 33 (Dooya Control DC2708L)
|
{ 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 - so as to use this protocol RCSWITCH_SEPARATION_LIMIT must be set to 2600
|
{ 120, 0, { 0, 0 }, 1, { 1, 28 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 34 DIGOO SD10 - so as to use this protocol RCSWITCH_SEPARATION_LIMIT must be set to 2600
|
||||||
{ 20, 0, { 0, 0 }, 1, { 239, 78 }, {20, 35 }, {35, 20}, false, 10000},// 35 Dooya 5-Channel blinds remote DC1603
|
{ 20, 0, { 0, 0 }, 1, { 239, 78 }, {20, 35 }, {35, 20}, false, 10000},// 35 Dooya 5-Channel blinds remote DC1603
|
||||||
{ 250, 0, { 0, 0 }, 1, { 18, 6 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 36 Dooya remote DC2700AC for Dooya DT82TV curtains motor
|
{ 250, 0, { 0, 0 }, 1, { 18, 6 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 36 Dooya remote DC2700AC for Dooya DT82TV curtains motor
|
||||||
{ 200, 0, { 0, 0 }, 0, { 0, 0 }, { 1, 3 }, { 3, 1} , false, 20} // 37 DEWENWILS Power Strip
|
{ 200, 0, { 0, 0 }, 0, { 0, 0 }, { 1, 3 }, { 3, 1 }, false, 20 }, // 37 DEWENWILS Power Strip
|
||||||
|
{ 500, 0, { 0, 0 }, 1, { 7, 1 }, { 2, 1 }, { 4, 1 }, true, 0 }, // 38 temperature and humidity sensor, various brands, nexus protocol, 36 bits + start impulse
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -166,7 +167,7 @@ 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 = RCSWITCH_SEPARATION_LIMIT;
|
unsigned int RCSwitch::nSeparationLimit = RCSWITCH_SEPARATION_LIMIT;
|
||||||
unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES];
|
unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES];
|
||||||
unsigned int RCSwitch::buftimings[4];
|
unsigned int RCSwitch::buftimings[4];
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,8 +239,50 @@ void RCSwitch::setReceiveTolerance(int nPercent) {
|
||||||
RCSwitch::nReceiveTolerance = nPercent;
|
RCSwitch::nReceiveTolerance = nPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCSwitch::setReceiveProtocolMask(unsigned long long mask) {
|
bool RCSwitch::setReceiveProtocolMask(unsigned long long mask) {
|
||||||
RCSwitch::nReceiveProtocolMask = mask;
|
RCSwitch::nReceiveProtocolMask = mask;
|
||||||
|
return updateSeparationLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RCSwitch::updateSeparationLimit()
|
||||||
|
{
|
||||||
|
unsigned int longestPulseTime = std::numeric_limits<unsigned int>::max();
|
||||||
|
unsigned int shortestPulseTime = 0;
|
||||||
|
|
||||||
|
unsigned long long thisMask = 1;
|
||||||
|
for(unsigned int i = 0; i < numProto; i++) {
|
||||||
|
if (RCSwitch::nReceiveProtocolMask & thisMask) {
|
||||||
|
const unsigned int headerShortPulseCount = std::min(proto[i].Header.high, proto[i].Header.low);
|
||||||
|
const unsigned int headerLongPulseCount = std::max(proto[i].Header.high, proto[i].Header.low);
|
||||||
|
|
||||||
|
// This must be the longest pulse-length of this protocol. nSeparationLimit must of this length or shorter.
|
||||||
|
// This pulse will be used to detect the beginning of a transmission.
|
||||||
|
const unsigned int headerLongPulseTime = proto[i].pulseLength * headerLongPulseCount;
|
||||||
|
|
||||||
|
// nSeparationLimit must be longer than any of the following pulses to avoid detecting a new transmission in the middle of a frame.
|
||||||
|
unsigned int longestDataPulseCount = headerShortPulseCount;
|
||||||
|
longestDataPulseCount = std::max<unsigned int>(longestDataPulseCount, proto[i].zero.high);
|
||||||
|
longestDataPulseCount = std::max<unsigned int>(longestDataPulseCount, proto[i].zero.low);
|
||||||
|
longestDataPulseCount = std::max<unsigned int>(longestDataPulseCount, proto[i].one.high);
|
||||||
|
longestDataPulseCount = std::max<unsigned int>(longestDataPulseCount, proto[i].one.low);
|
||||||
|
|
||||||
|
const unsigned int longestDataPulseTime = proto[i].pulseLength * longestDataPulseCount;
|
||||||
|
|
||||||
|
longestPulseTime = std::min(longestPulseTime, headerLongPulseTime);
|
||||||
|
shortestPulseTime = std::max(shortestPulseTime, longestDataPulseTime);
|
||||||
|
}
|
||||||
|
thisMask <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longestPulseTime <= shortestPulseTime) {
|
||||||
|
// incompatible protocols enabled, fall back to default value
|
||||||
|
nSeparationLimit = RCSWITCH_SEPARATION_LIMIT;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int timeDiff = longestPulseTime - shortestPulseTime;
|
||||||
|
nSeparationLimit = longestPulseTime - (timeDiff / 2);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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 36 bit * 2 H/L changes per bit + 2 for sync
|
||||||
// Для keeloq нужно увеличить RCSWITCH_MAX_CHANGES до 23+1+66*2+1=157
|
// Для keeloq нужно увеличить RCSWITCH_MAX_CHANGES до 23+1+66*2+1=157
|
||||||
#define RCSWITCH_MAX_CHANGES 67 // default 67
|
#define RCSWITCH_MAX_CHANGES 75 // default 75 - longest protocol that requires this buffer size is 38/nexus
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -108,7 +108,7 @@ class RCSwitch {
|
||||||
void setRepeatTransmit(int nRepeatTransmit);
|
void setRepeatTransmit(int nRepeatTransmit);
|
||||||
#if not defined( RCSwitchDisableReceiving )
|
#if not defined( RCSwitchDisableReceiving )
|
||||||
void setReceiveTolerance(int nPercent);
|
void setReceiveTolerance(int nPercent);
|
||||||
void setReceiveProtocolMask(unsigned long long mask);
|
bool setReceiveProtocolMask(unsigned long long mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,6 +171,7 @@ class RCSwitch {
|
||||||
#if not defined( RCSwitchDisableReceiving )
|
#if not defined( RCSwitchDisableReceiving )
|
||||||
static void handleInterrupt();
|
static void handleInterrupt();
|
||||||
static bool receiveProtocol(const int p, unsigned int changeCount);
|
static bool receiveProtocol(const int p, unsigned int changeCount);
|
||||||
|
static bool updateSeparationLimit();
|
||||||
int nReceiverInterrupt;
|
int nReceiverInterrupt;
|
||||||
#endif
|
#endif
|
||||||
int nTransmitterPin;
|
int nTransmitterPin;
|
||||||
|
@ -184,7 +185,7 @@ class RCSwitch {
|
||||||
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;
|
||||||
const static unsigned int nSeparationLimit;
|
static unsigned int nSeparationLimit;
|
||||||
/*
|
/*
|
||||||
* timings[0] contains sync timing, followed by a number of bits
|
* timings[0] contains sync timing, followed by a number of bits
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -92,7 +92,7 @@ void RfInit(void) {
|
||||||
if (!Settings->rf_protocol_mask) {
|
if (!Settings->rf_protocol_mask) {
|
||||||
Settings->rf_protocol_mask = (1ULL << mySwitch.getNumProtos()) -1;
|
Settings->rf_protocol_mask = (1ULL << mySwitch.getNumProtos()) -1;
|
||||||
}
|
}
|
||||||
mySwitch.setReceiveProtocolMask(Settings->rf_protocol_mask);
|
(void)mySwitch.setReceiveProtocolMask(Settings->rf_protocol_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,10 @@ void CmndRfProtocol(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mySwitch.setReceiveProtocolMask(Settings->rf_protocol_mask);
|
const bool incompatibleProtocolsSelected = !mySwitch.setReceiveProtocolMask(Settings->rf_protocol_mask);
|
||||||
|
if (incompatibleProtocolsSelected) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("RFR: CmndRfProtocol:: Incompatible protocols selected, using default separation limit, some protocols may not work"));
|
||||||
|
}
|
||||||
// AddLog(LOG_LEVEL_INFO, PSTR("RFR: CmndRfProtocol:: Start responce"));
|
// AddLog(LOG_LEVEL_INFO, PSTR("RFR: CmndRfProtocol:: Start responce"));
|
||||||
Response_P(PSTR("{\"" D_CMND_RFPROTOCOL "\":\""));
|
Response_P(PSTR("{\"" D_CMND_RFPROTOCOL "\":\""));
|
||||||
bool gotone = false;
|
bool gotone = false;
|
||||||
|
|
Loading…
Reference in New Issue