mirror of
https://github.com/seahu/rflink.git
synced 2025-12-09 23:47:22 +01:00
937 lines
49 KiB
C
937 lines
49 KiB
C
//#######################################################################################################
|
|
//## This Plugin is only for use with the RFLink software package ##
|
|
//## Plugin-03: Kaku (ARC) ##
|
|
//#######################################################################################################
|
|
/*********************************************************************************************\
|
|
* This plugin takes care of sending and receiving the ARC protocol known from Klik-Aan-Klik-Uit (KAKU)
|
|
* transmitter, switch, PIR, door sensor etc.
|
|
* Devices following the ARC protocol can often be recognized by their manual switch settings for
|
|
* the unit and house code number. Like for example by code wheel, dip switch or mini switch.
|
|
*
|
|
* This plugin also works with the following devices:
|
|
* Princeton PT2262 / MOSDESIGN M3EB / Domia Lite / Klik-Aan-Klik-Uit / Intertechno / Sartano 2606.
|
|
*
|
|
* Author : StuntTeam & Jonas Jespersen (Sartano)
|
|
* Support : http://sourceforge.net/projects/rflink/
|
|
* License : This code is free for use in any open source project when this header is included.
|
|
* 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!
|
|
***********************************************************************************************
|
|
* Address = A0..P16 according to KAKU adressing/notation
|
|
***********************************************************************************************
|
|
* Het signaal bestaat drie soorten reeksen van vier pulsen, te weten:
|
|
* 0 = T,3T,T,3T, 1 = T,3T,3T,T, short 0 = T,3T,T,T Hierbij is iedere pulse (T) 350us PWDM
|
|
*
|
|
* KAKU Supports:
|
|
* on/off, waarbij de pulsreeks er als volgt uit ziet: 000x en x staat voor Off / On
|
|
* all on/off, waarbij de pulsreeks er als volgt uit ziet: 001x en x staat voor All Off / All On
|
|
***********************************************************************************************
|
|
* Brand Model Chipset Timing L/H
|
|
* Intertechno ITK200 MDT10P61S 8/43
|
|
* Profile PN-47N SC5262 5/26-27
|
|
* Elro Home Comfort AB-600MA PT2262 7/29-30 6/30 6/31
|
|
* Eurodomest 972080 HS2303
|
|
* Elro Home Control AB-440 (Home Control) HX2262
|
|
* Elro Home Control AB-4xx (Home Control) HX2272
|
|
* Profile PN-44N SC2262 9/34
|
|
* ProMax RSL366T SC5262 11/41 10/54 11/54 ?
|
|
* Phenix YC-4000S HX2262
|
|
* Flamingo FA500R 8/30
|
|
* Select Remote 1728029 HS2262 3/22
|
|
***********************************************************************************************
|
|
* POSSIBLE BIT VARIATIONS: (Note: Bit order is reversed -compared to order in the RF signal- in the description below and in the processing!!!)
|
|
* ------------------------ ( real: 1111 0000 011 1 => reversed: 1 110 0000 1111)
|
|
* ARC with 0 & F bits:
|
|
* -------------------
|
|
* KAKU 1 110 0000 0000
|
|
* Intertechno ITK200 D CCC BBBB AAAA
|
|
* A bit 0-3 = address 2^4 = 16 addresses
|
|
* B bit 4-7 = device 2^4 = 16 devices
|
|
* C bit 8-10 = always (110) ! (AND with 0x700 result must be 0x600)
|
|
* D bit 11 = on/off command (1=on 0=off)
|
|
* Timing: 8-9 /33-34 (low/high)
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 1 110 0000 0000 A1 on
|
|
* 0 110 0000 0000 A1 off
|
|
* 1 110 0001 0000 A2 on
|
|
* 0 110 0001 0000 A2 off
|
|
* 1 110 0010 0000 A3 on
|
|
* 0 110 0010 0000 A3 off
|
|
* 1 110 0011 0000 A4 on
|
|
* 0 110 0011 0000 A4 off
|
|
* 1 110 0000 0000 itk200 on
|
|
* 0 110 0000 0000 itk200 off
|
|
* -------------------
|
|
* Perel 1 1111 1111 11 1
|
|
* A BBBB CCCC DD E
|
|
* A bit 0 = on/off command
|
|
* B bit 1-4 = system code 1111 each bit corresponds to a button number
|
|
* C bit 5-8 = device / Unitcode 1111 each bit corresponds to a button number
|
|
* D bit 9-10 = always '11'
|
|
* E bit 11 = on/off command (1=on 0=off)
|
|
* Timing: 8-9 /33-34
|
|
* Analyser: 362 / 1086
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 1 110 100 1110 1 1 on
|
|
* 0 110 100 1110 0 1 off
|
|
* 1 110 101 1110 1 2 on
|
|
* 0 110 101 1110 0 2 off
|
|
* 1 110 110 1110 1 3 on
|
|
* 0 110 110 1110 0 3 off
|
|
* -------------------
|
|
* Elro Home Easy 0 1 00001 10001
|
|
* Elro Home Control D C BBBBB AAAAA
|
|
* Brennenstuhl A bit 0-4 = address 2^5 = 32 addresses
|
|
* Comfort B bit 5-9 = device
|
|
* C bit 10 = unknown (always 1?)
|
|
* D bit 11 = on/off command (1=on 0=off)
|
|
* Timing: 7-8-9 /29-30
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 1 1 10101 11000 I12 on
|
|
* 0 1 10101 11000 I12 off
|
|
* 1 1 10011 00000 A7 on
|
|
* 0 1 10011 00000 A7 off
|
|
* -------------------
|
|
* AB400R 0 1 11111 11111
|
|
* D C BBBBB AAAAA
|
|
* A bit 0-4 = system code - each bit corresponds to a dip switch number (order 54321)
|
|
* B bit 5-9 = device/unit code
|
|
* C bit 10 = on/off command (reverse of D)
|
|
* D bit 11 = on/off command
|
|
* Timing: 8 /30
|
|
* Analyser: 330/990
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 10 11110 11110 A ON
|
|
* 10 11101 11110 B ON
|
|
* 10 11011 11110 C ON
|
|
* 10 10111 11110 D ON
|
|
* 01 11110 11110 A OFF
|
|
* 01 11101 11110 B OFF
|
|
* 01 11011 11110 C OFF
|
|
* 01 10111 11110 D OFF
|
|
* -------------------
|
|
* Sartano: 0 1 00001 10001
|
|
* Phenix YC-4000B D C BBBBB AAAAA
|
|
* A bit 0-4 = address 2^5 = 32 addresses / Housecode
|
|
* B bit 5-9 = device / Unitcode each bit corresponds to a button number
|
|
* C bit 10 = off command (inverse command)
|
|
* D bit 11 = on command
|
|
* Timing: 11-12 /31-37
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 01 01000 00000
|
|
|
|
* -------------------
|
|
* ProMAX: 0 111 0000 0001
|
|
* D CCC BBBB AAAA
|
|
* A bit 0-3 = address 2^5 = 32 addresses / Housecode
|
|
* B bit 4-7 = device / Unitcode 11111 each bit corresponds to a button number
|
|
* C bit 8-10 = Always 111
|
|
* D bit 11 = on command
|
|
* Timing: 10-11 / 40-41
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 111111101110 1 ON
|
|
* 111111011110 2 ON
|
|
* 111110111110 3 ON
|
|
* 111101111110 4 ON
|
|
|
|
* 011111101110 1 OFF
|
|
* 011111011110 2 OFF
|
|
* 011110111110 3 OFF
|
|
* 011101111110 4 OFF
|
|
* -------------------
|
|
* ProFile: 0 110 0001 0001
|
|
* D CCC BBBB AAAA
|
|
* A bit 0-3 = address 2^4 = 16 addresses / Housecode
|
|
* B bit 4-7 = device / Unitcode 11111 each bit corresponds to a button number
|
|
* C bit 8-10 = Always 110
|
|
* D bit 11 = on command
|
|
* Timing: 9/34
|
|
* Pulses: 0101 and 0110 eg. bit state 0 and f
|
|
* 111000000000 1 ON
|
|
* 111000010000 2 ON
|
|
* 111000100000 3 ON
|
|
* 111000110000 4 ON
|
|
* 011000000000 1 OFF
|
|
* 011000010000 2 OFF
|
|
* 011000100000 3 OFF
|
|
* 011000110000 4 OFF
|
|
* -------------------
|
|
* ProFile:
|
|
* Everflourish 0 110 0001 0001
|
|
* EMW203 D CCC BBBB AAAA
|
|
* A bit 0-3 = Button A/B/C/D
|
|
* B bit 4-6 = Button 1/2/3
|
|
* C bit 7-10 = Always 1111
|
|
* D bit 11 = on/off command (on = tri-state)
|
|
* Timing: 14/55
|
|
* Analyser:
|
|
* Pulses: 0101, 1010 and 0110 eg. bit state 0, 1 and f
|
|
* 211111101110 A1 on
|
|
* 211111011110 A2 on
|
|
* 211110111110 A3 on
|
|
* 211111101101 B1 on
|
|
* 211111011101 B2 on
|
|
* 211110111101 B3 on
|
|
* 011111101110 A1 off
|
|
* 011111011110 A2 off
|
|
* 011110111110 A3 off
|
|
* 011111101101 B1 off
|
|
* 011111011101 B2 off
|
|
* 011110111101 B3 off
|
|
* -------------------
|
|
|
|
|
|
* -------------------
|
|
* 0 111 0000 1 000 reverse: 000 1 0000 111 0 and EF1 = 0?
|
|
* A BBB CCCC D EEE
|
|
* SelectRemote A/C/E = always 0 0000 000 !
|
|
* Blokker: B bit 1-3 = device number
|
|
* D bit 8 = on/off command
|
|
* Timing: 0-1-2 /33-34
|
|
* Analyser: 232 / 692
|
|
* Pulses: 0101 and 1010 eg. bit state 0 and 1
|
|
|
|
* -------------------
|
|
* 1111 111111 11
|
|
* AAAA BBBBBB CC
|
|
* Action: A bit 0-3 = address 2^4 = 16 addresses
|
|
* Impuls B bit 4-9 = device
|
|
* C bit 10-11= on/off command 10=on 01=off
|
|
* -------------------
|
|
* 10100 00010 0 0
|
|
* AAAAA BBBBB C D
|
|
* InterTechno A bit 0-4 = address 2^5 = 32 addresses
|
|
* Düwi Terminal B bit 5-9 = device
|
|
* Cogex C bit 10 = always 0
|
|
* D bit 11 = on/off command
|
|
* -------------------
|
|
* 20;DB;DEBUG;Pulses=50;Pulses(uSec)=425,1050,250,1025,250,1025,250,1025,250,1025,250,1025,250,1025,250,1025,250,1050,250,1025,250,1025,250,1025,250,1025,250,1025,250,1025,250,1025,250,1050,250,1025,250,1025,950,300,250,1050,950,300,250,1025,950,300,250;
|
|
*
|
|
* KAKU Doorbell 010111101111
|
|
* 20;07;DEBUG;Pulses=50;Pulses(uSec)=300,950,250,950,250,950,950,275,250,950,250,950,250,950,950,275,250,950,950,275,250,950,950,250,250,950,950,275,250,950,250,950,250,950,950,275,250,950,950,250,250,950,950,275,250,950,950,250,250;
|
|
* 20;09;DEBUG;Pulses=50;Pulses(uSec)=3675,950,250,950,250,950,950,250,250,950,250,950,250,950,950,275,250,950,950,250,250,950,950,275,250,950,950,250,250,950,250,950,250,950,950,250,250,950,950,275,250,950,950,275,250,950,950,275,250;
|
|
* HE842
|
|
* 20;03;DEBUG;Pulses=50;Pulses(uSec)=270,870,840,240,210,870,840,240,210,870,210,870,210,870,840,240,210,870,210,870,210,870,210,870,210,870,210,870,210,870,840,240,210,870,210,870,210,870,840,240,210,870,840,240,210,870,210,870,210,6990;
|
|
* 360/1380 12/46
|
|
* 20;54;DEBUG;Pulses=50;Pulses(uSec)=1410,390,1350,360,1350,360,1380,360,1350,360,1380,360,1380,360,1380,360,1350,360,1350,360,1350,360,1380,360,1380,360,1380,360,1350,360,1380,360,1350,360,1350,360,390,1350,390,1350,390,1320,390,1320,420,1320,420,1320,390,6990;
|
|
\*********************************************************************************************/
|
|
#define KAKU_CodeLength 12 // number of data bits
|
|
#define KAKU_R 300/RAWSIGNAL_SAMPLE_RATE //360 // 300 // 370? 350 us
|
|
#define KAKU_PULSEMID 510/RAWSIGNAL_SAMPLE_RATE // (17) 510 = KAKU_R*2 not sufficient!
|
|
|
|
#ifdef PLUGIN_003
|
|
boolean Plugin_003(byte function, char *string) {
|
|
if (RawSignal.Number!=(KAKU_CodeLength*4)+2) return false; // conventionele KAKU bestaat altijd uit 12 data bits plus stop. Ongelijk, dan geen KAKU!
|
|
if (RawSignal.Pulses[0]==15) return true; // Home Easy, skip KAKU
|
|
if (RawSignal.Pulses[0]==63) return false; // No need to test, packet for plugin 63
|
|
if (RawSignal.Pulses[0]==19) return false; // No need to test, packet for plugin 19
|
|
// -------------------------------------------
|
|
int i,j;
|
|
boolean error=false;
|
|
unsigned long bitstream=0L; // to store a 12 bit code (ARC type)
|
|
unsigned long bitstream2=0L; // to store a 24 bit code (Extended ARC type)
|
|
byte tricount=0;
|
|
// -------------------------------------------
|
|
byte command=0; // ON/OFF/DIM/BRIGHT
|
|
byte group=0; // flags group command
|
|
byte housecode=0; // 0x40 + 1 to 16? (41-5a?)
|
|
byte unitcode=0; // 1 to 16
|
|
// -------------------------------------------
|
|
int PTLow=22; // Pulse Time - lowest found value (22 = a pulse duration of 550)
|
|
int PTHigh=22; // Pulse Time - highest found value
|
|
byte signaltype=0; // bit map: bit 0 = 0 bit 1 = f bit 2 = 0/1 (PT2262)
|
|
// meaning: byte value 3 = kaku (bit 0/f) 5=PT2262 7=tristate 0/1/f
|
|
byte devicetype=0; // 0=Kaku 5=Impuls 7=Perel
|
|
// -------------------------------------------
|
|
|
|
// -------------------------------------------
|
|
// ==========================================================================
|
|
j=KAKU_PULSEMID; // set MID value
|
|
j--;
|
|
if (RawSignal.Pulses[0]==33) { // If device is "Impuls"
|
|
RawSignal.Pulses[0]=0; // Unset Impuls conversion indicator
|
|
j=KAKU_R; // Set new (LOWER!) MID value
|
|
devicetype=5; // Indicate Impuls device
|
|
}
|
|
// -------------------------------------------
|
|
if (RawSignal.Pulses[49] > j) return false; // Last pulse has to be low! Otherwise we are not dealing with an ARC signal
|
|
// ==========================================================================
|
|
// TIMING MEASUREMENT, this will find the shortest and longest pulse within the RF packet
|
|
// ==========================================================================
|
|
for (i=2;i<RawSignal.Number;i++) { // skip first pulse as it is often affected by the start bit pulse duration
|
|
if(RawSignal.Pulses[i] < PTLow) { // shortest pulse?
|
|
PTLow=RawSignal.Pulses[i]; // new value
|
|
} else
|
|
if(RawSignal.Pulses[i] > PTHigh) { // longest pulse?
|
|
PTHigh=RawSignal.Pulses[i]; // new value
|
|
}
|
|
}
|
|
// -------------------------------------------
|
|
// TIMING MEASUREMENT to devicetype
|
|
if (devicetype != 5) { // Dont do the timing check for Impuls, it is already identified at this point
|
|
if( ((PTLow==7)||(PTLow==8)) && ((PTHigh ==30) || (PTHigh ==31) ) ) devicetype=4; // ELRO AB400
|
|
if( ((PTLow==9)||(PTLow==10)) && ((PTHigh==36)||(PTHigh==37)||((PTHigh >=40)&&(PTHigh <=42))) ) devicetype=1; // ELRO AB600
|
|
else
|
|
if( ((PTLow==10)||(PTLow == 11)) && ((PTHigh >=40)&&(PTHigh <=42)) ) devicetype=2; // Profile PR44N / Promax rsl366t
|
|
else
|
|
if( (PTLow==13) && ((PTHigh >=32)&&(PTHigh <=34)) ) devicetype=3; // Profile PR47N
|
|
else
|
|
if( ((PTLow >=11)&&(PTLow <=12)) && ((PTHigh >=31)&&(PTHigh <=37)) ) devicetype=4; // Sartano
|
|
else
|
|
if( ((PTLow==12)||(PTLow==13)) && ((PTHigh==45)||(PTHigh==46)) ) devicetype=4; // Philips SBC
|
|
else
|
|
if( (PTLow <=3) && ((PTHigh==22)||(PTHigh==23)) ) devicetype=5; // Philips SBC
|
|
//else
|
|
//if( (PTLow == 8 || PTLow == 9) && (PTHigh == 33 || PTHigh == 34) ) devicetype=7; // Perel st=0,dt=7
|
|
}
|
|
//sprintf(pbuffer, "ST=%d DT=%d %d/%d",signaltype,devicetype,PTLow,PTHigh);
|
|
//Serial.println( pbuffer );
|
|
// ==========================================================================
|
|
// Turn pulses into bits
|
|
// -------------------------------------------
|
|
for (i=0; i<KAKU_CodeLength; i++) {
|
|
if (RawSignal.Pulses[4*i+1]<j && RawSignal.Pulses[4*i+2]>j && RawSignal.Pulses[4*i+3]<j && RawSignal.Pulses[4*i+4]>j) { // 0101
|
|
bitstream=(bitstream >> 1); // bit '0'
|
|
bitstream2=(bitstream2 << 2); // bit '0' written as '00'
|
|
signaltype=signaltype|1; // bit '0' present in signal '0001'
|
|
} else
|
|
if (RawSignal.Pulses[4*i+1]<j && RawSignal.Pulses[4*i+2]>j && RawSignal.Pulses[4*i+3]>j && RawSignal.Pulses[4*i+4]<j) { // 0110
|
|
//!! untested !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
tricount++; // tri-state bit counter
|
|
if ((i==11) && (tricount==1)) { // only the last bit, "on/off command" is in tristate mode? then it must be EMW200
|
|
bitstream=(bitstream >> 1 | (1 << (KAKU_CodeLength-1))); // bit f (1)
|
|
bitstream2=(bitstream2 << 2) | 2; // bit 'f' written as '10'
|
|
// DONT CHANGE signal type to tri-state to keep EMW200 in KAKU mode
|
|
} else {
|
|
bitstream=(bitstream >> 1 | (1 << (KAKU_CodeLength-1))); // bit f (1)
|
|
bitstream2=(bitstream2 << 2) | 2; // bit 'f' written as '10'
|
|
signaltype=signaltype|2; // bit 'f' present in signal '0010'
|
|
}
|
|
} else
|
|
if (RawSignal.Pulses[4*i+1]<j && RawSignal.Pulses[4*i+2]>j && RawSignal.Pulses[4*i+3]<j && RawSignal.Pulses[4*i+4]<j) { // 0100
|
|
bitstream=(bitstream >> 1); // Short 0, Group command on 2nd bit. (NOT USED?!)
|
|
bitstream2=(bitstream2 << 2) | 3; // bit 'short' written as '11'
|
|
group=1;
|
|
} else
|
|
if (RawSignal.Pulses[4*i+1]>j && RawSignal.Pulses[4*i+2]<j && RawSignal.Pulses[4*i+3]>j && RawSignal.Pulses[4*i+4]<j) { // 1010
|
|
bitstream2=(bitstream2 << 2) | 1; // bit '1' written as '01'
|
|
signaltype=signaltype|4; // bit '1' present in signal '0100'
|
|
if (devicetype==5) { // in case of 'impuls remote' store
|
|
bitstream=(bitstream >> 1); // bit 1 (stored as 0) (IMPULS REMOTE)
|
|
} else {
|
|
if (i==11) { // last bit seems to cause trouble every now and then..?!
|
|
bitstream=(bitstream >> 1); // bit 1 (stored as 0) (IMPULS REMOTE)
|
|
} else {
|
|
devicetype=6;
|
|
bitstream=(bitstream >> 1 | (1 << (KAKU_CodeLength-1))); // bit f (1)
|
|
}
|
|
}
|
|
} else {
|
|
// -------------------------------------------
|
|
// following are signal patches to fix bad transmission/receptions
|
|
// -------------------------------------------
|
|
if (i==0) { // are we dealing with a RTK/AB600 device? then the first bit is sometimes mistakenly seen as 1101
|
|
bitstream2=(bitstream2 << 2); // bit 0
|
|
if (RawSignal.Pulses[4*i+1]>j && RawSignal.Pulses[4*i+2]>j && RawSignal.Pulses[4*i+3]<j && RawSignal.Pulses[4*i+4]>j) { // 1101
|
|
bitstream=(bitstream >> 1); // 0, treat as 0101 eg 0 bit
|
|
} else {
|
|
error=true;
|
|
signaltype=signaltype|8;
|
|
}
|
|
} else {
|
|
error=true;
|
|
signaltype=signaltype|8;
|
|
}
|
|
} // bad signal
|
|
}
|
|
//==================================================================================
|
|
// Sort out devices based on signal type and timing measurements
|
|
// -------------------------------------------
|
|
//sprintf(pbuffer, "ST=%d DT=%d [%d]",signaltype,devicetype, error);
|
|
//Serial.println( pbuffer );
|
|
//Serial.println(bitstream,BIN);
|
|
//Serial.println(bitstream2,BIN);
|
|
// -------------------------------------------
|
|
// END OF TIMING MEASUREMENTS
|
|
// ==========================================================================
|
|
if (error==true) { // Error means that a pattern other than 0101/0110 was found
|
|
return false; // This usually means we are dealing with a semi-compatible device
|
|
} // that might have more states than used by ARC
|
|
if ((signaltype != 0x03) && (signaltype != 0x05) && (signaltype != 0x07)) return false;
|
|
//==================================================================================
|
|
// Prevent repeating signals from showing up
|
|
//==================================================================================
|
|
//if( (SignalHash!=SignalHashPrevious) || ((RepeatingTimer+500)<millis()) ) {
|
|
if( (SignalHash!=SignalHashPrevious) || ((RepeatingTimer+500)<millis()) || (((RepeatingTimer+1000)>millis())&&(SignalCRC != bitstream2)) ) {
|
|
// not seen the RF packet recently
|
|
if (signaltype == 0x07) {
|
|
if (((RepeatingTimer+1000)>millis())&&(SignalCRC != bitstream2)) {
|
|
return true; // skip tristate after normal arc
|
|
}
|
|
}
|
|
//Serial.print("KAKU PREV:");
|
|
//Serial.println(SignalHashPrevious);
|
|
if ((SignalHashPrevious==14) && ((RepeatingTimer+2000)>millis()) ) {
|
|
SignalHash=14;
|
|
return true; // SignalHash 14 = HomeEasy, eg. cant switch KAKU after HE for 2 seconds
|
|
}
|
|
if ((SignalHashPrevious==11) && ((RepeatingTimer+2000)>millis()) ) {
|
|
SignalHash=11;
|
|
return true; // SignalHash 11 = FA500, eg. cant switch KAKU after FA500 for 2 seconds
|
|
}
|
|
SignalCRC=bitstream2; // store RF packet identifier
|
|
} else {
|
|
// already seen the RF packet recently
|
|
return true;
|
|
}
|
|
//==================================================================================
|
|
// Determine signal type to sort out the various houdecode/unitcode/button bits and on/off command bits
|
|
//==================================================================================
|
|
if (signaltype != 0x07) {
|
|
if ((bitstream&0x700)!=0x600) { // valid but not real KAKU
|
|
devicetype=4;
|
|
}
|
|
// -------------------------------------------
|
|
if (devicetype == 4) { // Sartano
|
|
// ---------------------------------- // Sartano
|
|
housecode = ((bitstream) & 0x0000001FL); // .......11111b
|
|
unitcode = (((bitstream) & 0x000003E0L) >> 5); // ..1111100000b
|
|
housecode = ~housecode; // Sartano housecode is 5 bit ('A' - '`')
|
|
housecode &= 0x0000001FL; // Translate housecode so that all jumpers off = 'A' and all jumpers on = '`'
|
|
housecode += 0x41;
|
|
switch(unitcode) { // Translate unit code into button number 1 - 5
|
|
case 0x1E: // E=1110
|
|
unitcode = 1;
|
|
break;
|
|
case 0x1D: // D=1101
|
|
unitcode = 2;
|
|
break;
|
|
case 0x1B: // B=1011
|
|
unitcode = 3;
|
|
break;
|
|
case 0x17: // 7=0111
|
|
unitcode = 4;
|
|
break;
|
|
case 0x0F: // f=1111
|
|
unitcode = 5;
|
|
break;
|
|
default:
|
|
//Serial.print("Sartano:");
|
|
devicetype=3; // invalid for Sartano, fall back
|
|
break;
|
|
}
|
|
if (devicetype == 4) { // Sartano
|
|
if ( ((bitstream >> 10) & 0x03) == 2) {
|
|
command = 1; // On
|
|
} else if ( ((bitstream >> 10) & 0x03) == 1){
|
|
command = 0;// Off
|
|
}
|
|
}
|
|
} else
|
|
// -------------------------------------------
|
|
if (devicetype == 5) { // IMPULS
|
|
housecode = ((bitstream) & 0x0000000FL); // ........1111b
|
|
unitcode = (((bitstream) & 0x000003F0L) >> 4); // ..1111110000b
|
|
housecode = ~housecode; // Impuls housecode is 4 bit ('A' - 'P')
|
|
housecode &= 0x0000000FL; // Translate housecode so that all jumpers off = 'A' and all jumpers on = 'P'
|
|
housecode += 0x41;
|
|
unitcode = ~unitcode; // Impuls unitcode is 5 bit
|
|
unitcode &= 0x0000001FL; // Translate unitcode so that all jumpers off = '1' and all jumpers on = '64'
|
|
if ( ((bitstream >> 10) & 0x03) == 2) {
|
|
command = 0; // Off
|
|
} else
|
|
if ( ((bitstream >> 10) & 0x03) == 1){
|
|
command = 1;// On
|
|
}
|
|
} else
|
|
// -------------------------------------------
|
|
if (devicetype == 6) { // Blokker/SelectRemote
|
|
// ----------------------------------
|
|
if ( ((bitstream)&0xef1) != 0) return false; // Not a valid bitstream
|
|
|
|
housecode = ((bitstream) & 0x0000000EL); // Isolate housecode
|
|
housecode = housecode >> 1; // shift right 1 bit
|
|
housecode = (~housecode)&0x07; // invert bits
|
|
housecode += 0x41; // add 'A'
|
|
unitcode = 0;
|
|
|
|
if ( ((bitstream >> 8) & 0x01) == 1) {
|
|
command = 1; // On
|
|
} else {
|
|
command = 0;// Off
|
|
}
|
|
// ---------------------------------- // Sartano
|
|
} else
|
|
// -------------------------------------------
|
|
if (devicetype != 4) { // KAKU (and some compatibles for now)
|
|
// ----------------------------------
|
|
if ((bitstream&0x700)!=0x600) { // valid but not real KAKU
|
|
housecode=(((bitstream) &0x0f) +0x41);
|
|
unitcode=((((bitstream) &0xf0) >> 4)+1);
|
|
devicetype=1;
|
|
} else {
|
|
if ((bitstream&0x600)!=0x600) {
|
|
//Serial.println("Kaku 0/1 error");
|
|
return false; // use two static bits as checksum
|
|
}
|
|
//bitstream=(bitstream)&0xffe; // kill bit to ensure Perel works -> actually kills code wheel letter B
|
|
housecode=(((bitstream) &0x0f) +0x41);
|
|
unitcode=((((bitstream) &0xf0) >> 4)+1);
|
|
// ----------------------------------
|
|
}
|
|
if ( ((bitstream >> 11) & 0x01) == 1) {
|
|
command=1; // ON
|
|
} else {
|
|
command=0; // OFF
|
|
}
|
|
}
|
|
}
|
|
// ==========================================================================
|
|
// Output
|
|
// ----------------------------------
|
|
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number
|
|
Serial.print( pbuffer );
|
|
// ----------------------------------
|
|
if (signaltype == 0x03) { // '0011' bits indicate bits 0 and f are used in the signal
|
|
if (devicetype < 4) { // KAKU (and some compatibles for now)
|
|
Serial.print(F("Kaku;")); // Label
|
|
} else {
|
|
if (devicetype == 4) { // AB440R and Sartano
|
|
Serial.print(F("AB400D;")); // Label
|
|
} else
|
|
if (devicetype == 5) { // Impuls
|
|
Serial.print(F("Impuls;")); // Label
|
|
} else {
|
|
Serial.print(F("Sartano;")); // Others
|
|
}
|
|
}
|
|
} else
|
|
if (signaltype == 0x05) { // '0101' bits indicate bits 0 and 1 are used in the signal
|
|
if (devicetype == 5) { // KAKU (and some compatibles for now)
|
|
Serial.print(F("Impuls;")); // Label
|
|
} else {
|
|
Serial.print(F("PT2262;")); // Label
|
|
}
|
|
} else
|
|
if (signaltype == 0x07) { // '0111' bits indicate bits 0, f and 1 are used in the signal (tri-state)
|
|
Serial.print(F("TriState;")); // Label
|
|
}
|
|
// ----------------------------------
|
|
if (signaltype == 0x07) { // '0111' bits indicate bits 0, f and 1 are used in the signal (tri-state)
|
|
sprintf(pbuffer, "ID=%06lx;",((bitstream2)>>4)&0xffffff) ; // ID
|
|
Serial.print( pbuffer );
|
|
housecode=(bitstream2)&0x03;
|
|
unitcode=((((bitstream2)>>2)&0x03)^0x03)^housecode;
|
|
//command=((bitstream2)&1)^1; << ^1 reverses lidl light
|
|
command=((bitstream2)&3); // 00 01 10 0 1 f
|
|
if (command > 1) command=1; // 0 stays 0 (OFF), 1 and f become 1 (ON)
|
|
} else {
|
|
sprintf(pbuffer, "ID=%02x;", housecode); // ID
|
|
Serial.print( pbuffer );
|
|
}
|
|
sprintf(pbuffer, "SWITCH=%d;", unitcode);
|
|
Serial.print( pbuffer );
|
|
Serial.print(F("CMD="));
|
|
if (group==1) Serial.print(F("ALL"));
|
|
if ( command == 1 ) {
|
|
Serial.print(F("ON;"));
|
|
} else {
|
|
Serial.print(F("OFF;"));
|
|
}
|
|
Serial.println();
|
|
// ----------------------------------
|
|
RawSignal.Repeats=true; // suppress repeats of the same RF packet
|
|
RawSignal.Number=0;
|
|
return true;
|
|
}
|
|
#endif //PLUGIN_003
|
|
|
|
#ifdef PLUGIN_TX_003
|
|
void Arc_Send(unsigned long address); // sends 0 and float
|
|
void NArc_Send(unsigned long bitstream); // sends 0 and 1
|
|
void TriState_Send(unsigned long bitstream); // sends 0, 1 and float
|
|
|
|
boolean PluginTX_003(byte function, char *string) {
|
|
boolean success=false;
|
|
unsigned long bitstream=0L;
|
|
byte command=0;
|
|
uint32_t housecode = 0;
|
|
uint32_t unitcode = 0;
|
|
byte Home=0; // KAKU home A..P
|
|
byte Address=0; // KAKU Address 1..16
|
|
byte c=0;
|
|
byte x=0;
|
|
// ==========================================================================
|
|
//10;Kaku;00004d;1;OFF;
|
|
//10;Kaku;00004f;e;ON;
|
|
//10;Kaku;000050;10;ON;
|
|
//10;Kaku;000049;b;ON;
|
|
//012345678901234567890
|
|
// ==========================================================================
|
|
if (strncasecmp(InputBuffer_Serial+3,"KAKU;",5) == 0) { // KAKU Command eg. Kaku;A1;On
|
|
if (InputBuffer_Serial[14] != ';') return false;
|
|
|
|
x=15; // character pointer
|
|
InputBuffer_Serial[10]=0x30;
|
|
InputBuffer_Serial[11]=0x78; // Get home from hexadecimal value
|
|
InputBuffer_Serial[14]=0x00; // Get home from hexadecimal value
|
|
Home=str2int(InputBuffer_Serial+10); // KAKU home A is intern 0
|
|
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 false; // invalid value
|
|
}
|
|
|
|
while((c=InputBuffer_Serial[x++])!=';'){ // Address: 1 to 16/32
|
|
if(c>='0' && c<='9'){Address=Address*10;Address=Address+c-'0';}
|
|
if(c>='a' && c<='f'){Address=Address+(c-'a'+10);} // 31?
|
|
if(c>='A' && c<='F'){Address=Address+(c-'A'+10);} // 51?
|
|
}
|
|
//if (Address==0) { // group command is given: 0=all
|
|
// command=2; // Set 2nd bit for group.
|
|
// bitstream=Home;
|
|
//} else {
|
|
// bitstream= Home | ((Address-1)<<4);
|
|
//}
|
|
|
|
bitstream= Home | ((Address-1)<<4);
|
|
command |= str2cmd(InputBuffer_Serial+x)==VALUE_ON; // ON/OFF command
|
|
bitstream = bitstream | (0x600 | ((command & 1) << 11)); // create the bitstream
|
|
//Serial.println(bitstream);
|
|
Arc_Send(bitstream);
|
|
success=true;
|
|
// --------------- END KAKU SEND ------------
|
|
} else
|
|
// ==========================================================================
|
|
//10;AB400D;00004d;1;OFF;
|
|
//012345678901234567890
|
|
// ==========================================================================
|
|
if (strncasecmp(InputBuffer_Serial+3,"AB400D;",7) == 0) { // KAKU Command eg. Kaku;A1;On
|
|
if (InputBuffer_Serial[16] != ';') return false;
|
|
x=17; // character pointer
|
|
InputBuffer_Serial[12]=0x30;
|
|
InputBuffer_Serial[13]=0x78; // Get home from hexadecimal value
|
|
InputBuffer_Serial[16]=0x00; // Get home from hexadecimal value
|
|
Home=str2int(InputBuffer_Serial+12); // KAKU home A is intern 0
|
|
if (Home < 0x61) // take care of upper/lower case
|
|
Home=Home - 'A';
|
|
else
|
|
if (Home < 0x81) // take care of upper/lower case
|
|
Home=Home - 'a';
|
|
else {
|
|
return false; // invalid value
|
|
}
|
|
while((c=InputBuffer_Serial[x++])!=';'){ // Address: 1 to 16/32
|
|
if(c>='0' && c<='9'){Address=Address*10;Address=Address+c-'0';}
|
|
}
|
|
command = str2cmd(InputBuffer_Serial+x)==VALUE_ON; // ON/OFF command
|
|
housecode = ~Home;
|
|
housecode &= 0x0000001FL;
|
|
unitcode=Address;
|
|
if ((unitcode >= 1) && (unitcode <= 5) ) {
|
|
bitstream = housecode & 0x0000001FL;
|
|
if (unitcode == 1) bitstream |= 0x000003C0L;
|
|
else if (unitcode == 2) bitstream |= 0x000003A0L;
|
|
else if (unitcode == 3) bitstream |= 0x00000360L;
|
|
else if (unitcode == 4) bitstream |= 0x000002E0L;
|
|
else if (unitcode == 5) bitstream |= 0x000001E0L;
|
|
|
|
if (command) bitstream |= 0x00000800L;
|
|
else bitstream |= 0x00000400L;
|
|
}
|
|
//Serial.println(bitstream);
|
|
Arc_Send(bitstream);
|
|
success=true;
|
|
} else
|
|
// --------------- END SARTANO SEND ------------
|
|
// ==========================================================================
|
|
//10;PT2262;000041;1;OFF;
|
|
//012345678901234567890
|
|
// ==========================================================================
|
|
if (strncasecmp(InputBuffer_Serial+3,"PT2262;",7) == 0) { // KAKU Command eg. Kaku;A1;On
|
|
if (InputBuffer_Serial[16] != ';') return false;
|
|
x=17; // character pointer
|
|
InputBuffer_Serial[12]=0x30;
|
|
InputBuffer_Serial[13]=0x78; // Get home from hexadecimal value
|
|
InputBuffer_Serial[16]=0x00; // Get home from hexadecimal value
|
|
Home=str2int(InputBuffer_Serial+12); // KAKU home A is intern 0
|
|
if (Home < 0x61) // take care of upper/lower case
|
|
Home=Home - 'A';
|
|
else
|
|
if (Home < 0x81) // take care of upper/lower case
|
|
Home=Home - 'a';
|
|
else {
|
|
return false; // invalid value
|
|
}
|
|
while((c=InputBuffer_Serial[x++])!=';'){ // Address: 1 to 16/32
|
|
if(c>='0' && c<='9'){Address=Address*10;Address=Address+c-'0';}
|
|
}
|
|
// reconstruct bitstream reversed order so that most right bit can be send first
|
|
command = str2cmd(InputBuffer_Serial+x)==VALUE_ON; // ON/OFF command
|
|
housecode = ~Home;
|
|
housecode &= 0x00000007L;
|
|
housecode=(housecode)<<1;
|
|
if (command) bitstream |= 0x00000100L;
|
|
NArc_Send(bitstream); // send 24 bits tristate signal (0/1/f)
|
|
success=true;
|
|
} else
|
|
// --------------- END Select Remote SEND ------------
|
|
// ==========================================================================
|
|
//10;TriState;00004d;1;OFF;
|
|
//10;TriState;08000a;2;OFF; 20;1B;TriState;ID=08000a;SWITCH=2;CMD=OFF;
|
|
//10;TriState;0a6980;2;OFF;
|
|
//01234567890123456789012
|
|
// ==========================================================================
|
|
if (strncasecmp(InputBuffer_Serial+3,"TriState;",9) == 0) { // KAKU Command eg. Kaku;A1;On
|
|
if (InputBuffer_Serial[18] != ';') return false;
|
|
x=19; // character pointer
|
|
InputBuffer_Serial[10]=0x30;
|
|
InputBuffer_Serial[11]=0x78; // Get home from hexadecimal value
|
|
InputBuffer_Serial[18]=0x00; // Get home from hexadecimal value
|
|
bitstream=str2int(InputBuffer_Serial+10); // KAKU home A is intern 0
|
|
bitstream=(bitstream<<4);
|
|
|
|
// 11^00^01=10 11^10^11=01 11^11^00=00
|
|
while((c=InputBuffer_Serial[x++])!=';'){ // Address: 0/1/2
|
|
if(c>='0' && c<='9'){Address=Address*10;Address=Address+c-'0';}
|
|
}
|
|
Address=(Address)&0x03; // only use 3 bits
|
|
command = str2cmd(InputBuffer_Serial+x); // ON/OFF command
|
|
if (command==VALUE_ON) { // on
|
|
if (Address==0x0) bitstream |= 0x0000000bL; // 0011
|
|
if (Address==0x1) bitstream |= 0x0000000cL; // 1011
|
|
if (Address==0x2) bitstream |= 0x00000001L; // 0001
|
|
} else { // off
|
|
if (Address==0x0) bitstream |= 0x0000000cL; // 1100
|
|
if (Address==0x1) bitstream |= 0x0000000eL; // 1110
|
|
if (Address==0x2) bitstream |= 0x00000004L; // 0100
|
|
}
|
|
TriState_Send(bitstream);
|
|
success=true;
|
|
} else
|
|
// --------------- END TRISTATE SEND ------------
|
|
// ==========================================================================
|
|
//10;Impuls;00004d;1;OFF;
|
|
//012345678901234567890
|
|
// ==========================================================================
|
|
if (strncasecmp(InputBuffer_Serial+3,"Impuls;",7) == 0) { // KAKU Command eg. Kaku;A1;On
|
|
if (InputBuffer_Serial[16] != ';') return false;
|
|
x=17; // character pointer
|
|
InputBuffer_Serial[12]=0x30;
|
|
InputBuffer_Serial[13]=0x78; // Get home from hexadecimal value
|
|
InputBuffer_Serial[16]=0x00; // Get home from hexadecimal value
|
|
Home=str2int(InputBuffer_Serial+12); // KAKU home A is intern 0
|
|
if (Home < 0x61) // take care of upper/lower case
|
|
Home=Home - 'A';
|
|
else
|
|
if (Home < 0x81) // take care of upper/lower case
|
|
Home=Home - 'a';
|
|
else {
|
|
return false; // invalid value
|
|
}
|
|
while((c=InputBuffer_Serial[x++])!=';'){ // Address: 1 to 16/32
|
|
if(c>='0' && c<='9'){Address=Address*10;Address=Address+c-'0';}
|
|
}
|
|
command = str2cmd(InputBuffer_Serial+x)==VALUE_ON; // ON/OFF command
|
|
housecode = ~Home;
|
|
housecode &= 0x0000001FL;
|
|
unitcode=Address;
|
|
if ((unitcode >= 1) && (unitcode <= 5) ) {
|
|
bitstream = housecode & 0x0000001FL;
|
|
if (unitcode == 1) bitstream |= 0x000003C0L;
|
|
else if (unitcode == 2) bitstream |= 0x000003A0L;
|
|
else if (unitcode == 3) bitstream |= 0x00000360L;
|
|
else if (unitcode == 4) bitstream |= 0x000002E0L;
|
|
else if (unitcode == 5) bitstream |= 0x000001E0L;
|
|
|
|
if (command) bitstream |= 0x00000800L;
|
|
else bitstream |= 0x00000400L;
|
|
}
|
|
TriState_Send(bitstream);
|
|
success=true;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
//#define KAKU_T 390 //420 // 370 // 370? 350 us
|
|
//#define Sartano_T 300 //360 // 300 // 300 uS
|
|
|
|
void Arc_Send(unsigned long bitstream) {
|
|
int fpulse = 360; // Pulse width in microseconds
|
|
int fretrans = 8; // Number of code retransmissions
|
|
uint32_t fdatabit;
|
|
uint32_t fdatamask = 0x00000001;
|
|
uint32_t fsendbuff;
|
|
|
|
digitalWrite(PIN_RF_RX_VCC,LOW); // Turn off power to the RF receiver
|
|
digitalWrite(PIN_RF_TX_VCC,HIGH); // Enable the 433Mhz 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 = bitstream;
|
|
// Send command
|
|
|
|
for (int i = 0; i < 12; i++) { // Arc packet is 12 bits
|
|
// read data bit
|
|
fdatabit = fsendbuff & fdatamask; // Get most right bit
|
|
fsendbuff = (fsendbuff >> 1); // Shift right
|
|
|
|
// PT2262 data can be 0, 1 or float. Only 0 and float is used by regular ARC
|
|
if (fdatabit != fdatamask) { // Write 0
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
} else { // Write float
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 1);
|
|
}
|
|
}
|
|
// Send sync bit
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW); // and lower the signal
|
|
delayMicroseconds(fpulse * 31);
|
|
}
|
|
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); // Turn the 433Mhz transmitter off
|
|
digitalWrite(PIN_RF_RX_VCC,HIGH); // Turn the 433Mhz receiver on
|
|
RFLinkHW();
|
|
}
|
|
|
|
void NArc_Send(unsigned long bitstream) {
|
|
int fpulse = 190; // Pulse width in microseconds
|
|
int fretrans = 7; // Number of code retransmissions
|
|
uint32_t fdatabit;
|
|
uint32_t fdatamask = 0x00000001;
|
|
uint32_t fsendbuff;
|
|
|
|
digitalWrite(PIN_RF_RX_VCC,LOW); // Turn off power to the RF receiver
|
|
digitalWrite(PIN_RF_TX_VCC,HIGH); // Enable the 433Mhz 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 = bitstream;
|
|
// Send command
|
|
|
|
for (int i = 0; i < 12; i++) { // Arc packet is 12 bits
|
|
// read data bit
|
|
fdatabit = fsendbuff & fdatamask; // Get most right bit
|
|
fsendbuff = (fsendbuff >> 1); // Shift right
|
|
|
|
// PT2262 data can be 0, 1 or float. Only 0 and float is used by regular ARC
|
|
if (fdatabit != fdatamask) { // Write 0
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
} else { // Write 1
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 1);
|
|
}
|
|
}
|
|
// Send sync bit
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW); // and lower the signal
|
|
delayMicroseconds(fpulse * 31);
|
|
}
|
|
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); // Turn thew 433Mhz transmitter off
|
|
digitalWrite(PIN_RF_RX_VCC,HIGH); // Turn the 433Mhz receiver on
|
|
RFLinkHW();
|
|
}
|
|
|
|
void TriState_Send(unsigned long bitstream) {
|
|
int fpulse = 360; // Pulse width in microseconds
|
|
int fretrans = 8; // Number of code retransmissions
|
|
uint32_t fdatabit;
|
|
uint32_t fdatamask = 0x00000003;
|
|
uint32_t fsendbuff;
|
|
|
|
digitalWrite(PIN_RF_RX_VCC,LOW); // Turn off power to the RF receiver
|
|
digitalWrite(PIN_RF_TX_VCC,HIGH); // Enable the 433Mhz transmitter
|
|
delayMicroseconds(TRANSMITTER_STABLE_DELAY); // short delay to let the transmitter become stable (Note: Aurel RTX MID needs 500µS/0,5ms)
|
|
|
|
// reverse data bits (2 by 2)
|
|
for (unsigned short i=0; i<12; i++) { // reverse data bits (12 times 2 bits = 24 bits in total)
|
|
fsendbuff<<=2;
|
|
fsendbuff|=(bitstream & B11);
|
|
bitstream>>=2;
|
|
}
|
|
bitstream=fsendbuff; // store result
|
|
|
|
for (int nRepeat = 0; nRepeat <= fretrans; nRepeat++) {
|
|
fsendbuff = bitstream;
|
|
// Send command
|
|
for (int i = 0; i < 12; i++) { // 12 times 2 bits = 24 bits in total
|
|
// read data bit
|
|
fdatabit = fsendbuff & fdatamask; // Get most right 2 bits
|
|
fsendbuff = (fsendbuff >> 2); // Shift right
|
|
// data can be 0, 1 or float.
|
|
if (fdatabit == 0) { // Write 0
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
} else
|
|
if (fdatabit == 1) { // Write 1
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 1);
|
|
} else { // Write float
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 3);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW);
|
|
delayMicroseconds(fpulse * 1);
|
|
}
|
|
}
|
|
// Send sync bit
|
|
digitalWrite(PIN_RF_TX_DATA, HIGH);
|
|
delayMicroseconds(fpulse * 1);
|
|
digitalWrite(PIN_RF_TX_DATA, LOW); // and lower the signal
|
|
delayMicroseconds(fpulse * 31);
|
|
}
|
|
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); // Turn thew 433Mhz transmitter off
|
|
digitalWrite(PIN_RF_RX_VCC,HIGH); // Turn the 433Mhz receiver on
|
|
RFLinkHW();
|
|
}
|
|
#endif //PLUGIN_TX_003
|