Skip to content

Commit db0d522

Browse files
IR Remote: make it work
1 parent 78ae1a0 commit db0d522

5 files changed

Lines changed: 125 additions & 6 deletions

File tree

internal_filesystem/apps/com.micropythonos.ir_remote/assets/ir/ir_rx/acquire.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ def near(v, target):
2323
return target * 0.8 < v < target * 1.2
2424
lb = self.edge - 1 # Possible length of burst
2525
if lb < 3:
26+
print("lb < 3 so it's noise")
27+
self.do_callback(0, 0, 0) # resets the state
2628
return # Noise
2729
burst = []
2830
for x in range(lb):

internal_filesystem/apps/com.micropythonos.ir_remote/assets/ir/ir_rx/nec.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ def __init__(self, pin, extended, samsung, callback, *args):
1919
self._leader = 2500 if samsung else 4000 # 4.5ms for Samsung else 9ms
2020

2121
def decode(self, _):
22-
print("ir_rx nec.py trying to decode")
22+
print("ir_rx nec.py decoding burst")
23+
lb = self.edge - 1 # Possible length of burst
24+
# Convert absolute timings to relative timings for later retrieval:
25+
self.burst = []
26+
for x in range(lb):
27+
dt = ticks_diff(self._times[x + 1], self._times[x])
28+
if x > 0 and dt > 10000: # Reached gap between repeats
29+
break
30+
self.burst.append(dt)
31+
print(f"burst: {self.burst}")
2332
try:
2433
if self.edge > 68:
2534
raise RuntimeError(self.OVERRUN)

internal_filesystem/apps/com.micropythonos.ir_remote/assets/ir_remote.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from mpos.ui.display_metrics import DisplayMetrics
66

77
from learn_ir import LearnIR
8+
from learn_nec_ir import LearnNECIR
89

910
try:
1011
from machine import Pin
@@ -36,7 +37,7 @@ class IRRemote(Activity):
3637
"Optoma": {
3738
"protocol": "nec",
3839
"addr": 50,
39-
"power": [2],
40+
"power": [129],
4041
"vol_up": [17],
4142
"vol_down": [20],
4243
"samsung": False,
@@ -124,13 +125,21 @@ def _open_settings(self, event):
124125
"default_value": self.DEFAULT_PROFILE,
125126
},
126127
{
127-
"title": "Learn IR",
128+
"title": "Print IR timings",
128129
"key": "learn_ir",
129130
"dont_persist": True,
130131
"ui": "activity",
131132
"activity_class": LearnIR,
132133
"placeholder": "Receive and decode IR signals (needs receiver diode)",
133134
},
135+
{
136+
"title": "Decode and print NEC IR",
137+
"key": "learn_nec_ir",
138+
"dont_persist": True,
139+
"ui": "activity",
140+
"activity_class": LearnNECIR,
141+
"placeholder": "Receive and decode NEC IR signals (needs receiver diode)",
142+
},
134143
],
135144
)
136145
self.startActivity(intent)

internal_filesystem/apps/com.micropythonos.ir_remote/assets/learn_ir.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class LearnIR(Activity):
2020
status = None
2121
screen = None
2222

23+
check_timer = None
24+
2325
def onCreate(self):
2426
print("learn_ir.py")
2527
self.screen = lv.obj()
@@ -29,32 +31,47 @@ def onCreate(self):
2931

3032
def onResume(self, screen):
3133
super().onResume(screen)
34+
import mpos.ui
35+
mpos.ui.change_task_handler(100) # needed for accurate timings
3236
if simulation_mode:
3337
print("IR receiver not available; running in simulation mode.")
3438
self.ir = None
3539
return
3640
try:
37-
self.ir = SAMSUNG(IRManager.rxPin, self._on_ir)
38-
#self.ir = NEC_16(IRManager.rxPin, self._on_ir)
39-
#self.ir = IR_GET(IRManager.rxPin)
41+
self.ir = IR_GET(IRManager.rxPin, display=False)
4042
except Exception as e:
4143
print(f"Failed to init IR receiver: {e}")
4244
self.ir = None
45+
self.check_timer = lv.timer_create(self.check_data, 1000, None)
4346

4447
def onPause(self, screen):
48+
if self.check_timer is not None:
49+
self.check_timer.delete()
50+
self.check_timer = None
4551
if getattr(self, "ir", None):
4652
try:
4753
self.ir.close()
4854
except Exception as e:
4955
print(f"Failed to close IR receiver: {e}")
5056
self.ir = None
57+
import mpos.ui
58+
mpos.ui.change_task_handler() # back to default
59+
60+
def check_data(self, args):
61+
if self.ir.data is not None:
62+
print(self.ir.data)
63+
self.add_data(self.ir.data)
64+
self.ir.data = None
5165

5266
def _on_ir(self, data, addr, ctrl):
5367
if data < 0:
5468
line = "Repeat code."
5569
else:
5670
line = f"Data 0x{data:02x} Addr 0x{addr:04x} Ctrl 0x{ctrl:02x}"
5771
print(line)
72+
self.add_data(line)
73+
74+
def add_data(self, line):
5875
current = self.status.get_text() if self.status else ""
5976
if current:
6077
current = f"{current}\n{line}"
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import lvgl as lv
2+
3+
from mpos import Activity, IRManager
4+
5+
try:
6+
from machine import Pin
7+
from ir.ir_rx.nec import SAMSUNG
8+
9+
simulation_mode = False
10+
except Exception as e:
11+
print(f"Activating simulation mode because could not import Pin/SAMSUNG: {e}")
12+
simulation_mode = True
13+
Pin = None
14+
SAMSUNG = None
15+
16+
class LearnNECIR(Activity):
17+
18+
status = None
19+
screen = None
20+
21+
check_timer = None
22+
23+
def onCreate(self):
24+
print("learn_ir.py")
25+
self.screen = lv.obj()
26+
self.status = lv.label(self.screen)
27+
self.status.set_text("Listening for NEC IR data...")
28+
self.setContentView(self.screen)
29+
30+
def onResume(self, screen):
31+
super().onResume(screen)
32+
import mpos.ui
33+
mpos.ui.change_task_handler(100) # needed for accurate timings
34+
if simulation_mode:
35+
print("IR receiver not available; running in simulation mode.")
36+
self.ir = None
37+
return
38+
try:
39+
# not 16 bit has more failure possibility and 'samsung' variant has a smaller "leader" (otherwise it refuses)
40+
# so NEC_16 is the most generic:
41+
self.ir = NEC_16(IRManager.rxPin, self._on_ir)
42+
except Exception as e:
43+
print(f"Failed to init IR receiver: {e}")
44+
self.ir = None
45+
#self.check_timer = lv.timer_create(self.check_data, 1000, None)
46+
47+
def onPause(self, screen):
48+
if self.check_timer is not None:
49+
self.check_timer.delete()
50+
self.check_timer = None
51+
if getattr(self, "ir", None):
52+
try:
53+
self.ir.close()
54+
except Exception as e:
55+
print(f"Failed to close IR receiver: {e}")
56+
self.ir = None
57+
import mpos.ui
58+
mpos.ui.change_task_handler() # back to default
59+
60+
def check_data(self, args):
61+
if self.ir.data is not None:
62+
print(self.ir.data)
63+
self.add_data(self.ir.data)
64+
self.ir.data = None
65+
66+
def _on_ir(self, data, addr, ctrl):
67+
if data < 0:
68+
line = "Repeat code."
69+
else:
70+
line = f"Data 0x{data:02x} Addr 0x{addr:04x} Ctrl 0x{ctrl:02x}"
71+
print(line)
72+
self.add_data(line)
73+
74+
def add_data(self, line):
75+
current = self.status.get_text() if self.status else ""
76+
if current:
77+
current = f"{current}\n{line}"
78+
else:
79+
current = line
80+
if self.status:
81+
self.status.set_text(current)
82+

0 commit comments

Comments
 (0)