]>
vault307.fbx.one Git - micorpython_ir.git/blob - ir_tx/__init__.py
6fe771048d3d535c921d6aec0185580b70609f0f
1 # __init__.py Nonblocking IR blaster
2 # Runs on Pyboard D or Pyboard 1.x (not Pyboard Lite) and ESP32
4 # Released under the MIT License (MIT). See LICENSE.
6 # Copyright (c) 2020 Peter Hinch
7 from sys
import platform
8 ESP32
= platform
== 'esp32' # Loboris not supported owing to RMT
10 from machine
import Pin
, PWM
13 from pyb
import Pin
, Timer
# Pyboard does not support machine.PWM
15 from micropython
import const
16 from array
import array
19 # micropython.alloc_emergency_exception_buf(100)
21 # ABC and Pyboard only: ESP32 ignores this value.
22 # Duty ratio in carrier off state: if driver is such that 3.3V turns the LED
23 # off, set _SPACE = 100
25 # On ESP32 gate hardware design is led_on = rmt and carrier
28 STOP
= const(0) # End of data
30 # IR abstract base class. Array holds periods in μs between toggling 36/38KHz
31 # carrier on or off. Physical transmission occurs in an ISR context controlled
32 # by timer 2 and timer 5. See README.md for details of operation.
35 def __init__(self
, pin
, cfreq
, asize
, duty
, verbose
):
37 self
._pwm
= PWM(pin
[0]) # Continuous 36/38/40KHz carrier
39 # ESP32: 0 <= duty <= 1023
40 self
._pwm
.init(freq
=cfreq
, duty
=round(duty
* 10.23))
41 self
._rmt
= RMT(0, pin
=pin
[1], clock_div
=80) # 1μs resolution
43 tim
= Timer(2, freq
=cfreq
) # Timer 2/pin produces 36/38/40KHz carrier
44 self
._ch
= tim
.channel(1, Timer
.PWM
, pin
=pin
)
45 self
._ch
.pulse_width_percent(_SPACE
) # Turn off IR LED
46 # Pyboard: 0 <= pulse_width_percent <= 100
47 self
._duty
= duty
if not _SPACE
else (100 - duty
)
48 self
._tim
= Timer(5) # Timer 5 controls carrier on/off times
49 self
._tcb
= self
._cb
# Pre-allocate
50 self
._arr
= array('H', 0 for _
in range(asize
)) # on/off times (μs)
51 self
._mva
= memoryview(self
._arr
)
53 self
.verbose
= verbose
54 self
.carrier
= False # Notional carrier state while encoding biphase
55 self
.aptr
= 0 # Index into array
57 def _cb(self
, t
): # T5 callback, generate a carrier mark or space
62 self
._ch
.pulse_width_percent(_SPACE
) # Turn off IR LED.
64 self
._ch
.pulse_width_percent(_SPACE
if p
& 1 else self
._duty
)
65 self
._tim
.init(prescaler
=84, period
=v
, callback
=self
._tcb
)
69 # Before populating array, zero pointer, set notional carrier state (off).
70 def transmit(self
, addr
, data
, toggle
=0): # NEC: toggle is unused
71 self
.aptr
= 0 # Inital conditions for tx: index into array
73 self
.tx(addr
, data
, toggle
) # Subclass populates ._arr
74 self
.trigger() # Initiate transmission
77 def trigger(self
): # Used by NEC to initiate a repeat frame
79 self
._rmt
.write_pulses(tuple(self
._mva
[0 : self
.aptr
]), start
= 1)
82 self
.aptr
= 0 # Reset pointer
83 self
._cb
(self
._tim
) # Initiate physical transmission.
85 def append(self
, *times
): # Append one or more time peiods to ._arr
87 self
._arr
[self
.aptr
] = t
89 self
.carrier
= not self
.carrier
# Keep track of carrier state
90 self
.verbose
and print('append', t
, 'carrier', self
.carrier
)
92 def add(self
, t
): # Increase last time value (for biphase)
94 self
.verbose
and print('add', t
)
96 self
._arr
[self
.aptr
- 1] += t