Skip to content
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
99 changes: 51 additions & 48 deletions RCSwitch.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
RCSwitch - Arduino libary for remote control outlet switches
Copyright (c) 2011 Suat Özgür. All right reserved.

Contributors:
- Andre Koehler / info(at)tomate-online(dot)de
- Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com
Expand All @@ -13,8 +13,8 @@
- Robert ter Vehn / <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
- Matias Cuenca-Acuna
- Matias Cuenca-Acuna

Project home: https://github.com/sui77/rc-switch/

This library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -54,10 +54,14 @@
#define VAR_ISR_ATTR
#endif

// defined if compiled with ESP8266 SDK, otherwise make an empty define here
#ifndef ICACHE_FLASH_ATTR
#define ICACHE_FLASH_ATTR
#endif

/* Format for protocol definitions:
* {pulselength, Sync bit, "0" bit, "1" bit, invertedSignal}
*
*
* 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
Expand Down Expand Up @@ -124,14 +128,14 @@ RCSwitch::RCSwitch() {
/**
* Sets the protocol to send.
*/
void RCSwitch::setProtocol(Protocol protocol) {
void ICACHE_FLASH_ATTR RCSwitch::setProtocol(Protocol protocol) {
this->protocol = protocol;
}

/**
* Sets the protocol to send, from a list of predefined protocols
*/
void RCSwitch::setProtocol(int nProtocol) {
void ICACHE_FLASH_ATTR RCSwitch::setProtocol(int nProtocol) {
if (nProtocol < 1 || nProtocol > numProto) {
nProtocol = 1; // TODO: trigger an error, e.g. "bad protocol" ???
}
Expand All @@ -145,50 +149,49 @@ void RCSwitch::setProtocol(int nProtocol) {
/**
* Sets the protocol to send with pulse length in microseconds.
*/
void RCSwitch::setProtocol(int nProtocol, int nPulseLength) {
void ICACHE_FLASH_ATTR RCSwitch::setProtocol(int nProtocol, int nPulseLength) {
setProtocol(nProtocol);
this->setPulseLength(nPulseLength);
}


/**
* Sets pulse length in microseconds
*/
void RCSwitch::setPulseLength(int nPulseLength) {
void ICACHE_FLASH_ATTR RCSwitch::setPulseLength(int nPulseLength) {
this->protocol.pulseLength = nPulseLength;
}

/**
* Sets Repeat Transmits
*/
void RCSwitch::setRepeatTransmit(int nRepeatTransmit) {
void ICACHE_FLASH_ATTR RCSwitch::setRepeatTransmit(int nRepeatTransmit) {
this->nRepeatTransmit = nRepeatTransmit;
}

/**
* Set Receiving Tolerance
*/
#if not defined( RCSwitchDisableReceiving )
void RCSwitch::setReceiveTolerance(int nPercent) {
void ICACHE_FLASH_ATTR RCSwitch::setReceiveTolerance(int nPercent) {
RCSwitch::nReceiveTolerance = nPercent;
}
#endif


/**
* Enable transmissions
*
* @param nTransmitterPin Arduino Pin to which the sender is connected to
*/
void RCSwitch::enableTransmit(int nTransmitterPin) {
void ICACHE_FLASH_ATTR RCSwitch::enableTransmit(int nTransmitterPin) {
this->nTransmitterPin = nTransmitterPin;
pinMode(this->nTransmitterPin, OUTPUT);
}

/**
* Disable transmissions
*/
void RCSwitch::disableTransmit() {
void ICACHE_FLASH_ATTR RCSwitch::disableTransmit() {
this->nTransmitterPin = -1;
}

Expand All @@ -198,7 +201,7 @@ void RCSwitch::disableTransmit() {
* @param sGroup Code of the switch group (A,B,C,D)
* @param nDevice Number of the switch itself (1..3)
*/
void RCSwitch::switchOn(char sGroup, int nDevice) {
void ICACHE_FLASH_ATTR RCSwitch::switchOn(char sGroup, int nDevice) {
this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) );
}

Expand All @@ -208,7 +211,7 @@ void RCSwitch::switchOn(char sGroup, int nDevice) {
* @param sGroup Code of the switch group (A,B,C,D)
* @param nDevice Number of the switch itself (1..3)
*/
void RCSwitch::switchOff(char sGroup, int nDevice) {
void ICACHE_FLASH_ATTR RCSwitch::switchOff(char sGroup, int nDevice) {
this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) );
}

Expand All @@ -219,7 +222,7 @@ void RCSwitch::switchOff(char sGroup, int nDevice) {
* @param nGroup Number of group (1..4)
* @param nDevice Number of device (1..4)
*/
void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) {
void ICACHE_FLASH_ATTR RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) {
this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, true) );
}

Expand All @@ -230,7 +233,7 @@ void RCSwitch::switchOn(char sFamily, int nGroup, int nDevice) {
* @param nGroup Number of group (1..4)
* @param nDevice Number of device (1..4)
*/
void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) {
void ICACHE_FLASH_ATTR RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) {
this->sendTriState( this->getCodeWordC(sFamily, nGroup, nDevice, false) );
}

Expand All @@ -240,7 +243,7 @@ void RCSwitch::switchOff(char sFamily, int nGroup, int nDevice) {
* @param nAddressCode Number of the switch group (1..4)
* @param nChannelCode Number of the switch itself (1..4)
*/
void RCSwitch::switchOn(int nAddressCode, int nChannelCode) {
void ICACHE_FLASH_ATTR RCSwitch::switchOn(int nAddressCode, int nChannelCode) {
this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, true) );
}

Expand All @@ -250,7 +253,7 @@ void RCSwitch::switchOn(int nAddressCode, int nChannelCode) {
* @param nAddressCode Number of the switch group (1..4)
* @param nChannelCode Number of the switch itself (1..4)
*/
void RCSwitch::switchOff(int nAddressCode, int nChannelCode) {
void ICACHE_FLASH_ATTR RCSwitch::switchOff(int nAddressCode, int nChannelCode) {
this->sendTriState( this->getCodeWordB(nAddressCode, nChannelCode, false) );
}

Expand All @@ -261,7 +264,7 @@ void RCSwitch::switchOff(int nAddressCode, int nChannelCode) {
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
* @param nChannelCode Number of the switch itself (1..5)
*/
void RCSwitch::switchOn(const char* sGroup, int nChannel) {
void ICACHE_FLASH_ATTR RCSwitch::switchOn(const char* sGroup, int nChannel) {
const char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" };
this->switchOn(sGroup, code[nChannel]);
}
Expand All @@ -273,7 +276,7 @@ void RCSwitch::switchOn(const char* sGroup, int nChannel) {
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
* @param nChannelCode Number of the switch itself (1..5)
*/
void RCSwitch::switchOff(const char* sGroup, int nChannel) {
void ICACHE_FLASH_ATTR RCSwitch::switchOff(const char* sGroup, int nChannel) {
const char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" };
this->switchOff(sGroup, code[nChannel]);
}
Expand All @@ -284,7 +287,7 @@ void RCSwitch::switchOff(const char* sGroup, int nChannel) {
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
* @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111")
*/
void RCSwitch::switchOn(const char* sGroup, const char* sDevice) {
void ICACHE_FLASH_ATTR RCSwitch::switchOn(const char* sGroup, const char* sDevice) {
this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) );
}

Expand All @@ -294,7 +297,7 @@ void RCSwitch::switchOn(const char* sGroup, const char* sDevice) {
* @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111")
* @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111")
*/
void RCSwitch::switchOff(const char* sGroup, const char* sDevice) {
void ICACHE_FLASH_ATTR RCSwitch::switchOff(const char* sGroup, const char* sDevice) {
this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) );
}

Expand All @@ -303,7 +306,7 @@ void RCSwitch::switchOff(const char* sGroup, const char* sDevice) {
* Returns a char[13], representing the code word to be send.
*
*/
char* RCSwitch::getCodeWordA(const char* sGroup, const char* sDevice, bool bStatus) {
char* ICACHE_FLASH_ATTR RCSwitch::getCodeWordA(const char* sGroup, const char* sDevice, bool bStatus) {
static char sReturn[13];
int nReturnPos = 0;

Expand Down Expand Up @@ -339,7 +342,7 @@ char* RCSwitch::getCodeWordA(const char* sGroup, const char* sDevice, bool bStat
*
* @return char[13], representing a tristate code word of length 12
*/
char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) {
char* ICACHE_FLASH_ATTR RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) {
static char sReturn[13];
int nReturnPos = 0;

Expand Down Expand Up @@ -368,15 +371,15 @@ char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) {
/**
* Like getCodeWord (Type C = Intertechno)
*/
char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) {
char* ICACHE_FLASH_ATTR RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) {
static char sReturn[13];
int nReturnPos = 0;

int nFamily = (int)sFamily - 'a';
if ( nFamily < 0 || nFamily > 15 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) {
return 0;
}

// encode the family into four bits
sReturn[nReturnPos++] = (nFamily & 1) ? 'F' : '0';
sReturn[nReturnPos++] = (nFamily & 2) ? 'F' : '0';
Expand Down Expand Up @@ -412,13 +415,13 @@ char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus
*
* Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/
*
* @param sGroup Name of the switch group (A..D, resp. a..d)
* @param sGroup Name of the switch group (A..D, resp. a..d)
* @param nDevice Number of the switch itself (1..3)
* @param bStatus Whether to switch on (true) or off (false)
*
* @return char[13], representing a tristate code word of length 12
*/
char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) {
char* ICACHE_FLASH_ATTR RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) {
static char sReturn[13];
int nReturnPos = 0;

Expand Down Expand Up @@ -450,7 +453,7 @@ char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) {
/**
* @param sCodeWord a tristate code word consisting of the letter 0, 1, F
*/
void RCSwitch::sendTriState(const char* sCodeWord) {
void ICACHE_FLASH_ATTR RCSwitch::sendTriState(const char* sCodeWord) {
// turn the tristate code word into the corresponding bit pattern, then send it
unsigned long code = 0;
unsigned int length = 0;
Expand All @@ -477,7 +480,7 @@ void RCSwitch::sendTriState(const char* sCodeWord) {
/**
* @param sCodeWord a binary code word consisting of the letter 0, 1
*/
void RCSwitch::send(const char* sCodeWord) {
void ICACHE_FLASH_ATTR RCSwitch::send(const char* sCodeWord) {
// turn the tristate code word into the corresponding bit pattern, then send it
unsigned long code = 0;
unsigned int length = 0;
Expand All @@ -495,7 +498,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 ICACHE_FLASH_ATTR RCSwitch::send(unsigned long code, unsigned int length) {
if (this->nTransmitterPin == -1)
return;

Expand Down Expand Up @@ -531,10 +534,10 @@ void RCSwitch::send(unsigned long code, unsigned int length) {
/**
* Transmit a single high-low pulse.
*/
void RCSwitch::transmit(HighLow pulses) {
void ICACHE_FLASH_ATTR 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);
Expand All @@ -546,12 +549,12 @@ void RCSwitch::transmit(HighLow pulses) {
/**
* Enable receiving data
*/
void RCSwitch::enableReceive(int interrupt) {
void ICACHE_FLASH_ATTR RCSwitch::enableReceive(int interrupt) {
this->nReceiverInterrupt = interrupt;
this->enableReceive();
}

void RCSwitch::enableReceive() {
void ICACHE_FLASH_ATTR RCSwitch::enableReceive() {
if (this->nReceiverInterrupt != -1) {
RCSwitch::nReceivedValue = 0;
RCSwitch::nReceivedBitlength = 0;
Expand All @@ -566,38 +569,38 @@ void RCSwitch::enableReceive() {
/**
* Disable receiving data
*/
void RCSwitch::disableReceive() {
void ICACHE_FLASH_ATTR RCSwitch::disableReceive() {
#if not defined(RaspberryPi) // Arduino
detachInterrupt(this->nReceiverInterrupt);
#endif // For Raspberry Pi (wiringPi) you can't unregister the ISR
this->nReceiverInterrupt = -1;
}

bool RCSwitch::available() {
bool ICACHE_FLASH_ATTR RCSwitch::available() {
return RCSwitch::nReceivedValue != 0;
}

void RCSwitch::resetAvailable() {
void ICACHE_FLASH_ATTR RCSwitch::resetAvailable() {
RCSwitch::nReceivedValue = 0;
}

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

unsigned int RCSwitch::getReceivedBitlength() {
unsigned int ICACHE_FLASH_ATTR RCSwitch::getReceivedBitlength() {
return RCSwitch::nReceivedBitlength;
}

unsigned int RCSwitch::getReceivedDelay() {
unsigned int ICACHE_FLASH_ATTR RCSwitch::getReceivedDelay() {
return RCSwitch::nReceivedDelay;
}

unsigned int RCSwitch::getReceivedProtocol() {
unsigned int ICACHE_FLASH_ATTR RCSwitch::getReceivedProtocol() {
return RCSwitch::nReceivedProtocol;
}

unsigned int* RCSwitch::getReceivedRawdata() {
unsigned int* ICACHE_FLASH_ATTR RCSwitch::getReceivedRawdata() {
return RCSwitch::timings;
}

Expand All @@ -622,7 +625,7 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
const unsigned int syncLengthInPulses = ((pro.syncFactor.low) > (pro.syncFactor.high)) ? (pro.syncFactor.low) : (pro.syncFactor.high);
const unsigned int delay = RCSwitch::timings[0] / syncLengthInPulses;
const unsigned int delayTolerance = delay * RCSwitch::nReceiveTolerance / 100;

/* For protocols that start low, the sync period looks like
* _________
* _____________| |XXXXXXXXXXXX|
Expand Down Expand Up @@ -699,14 +702,14 @@ void RECEIVE_ATTR RCSwitch::handleInterrupt() {
}
changeCount = 0;
}

// detect overflow
if (changeCount >= RCSWITCH_MAX_CHANGES) {
changeCount = 0;
repeatCount = 0;
}

RCSwitch::timings[changeCount++] = duration;
lastTime = time;
lastTime = time;
}
#endif
8 changes: 8 additions & 0 deletions RCSwitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#elif defined(__ets__)
#define ESP8266

#include <c_types.h>
#include <stdlib.h> /* abs */
#include "wiringESP.h"

#define ICACHE_RAM_ATTR
#elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific
#include "Energia.h"
#elif defined(RPI) // Raspberry Pi
Expand Down