Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 64 bit codes #405

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions RCSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,16 @@ static const RCSwitch::Protocol PROGMEM proto[] = {
{ 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)
{ 320, { 36, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 12 (SM5212)
{ 100, { 3, 100 }, { 3, 8 }, { 8, 3 }, false } // protocol 13 (Mumbi RC-10)
};

enum {
numProto = sizeof(proto) / sizeof(proto[0])
};

#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;
Expand Down Expand Up @@ -133,7 +134,8 @@ void RCSwitch::setProtocol(Protocol protocol) {
*/
void RCSwitch::setProtocol(int nProtocol) {
if (nProtocol < 1 || nProtocol > numProto) {
nProtocol = 1; // TODO: trigger an error, e.g. "bad protocol" ???
nProtocol = 1;
printf("Error, bad protocol ID. Falling back to protocol 1.\n");
}
#if defined(ESP8266) || defined(ESP32)
this->protocol = proto[nProtocol-1];
Expand Down Expand Up @@ -452,7 +454,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;
Expand All @@ -462,11 +464,11 @@ void RCSwitch::sendTriState(const char* sCodeWord) {
break;
case 'F':
// bit pattern 01
code |= 1L;
code |= 1LL;
break;
case '1':
// bit pattern 11
code |= 3L;
code |= 3LL;
break;
}
length += 2;
Expand All @@ -479,12 +481,12 @@ void RCSwitch::sendTriState(const char* sCodeWord) {
*/
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 <<= 1LL;
if (*p != '0')
code |= 1L;
code |= 1LL;
length++;
}
this->send(code, length);
Expand All @@ -495,7 +497,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;

Expand All @@ -509,7 +511,7 @@ void RCSwitch::send(unsigned long code, unsigned int length) {

for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) {
for (int i = length-1; i >= 0; i--) {
if (code & (1L << i))
if (code & (1LL << i))
this->transmit(protocol.one);
else
this->transmit(protocol.zero);
Expand Down Expand Up @@ -581,7 +583,7 @@ void RCSwitch::resetAvailable() {
RCSwitch::nReceivedValue = 0;
}

unsigned long RCSwitch::getReceivedValue() {
unsigned long long RCSwitch::getReceivedValue() {
return RCSwitch::nReceivedValue;
}

Expand Down Expand Up @@ -617,7 +619,7 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
memcpy_P(&pro, &proto[p-1], sizeof(Protocol));
#endif

unsigned long code = 0;
unsigned long 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;
Expand All @@ -643,14 +645,14 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
const unsigned int firstDataTiming = (pro.invertedSignal) ? (2) : (1);

for (unsigned int i = firstDataTiming; i < changeCount - 1; i += 2) {
code <<= 1;
code <<= 1LL;
if (diff(RCSwitch::timings[i], delay * pro.zero.high) < delayTolerance &&
diff(RCSwitch::timings[i + 1], delay * pro.zero.low) < delayTolerance) {
// zero
} else if (diff(RCSwitch::timings[i], delay * pro.one.high) < delayTolerance &&
diff(RCSwitch::timings[i + 1], delay * pro.one.low) < delayTolerance) {
// one
code |= 1;
code |= 1LL;
} else {
// Failed
return false;
Expand Down
8 changes: 4 additions & 4 deletions RCSwitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

// 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
#define RCSWITCH_MAX_CHANGES 131

class RCSwitch {

Expand All @@ -77,7 +77,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 )
Expand All @@ -87,7 +87,7 @@ class RCSwitch {
bool available();
void resetAvailable();

unsigned long getReceivedValue();
unsigned long long getReceivedValue();
unsigned int getReceivedBitlength();
unsigned int getReceivedDelay();
unsigned int getReceivedProtocol();
Expand Down Expand Up @@ -167,7 +167,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;
Expand Down
49 changes: 28 additions & 21 deletions examples/ReceiveDemo_Advanced/output.ino
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
static const char* bin2tristate(const char* bin);
static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength);
static char * dec2binWzerofill(unsigned long long Dec, unsigned int bitLength);

void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw, unsigned int protocol) {

const char* b = dec2binWzerofill(decimal, length);
Serial.print("Decimal: ");
Serial.print(decimal);
Serial.print(" (");
Serial.print( length );
Serial.print("Bit) Binary: ");
Serial.print( b );
Serial.print(" Tri-State: ");
Serial.print( bin2tristate( b) );
Serial.print(" PulseLength: ");
Serial.print(delay);
Serial.print(" microseconds");
Serial.print(" Protocol: ");
Serial.println(protocol);
void output(unsigned long long decimal, unsigned int length, unsigned int delay, unsigned int* raw, unsigned int protocol) {
if (decimal == 0) {
Serial.print("Unknown encoding.");
} else {
const char* b = dec2binWzerofill(decimal, length);
char buffer[100];
Serial.print("Decimal: ");
sprintf(buffer, "%0ld", decimal/1000000L);
Serial.print(buffer);
sprintf(buffer, "%0ld", decimal%1000000L);
Serial.print(buffer);
Serial.print(" (");
Serial.print( length );
Serial.print("Bit) Binary: ");
Serial.print( b );
Serial.print(" Tri-State: ");
Serial.print( bin2tristate( b) );
Serial.print(" PulseLength: ");
Serial.print(delay);
Serial.print(" microseconds");
Serial.print(" Protocol: ");
Serial.println(protocol);
}

Serial.print("Raw data: ");
for (unsigned int i=0; i<= length*2; i++) {
Expand Down Expand Up @@ -48,18 +55,18 @@ static const char* bin2tristate(const char* bin) {
return returnValue;
}

static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength) {
static char bin[64];
static char * dec2binWzerofill(unsigned long long Dec, unsigned int bitLength) {
static char bin[128];
unsigned int i=0;

while (Dec > 0) {
bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0';
bin[64+i++] = ((Dec & 1) > 0) ? '1' : '0';
Dec = Dec >> 1;
}

for (unsigned int j = 0; j< bitLength; j++) {
if (j >= bitLength - i) {
bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
bin[j] = bin[ 63 + i - (j - (bitLength - i)) ];
} else {
bin[j] = '0';
}
Expand Down
23 changes: 16 additions & 7 deletions examples/ReceiveDemo_Simple/ReceiveDemo_Simple.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@ void setup() {

void loop() {
if (mySwitch.available()) {
unsigned long long value = mySwitch.getReceivedValue();
char buffer[100];

Serial.print("Received ");
Serial.print( mySwitch.getReceivedValue() );
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
if (value == 0) {
Serial.print("Unknown encoding");
} else {
Serial.print("Received ");
sprintf(buffer, "%0ld", value/1000000L);
Serial.print(buffer);
sprintf(buffer, "%0ld", value%1000000L);
Serial.print(buffer);
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
}

mySwitch.resetAvailable();
}
Expand Down