1
0
mirror of https://github.com/seahu/rflink.git synced 2025-12-10 07:57:23 +01:00

first commit

This commit is contained in:
Ondrej Lycka
2017-04-29 03:27:02 +02:00
commit 406093e31d
85 changed files with 25806 additions and 0 deletions

347
Plugins/Plugin_009.c Normal file
View File

@@ -0,0 +1,347 @@
//#######################################################################################################
//## 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 <adres>, <On | Off>
* Send : "X10Send <Adres>, <On | Off>
*
* 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<millis()) {
// not seen the RF packet recently
if (bitstream == 0) return false; // sanity check
} else {
// already seen the RF packet recently
return true;
}
//==================================================================================
// order received data
data[0]=((bitstream)>>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