/* * RemoteSwitch library v2.3.0 (20121229) made by Randy Simons http://randysimons.nl/ * See RemoteTransmitter.h for details. * * License: GPLv3. See license.txt */ #include "RemoteTransmitter.h" /************ * RemoteTransmitter ************/ RemoteTransmitter::RemoteTransmitter(byte pin, unsigned int periodusec, byte repeats) { _pin=pin; _periodusec=periodusec; _repeats=repeats; pinMode(_pin, OUTPUT); } unsigned long RemoteTransmitter::encodeTelegram(byte trits[]) { unsigned long data = 0; // Encode data for (byte i=0;i<12;i++) { data*=3; data+=trits[i]; } // Encode period duration data |= (unsigned long)_periodusec << 23; // Encode repeats data |= (unsigned long)_repeats << 20; return data; } void RemoteTransmitter::sendTelegram(byte trits[]) { sendTelegram(encodeTelegram(trits),_pin); } /** * Format data: * pppppppp|prrrdddd|dddddddd|dddddddd (32 bit) * p = perioud (9 bit unsigned int * r = repeats as 2log. Thus, if r = 3, then signal is sent 2^3=8 times * d = data */ void RemoteTransmitter::sendTelegram(unsigned long data, byte pin) { unsigned int periodusec = (unsigned long)data >> 23; byte repeats = ((unsigned long)data >> 20) & B111; sendCode(pin, data, periodusec, repeats); } void RemoteTransmitter::sendCode(byte pin, unsigned long code, unsigned int periodusec, byte repeats) { code &= 0xfffff; // Truncate to 20 bit ; // Convert the base3-code to base4, to avoid lengthy calculations when transmitting.. Messes op timings. // Also note this swaps endianess in the process. The MSB must be transmitted first, but is converted to // LSB here. This is easier when actually transmitting later on. unsigned long dataBase4 = 0; for (byte i=0; i<12; i++) { dataBase4<<=2; dataBase4|=(code%3); code/=3; } repeats = 1 << (repeats & B111); // repeats := 2^repeats; for (byte j=0;j>=2; } // Send termination/synchronization-signal. Total length: 32 periods digitalWrite(pin, HIGH); delayMicroseconds(periodusec); digitalWrite(pin, LOW); delayMicroseconds(periodusec*31); } } boolean RemoteTransmitter::isSameCode(unsigned long encodedTelegram, unsigned long receivedData) { return (receivedData==(encodedTelegram & 0xFFFFF)); // compare the 20 LSB's } /************ * ActionTransmitter ************/ ActionTransmitter::ActionTransmitter(byte pin, unsigned int periodusec, byte repeats) : RemoteTransmitter(pin,periodusec,repeats) { // Call constructor } void ActionTransmitter::sendSignal(byte systemCode, char device, boolean on) { sendTelegram(getTelegram(systemCode,device,on), _pin); } unsigned long ActionTransmitter::getTelegram(byte systemCode, char device, boolean on) { byte trits[12]; device-=65; for (byte i=0; i<5; i++) { // Trits 0-4 contain address (2^5=32 addresses) trits[i]=(systemCode & 1)?1:2; systemCode>>=1; // Trits 5-9 contain device. Only one trit has value 0, others have 2 (float)! trits[i+5]=(i==device?0:2); } // Switch on or off trits[10]=(!on?0:2); trits[11]=(on?0:2); return encodeTelegram(trits); } /************ * BlokkerTransmitter ************/ BlokkerTransmitter::BlokkerTransmitter(byte pin, unsigned int periodusec, byte repeats) : RemoteTransmitter(pin,periodusec,repeats) { // Call constructor } void BlokkerTransmitter::sendSignal(byte device, boolean on) { sendTelegram(getTelegram(device,on), _pin); } unsigned long BlokkerTransmitter::getTelegram(byte device, boolean on) { byte trits[12]={0}; device--; for (byte i=1; i<4; i++) { // Trits 1-3 contain device trits[i]=(device & 1)?0:1; device>>=1; } // Switch on or off trits[8]=(on?1:0); return encodeTelegram(trits); } /************ * KaKuTransmitter ************/ KaKuTransmitter::KaKuTransmitter(byte pin, unsigned int periodusec, byte repeats) : RemoteTransmitter(pin,periodusec,repeats) { // Call constructor } void KaKuTransmitter::sendSignal(char address, byte device, boolean on) { sendTelegram(getTelegram(address, device, on), _pin); } unsigned long KaKuTransmitter::getTelegram(char address, byte device, boolean on) { byte trits[12]; address-=65; device-=1; for (byte i=0; i<4; i++) { // Trits 0-3 contain address (2^4 = 16 addresses) trits[i]=(address & 1)?2:0; address>>=1; // Trits 4-8 contain device (2^4 = 16 addresses) trits[i+4]=(device & 1)?2:0; device>>=1; } // Trits 8-10 seem to be fixed trits[8]=0; trits[9]=2; trits[10]=2; // Switch on or off trits[11]=(on?2:0); return encodeTelegram(trits); } void KaKuTransmitter::sendSignal(char address, byte group, byte device, boolean on) { sendTelegram(getTelegram(address, group, on), _pin); } unsigned long KaKuTransmitter::getTelegram(char address, byte group, byte device, boolean on) { byte trits[12], i; address-=65; group-=1; device-=1; // Address. M3E Pin A0-A3 for (i=0; i<4; i++) { // Trits 0-3 contain address (2^4 = 16 addresses) trits[i]=(address & 1)?2:0; address>>=1; } // Device. M3E Pin A4-A5 for (; i<6; i++) { trits[i]=(device & 1)?2:0; device>>=1; } // Group. M3E Pin A6-A7 for (; i<8; i++) { trits[i]=(group & 1)?2:0; group>>=1; } // Trits 8-10 are be fixed. M3E Pin A8/D0-A10/D2 trits[8]=0; trits[9]=2; trits[10]=2; // Switch on or off, M3E Pin A11/D3 trits[11]=(on?2:0); return encodeTelegram(trits); } /************ * ElroTransmitter ************/ ElroTransmitter::ElroTransmitter(byte pin, unsigned int periodusec, byte repeats) : RemoteTransmitter(pin, periodusec, repeats) { //Call constructor } void ElroTransmitter::sendSignal(byte systemCode, char device, boolean on) { sendTelegram(getTelegram(systemCode, device, on), _pin); } unsigned long ElroTransmitter::getTelegram(byte systemCode, char device, boolean on) { byte trits[12]; device-=65; for (byte i=0; i<5; i++) { //trits 0-4 contain address (2^5=32 addresses) trits[i]=(systemCode & 1)?0:2; systemCode>>=1; //trits 5-9 contain device. Only one trit has value 0, others have 2 (float)! trits[i+5]=(i==device?0:2); } //switch on or off trits[10]=(on?0:2); trits[11]=(!on?0:2); return encodeTelegram(trits); }