//####################################################################################################### //## This Plugin is only for use with the RFLink software package ## //## Plugin-06: X10 RF ## //####################################################################################################### /*********************************************************************************************\ * This plugin takes care of sending and receiving the X10 RF protocol. * * Author : StuntTeam * Support : http://sourceforge.net/projects/rflink/ * License : This code is free for use in any open source project when this header is included. * Usage of any parts of this code in a commercial application is prohibited! *********************************************************************************************** * Incoming event: "X10 , * Send : "X10Send , * * Address = A1 - P16 *********************************************************************************************** * Technical information: * RF packets are 68 bits long transferring 64 manchester encoded bits resulting in 32 bits / 4 bytes. * * address address^ data data^ * 01100000 10011111 00000000 11111111 609F00FF * 10011111 01100000 11111111 00000000 9F60FF00 * * 4 bytes are transmitted, the second and fourth are the inverse of the first and third byte. * So the actual data is only 2 bytes * * 01100000 00000000 * AAAABBBB CDEDDDDD * * A = Housecode 0110 a 6 0111 b 7 0100 c 4 0101 d 5 1000 e 8 1001 f 9 1010 g a 1011 h b * 1110 i e 1111 j f 1100 k c 1101 l d 0000 m 0 0001 n 1 0010 o 2 0011 p 3 * B = Unitcode 1-8 / 9-16 indicator * C = Group/Dimmer indicator * D = Unitcode * E = on/off indicator * * on * 20;06;DEBUG;Pulses=68;Pulses(uSec)=3300,4225,400,375,400,1325,400,1325,400,1325,400,375,400,375,400,375,400,375,400,1325,400,375,400,375,400,375,400,1350,400,1350,375,1350,400,1350,400,375,400,375,400,375,400,1325,400,1325,400,375,400,375,400,375,400,1350,400,1325,400,1325,400,375,400,375,400,1325,400,1325,400,1325,400 * off * 20;10;DEBUG;Pulses=68;Pulses(uSec)=3300,4225,400,375,400,1350,400,1350,400,1325,400,375,400,375,400,375,400,375,400,1325,400,375,400,375,400,375,400,1325,400,1325,400,1325,400,1325,400,375,400,375,400,1325,400,1350,400,1350,400,375,400,375,400,375,375,1350,400,1350,400,375,400,375,400,375,400,1325,400,1350,400,1325,400; * 20;20;DEBUG;Pulses=66;Pulses(uSec)=425,350,375,1300,375,1300,375,1350,375,375,375,1350,375,375,375,375,375,1350,375,375,375,375,375,375,400,1350,375,375,400,1350,375,1350,400,1325,400,375,400,375,400,375,400,375,400,375,400,375,400,375,400,375,400,1325,400,1325,400,1325,400,1325,400,1325,400,1350,375,1350,375; \*********************************************************************************************/ #define X10_PulseLength 66 #define X10_PULSEMID 600/RAWSIGNAL_SAMPLE_RATE #ifdef PLUGIN_009 boolean Plugin_009(byte function, char *string) { if ( (RawSignal.Number != (X10_PulseLength )) && (RawSignal.Number != (X10_PulseLength+2)) ) return false; unsigned long bitstream=0L; byte housecode=0; byte unitcode=0; byte command=0; byte data[4]; byte start=0; if (RawSignal.Number == X10_PulseLength+2) { if ( (RawSignal.Pulses[1]*RawSignal.Multiply > 3000) && (RawSignal.Pulses[2]*RawSignal.Multiply > 3000) ) { start=2; } else { return false; // not an X10 packet } } // get all 24 bits for(byte x=2+start;x < ((X10_PulseLength)+start) ;x+=2) { if(RawSignal.Pulses[x] > X10_PULSEMID) { bitstream = (bitstream << 1) | 0x1; } else { bitstream = (bitstream << 1); } } //================================================================================== // Prevent repeating signals from showing up //================================================================================== if(SignalHash!=SignalHashPrevious || RepeatingTimer>24)&0xff; data[1]=((bitstream)>>16)&0xff; data[2]=((bitstream)>>8)&0xff; data[3]=(bitstream)&0xff; // ---------------------------------- // perform sanity checks data[1]=data[1]^0xff; data[3]=data[3]^0xff; if (data[0] != data[1]) return false; if (data[2] != data[3]) return false; // ---------------------------------- data[1]=data[1]&0x0f; // lower nibble only data[0]=data[0]&0xf0; // upper nibble only housecode=0; if (data[0]==0x60) housecode=0; if (data[0]==0x70) housecode=1; if (data[0]==0x40) housecode=2; if (data[0]==0x50) housecode=3; if (data[0]==0x80) housecode=4; if (data[0]==0x90) housecode=5; if (data[0]==0xa0) housecode=6; if (data[0]==0xb0) housecode=7; if (data[0]==0xe0) housecode=8; if (data[0]==0xf0) housecode=9; if (data[0]==0xc0) housecode=10; if (data[0]==0xd0) housecode=11; if (data[0]==0x00) housecode=12; if (data[0]==0x10) housecode=13; if (data[0]==0x20) housecode=14; if (data[0]==0x30) housecode=15; if (data[2]==0x00) { unitcode=1; command=1;} if (data[2]==0x20) { unitcode=1; command=0;} if (data[2]==0x10) { unitcode=2; command=1;} if (data[2]==0x30) { unitcode=2; command=0;} if (data[2]==0x08) { unitcode=3; command=1;} if (data[2]==0x28) { unitcode=3; command=0;} if (data[2]==0x18) { unitcode=4; command=1;} if (data[2]==0x38) { unitcode=4; command=0;} if (data[2]==0x40) { unitcode=5; command=1;} if (data[2]==0x60) { unitcode=5; command=0;} if (data[2]==0x50) { unitcode=6; command=1;} if (data[2]==0x70) { unitcode=6; command=0;} if (data[2]==0x48) { unitcode=7; command=1;} if (data[2]==0x68) { unitcode=7; command=0;} if (data[2]==0x58) { unitcode=8; command=1;} if (data[2]==0x78) { unitcode=8; command=0;} if (data[2]==0x88) { unitcode=0; command=2;} if (data[2]==0x98) { unitcode=0; command=3;} if (data[2]==0x80) { unitcode=0; command=4;} if (data[2]==0x90) { unitcode=0; command=5;} if ( (data[1]==0x04) && (command < 2) ) { unitcode=unitcode+8; } //================================================================================== // ---------------------------------- // All is OK, build event // ---------------------------------- // Output // ---------------------------------- sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number Serial.print( pbuffer ); // ---------------------------------- Serial.print(F("X10;")); // Label sprintf(pbuffer, "ID=%02x;", 0x41+housecode); // ID Serial.print( pbuffer ); sprintf(pbuffer, "SWITCH=%d;", unitcode); Serial.print( pbuffer ); Serial.print(F("CMD=")); if ( command == 0) { Serial.print(F("OFF;")); } else if ( command == 1) { Serial.print(F("ON;")); } else if ( command == 2) { Serial.print(F("BRIGHT;")); } else if ( command == 3) { Serial.print(F("DIM;")); } else if ( command == 4) { Serial.print(F("ALLOFF;")); } else if ( command == 5) { Serial.print(F("ALLON;")); } Serial.println(); // ---------------------------------- RawSignal.Repeats=true; // suppress repeats of the same RF packet RawSignal.Number=0; return true; } #endif //PLUGIN_009 #ifdef PLUGIN_TX_009 void X10_Send(uint32_t address); boolean PluginTX_009(byte function, char *string) { boolean success=false; //10;X10;000041;1;OFF; //0123456789012345678 // Hier aangekomen bevat string het volledige commando. Test als eerste of het opgegeven commando overeen komt if (strncasecmp(InputBuffer_Serial+3,"X10;",4) == 0) { // X10 Command eg. unsigned long bitstream=0L; byte x=14; // teller die wijst naar het te behandelen teken byte command=0; byte Home=0; // Home A..P byte Address=0; // Blyss subchannel 1..5 byte c; uint32_t newadd=0; InputBuffer_Serial[ 9]=0x30; InputBuffer_Serial[10]=0x78; InputBuffer_Serial[13]=0; Home=str2int(InputBuffer_Serial+9); // Home: A..P if (Home < 0x51) // take care of upper/lower case Home=Home - 'A'; else if (Home < 0x71) // take care of upper/lower case Home=Home - 'a'; else { return success; // invalid value } while((c=tolower(InputBuffer_Serial[x++]))!=';'){ // Address: 1 to 16 if(c>='0' && c<='9'){Address=Address*10;Address=Address+c-'0';} } if (Home == 0) c = 0x60; if (Home == 1) c = 0x70; if (Home == 2) c = 0x40; if (Home == 3) c = 0x50; if (Home == 4) c = 0x80; if (Home == 5) c = 0x90; if (Home == 6) c = 0xa0; if (Home == 7) c = 0xb0; if (Home == 8) c = 0xe0; if (Home == 9) c = 0xf0; if (Home ==10) c = 0xc0; if (Home ==11) c = 0xd0; if (Home ==12) c = 0x00; if (Home ==13) c = 0x10; if (Home ==14) c = 0x20; if (Home ==15) c = 0x30; if (Address > 7) { c = c + 4; Address=Address-8; } // --------------- Home=str2cmd(InputBuffer_Serial+x); if (Home == 0) { // DIM/BRIGHT command if (strcasecmp(InputBuffer_Serial+x,"DIM")==0) { command=3; } else if (strcasecmp(InputBuffer_Serial+x,"BRIGHT")==0) { command=2; } c = c + 4; } else { if (Home==VALUE_ON) { command=1; } else if (Home==VALUE_OFF) { command=0; } else if (Home==VALUE_ALLOFF) { command=4; c = c + 4; } else if (Home==VALUE_ALLON) { command=5; c = c + 4; } } if (Address == 1 && command == 1) bitstream=0x00; if (Address == 1 && command == 0) bitstream=0x20; if (Address == 2 && command == 1) bitstream=0x10; if (Address == 2 && command == 0) bitstream=0x30; if (Address == 3 && command == 1) bitstream=0x08; if (Address == 3 && command == 0) bitstream=0x28; if (Address == 4 && command == 1) bitstream=0x18; if (Address == 4 && command == 0) bitstream=0x38; if (Address == 5 && command == 1) bitstream=0x40; if (Address == 5 && command == 0) bitstream=0x60; if (Address == 6 && command == 1) bitstream=0x50; if (Address == 6 && command == 0) bitstream=0x70; if (Address == 7 && command == 1) bitstream=0x48; if (Address == 7 && command == 0) bitstream=0x68; if (Address == 8 && command == 1) bitstream=0x58; if (Address == 8 && command == 0) bitstream=0x78; if (command == 2) bitstream=0x88; if (command == 3) bitstream=0x98; if (command == 4) bitstream=0x80; if (command == 5) bitstream=0x90; // ----------------------------- newadd=bitstream <<8; bitstream=bitstream^0xff; newadd=newadd+bitstream; bitstream=c^0xff; bitstream=bitstream<<16; newadd=newadd+bitstream; bitstream=c; bitstream=bitstream<<24; newadd=newadd+bitstream; bitstream=newadd; // ----------------------------- X10_Send(bitstream); // full bitstream to send success=true; } return success; } void X10_Send(uint32_t address) { int fpulse = 375; // Pulse witdh in microseconds int fretrans = 4; // Number of code retransmissions uint32_t fdatabit; uint32_t fdatamask = 0x80000000; uint32_t fsendbuff; digitalWrite(PIN_RF_RX_VCC,LOW); // Disable RF receiver digitalWrite(PIN_RF_TX_VCC,HIGH); // Enable RF transmitter delayMicroseconds(TRANSMITTER_STABLE_DELAY); // short delay to let the transmitter become stable (Note: Aurel RTX MID needs 500µS/0,5ms) for (int nRepeat = 0; nRepeat <= fretrans; nRepeat++) { fsendbuff=address; // send SYNC 12P High, 10P low digitalWrite(PIN_RF_TX_DATA, HIGH); delayMicroseconds(fpulse * 12); digitalWrite(PIN_RF_TX_DATA, LOW); delayMicroseconds(fpulse * 10); // end send SYNC // Send command for (int i = 0; i < 32; i++) { // 32 bits // read data bit fdatabit = fsendbuff & fdatamask; // Get most left bit fsendbuff = (fsendbuff << 1); // Shift left if (fdatabit != fdatamask) { // Write 0 digitalWrite(PIN_RF_TX_DATA, HIGH); delayMicroseconds(fpulse * 1); digitalWrite(PIN_RF_TX_DATA, LOW); delayMicroseconds(fpulse * 1); } else { // Write 1 digitalWrite(PIN_RF_TX_DATA, HIGH); delayMicroseconds(fpulse * 1); digitalWrite(PIN_RF_TX_DATA, LOW); delayMicroseconds(fpulse * 4); } } // Send Stop/delay digitalWrite(PIN_RF_TX_DATA, HIGH); delayMicroseconds(fpulse * 1); digitalWrite(PIN_RF_TX_DATA, LOW); delayMicroseconds(fpulse * 20); } delayMicroseconds(TRANSMITTER_STABLE_DELAY); // short delay to let the transmitter become stable (Note: Aurel RTX MID needs 500µS/0,5ms) digitalWrite(PIN_RF_TX_VCC,LOW); // Disable RF transmitter digitalWrite(PIN_RF_RX_VCC,HIGH); // Enable RF receiver RFLinkHW(); return; } #endif //PLUGIN_TX_009