//####################################################################################################### //## 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> 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