Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/rc-transceiver.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2022-04-10 19:35:29 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2022-04-10 19:35:29 +0300
commit8f5b64e68f33a2079d99615e1e0653e482a2c303 (patch)
treed1f31011b2add1bdd44f8bdda98bad81f5351152 /demo_scripts
First commit
Diffstat (limited to 'demo_scripts')
-rw-r--r--demo_scripts/necrc.py67
-rw-r--r--demo_scripts/rc6.py82
-rw-r--r--demo_scripts/receiver-test.py27
-rw-r--r--demo_scripts/transmitter-test.py20
4 files changed, 196 insertions, 0 deletions
diff --git a/demo_scripts/necrc.py b/demo_scripts/necrc.py
new file mode 100644
index 0000000..646b48b
--- /dev/null
+++ b/demo_scripts/necrc.py
@@ -0,0 +1,67 @@
+NEC_LEADING_PULSE = 9000
+NEC_LEADING_GAP = 4500
+NEC_GAP = 562
+NEC_PULSE_0 = 562
+NEC_PULSE_1 = 1600
+NEC_PRECITION = 0.25
+NEC_REPEAT_GAP = 2250
+
+def nec_decode(s):
+ b = bytes.fromhex(s)
+ values = [int.from_bytes(b[i:i+2], byteorder='little') for i in range(0, len(b), 2)]
+ if not (NEC_LEADING_PULSE * (1 - NEC_PRECITION) <= values[0] <= NEC_LEADING_PULSE * (1 + NEC_PRECITION)):
+ raise ValueError(f"Invalid leading pulse length: {values[0]}")
+ if not (NEC_LEADING_GAP * (1 - NEC_PRECITION) <= values[1] <= NEC_LEADING_GAP * (1 + NEC_PRECITION)):
+ raise ValueError(f"Invalid leading gap length: {values[1]}")
+ if not (NEC_GAP * (1 - NEC_PRECITION) <= values[2] <= NEC_GAP * (1 + NEC_PRECITION)):
+ raise ValueError(f"Invalid first pulse length: {values[2]}")
+ i = 0
+ for p in range(3, 3 + 2 * 32, 2):
+ v = values[p]
+ v = 1 if v > (NEC_PULSE_0 + NEC_PULSE_1) / 2 else 0
+ i = (i >> 1) | (v << 31)
+ return int.to_bytes(i, length=4, byteorder='little')
+
+def nec_encode(h):
+ # Type check
+ if type(h) == int:
+ h = int.to_bytes(h, length=4, byteorder='little')
+ elif type(h) is list:
+ h = bytes(h)
+ elif type(h) is bytes:
+ pass
+ else:
+ raise TypeError(f"Invalid type of input data: {type(h)}")
+ # Length check
+ if len(h) == 2:
+ h = bytes([h[0], h[0] ^ 0xFF, h[1], h[1] ^ 0xFF])
+ elif len(h) == 3:
+ h = bytes([h[0], h[1], h[2], h[2] ^ 0xFF])
+ elif len(h) == 4:
+ pass
+ else:
+ raise ValueError(f"Invalid length of input data: {len(h)}")
+ # Encoding
+ len2str = lambda i: f"{((i >> 8) | (i << 8)) & 0xFFFF:04x}"
+ i = int.from_bytes(h, byteorder='little')
+ pulses = [NEC_PULSE_1 if i & (1 << bit) > 0 else NEC_PULSE_0 for bit in range(32)]
+ s = (
+ len2str(NEC_LEADING_PULSE) +
+ len2str(NEC_LEADING_GAP) +
+ len2str(NEC_GAP) +
+ len2str(NEC_GAP).join([len2str(pulse) for pulse in pulses]) +
+ len2str(NEC_GAP)
+ )
+ return s
+
+def is_nec_repeat(s):
+ b = bytes.fromhex(s)
+ values = [int.from_bytes(b[i:i+2], byteorder='little') for i in range(0, len(b), 2)]
+ if len(values) > 3: return False
+ if not (NEC_LEADING_PULSE * (1 - NEC_PRECITION) <= values[0] <= NEC_LEADING_PULSE * (1 + NEC_PRECITION)):
+ return False
+ if not (NEC_REPEAT_GAP * (1 - NEC_PRECITION) <= values[1] <= NEC_REPEAT_GAP * (1 + NEC_PRECITION)):
+ return False
+ if not (NEC_GAP * (1 - NEC_PRECITION) <= values[2] <= NEC_GAP * (1 + NEC_PRECITION)):
+ return False
+ return True
diff --git a/demo_scripts/rc6.py b/demo_scripts/rc6.py
new file mode 100644
index 0000000..dc215fb
--- /dev/null
+++ b/demo_scripts/rc6.py
@@ -0,0 +1,82 @@
+RC6_T = 444
+RC6_PRECITION = 0.5
+
+def rc6_decode(s):
+ b = bytes.fromhex(s)
+ values = [int.from_bytes(b[i:i+2], byteorder='little') for i in range(0, len(b), 2)]
+ if len(values) % 2 != 0: values.append(65535)
+ if not (RC6_T * (6 - RC6_PRECITION) <= values[0] <= RC6_T * (6 + RC6_PRECITION)):
+ raise ValueError(f"Invalid leading pulse length: {values[0]}")
+ if not (RC6_T * (2 - RC6_PRECITION) <= values[1] <= RC6_T * (2 + RC6_PRECITION)):
+ raise ValueError(f"Invalid leading gap length: {values[1]}")
+ i = 0
+ bit = 0
+ pos = 2
+ while bit <= 20:
+ i = i << 1
+ bit = bit + 1
+ if pos % 2 == 1: i = i | 1
+ if values[pos] < RC6_T*3/2 if (pos != 10) else RC6_T*3:
+ pos = pos + 2
+ else:
+ pos = pos + 1
+ info = i & 0xFF
+ control = (i >> 8) & 0xFF
+ toggle = (i >> 16) & 1
+ mode = (i >> 17) & 0b111
+ return {"info": info, "control": control, "toggle": toggle, "mode": mode}
+
+def rc6_encode(command, control = 0, toggle = 0, mode = 0):
+ if type(command) == dict:
+ info = command.get("info", 0)
+ control = command.get("control", 0)
+ toggle = command.get("toggle", 0)
+ mode = command.get("mode", 0)
+ elif type(command) == tuple:
+ info = command[0]
+ control = command[1] if len(command) > 1 else 0
+ toggle = command[2] if len(command) > 2 else 0
+ mode = command[3] if len(command) > 3 else 0
+ elif type(command) == int:
+ info = command
+ else:
+ raise ValueError(f"Invalid command type: {type(command)}")
+
+ pulses = []
+ bits = []
+ data = (1 << 20) | ((mode & 0b111) << 17) | ((toggle & 1) << 16) | ((control & 0xFF) << 8) | (info & 0xFF)
+ # Leading pulse
+ bits.append((1, RC6_T*6))
+ bits.append((0, RC6_T*2))
+ pulses.append(RC6_T*6)
+ pulses.append(RC6_T*2)
+ # Data
+ for i in range(20, -1, -1):
+ T = RC6_T if i != 16 else RC6_T * 2
+ if ((data >> i) & 1 == 0):
+ bits.append(i)
+ bits.append(0)
+ bits.append((0, T))
+ bits.append((1, T))
+ if (len(pulses) % 2) == 0:
+ pulses[len(pulses) - 1] = pulses[len(pulses) - 1] + T
+ pulses.append(T)
+ else:
+ pulses.append(T)
+ pulses.append(T)
+ else:
+ bits.append(i)
+ bits.append(1)
+ bits.append((1, T))
+ bits.append((0, T))
+ if (len(pulses) % 2) == 1:
+ pulses[len(pulses) - 1] = pulses[len(pulses) - 1] + T
+ pulses.append(T)
+ else:
+ pulses.append(T)
+ pulses.append(T)
+ if (len(pulses) % 2 == 0):
+ pulses = pulses[0:len(pulses) - 1]
+ len2str = lambda i: f"{((i >> 8) | (i << 8)) & 0xFFFF:04x}"
+ s = "".join([len2str(pulse) for pulse in pulses])
+ return s
diff --git a/demo_scripts/receiver-test.py b/demo_scripts/receiver-test.py
new file mode 100644
index 0000000..3057717
--- /dev/null
+++ b/demo_scripts/receiver-test.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python3
+
+from necrc import *
+from rc6 import *
+
+DEVICE = "/dev/rc"
+
+with open(DEVICE, "r") as f:
+ while True:
+ raw = f.readline().strip()
+ # Try to decode button data using different encoding methods
+ try:
+ decoded = nec_decode(raw)
+ print("Decoded as NEC:", " ".join(f"{b:02x}" for b in decoded))
+ continue
+ except:
+ pass
+ if is_nec_repeat(raw):
+ print("Decoded as NEC repeat code")
+ continue
+ try:
+ decoded = rc6_decode(raw)
+ print("Decoded as RC6:", decoded)
+ continue
+ except:
+ pass
+ print("Can't decode, raw data:", raw)
diff --git a/demo_scripts/transmitter-test.py b/demo_scripts/transmitter-test.py
new file mode 100644
index 0000000..152c95d
--- /dev/null
+++ b/demo_scripts/transmitter-test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python3
+
+from necrc import *
+from rc6 import *
+from time import sleep
+
+DEVICE = "/dev/rc"
+
+with open(DEVICE, "w") as f:
+ # Send '0' button code for Philips TV
+ raw = rc6_encode(command=0, control=0, toggle=0, mode=0)
+ f.write(raw + "\n")
+ f.flush()
+
+ sleep(0.1)
+
+ # Send NEC code
+ raw = nec_encode([0x00, 0xef, 0x03, 0xfc])
+ f.write(raw + "\n")
+ f.flush()