]>
vault307.fbx.one Git - micorpython_ir.git/blob - ir_tx.py
4a91336680394e324f9a9815a3156ce4dfd07448
1 # ir_tx.py Nonblocking IR blaster
2 # Runs on Pyboard D or Pyboard 1.x only (not Pyboard Lite)
4 # Released under the MIT License (MIT). See LICENSE.
6 # Copyright (c) 2020 Peter Hinch
8 from pyb
import Pin
, Timer
9 from micropython
import const
10 from array
import array
13 # micropython.alloc_emergency_exception_buf(100)
16 _SPACE
= const(0) # Or 100. Depends on wiring: 0 assumes logic 0 turns IR off.
17 _STOP
= const(0) # End of data
22 _T_RC5
= const(889) # Time for pulse of carrier
27 # IR abstract base class. Array holds periods in μs between toggling 36/38KHz
28 # carrier on or off. Physical transmission occurs in an ISR context controlled
29 # by timer 2 and timer 5. See README.md for details of operation.
32 def __init__(self
, pin
, freq
, asize
, duty
, verbose
):
33 tim
= Timer(2, freq
=freq
) # Timer 2/pin produces 36/38KHz carrier
34 self
._ch
= tim
.channel(1, Timer
.PWM
, pin
=pin
)
35 self
._ch
.pulse_width_percent(_SPACE
) # Turn off IR LED
36 self
._duty
= duty
if not _SPACE
else (100 - duty
)
37 self
._tim
= Timer(5) # Timer 5 controls carrier on/off times
38 self
._tcb
= self
.cb
# Pre-allocate
39 self
.verbose
= verbose
40 self
.arr
= array('H', 0 for _
in range(asize
)) # on/off times (μs)
41 self
.carrier
= False # Notional carrier state while encoding biphase
42 self
.aptr
= 0 # Index into array
44 # Before populating array, zero pointer, set notional carrier state (off).
45 def transmit(self
, addr
, data
, toggle
=0): # NEC: toggle is unused
46 self
.aptr
= 0 # Inital conditions for tx: index into array
48 self
.tx(addr
, data
, toggle
)
50 self
.aptr
= 0 # Reset pointer
51 self
.cb(self
._tim
) # Initiate physical transmission.
53 def cb(self
, t
): # T5 callback, generate a carrier mark or space
58 self
._ch
.pulse_width_percent(_SPACE
) # Turn off IR LED.
60 self
._ch
.pulse_width_percent(_SPACE
if p
& 1 else self
._duty
)
61 self
._tim
.init(prescaler
=84, period
=v
, callback
=self
._tcb
)
64 def append(self
, *times
): # Append one or more time peiods to .arr
66 self
.arr
[self
.aptr
] = t
68 self
.carrier
= not self
.carrier
# Keep track of carrier state
69 self
.verbose
and print('append', t
, 'carrier', self
.carrier
)
71 def add(self
, t
): # Increase last time value
72 self
.verbose
and print('add', t
)
73 self
.arr
[self
.aptr
- 1] += t
# Carrier unaffected
78 def __init__(self
, pin
, freq
=38000, verbose
=False): # NEC specifies 38KHz
79 super().__init
__(pin
, freq
, 68, 50, verbose
)
82 self
.append(_TBURST
, _T_ONE
if b
else _TBURST
)
84 def tx(self
, addr
, data
, _
): # Ignore toggle
85 self
.append(9000, 4500)
86 if addr
< 256: # Short address: append complement
87 addr |
= ((addr ^
0xff) << 8)
91 data |
= ((data ^
0xff) << 8)
99 self
.append(9000, 2250, _TBURST
, _STOP
)
100 self
.aptr
= 0 # Reset pointer
101 self
.cb(self
._tim
) # Initiate physical transmission.
106 def __init__(self
, pin
, bits
=12, freq
=40000, verbose
=False): # Sony specifies 40KHz
107 super().__init
__(pin
, freq
, 3 + bits
* 2, 30, verbose
)
108 if bits
not in (12, 15, 20):
109 raise ValueError('bits must be 12, 15 or 20.')
112 def tx(self
, addr
, data
, ext
):
113 self
.append(2400, 600)
117 v |
= (addr
& 0x1f) << 7
119 v |
= (addr
& 0xff) << 7
121 v |
= (addr
& 0x1f) << 7
122 v |
= (ext
& 0xff) << 12
123 for _
in range(bits
):
124 self
.append(1200 if v
& 1 else 600, 600)
128 # Philips RC5 protocol
131 def __init__(self
, pin
, freq
=36000, verbose
=False):
132 super().__init
__(pin
, freq
, 28, 30, verbose
)
134 def tx(self
, addr
, data
, toggle
):
135 d
= (data
& 0x3f) |
((addr
& 0x1f) << 6) |
((data
& 0x40) << 6) |
((toggle
& 1) << 11)
136 self
.verbose
and print(bin(d
))
143 if bit ^ self
.carrier
:
147 self
.append(_T_RC5
, _T_RC5
)
150 # Philips RC6 mode 0 protocol
153 def __init__(self
, pin
, freq
=36000, verbose
=False):
154 super().__init
__(pin
, freq
, 44, 30, verbose
)
156 def tx(self
, addr
, data
, toggle
):
158 self
.append(2666, _T2_RC6
, _T_RC6
, _T2_RC6
, _T_RC6
, _T_RC6
, _T_RC6
, _T_RC6
, _T_RC6
)
159 # Append a single bit of twice duration
164 self
.append(_T2_RC6
, _T2_RC6
)
165 d
= (data
& 0xff) |
((addr
& 0xff) << 8)
167 self
.verbose
and print('toggle', toggle
, self
.carrier
, bool(d
& mask
))
170 if bit ^ self
.carrier
:
171 self
.append(_T_RC6
, _T_RC6
)