321 lines
15 KiB
C
321 lines
15 KiB
C
//#######################################################################################################
|
|
//## This Plugin is only for use with the RFLink software package ##
|
|
//## Plugin-007 CONRAD RSL2 ##
|
|
//#######################################################################################################
|
|
/*********************************************************************************************\
|
|
* This Plugin takes care of receiving of the Conrad RSL2 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!
|
|
*********************************************************************************************
|
|
* Changelog: v1.0 initial release
|
|
*********************************************************************************************
|
|
* Technical information:
|
|
* RF packets contain 66 pulses, 32 bits
|
|
*
|
|
* Conrad RSL2 Message Format:
|
|
* AABBCDDD EEEEEEEE EEEEEEEE EEEEEEEE
|
|
*
|
|
* A = always 10
|
|
* B = Button code
|
|
* C = on/off command (inverted for some buttons/groups)
|
|
* D = group code
|
|
* E = 24 bit address
|
|
*
|
|
* Details: http://www.mikrocontroller.net/topic/252895
|
|
*
|
|
* ConradSend address,switch,cmd; => (16 bits,8 bits,on/off/allon/alloff)
|
|
|
|
20;5B;DEBUG;Pulses=66;Pulses(uSec)=400,1200,350,1200,350,1200,350,1200,350,1225,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1225,350,1200,350,1200,1200,350,350,1225,350,1200,1200,350,350,1200,350,1200,1200,350,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350;
|
|
|
|
400,1200,350,1200,350,1200,350,1200,350,1225,350,1200,350,1200,350,1200,350,1200,350,1200,
|
|
350,1200,350,1200,350,1200,350,1225,350,1200,350,1200,1200,350,350,1225,350,1200,1200,350,
|
|
350,1200,350,1200,1200,350,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,350,1200,
|
|
350,1200,350,1200,350;
|
|
|
|
20;3D;DEBUG;Pulses=68;Pulses(uSec)=600,6450,1290,330,390,1260,390,1260,360,1260,360,1260,390,1260,390,1260,1290,360,1260,360,1290,360,1290,330,1290,360,1260,360,1260,360,1290,330,1290,360,360,1260,360,1260,390,1260,390,1260,360,1260,1290,360,1260,360,360,1260,390,1260,360,1260,360,1260,360,1260,390,1260,1290,360,1290,360,1260,360,390,6990;
|
|
20;3E;DEBUG;Pulses=68;Pulses(uSec)=720,6450,1290,330,390,1260,360,1260,360,1260,390,1260,390,1260,360,1260,1260,360,1290,330,1290,330,1290,360,1260,360,1260,360,1290,330,1290,360,1290,360,360,1260,360,1260,390,1260,360,1260,360,1260,1260,360,1290,330,390,1260,360,1260,360,1260,360,1260,390,1260,390,1260,1260,360,1260,360,1290,330,390,6990;
|
|
20;3F;DEBUG;Pulses=68;Pulses(uSec)=630,6450,1290,360,360,1260,360,1260,390,1260,390,1260,360,1260,360,1260,1290,330,1290,330,1290,360,1260,360,1290,330,1290,330,1290,360,1260,360,1260,360,390,1260,390,1260,360,1260,360,1260,360,1260,1290,330,1290,360,360,1260,360,1260,390,1260,390,1260,360,1260,360,1260,1290,330,1290,330,1290,360,360,6990;
|
|
|
|
\*********************************************************************************************/
|
|
#define CONRADRSL2_PULSECOUNT 66
|
|
#define CONRADRSL2_PULSEMID 600/RAWSIGNAL_SAMPLE_RATE
|
|
|
|
#ifdef PLUGIN_007
|
|
boolean Plugin_007(byte function, char *string){
|
|
if ((RawSignal.Number != CONRADRSL2_PULSECOUNT) && (RawSignal.Number != CONRADRSL2_PULSECOUNT+2) ) return false;
|
|
unsigned long bitstream=0L;
|
|
byte checksum=0;
|
|
byte button=0;
|
|
byte group=0;
|
|
byte action=0;
|
|
byte start=0;
|
|
if (RawSignal.Number == CONRADRSL2_PULSECOUNT+2) {
|
|
start=2;
|
|
}
|
|
//==================================================================================
|
|
// get bits
|
|
for(byte x=1+start;x < RawSignal.Number-2;x=x+2) {
|
|
if (RawSignal.Pulses[x] > CONRADRSL2_PULSEMID) {
|
|
if (RawSignal.Pulses[x+1] > CONRADRSL2_PULSEMID) return false; // manchester check
|
|
bitstream = (bitstream << 1) | 0x1; // 1
|
|
} else {
|
|
if (RawSignal.Pulses[x+1] < CONRADRSL2_PULSEMID) return false; // manchester check
|
|
bitstream = (bitstream << 1); // 0
|
|
}
|
|
}
|
|
//==================================================================================
|
|
// 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;
|
|
}
|
|
//==================================================================================
|
|
// all bits received, make sure checksum is okay
|
|
//==================================================================================
|
|
checksum=(((bitstream) >> 30)&0x0f); // first two bits should always be '10'
|
|
if (checksum != 2) return false;
|
|
//==================================================================================
|
|
button=(((bitstream) >> 24)&0xff); // 10100011
|
|
// ----- check for possible valid values
|
|
if (button < 0x81) return false;
|
|
if (button > 0xbe) return false;
|
|
byte temp=(button)&0xf;
|
|
if (temp == 0x07 || temp == 0x0b || temp == 0x0f ) return false;
|
|
if (button == 0x83 || button == 0x86 || button == 0x89 || button == 0x8c || button == 0x91 ) return false;
|
|
if (button == 0x94 || button == 0x9a || button == 0x9d || button == 0xa1 || button == 0xa4 ) return false;
|
|
if (button == 0xaa || button == 0xad || button == 0xb1 || button == 0xb3 || button == 0xb4 ) return false;
|
|
if (button == 0xba || button == 0xbd ) return false;
|
|
// -----
|
|
group=(button) & 0x7; // -- 111
|
|
action=((button) >> 3) & 0x1; // -- a
|
|
button = ((button) >> 4) & 0x3; // --bb
|
|
// -----
|
|
if (group == 3) {
|
|
action=button;
|
|
button=0;
|
|
} else {
|
|
if (button==3) {
|
|
if (group == 6) { // toggle command bit
|
|
button=0;
|
|
action=(~action)&1;
|
|
}
|
|
if (group == 1 || group == 5) { // no toggle
|
|
button=4;
|
|
}
|
|
if (group == 0) {
|
|
action=(~action)&1; // toggle command bit
|
|
button=8;
|
|
}
|
|
if (group == 2 || group == 4) { // no toggle
|
|
button=12;
|
|
}
|
|
} else
|
|
if (button==0) {
|
|
if (group == 6 || group == 1) { // no toggle
|
|
button=1;
|
|
}
|
|
if (group == 5) { // toggle command bit
|
|
button=5;
|
|
action=(~action)&1;
|
|
}
|
|
if (group == 0 || group == 4) { // no toggle
|
|
button=9;
|
|
}
|
|
if (group == 2) { // toggle command bit
|
|
button=13;
|
|
action=(~action)&1;
|
|
}
|
|
} else
|
|
if (button==2) {
|
|
if (group == 6) { // toggle command bit
|
|
button=2;
|
|
action=(~action)&1;
|
|
}
|
|
if (group == 1 || group == 5) button=6; //
|
|
|
|
if (group == 0) { // toggle command bit
|
|
button=10;
|
|
action=(~action)&1;
|
|
}
|
|
|
|
if (group == 2 || group == 4) { // no toggle
|
|
button=14;
|
|
//action=(~action)&1;
|
|
}
|
|
} else
|
|
if (button==1) {
|
|
if (group == 6) { // toggle command bit
|
|
button=3;
|
|
action=(~action)&1;
|
|
}
|
|
if (group == 1 || group == 5) { // no toggle
|
|
button=7;
|
|
//action=(~action)&1;
|
|
}
|
|
if (group == 0) { // toggle command bit
|
|
button=11;
|
|
action=(~action)&1;
|
|
}
|
|
if (group == 2 || group == 4) { // no toggle
|
|
button=15;
|
|
//action=(~action)&1;
|
|
}
|
|
}
|
|
}
|
|
//==================================================================================
|
|
// Output
|
|
// ----------------------------------
|
|
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++);// Node and packet number
|
|
Serial.print( pbuffer );
|
|
// ----------------------------------
|
|
Serial.print(F("Conrad;")); // Label
|
|
sprintf(pbuffer, "ID=%06lx;",((bitstream) &0xffffff) ); // ID
|
|
Serial.print( pbuffer );
|
|
sprintf(pbuffer, "SWITCH=%02x;", button); // Button number
|
|
Serial.print( pbuffer );
|
|
Serial.print(F("CMD=")); // command
|
|
if (group==3) {
|
|
Serial.print(F("ALL"));
|
|
}
|
|
if (action==1) {
|
|
Serial.print(F("ON;"));
|
|
} else { // 0 normal off, 2 group off
|
|
Serial.print(F("OFF;"));
|
|
}
|
|
Serial.println();
|
|
//==================================================================================
|
|
RawSignal.Repeats=true; // suppress repeats of the same RF packet
|
|
RawSignal.Number=0;
|
|
return true;
|
|
}
|
|
#endif // PLUGIN_007
|
|
|
|
#ifdef PLUGIN_TX_007
|
|
void RSL2_Send(unsigned long address);
|
|
|
|
boolean PluginTX_007(byte function, char *string) {
|
|
boolean success=false;
|
|
//10;CONRAD;000fa0;0;OFF;
|
|
//10;CONRAD;009200;1;ON;
|
|
//10;CONRAD;ff0607;1;OFF;
|
|
//012345678901234567890123
|
|
if (strncasecmp(InputBuffer_Serial+3,"CONRAD;",7) == 0) { // KAKU Command eg.
|
|
unsigned long bitstream=0L;
|
|
unsigned long command=0L;
|
|
if (InputBuffer_Serial[16] != ';') return success;
|
|
InputBuffer_Serial[8]=0x30;
|
|
InputBuffer_Serial[9]=0x78;
|
|
InputBuffer_Serial[16]=0;
|
|
bitstream=str2int(InputBuffer_Serial+8); // Address
|
|
|
|
byte temp=str2int(InputBuffer_Serial+17); // het button/unit number (0x00..0x0f)
|
|
if (temp < 16) { // No button with a number higher than 15
|
|
byte cmd=str2cmd(InputBuffer_Serial+19); // ON/OFF
|
|
if (cmd==VALUE_OFF) {
|
|
if (temp == 0) command=0xbe;
|
|
if (temp == 1) command=0x81;
|
|
if (temp == 2) command=0xae;
|
|
if (temp == 3) command=0x9e;
|
|
if (temp == 4) command=0xb5;
|
|
if (temp == 5) command=0x8d;
|
|
if (temp == 6) command=0xa5;
|
|
if (temp == 7) command=0x95;
|
|
if (temp == 8) command=0xb8;
|
|
if (temp == 9) command=0x84;
|
|
if (temp ==10) command=0xa8;
|
|
if (temp ==11) command=0x98;
|
|
if (temp ==12) command=0xb2;
|
|
if (temp ==13) command=0x8a;
|
|
if (temp ==14) command=0xa2;
|
|
if (temp ==15) command=0x92;
|
|
} else // ON
|
|
if (cmd==VALUE_ON) {
|
|
if (temp == 0) command=0xb6;
|
|
if (temp == 1) command=0x8e;
|
|
if (temp == 2) command=0xa6;
|
|
if (temp == 3) command=0x96;
|
|
if (temp == 4) command=0xb9;
|
|
if (temp == 5) command=0x85;
|
|
if (temp == 6) command=0xa9;
|
|
if (temp == 7) command=0x99;
|
|
if (temp == 8) command=0xb0;
|
|
if (temp == 9) command=0x88;
|
|
if (temp ==10) command=0xa0;
|
|
if (temp ==11) command=0x90;
|
|
if (temp ==12) command=0xbc;
|
|
if (temp ==13) command=0x82;
|
|
if (temp ==14) command=0xac;
|
|
if (temp ==15) command=0x9c;
|
|
} else // AllON
|
|
if (cmd==VALUE_ALLON) {
|
|
command=0x93;
|
|
} else // AllOff
|
|
if (cmd==VALUE_ALLOFF) {
|
|
command=0xa3;
|
|
}
|
|
command=command << 24;
|
|
bitstream=bitstream+command;
|
|
}
|
|
RSL2_Send(bitstream); // the full bitstream to send
|
|
success=true;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
void RSL2_Send(unsigned long address) {
|
|
int fpulse = 650; // Pulse witdh in microseconds 650?
|
|
int fpulse2 = 450; // Pulse witdh in microseconds 650?
|
|
int fretrans = 4; // Number of code retransmissions
|
|
uint32_t fdatabit;
|
|
uint32_t fdatamask = 0x80000000;
|
|
uint32_t fsendbuff;
|
|
|
|
digitalWrite(PIN_RF_RX_VCC,LOW); // Spanning naar de RF ontvanger uit om interferentie met de zender te voorkomen.
|
|
digitalWrite(PIN_RF_TX_VCC,HIGH); // zet de 433Mhz zender aan
|
|
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 1P High, 10P low
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
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(fpulse2 * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse2 * 3);
|
|
} else { // Write 1
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse2 * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse2 * 1);
|
|
}
|
|
}
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse2 * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 14);
|
|
}
|
|
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); // zet de 433Mhz zender weer uit
|
|
digitalWrite(PIN_RF_RX_VCC,HIGH); // Spanning naar de RF ontvanger weer aan.
|
|
RFLinkHW();
|
|
}
|
|
#endif // PLUGIN_TX_007
|