diff -r 4eebab50993e -r 6d139c21e22c rc433/rc-switch.c --- a/rc433/rc-switch.c Sun Jul 15 14:08:19 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,955 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2014 - * - * Michiel Broek - * - * This file is part of the mbsePi-apps - * - * Based on the Arduino libary for remote control outlet switches. - * Project home: http://code.google.com/p/rc-switch/ - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * mbsePi-apps 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with EC-65K; see the file COPYING. If not, write to the Free - * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - *****************************************************************************/ - -#include "rc433.h" - -#ifdef HAVE_WIRINGPI_H - - -#define TYPE_UNDEF 0 -#define TYPE_MINIMUM 0 -#define TYPE_A 1 -#define TYPE_B 2 -#define TYPE_C 3 -#define TYPE_D 4 -#define TYPE_E 3 // TODO: Which Protocol does REV use? -#define TYPE_MAXIMUM 4 - -// 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 - -// i.e. ProtocolCount + 1 (for TYPE_UNDEF) -#define MAX_PROTOCOLS 5 - -#define PROTOCOL_A_SYNC_FACTOR 31 -#define PROTOCOL_A_ZERO_FIRST_CYCLES 1 -#define PROTOCOL_A_ZERO_SECOND_CYCLES 3 -#define PROTOCOL_A_ONE_FIRST_CYCLES 3 -#define PROTOCOL_A_ONE_SECOND_CYCLES 1 -#define PROTOCOL_A_HIGH_FIRST true - -#define PROTOCOL_B_SYNC_FACTOR 10 -#define PROTOCOL_B_ZERO_FIRST_CYCLES 1 -#define PROTOCOL_B_ZERO_SECOND_CYCLES 2 -#define PROTOCOL_B_ONE_FIRST_CYCLES 2 -#define PROTOCOL_B_ONE_SECOND_CYCLES 1 -#define PROTOCOL_B_HIGH_FIRST true - -#define PROTOCOL_C_SYNC_FACTOR 71 -#define PROTOCOL_C_ZERO_FIRST_CYCLES 4 -#define PROTOCOL_C_ZERO_SECOND_CYCLES 11 -#define PROTOCOL_C_ONE_FIRST_CYCLES 9 -#define PROTOCOL_C_ONE_SECOND_CYCLES 6 -#define PROTOCOL_C_HIGH_FIRST true - -// I think, this will work for receive, however, I haven't tested, as I don't own a receiver... -// As Type D doesn't sync acc. to https://github.com/d-a-n/433-codes/blob/master/database.md#quigg -// the sync factor is totally undetermined. -// Malte Diers, 22.11.2013 -#define PROTOCOL_D_SYNC_FACTOR 1 -#define PROTOCOL_D_ZERO_FIRST_CYCLES 1 -#define PROTOCOL_D_ZERO_SECOND_CYCLES 2 -#define PROTOCOL_D_ONE_FIRST_CYCLES 2 -#define PROTOCOL_D_ONE_SECOND_CYCLES 1 -#define PROTOCOL_D_HIGH_FIRST false - - -#define PROTOCOL3_SYNC_FACTOR 71 -#define PROTOCOL3_0_HIGH_CYCLES 4 -#define PROTOCOL3_0_LOW_CYCLES 11 -#define PROTOCOL3_1_HIGH_CYCLES 9 -#define PROTOCOL3_1_LOW_CYCLES 6 - - - -unsigned long rcReceivedValue = 0; -unsigned int rcReceivedBitlength = 0; -unsigned int rcReceivedDelay = 0; -unsigned int rcReceivedProtocol = 0; -int rcReceiveTolerance = 60; -int rcReceiverInterruptPin = -1; - -unsigned int timings[RCSWITCH_MAX_CHANGES]; -int rcTransmitterPin = -1; -int rcPulseLength = 350; // thermometers 2.4 msec = 2400 -int rcRepeatTransmit = 10; -int rcProtocol = 1; - -int backupProtocol; -int backupPulseLength; -int backupRepeatTransmit; - - -//const char TYPE_A_CODE[ 6][6] = { "00000", "10000", "01000", "00100", "00010", "00001"}; -const char TYPE_B_CODE[ 5][5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; -const char TYPE_C_CODE[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", - "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" }; -const char TYPE_D_CODE[5][2][9] = { { "11100001", "11110000" }, { "00000000", "00010001" }, { "10000010", "10010011" }, - { "11000011", "11010010" }, { "01000001", "01010000" } }; - /* Type A Type D */ -const int PULSE_LENGTH[MAX_PROTOCOLS] = { 0, 350, 650, 100, 666, }; -const int REPEAT_TRANSMIT[MAX_PROTOCOLS] = { 0, 10, 10, 10, 4, }; -const int SYNC_FACTOR[MAX_PROTOCOLS] = { 0, PROTOCOL_A_SYNC_FACTOR, PROTOCOL_B_SYNC_FACTOR, PROTOCOL_C_SYNC_FACTOR, PROTOCOL_D_SYNC_FACTOR, }; -const int ZERO_FIRST_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ZERO_FIRST_CYCLES, PROTOCOL_B_ZERO_FIRST_CYCLES, PROTOCOL_C_ZERO_FIRST_CYCLES, PROTOCOL_D_ZERO_FIRST_CYCLES, }; -const int ZERO_SECOND_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ZERO_SECOND_CYCLES, PROTOCOL_B_ZERO_SECOND_CYCLES, PROTOCOL_C_ZERO_SECOND_CYCLES, PROTOCOL_D_ZERO_SECOND_CYCLES, }; -const int ONE_FIRST_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ONE_FIRST_CYCLES, PROTOCOL_B_ONE_FIRST_CYCLES, PROTOCOL_C_ONE_FIRST_CYCLES, PROTOCOL_D_ONE_FIRST_CYCLES, }; -const int ONE_SECOND_CYCLES[MAX_PROTOCOLS] = { 0, PROTOCOL_A_ONE_SECOND_CYCLES, PROTOCOL_B_ONE_SECOND_CYCLES, PROTOCOL_C_ONE_SECOND_CYCLES, PROTOCOL_D_ONE_SECOND_CYCLES, }; -const bool HIGH_FIRST[MAX_PROTOCOLS] = { 0, PROTOCOL_A_HIGH_FIRST, PROTOCOL_B_HIGH_FIRST, PROTOCOL_C_HIGH_FIRST, PROTOCOL_D_HIGH_FIRST, }; - - -char *getCodeWordA(char*, char*, bool); -char *getCodeWordB(int, int, bool); -char *getCodeWordC(char, int, int, bool); - -char *getCodeWordE(char, int, bool); -void sendTriState(char*); -void transmit(int, int, bool); -void send0(void); -void send1(void); -void sendT0(void); -void sendT1(void); -void sendTF(void); -void sendSync(void); -bool receiveProtocol(int, unsigned int); -void handleInterrupt(void); -char *dec2binWcharfill(unsigned long, unsigned int, char); - -void setReceiveTolerance(int); -void setProtocol(int); - -void saveProtocol(int); -void loadProtocol(void); - - - -/* - * Sets the protocol to send. - */ -void setProtocol(int nProtocol) { - - if ((nProtocol < TYPE_MINIMUM) || (nProtocol > TYPE_MAXIMUM)) { - return; - } - - rcProtocol = nProtocol; - rcPulseLength = PULSE_LENGTH[nProtocol]; - rcRepeatTransmit = REPEAT_TRANSMIT[nProtocol]; -} - - - -/* - * Set Receiving Tolerance - */ -void setReceiveTolerance(int nPercent) { - rcReceiveTolerance = nPercent; -} - - - -/* - * Enable transmissions - * - * @param nTransmitterPin Pin to which the sender is connected to - */ -void enableTransmit(int nTransmitterPin) { - rcTransmitterPin = nTransmitterPin; - pinMode(rcTransmitterPin, OUTPUT); -} - - - -/* - * Disable transmissions - */ -void disableTransmit(void) { - rcTransmitterPin = -1; -} - - - -/* - * Toggle switch, a command looks like B,3,2,1 which means switch type B, - * group 3, device 2, status on. - */ -int toggleSwitch(char *command) -{ - static char *cmd = NULL; - char *s, cType; - int rc, iGroup, iDevice, iState; - - cmd = xstrcpy(command); - s = strtok(cmd, ",\0"); - cType = s[0]; - - if (cType == 'A') { - - } else if (cType == 'B') { - s = strtok(NULL, ",\0"); - rc = sscanf(s, "%d", &iGroup); - if (rc != 1) - return 1; - s = strtok(NULL, ",\0"); - rc = sscanf(s, "%d", &iDevice); - if (rc != 1) - return 1; - s = strtok(NULL, ",\0"); - rc = sscanf(s, "%d", &iState); - if (rc != 1) - return 1; - free(cmd); - return toggleTypeB(iGroup, iDevice, iState); - } - - free(cmd); - return 1; -} - - - -/* - * Switch a remote switch on (Type E REV) - * - * @param sGroup Code of the switch group (A,B,C,D) - * @param nDevice Number of the switch itself (1..3) - * @param bStatus Status to toggle to - */ -int toggleTypeE(char sGroup, int nDevice, bool bStatus) { - sendTriState( getCodeWordE(sGroup, nDevice, bStatus) ); - return 0; -} - - - -/* - * Switch a remote switch on (Type C Intertechno) - * - * @param sFamily Familycode (a..f) - * @param nGroup Number of group (1..4) - * @param nDevice Number of device (1..4) - * @param bStatus Status to toggle to - */ -int toggleTypeC(char sFamily, int nGroup, int nDevice, bool bStatus) { - char *str = xstrcpy(getCodeWordC(sFamily, nGroup, nDevice, bStatus)); - - if (strlen(str) == 0) - return 1; - - saveProtocol(TYPE_A); // ??? - sendTriState( str ); - loadProtocol(); - free(str); - return 0; -} - - - -/* - * Switch a remote switch on/off (Type B with two rotary/sliding switches) - * - * @param iGroup Number of the switch group (1..4) - * @param iDevice Number of the switch itself (1..4) - * @param bStatus Status to toggle to - */ -int toggleTypeB(int iGroup, int iDevice, bool bStatus) -{ - char *str = xstrcpy(getCodeWordB(iGroup, iDevice, bStatus)); - - if (strlen(str) == 0) - return 1; - - saveProtocol(TYPE_A); // They do better with protocol A timings. - sendTriState( str ); - loadProtocol(); - free(str); - return 0; -} - - - -/* - * Switch a remote switch on (Type A with 10 pole DIP switches) - * - * @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") - * @param bStatus Status to toggle to - */ -int toggleTypeA(char* sGroup, char* sDevice, bool bStatus) { - char *str = xstrcpy(getCodeWordA(sGroup, sDevice, bStatus)); - - if (strlen(str) == 0) - return 1; - - saveProtocol(TYPE_A); - sendTriState( str ); - loadProtocol(); - free(str); - return 0; -} - - - -/* - * Returns a char[13], representing the Code Word to be send. - * A Code Word consists of 9 address bits, 3 data bits and one sync bit but in our case only the first 8 address bits and the last 2 data bits were used. - * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit) - * - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit | - * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S | - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * - * @param nAddressCode Number of the switch group (1..4) - * @param nChannelCode Number of the switch itself (1..4) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[13] - */ -char *getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) -{ - int i, nReturnPos = 0; - static char sReturn[13]; - - if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { - return '\0'; - } - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = TYPE_B_CODE[nAddressCode][i]; - } - - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = TYPE_B_CODE[nChannelCode][i]; - } - - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = bStatus ? 'F' : '0'; - sReturn[nReturnPos] = '\0'; - - return sReturn; -} - - - -/* - * Returns a char[13], representing the Code Word to be send. - * - * getCodeWordA(char*, char*) - * - */ -char *getCodeWordA(char* sGroup, char* sDevice, bool bOn) -{ - static char sDipSwitches[13]; - int i, j = 0; - - for (i=0; i < 5; i++) { - sDipSwitches[j++] = (sGroup[i] == '0') ? 'F' : '0'; - } - - for (i=0; i < 5; i++) { - sDipSwitches[j++] = (sDevice[i] == '0') ? 'F' : '0'; - } - - if ( bOn ) { - sDipSwitches[j++] = '0'; - sDipSwitches[j++] = 'F'; - } else { - sDipSwitches[j++] = 'F'; - sDipSwitches[j++] = '0'; - } - - sDipSwitches[j] = '\0'; - return sDipSwitches; -} - - - -/* - * Like getCodeWord (Type C = Intertechno) - */ -char *getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) -{ - static char sReturn[13]; - int i, nReturnPos = 0; - - if (sFamily < 'a') { - // To also enable capital 'A' to 'F' - sFamily += 32; - } - - if ( sFamily < 'a' || sFamily > 'f' || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { - return '\0'; - } - - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = TYPE_C_CODE[ sFamily - 'a' ][i]; - } - - char *sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 ); - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0'); - } - - sReturn[nReturnPos++] = '0'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = bStatus ? 'F' : '0'; - sReturn[nReturnPos] = '\0'; - - return sReturn; -} - - - -/* - * Decoding for the Quigg Switch Type - * - * Returns a char[22], representing the States to be send. - * A Code Word consists of 1 start bit, 12 address bits and 8 command data bits. - * A Code Bit can have 2 different states: "0" (low), "1" (high) - * - * +--------------+--------------------------------+------------------------------+ - * | 1 bits start | 12 bits address (device group) | 8 bits (command/switch data) | - * | 1 | 110011001100 | 00010001 | - * +--------------+--------------------------------+------------------------------+ - * - * Source: https://github.com/d-a-n/433-codes/blob/master/database.md#quigg - * - * @param sGroup 12-bit Binary ID of the Device Group - * @param nDevice Number of the switch itself (1..4, or 0 to switch the entire Group) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[22] - */ -char *getCodeWordD(char *sGroup, int nDevice, bool bStatus) -{ - static char sReturn[22]; - int i, nReturnPos = 0; - - /* Startbit */ - sReturn[nReturnPos++] = '1'; - - /* 12 bit Group */ - for (i = 0; i < 12; ++i) { - sReturn[nReturnPos++] = sGroup[i]; - } - - /* 8 Bit Device Identifier + Status (undividable!) */ - for (i = 0; i < 8; ++i) { - sReturn[nReturnPos++] = TYPE_D_CODE[nDevice][bStatus][i]; - } - sReturn[nReturnPos] = 0; - - return sReturn; -} - - - -/* - * Decoding for the REV Switch Type - * - * Returns a char[13], representing the Tristate to be send. - * A Code Word consists of 7 address bits and 5 command data bits. - * A Code Bit can have 3 different states: "F" (floating), "0" (low), "1" (high) - * - * +-------------------------------+--------------------------------+-----------------------+ - * | 4 bits address (switch group) | 3 bits address (device number) | 5 bits (command data) | - * | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | on=00010 off=00001 | - * +-------------------------------+--------------------------------+-----------------------+ - * - * 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 nDevice Number of the switch itself (1..3) - * @param bStatus Wether to switch on (true) or off (false) - * - * @return char[13] - */ -char *getCodeWordE(char sGroup, int nDevice, bool bStatus){ - static char sReturn[13]; - int i, nReturnPos = 0; - - // Building 4 bits address - // (Potential problem if dec2binWcharfill not returning correct string) - char *sGroupCode; - switch(sGroup){ - case 'a': - case 'A': - sGroupCode = dec2binWcharfill(8, 4, 'F'); break; - case 'b': - case 'B': - sGroupCode = dec2binWcharfill(4, 4, 'F'); break; - case 'c': - case 'C': - sGroupCode = dec2binWcharfill(2, 4, 'F'); break; - case 'd': - case 'D': - sGroupCode = dec2binWcharfill(1, 4, 'F'); break; - default: - return '\0'; - } - - for (i = 0; i<4; i++) { - sReturn[nReturnPos++] = sGroupCode[i]; - } - - - // Building 3 bits address - // (Potential problem if dec2binWcharfill not returning correct string) - char *sDevice; - switch(nDevice) { - case 1: - sDevice = dec2binWcharfill(4, 3, 'F'); break; - case 2: - sDevice = dec2binWcharfill(2, 3, 'F'); break; - case 3: - sDevice = dec2binWcharfill(1, 3, 'F'); break; - default: - return '\0'; - } - - for (i = 0; i<3; i++) - sReturn[nReturnPos++] = sDevice[i]; - - // fill up rest with zeros - for (i = 0; i<5; i++) - sReturn[nReturnPos++] = '0'; - - // encode on or off - if (bStatus) - sReturn[10] = '1'; - else - sReturn[11] = '1'; - - // last position terminate string - sReturn[12] = '\0'; - return sReturn; - -} - - - -/* - * @param sCodeWord /^[10FS]*$/ -> see getCodeWord - */ -void sendTriState(char* sCodeWord) { - int nRepeat; - - for (nRepeat = 0; nRepeat < rcRepeatTransmit; nRepeat++) { - int i = 0; - while (sCodeWord[i] != '\0') { - switch(sCodeWord[i]) { - case '0': - sendT0(); - break; - case 'F': - sendTF(); - break; - case '1': - sendT1(); - break; - } - i++; - } - sendSync(); - } -} - - - -/* -void RCSwitch::send(unsigned long Code, unsigned int length) { - this->send( this->dec2binWzerofill(Code, length) ); -} - -void RCSwitch::send(char* sCodeWord) { - for (int nRepeat=0; nRepeatsend0(); - break; - case '1': - this->send1(); - break; - } - i++; - } - this->sendSync(); - } -} -*/ - - -void transmit(int nFirstPulses, int nSecondPulses, bool bHighFirst) -{ - bool disabled_Receive = false; - int nReceiverInterrupt_backup = rcReceiverInterruptPin; - - if (rcTransmitterPin != -1) { - if (rcReceiverInterruptPin != -1) { - disableReceive(); - disabled_Receive = true; - } - digitalWrite(rcTransmitterPin, bHighFirst ? HIGH : LOW); - delayMicroseconds( rcPulseLength * nFirstPulses); - digitalWrite(rcTransmitterPin, bHighFirst ? LOW : HIGH); - delayMicroseconds( rcPulseLength * nSecondPulses); - - if (disabled_Receive) { - enableReceiveIRQ(nReceiverInterrupt_backup); - } - } -} - - - -/* - * Sends a "0" Bit - * _ - * Waveform Protocol 1: | |___ - * _ - * Waveform Protocol 2: | |__ - * ____ - * Waveform Protocol 3: | |___________ - */ -//void send0(void) { -// if (rcProtocol == 1){ -// transmit(1,3); -// } -// else if (rcProtocol == 2) { -// transmit(1,2); -// } -// else if (rcProtocol == 3) { -// transmit(4,11); -// } -//} - - - -/* - * Sends a "1" Bit - * ___ - * Waveform Protocol 1: | |_ - * __ - * Waveform Protocol 2: | |_ - * _________ - * Waveform Protocol 3: | |______ - */ -//void send1(void) { -// if (rcProtocol == 1){ -// transmit(3,1); -// } -// else if (rcProtocol == 2) { -// transmit(2,1); -// } -// else if (rcProtocol == 3) { -// transmit(9,6); -// } -//} - - - -/* - * Sends a Tri-State "0" Bit - * _ _ - * Waveform: | |___| |___ - */ -void sendT0(void) { - transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); - transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); -// transmit(1,3,true); -// transmit(1,3,true); -} - - - -/* - * Sends a Tri-State "1" Bit - * ___ ___ - * Waveform: | |_| |_ - */ -void sendT1(void) { - transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); - transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); -// transmit(3,1,true); -// transmit(3,1,true); -} - - - -/* - * Sends a Tri-State "F" Bit - * _ ___ - * Waveform: | |___| |_ - */ -void sendTF(void) { - transmit(ZERO_FIRST_CYCLES[rcProtocol], ZERO_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); - transmit(ONE_FIRST_CYCLES[rcProtocol], ONE_SECOND_CYCLES[rcProtocol], HIGH_FIRST[rcProtocol]); -// transmit(1,3,true); -// transmit(3,1,true); -} - - - -/* - * Sends a "Sync" Bit - * _ - * Waveform Protocol 1: | |_______________________________ - * _ - * Waveform Protocol 2: | |__________ - * ____ - * Waveform Protocol 3: | |_______________________________________________________________________ - * - * Waveform Protocol D: (none, just pause 80 msecs) - */ -void sendSync(void) { - - if (rcProtocol == TYPE_A) { - transmit(1,31,true); - } else if (rcProtocol == TYPE_B) { - transmit(1,10,true); - } else if (rcProtocol == TYPE_C) { - transmit(4,71,true); - } else if (rcProtocol == TYPE_D) { - transmit(0,1,false); - delayMicroseconds(80000); - } -} - - - -/* - * Enable receiving data - */ -void enableReceiveIRQ(int Pin) { - rcReceiverInterruptPin = Pin; - enableReceive(); -} - -void enableReceive(void) { - if (rcReceiverInterruptPin != -1) { - rcReceivedValue = 0; - rcReceivedBitlength = 0; - wiringPiISR(rcReceiverInterruptPin, INT_EDGE_BOTH, &handleInterrupt); - } -} - - - -/* - * Disable receiving data - */ -void disableReceive() { - // wiringPi disable interrupts ??? - rcReceiverInterruptPin = -1; -} - - - -bool available(void) { - return rcReceivedValue != 0; -} - - - -void resetAvailable(void) { - rcReceivedValue = 0; -} - - - -unsigned long getReceivedValue(void) { - return rcReceivedValue; -} - - - -unsigned int getReceivedBitlength(void) { - return rcReceivedBitlength; -} - - - -unsigned int getReceivedDelay(void) { - return rcReceivedDelay; -} - - - -unsigned int getReceivedProtocol(void) { - return rcReceivedProtocol; -} - - - -unsigned int* getReceivedRawdata(void) { - return timings; -} - - - -/* - * ASK protool 1 - */ -bool receiveProtocol(int prot, unsigned int changeCount) -{ - unsigned long code = 0; - unsigned long ldelay = timings[0] / SYNC_FACTOR[prot]; - unsigned long delayTolerance = ldelay * rcReceiveTolerance * 0.01; - int i; - - if (prot < TYPE_MINIMUM || prot > TYPE_MAXIMUM) { - return false; - } - - for (i = 1; i ldelay * ZERO_FIRST_CYCLES[prot] - delayTolerance && - timings[i] < ldelay * ZERO_FIRST_CYCLES[prot] + delayTolerance && - timings[i+1] > ldelay * ZERO_SECOND_CYCLES[prot] - delayTolerance && - timings[i+1] < ldelay * ZERO_SECOND_CYCLES[prot] + delayTolerance) { - code = code << 1; - } else if (timings[i] > ldelay * ONE_FIRST_CYCLES[prot] - delayTolerance && - timings[i] < ldelay * ONE_FIRST_CYCLES[prot] + delayTolerance && - timings[i+1] > ldelay * ONE_SECOND_CYCLES[prot] - delayTolerance && - timings[i+1] < ldelay * ONE_SECOND_CYCLES[prot] + delayTolerance) { - code+=1; - code = code << 1; - } else { - // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - rcReceivedValue = code; - rcReceivedBitlength = changeCount / 2; - rcReceivedDelay = ldelay; - rcReceivedProtocol = prot; - } - - return (code != 0); -} - - - -void handleInterrupt() { - - static unsigned int duration; - static unsigned int changeCount; - static unsigned long lastTime; - static unsigned int repeatCount; - - - long thistime = micros(); - duration = thistime - lastTime; - - if (duration > 5000 && duration > timings[0] - 200 && duration < timings[0] + 200) { - repeatCount++; - changeCount--; - if (repeatCount == 2) { - if (receiveProtocol(TYPE_A, changeCount) == false) { - if (receiveProtocol(TYPE_B, changeCount) == false) { - if (receiveProtocol(TYPE_C, changeCount) == false) { - if (receiveProtocol(TYPE_D, changeCount) == false) { - //failed - } - } - } - } - repeatCount = 0; - } - changeCount = 0; - } else if (duration > 5000) { - changeCount = 0; - } - - if (changeCount >= RCSWITCH_MAX_CHANGES) { - changeCount = 0; - repeatCount = 0; - } - timings[changeCount++] = duration; - lastTime = thistime; -} - - - -/* - * Turns a decimal value to its binary representation - */ -char *dec2binWzerofill(unsigned long Dec, unsigned int bitLength) -{ - return dec2binWcharfill(Dec, bitLength, '0'); -} - -char *dec2binWcharfill(unsigned long Dec, unsigned int bitLength, char fill) -{ - static char bin[64]; - unsigned int i = 0, j; - - while (Dec > 0) { - bin[32+i++] = ((Dec & 1) > 0) ? '1' : fill; - Dec = Dec >> 1; - } - - for (j = 0; j< bitLength; j++) { - if (j >= bitLength - i) { - bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; - } else { - bin[j] = fill; - } - } - bin[bitLength] = '\0'; - - return bin; -} - - -void saveProtocol(int prot) -{ - backupProtocol = rcProtocol; - backupPulseLength = rcPulseLength; - backupRepeatTransmit = rcRepeatTransmit; - - setProtocol(prot); -} - - - -void loadProtocol(void) -{ - rcProtocol = backupProtocol; - rcPulseLength = backupPulseLength; - rcRepeatTransmit = backupRepeatTransmit; -} - - -#endif -