-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathPlugin_010.c
242 lines (233 loc) · 11.3 KB
/
Plugin_010.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
//## This Plugin is only for use with the RFLink software package ##
//## Plugin-10 TRC02 RGB Controller ##
//#######################################################################################################
/*********************************************************************************************\
* Decodes signals from a wireless RGB TRC02 controller remote control
*
*
* Author : StuntTeam, Marek Zlatos,
* 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:
* Decodes signals from a wireless TRC02 RGB controller remote control
* --------------------------------------------------------------------------------------------
* _Byte 0_ _Byte 1_ _Byte 2_ _Byte 3_ _Bit_
* 76543210 76543210 76543210 76543210 0
* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD E
*
* A = Rolling Code
* B = Rolling Code
* C = Rolling Code
* D = Command
* E = Checksum. bit is XOR of all bits in the RF message
*
* Commands:
* 00 ON
* 01 OFF
* 02 Dim Down
* 03 DIM UP
* 05 Color Mix UP
* 04 Color Mix Down
* 87 Color Wheel Red
* 34 Color Wheel Blue
* 78 Color Wheel Yellow
* 5D Color Wheel Green
*
* Sample:
* 20;30;DEBUG;Pulses=180;Pulses(uSec)=450,420,420,420,420,420,1410,960,420,420,420,420,420,420,420,420,420,420,930,420,420,960,420,420,420,420,420,420,420,420,420,420,930,960,420,420,420,420,930,420,420,420,420,420,420,960,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,930,390,1440,960,420,420,420,420,420,420,420,420,420,420,930,420,420,960,420,420,420,420,420,420,420,420,420,420,930,960,420,420,420,420,930,420,420,420,420,420,420,960,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,930,390,1440,960,420,420,420,420,420,420,420,420,420,420,930,420,420,960,420,420,420,420,420,420,420,420,420,420,930,960,420,420,420,420,930,420,420,420,420,420,420,960,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,930,6990
* TRC02:00000011 00000010 00111100 00000000 1
* 20;01;TRC02;ID=03023c;SWITCH=00;CMD=ON;
\*********************************************************************************************/
#define RGB_MIN_PULSECOUNT 180
#define RGB_MAX_PULSECOUNT 186
#define RGB_PULSE_STHI 1600/RAWSIGNAL_SAMPLE_RATE
#define RGB_PULSE_STLO 1300/RAWSIGNAL_SAMPLE_RATE
#define RGB_PULSE_HIHI 1100/RAWSIGNAL_SAMPLE_RATE
#define RGB_PULSE_HILO 900/RAWSIGNAL_SAMPLE_RATE
#define RGB_PULSE_LOHI 600/RAWSIGNAL_SAMPLE_RATE
#define RGB_PULSE_LOLO 400/RAWSIGNAL_SAMPLE_RATE
#ifdef PLUGIN_010
boolean Plugin_010(byte function, char *string) {
if (RawSignal.Number < RGB_MIN_PULSECOUNT || RawSignal.Number > RGB_MAX_PULSECOUNT) return false;
unsigned long bitstream=0L; // holds first 32 bits
byte checksum=0; // holds the checksum calculation
byte crc=0; // holds the crc bit from the signal
byte bitcounter=0; // counts number of received bits (converted from pulses)
byte halfbit=0; // high pulse = 1, 2 low pulses = 0, halfbit keeps track of low pulses
byte bitmask = 0;
int command=0;
byte start_stop=0;
byte x=1;
//==================================================================================
for(x=1;x <RawSignal.Number-2;x++) { // get bytes
if (start_stop!=0x01) {
//if (RawSignal.Pulses[x]*RawSignal.Multiply > 1200 && RawSignal.Pulses[x]*RawSignal.Multiply < 1500) {
if (RawSignal.Pulses[x] > RGB_PULSE_STLO && RawSignal.Pulses[x] < RGB_PULSE_STHI) {
start_stop=0x01;
continue;
} else {
if (x > 100) return false; // bad packet
continue;
}
}
if (RawSignal.Pulses[x]*RawSignal.Multiply > 750 && RawSignal.Pulses[x]*RawSignal.Multiply < 1000) {
if (halfbit==1) { // cant receive a 1 bit after a single low value
return false; // pulse error, must not be a UPM packet or reception error
}
bitmask = !bitmask;
if (bitcounter < 32) {
if (bitmask == 1){
bitstream = (bitstream << 1);
} else {
bitstream = (bitstream << 1) | 0x1;
}
bitcounter++; // only need to count the first 10 bits
} else {
crc =1;
break;
}
halfbit=0; // wait for next first low or high pulse
} else {
if (RawSignal.Pulses[x]*RawSignal.Multiply > 625 && RawSignal.Pulses[x]*RawSignal.Multiply < 250) return false; // Not a valid UPM pulse length
if (halfbit == 0) { // 2 times a low value = 0 bit
halfbit=1; // first half received
} else {
if (bitcounter < 32) {
if (bitmask == 1){
bitstream = (bitstream << 1);
} else {
bitstream = (bitstream << 1) | 0x1;
}
checksum=checksum^1;
bitcounter++; // only need to count the first 10 bits
} else {
crc=0;
break;
}
halfbit=0; // wait for next first low or high pulse
}
}
}
//==================================================================================
// Validity checks
if (RawSignal.Pulses[x+2]*RawSignal.Multiply < 1200 || RawSignal.Pulses[x+2]*RawSignal.Multiply > 1500) return false;
//==================================================================================
// perform a checksum check to make sure the packet is a valid RGB control packet
// Checksum: xor all odd and all even bits should match the last bit
// ----------------------------------
if (checksum != crc) {
//Serial.println("crc2 error");
return false;
}
//==================================================================================
// now process the command
//==================================================================================
command = (bitstream) &0xff; // command
int id3 = (bitstream >> 8) &0xff;
bitstream = (bitstream >> 16) &0xffff; // rolling code
//==================================================================================
// Output
// ----------------------------------
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number
Serial.print( pbuffer );
Serial.print(F("TRC02RGB;")); // Label
sprintf(pbuffer, "ID=%04x", bitstream); // ID
Serial.print( pbuffer );
sprintf(pbuffer, "%02x;", id3);
Serial.print( pbuffer );
sprintf(pbuffer, "SWITCH=%02x;", command);
Serial.print( pbuffer );
Serial.print(F("CMD="));
if (command==0x00) Serial.print("ON;");
else if (command==0x01) Serial.print(F("OFF;"));
else if (command==0x02) Serial.print(F("DIM DOWN;"));
else if (command==0x03) Serial.print(F("DIM UP;"));
else if (command==0x05) Serial.print(F("COLORMIX UP;"));
else if (command==0x04) Serial.print(F("COLORMIX DOWN;"));
else if (command==0x87) Serial.print(F("COLOR RED;"));
else if (command==0x34) Serial.print(F("COLOR BLUE;"));
else if (command==0x78) Serial.print(F("COLOR YELLOW;"));
else if (command==0x5D) Serial.print(F("COLOR GREEN;"));
else {
sprintf(pbuffer, "SET_LEVEL=%d;", command );
Serial.print( pbuffer );
}
Serial.println();
//==================================================================================
RawSignal.Repeats=true; // suppress repeats of the same RF packet
RawSignal.Number=0;
return true;
}
#endif // PLUGIN_010
#ifdef PLUGIN_TX_010
void TRC02_Send(unsigned long address, int command);
boolean PluginTX_010(byte function, char *string) {
//10;TRC02RGB;03023c;00;
//012345678901234567890123456
boolean success=false;
if (strncasecmp(InputBuffer_Serial+3,"TRC02RGB;",9) == 0) { // KAKU Command eg.
TRC02_Send(strtoul(InputBuffer_Serial+12,NULL,16),strtoul(InputBuffer_Serial+19,NULL,16));
success=true;
}
return success;
}
void TRC02_Send(unsigned long address, int command) {
int fpulse = 500;
int fretrans = 2; // Number of code retransmissions
byte crc = 0;
uint32_t fdatabit;
uint32_t fdatamask = 0x80000000;
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++) {
crc=0;
fsendbuff=address;
fsendbuff=(fsendbuff<<8)+command;
digitalWrite(PIN_RF_TX_DATA, HIGH); // start pulse
delayMicroseconds(fpulse * 3);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse);
for (int i = 0; i < 32; i++) { // TRC02 packet is 32 bits + 1 bit crc
// 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, LOW);
delayMicroseconds(fpulse);
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse);
crc += crc^0;
} else { // Write 1
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse);
crc += crc^1;
}
}
if (crc==1) { // crc pulse
delayMicroseconds(fpulse);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse);
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse);
} else {
delayMicroseconds(fpulse);
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse);
}
}
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_010