Skip to content

Commit 5353f19

Browse files
committed
Add support for Compustar 1WG3R Car Remote
1 parent d6ccd09 commit 5353f19

File tree

4 files changed

+198
-1
lines changed

4 files changed

+198
-1
lines changed

conf/rtl_433.example.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ convert si
481481
protocol 252 # Audiovox Car Remote
482482
protocol 253 # Astrostart 2000 Car Remote (-f 372.5M)
483483
protocol 254 # Compustar 700R Car Remote
484+
protocol 255 # Compustar 1WG3R Car Remote
484485

485486
## Flex devices (command line option "-X")
486487

include/rtl_433_devices.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@
261261
DECL(fineoffset_wh55) \
262262
DECL(audiovox_car_remote) \
263263
DECL(astrostart_2000) \
264-
DECL(compustar_700r)
264+
DECL(compustar_700r) \
265+
DECL(compustar_1wg3r)
265266

266267
/* Add new decoders here. */
267268

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ add_library(r_433 STATIC
8383
devices/cmr113.c
8484
devices/companion_wtr001.c
8585
devices/compustar_700r.c
86+
devices/compustar_1wg3r.c
8687
devices/cotech_36_7959.c
8788
devices/current_cost.c
8889
devices/danfoss.c

src/devices/compustar_1wg3r.c

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/** @file
2+
Compustar 1WG3R-SH - Car Remote.
3+
4+
Copyright (C) 2023 Ethan Halsall
5+
6+
This program is free software; you can panicistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation; either version 2 of the License, or
9+
(at your option) any later version.
10+
*/
11+
/** @fn int compustar_1wg3r_decode(r_device *decoder, bitbuffer_t *bitbuffer)
12+
Compustar 1WG3R-SH - Car Remote
13+
14+
Manufacturer:
15+
- Compustar
16+
17+
Supported Models:
18+
- 1WG3R-SH
19+
- 1WAMR-1900
20+
21+
Data structure:
22+
23+
Compustar 1WG3R-SH Transmitters
24+
25+
The transmitter uses a fixed code message.
26+
27+
Button operation:
28+
This transmitter has 4 buttons which can be pressed once to transmit a single message
29+
Multiple buttons can be pressed down to send unique codes.
30+
31+
Long Press:
32+
Hold the button combination down for 2.5 seconds to send a long press signal.
33+
34+
Secondary mode:
35+
Press and hold the unlock and the trunk buttons (II & III) at the same time. (press and hold for 2.5 seconds)
36+
The LED will flash slowly indicating the remote is in the secondary mode.
37+
Button presses are batched by the remote when secondary mode is activated.
38+
39+
40+
Data layout:
41+
42+
IIII x bbbbbbbb iiiiiiii z
43+
44+
- I: 16 bit remote ID
45+
- x: 3 bit unknown (always set to 111)
46+
- i: 8 bit inverted button code
47+
- b: 8 bit button code
48+
- z: 1 bit unknown (always set to 0)
49+
50+
Format string:
51+
52+
ID: hhhh UNKNOWN: bbb BUTTON_INVERSE: bbbbbbbb BUTTON: bbbbbbbb UNKNOWN: b
53+
54+
*/
55+
56+
#include "decoder.h"
57+
#include <stdlib.h>
58+
59+
static int compustar_1wg3r_decode(r_device *decoder, bitbuffer_t *bitbuffer)
60+
{
61+
int rows_data_idx = -1;
62+
data_t **rows_data = malloc(bitbuffer->num_rows);
63+
64+
// loop through all of the rows and only return unique valid results
65+
// programming mode will send a sequence of key presses all in one message
66+
int previous_row = -1;
67+
for (int current_row = 0; current_row < bitbuffer->num_rows; current_row++) {
68+
uint8_t *bytes = bitbuffer->bb[current_row];
69+
70+
// reset row count for the row separator
71+
if (bitbuffer->bits_per_row[current_row] == 5 && (bytes[0] & 0xf8) == 0xf8) {
72+
previous_row = -1;
73+
continue;
74+
}
75+
76+
if ((bytes[2] & 0xe0) != 0xe0 || (bytes[4] & 1) != 0x0) {
77+
continue; // DECODE_ABORT_EARLY;
78+
}
79+
80+
if ((bytes[0] = 0xff && bytes[1] == 0xff) ||
81+
(bytes[0] == 0x00 && bytes[1] == 0x00)) {
82+
continue; // DECODE_FAIL_SANITY;
83+
}
84+
85+
int id = bytes[0] << 8 | bytes[1];
86+
int button_inverse = (bytes[2] << 3 & 0xff) | bytes[3] >> 5;
87+
int button = ((bytes[3] << 3) & 0xff) | bytes[4] >> 5;
88+
89+
if ((~button_inverse & 0xff) != button) {
90+
continue; // DECODE_FAIL_MIC;
91+
}
92+
93+
// button flags
94+
int long_press = (button & 0x10) > 0;
95+
int secondary_mode = (button & 0x80) > 0;
96+
int alarm = 0;
97+
int unlock = 0;
98+
int lock = 0;
99+
int trunk = 0;
100+
int start = 0;
101+
102+
// these are not bit flags
103+
// the remote maps the button combinations to tbe below table
104+
/* clang-format off */
105+
// shared codes between normal and long press
106+
switch (button & 0xf) {
107+
case 0x3: lock = 1; unlock = 1; break;
108+
case 0x5: lock = 1; trunk = 1; break;
109+
case 0x9: lock = 1; start = 1; break;
110+
case 0x6: unlock = 1; trunk = 1; break;
111+
case 0xa: unlock = 1; start = 1; break;
112+
case 0xc: start = 1; trunk = 1; break;
113+
case 0xb: lock = 1; unlock = 1; start = 1; break;
114+
case 0xe: unlock = 1; start = 1; trunk = 1; break;
115+
case 0xd: lock = 1; start = 1; trunk = 1; break;
116+
}
117+
118+
// unique codes between normal and long press
119+
switch (button & 0x1f) {
120+
case 0x0f: lock = 1; break;
121+
case 0x1f: lock = 1; unlock = 1; start = 1; trunk = 1; break;
122+
case 0x07: unlock = 1; break;
123+
case 0x17: lock = 1; unlock = 1; trunk = 1; break;
124+
case 0x02: trunk = 1; break;
125+
case 0x04: start = 1; break;
126+
case 0x12: start = 1; break;
127+
case 0x14: trunk = 1; break;
128+
case 0x08: start = 1; trunk = 1; long_press = 1; break;
129+
case 0x18: alarm = 1; break;
130+
}
131+
/* clang-format on */
132+
133+
if (previous_row >= 0 && bitbuffer_compare_rows(bitbuffer, previous_row, current_row, 35)) {
134+
continue; // duplicate of previous row
135+
}
136+
137+
previous_row = current_row;
138+
rows_data_idx++;
139+
/* clang-format off */
140+
rows_data[rows_data_idx] = data_make(
141+
"model", "model", DATA_STRING, "Compustar-1WG3R-SH",
142+
"id", "device-id", DATA_INT, id,
143+
"button_code", "Button Code", DATA_INT, button,
144+
"alarm", "Alarm", DATA_INT, alarm,
145+
"start", "Start", DATA_INT, start,
146+
"lock", "Lock", DATA_INT, lock,
147+
"unlock", "Unlock", DATA_INT, unlock,
148+
"trunk", "Trunk", DATA_INT, trunk,
149+
"long_press", "Long Press", DATA_INT, long_press,
150+
"secondary_mode", "Secondary Mode", DATA_INT, secondary_mode,
151+
"mic", "Integrity", DATA_STRING, "CHECKSUM",
152+
NULL);
153+
/* clang-format on */
154+
}
155+
156+
// send the messages in order
157+
for (int i = 0; i <= rows_data_idx; i++) {
158+
decoder_output_data(decoder, rows_data[i]);
159+
}
160+
161+
free(rows_data);
162+
163+
if (rows_data_idx < 0) {
164+
return DECODE_FAIL_OTHER;
165+
}
166+
167+
return 1;
168+
}
169+
170+
static char const *const output_fields[] = {
171+
"model",
172+
"id",
173+
"button_code",
174+
"alarm",
175+
"start",
176+
"lock",
177+
"unlock",
178+
"trunk",
179+
"long_press",
180+
"secondary_mode",
181+
"mic",
182+
NULL,
183+
};
184+
185+
r_device const compustar_1wg3r = {
186+
.name = "Compustar 1WG3R-SH Car Remote",
187+
.modulation = OOK_PULSE_PWM,
188+
.short_width = 708,
189+
.long_width = 1076,
190+
.reset_limit = 1532,
191+
.sync_width = 1448,
192+
.decode_fn = &compustar_1wg3r_decode,
193+
.fields = output_fields,
194+
};

0 commit comments

Comments
 (0)