up info
This commit is contained in:
parent
65b0f86732
commit
7e0d21d627
@ -7,6 +7,9 @@ https://www.kradex.com.pl/product/enclosures_with_battery_basket/z62
|
||||
https://www.krabicky-pro-elektroniku.cz/plastova-krabicka-z62--cerna/
|
||||
|
||||
|
||||
### BLE Bluetooth UART - terminal
|
||||
https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal
|
||||
|
||||
|
||||
## Pi Pico
|
||||
|
||||
@ -17,7 +20,7 @@ pin1 OUT - Pi Pico pin 16
|
||||
pin2 VCC
|
||||
pin3 GND
|
||||
|
||||
IR TX TSAL6200
|
||||
IR TX TSAL6200 / TSAL6100
|
||||
|
||||
|
||||
### Pi Pico pin:
|
||||
@ -30,4 +33,5 @@ pin 20 - button
|
||||
pin 21 - button
|
||||
pin 22 - Red LED
|
||||
pin 26 - Green LED
|
||||
pin 27 - Blue LED
|
||||
pin 27 - Blue LED
|
||||
|
||||
|
@ -22,6 +22,10 @@ Pi Pico VSCode:
|
||||
https://randomnerdtutorials.com/raspberry-pi-pico-vs-code-micropython/
|
||||
|
||||
|
||||
## BLE Bluetooth UART - terminal
|
||||
https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal
|
||||
|
||||
|
||||
## install OpenLaserTag on Pi Pico W
|
||||
|
||||
### install primitives lib
|
||||
|
@ -1,11 +1,12 @@
|
||||
# IR_RX abstract base class for OpenLaserTag IR receiver.
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
|
||||
from machine import Timer, Pin
|
||||
from array import array
|
||||
from utime import ticks_us
|
||||
import uasyncio as asyncio
|
||||
|
||||
|
||||
class IR_RX:
|
||||
Timer_id = -1 # Software timer but enable override
|
||||
# Result/error codes
|
||||
@ -19,7 +20,9 @@ class IR_RX:
|
||||
BADDATA = -6
|
||||
BADADDR = -7
|
||||
|
||||
def __init__(self, pin, nedges, tblock, callback, *args): # Optional args for callback
|
||||
def __init__(
|
||||
self, pin, nedges, tblock, callback, *args
|
||||
): # Optional args for callback
|
||||
self._pin = pin
|
||||
self._nedges = nedges
|
||||
self._tblock = tblock
|
||||
@ -40,7 +43,9 @@ class IR_RX:
|
||||
# On overrun ignore pulses until software timer times out
|
||||
if self.edge <= self._nedges: # Allow 1 extra pulse to record overrun
|
||||
if not self.edge: # First edge received
|
||||
self.tim.init(period=self._tblock, mode=Timer.ONE_SHOT, callback=self.cb)
|
||||
self.tim.init(
|
||||
period=self._tblock, mode=Timer.ONE_SHOT, callback=self.cb
|
||||
)
|
||||
self._times[self.edge] = t
|
||||
self.edge += 1
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Acquire a pulse from OpenLaserTag IR remote
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
|
||||
from machine import Pin, freq
|
||||
from sys import platform
|
||||
@ -11,12 +11,13 @@ from ir_rx import IR_RX
|
||||
class IR_GET(IR_RX):
|
||||
def __init__(self, pin, nedges=100, twait=100, display=True):
|
||||
self.display = display
|
||||
super().__init__(pin, nedges, twait, lambda *_ : None)
|
||||
super().__init__(pin, nedges, twait, lambda *_: None)
|
||||
self.data = None
|
||||
|
||||
def decode(self, _):
|
||||
def near(v, target):
|
||||
return target * 0.8 < v < target * 1.2
|
||||
|
||||
lb = self.edge - 1 # Possible length of burst
|
||||
if lb < 3:
|
||||
return # Noise
|
||||
@ -32,50 +33,64 @@ class IR_GET(IR_RX):
|
||||
|
||||
if self.display:
|
||||
for x, e in enumerate(burst):
|
||||
print('{:03d} {:5d}'.format(x, e))
|
||||
print("{:03d} {:5d}".format(x, e))
|
||||
print()
|
||||
# Attempt to determine protocol
|
||||
ok = False # Protocol not yet found
|
||||
if near(burst[0], 9000) and lb == 67:
|
||||
print('NEC')
|
||||
print("NEC")
|
||||
ok = True
|
||||
|
||||
if not ok and near(burst[0], 2400) and near(burst[1], 600): # Maybe Sony
|
||||
try:
|
||||
nbits = {25:12, 31:15, 41:20}[lb]
|
||||
nbits = {25: 12, 31: 15, 41: 20}[lb]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
ok = True
|
||||
print('Sony {}bit'.format(nbits))
|
||||
print("Sony {}bit".format(nbits))
|
||||
|
||||
if not ok and near(burst[0], 889): # Maybe RC-5
|
||||
if near(duration, 24892) and near(max(burst), 1778):
|
||||
print('Philps RC-5')
|
||||
print("Philps RC-5")
|
||||
ok = True
|
||||
|
||||
if not ok and near(burst[0], 2666) and near(burst[1], 889): # RC-6?
|
||||
if near(duration, 22205) and near(burst[1], 889) and near(burst[2], 444):
|
||||
print('Philips RC-6 mode 0')
|
||||
if (
|
||||
near(duration, 22205)
|
||||
and near(burst[1], 889)
|
||||
and near(burst[2], 444)
|
||||
):
|
||||
print("Philips RC-6 mode 0")
|
||||
ok = True
|
||||
|
||||
if not ok and near(burst[0], 2000) and near(burst[1], 1000):
|
||||
if near(duration, 19000):
|
||||
print('Microsoft MCE edition protocol.')
|
||||
print("Microsoft MCE edition protocol.")
|
||||
# Constant duration, variable burst length, presumably bi-phase
|
||||
print('Protocol start {} {} Burst length {} duration {}'.format(burst[0], burst[1], lb, duration))
|
||||
print(
|
||||
"Protocol start {} {} Burst length {} duration {}".format(
|
||||
burst[0], burst[1], lb, duration
|
||||
)
|
||||
)
|
||||
ok = True
|
||||
|
||||
if not ok and near(burst[0], 4500) and near(burst[1], 4500) and lb == 67: # Samsung
|
||||
print('Samsung')
|
||||
if (
|
||||
not ok and near(burst[0], 4500) and near(burst[1], 4500) and lb == 67
|
||||
): # Samsung
|
||||
print("Samsung")
|
||||
ok = True
|
||||
|
||||
if not ok and near(burst[0], 3500) and near(burst[1], 1680): # Panasonic?
|
||||
print('Unsupported protocol. Panasonic?')
|
||||
print("Unsupported protocol. Panasonic?")
|
||||
ok = True
|
||||
|
||||
if not ok:
|
||||
print('Unknown protocol start {} {} Burst length {} duration {}'.format(burst[0], burst[1], lb, duration))
|
||||
print(
|
||||
"Unknown protocol start {} {} Burst length {} duration {}".format(
|
||||
burst[0], burst[1], lb, duration
|
||||
)
|
||||
)
|
||||
|
||||
print()
|
||||
self.data = burst
|
||||
@ -88,17 +103,18 @@ class IR_GET(IR_RX):
|
||||
self.close()
|
||||
return self.data
|
||||
|
||||
|
||||
def test():
|
||||
# Define pin according to platform
|
||||
if platform == 'pyboard':
|
||||
pin = Pin('X3', Pin.IN)
|
||||
elif platform == 'esp8266':
|
||||
if platform == "pyboard":
|
||||
pin = Pin("X3", Pin.IN)
|
||||
elif platform == "esp8266":
|
||||
freq(160000000)
|
||||
pin = Pin(13, Pin.IN)
|
||||
elif platform == 'esp32' or platform == 'esp32_LoBo':
|
||||
elif platform == "esp32" or platform == "esp32_LoBo":
|
||||
pin = Pin(23, Pin.IN)
|
||||
elif platform == 'rp2':
|
||||
elif platform == "rp2":
|
||||
pin = Pin(16, Pin.IN)
|
||||
irg = IR_GET(pin)
|
||||
print('Waiting for IR data...')
|
||||
print("Waiting for IR data...")
|
||||
return irg.acquire()
|
||||
|
@ -4,13 +4,14 @@
|
||||
from utime import ticks_us, ticks_diff
|
||||
from olt_lib.ir_rx import IR_RX
|
||||
|
||||
|
||||
# Bit reverse a 32 bit value
|
||||
def rbit32(v):
|
||||
v = (v & 0x0000ffff) << 16 | (v & 0xffff0000) >> 16
|
||||
v = (v & 0x00ff00ff) << 8 | (v & 0xff00ff00) >> 8
|
||||
v = (v & 0x0f0f0f0f) << 4 | (v & 0xf0f0f0f0) >> 4
|
||||
v = (v & 0x33333333) << 2 | (v & 0xcccccccc) >> 2
|
||||
return (v & 0x55555555) << 1 | (v & 0xaaaaaaaa) >> 1
|
||||
v = (v & 0x0000FFFF) << 16 | (v & 0xFFFF0000) >> 16
|
||||
v = (v & 0x00FF00FF) << 8 | (v & 0xFF00FF00) >> 8
|
||||
v = (v & 0x0F0F0F0F) << 4 | (v & 0xF0F0F0F0) >> 4
|
||||
v = (v & 0x33333333) << 2 | (v & 0xCCCCCCCC) >> 2
|
||||
return (v & 0x55555555) << 1 | (v & 0xAAAAAAAA) >> 1
|
||||
|
||||
|
||||
class SONY_ABC(IR_RX): # Abstract base class
|
||||
@ -26,13 +27,13 @@ class SONY_ABC(IR_RX): # Abstract base class
|
||||
def decode(self, _):
|
||||
try:
|
||||
nedges = self.edge # No. of edges detected
|
||||
self.verbose and print('nedges', nedges)
|
||||
self.verbose and print("nedges", nedges)
|
||||
if nedges > 50:
|
||||
raise RuntimeError(self.OVERRUN)
|
||||
bits = (nedges - 2) // 2
|
||||
if nedges not in (26, 32, 42, 50) or bits > self._bits:
|
||||
raise RuntimeError(self.BADBLOCK)
|
||||
self.verbose and print('SIRC {}bit'.format(bits))
|
||||
self.verbose and print("SIRC {}bit".format(bits))
|
||||
width = ticks_diff(self._times[1], self._times[0])
|
||||
if not 1800 < width < 3000: # 2.4ms leading mark for all valid data
|
||||
raise RuntimeError(self.BADSTART)
|
||||
@ -55,15 +56,15 @@ class SONY_ABC(IR_RX): # Abstract base class
|
||||
val = rbit32(val)
|
||||
val >>= 8
|
||||
packet = val
|
||||
byte3 = val & 0xff # 8 bit command
|
||||
byte3 = val & 0xFF # 8 bit command
|
||||
val >>= 8
|
||||
byte2 = val & 0xff # 8 bit command
|
||||
byte2 = val & 0xFF # 8 bit command
|
||||
val >>= 8
|
||||
byte1 = val & 0xff # 8 bit command
|
||||
#if nedges < 42:
|
||||
byte1 = val & 0xFF # 8 bit command
|
||||
# if nedges < 42:
|
||||
# addr = val & 0xff # 5 or 8 bit addr
|
||||
# val = 0
|
||||
#else:
|
||||
# else:
|
||||
# addr = val & 0x1f # 5 bit addr
|
||||
# val >>= 5 # 8 bit extended
|
||||
except RuntimeError as e:
|
||||
@ -71,21 +72,25 @@ class SONY_ABC(IR_RX): # Abstract base class
|
||||
byte1 = 0
|
||||
byte2 = 0
|
||||
byte3 = 0
|
||||
#packet = 0
|
||||
# packet = 0
|
||||
self.do_callback(byte1, byte2, byte3, packet)
|
||||
|
||||
|
||||
class SONY_12(SONY_ABC):
|
||||
def __init__(self, pin, callback, *args):
|
||||
super().__init__(pin, 12, callback, *args)
|
||||
|
||||
|
||||
class SONY_15(SONY_ABC):
|
||||
def __init__(self, pin, callback, *args):
|
||||
super().__init__(pin, 15, callback, *args)
|
||||
|
||||
|
||||
class SONY_20(SONY_ABC):
|
||||
def __init__(self, pin, callback, *args):
|
||||
super().__init__(pin, 20, callback, *args)
|
||||
|
||||
|
||||
class LT_24(SONY_ABC):
|
||||
def __init__(self, pin, callback, *args):
|
||||
super().__init__(pin, 24, callback, *args)
|
||||
|
@ -1,17 +1,20 @@
|
||||
# Error print for OpenLaserTag IR receiver
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
|
||||
from olt_lib.ir_rx import IR_RX
|
||||
|
||||
_errors = {IR_RX.BADSTART : 'Invalid start pulse',
|
||||
IR_RX.BADBLOCK : 'Error: bad block',
|
||||
IR_RX.BADREP : 'Error: repeat',
|
||||
IR_RX.OVERRUN : 'Error: overrun',
|
||||
IR_RX.BADDATA : 'Error: invalid data',
|
||||
IR_RX.BADADDR : 'Error: invalid address'}
|
||||
_errors = {
|
||||
IR_RX.BADSTART: "Invalid start pulse",
|
||||
IR_RX.BADBLOCK: "Error: bad block",
|
||||
IR_RX.BADREP: "Error: repeat",
|
||||
IR_RX.OVERRUN: "Error: overrun",
|
||||
IR_RX.BADDATA: "Error: invalid data",
|
||||
IR_RX.BADADDR: "Error: invalid address",
|
||||
}
|
||||
|
||||
|
||||
def print_error(data):
|
||||
if data in _errors:
|
||||
print(_errors[data])
|
||||
else:
|
||||
print('Unknown error code:', data)
|
||||
print("Unknown error code:", data)
|
||||
|
@ -1,5 +1,5 @@
|
||||
## test.py Test program for OpenLaserTag IR remote control decoder
|
||||
## Tomas Krejci [Njord]
|
||||
|
||||
|
||||
# Run this to characterise a remote.
|
||||
import ustruct
|
||||
@ -24,11 +24,13 @@ elif platform == "rp2":
|
||||
p = Pin(16, Pin.IN)
|
||||
|
||||
|
||||
|
||||
# User callback
|
||||
def cb(byte1, byte2, byte3, packet):
|
||||
print(f"byte1 0x{byte1:02x} byte2 0x{byte2:02x} byte3 0x{byte3:02x} packet 0x{packet:06x}")
|
||||
|
||||
print(
|
||||
f"byte1 0x{byte1:02x} byte2 0x{byte2:02x} byte3 0x{byte3:02x} packet 0x{packet:06x}"
|
||||
)
|
||||
|
||||
|
||||
def test(proto=0):
|
||||
classes = (LT_24, SONY_12, SONY_15, SONY_20)
|
||||
ir = classes[proto](p, cb) # Instantiate receiver
|
||||
|
@ -1,9 +1,10 @@
|
||||
# __init__.py Nonblocking OpenLaserTag IR transmitter
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
|
||||
from sys import platform
|
||||
ESP32 = platform == 'esp32' # Loboris not supported owing to RMT
|
||||
RP2 = platform == 'rp2'
|
||||
|
||||
ESP32 = platform == "esp32" # Loboris not supported owing to RMT
|
||||
RP2 = platform == "rp2"
|
||||
if ESP32:
|
||||
from machine import Pin, PWM
|
||||
from esp32 import RMT
|
||||
@ -20,9 +21,9 @@ import uasyncio as asyncio
|
||||
# micropython.alloc_emergency_exception_buf(100)
|
||||
|
||||
|
||||
|
||||
STOP = const(0) # End of data
|
||||
|
||||
|
||||
# IR abstract base class. Array holds periods in μs between toggling 36/38KHz
|
||||
# carrier on or off. Physical transmission occurs in an ISR context controlled
|
||||
# by timer 2 and timer 5. See TRANSMITTER.md for details of operation.
|
||||
@ -34,16 +35,18 @@ class IR:
|
||||
@classmethod
|
||||
def active_low(cls):
|
||||
if ESP32:
|
||||
raise ValueError('Cannot set active low on ESP32')
|
||||
raise ValueError("Cannot set active low on ESP32")
|
||||
cls._active_high = False
|
||||
cls._space = 100
|
||||
|
||||
def __init__(self, pin, cfreq, asize, duty, verbose):
|
||||
if ESP32:
|
||||
self._rmt = RMT(0, pin=pin, clock_div=80, tx_carrier = (cfreq, duty, 1))
|
||||
self._rmt = RMT(0, pin=pin, clock_div=80, tx_carrier=(cfreq, duty, 1))
|
||||
# 1μs resolution
|
||||
elif RP2: # PIO-based RMT-like device
|
||||
self._rmt = RP2_RMT(pin_pulse=None, carrier=(pin, cfreq, duty)) # 1μs resolution
|
||||
self._rmt = RP2_RMT(
|
||||
pin_pulse=None, carrier=(pin, cfreq, duty)
|
||||
) # 1μs resolution
|
||||
asize += 1 # Allow for possible extra space pulse
|
||||
else: # Pyboard
|
||||
if not IR._active_high:
|
||||
@ -55,7 +58,7 @@ class IR:
|
||||
self._duty = duty
|
||||
self._tim = Timer(5) # Timer 5 controls carrier on/off times
|
||||
self._tcb = self._cb # Pre-allocate
|
||||
self._arr = array('H', 0 for _ in range(asize)) # on/off times (μs)
|
||||
self._arr = array("H", (0 for _ in range(asize))) # on/off times (μs)
|
||||
self._mva = memoryview(self._arr)
|
||||
# Subclass interface
|
||||
self.verbose = verbose
|
||||
@ -91,22 +94,22 @@ class IR:
|
||||
t = ticks_us()
|
||||
if validate:
|
||||
if tx1 > self.valid[0] or tx1 < 0:
|
||||
raise ValueError('Address out of range', tx1)
|
||||
raise ValueError("Address out of range", tx1)
|
||||
if tx2 > self.valid[1] or tx2 < 0:
|
||||
raise ValueError('Data out of range', tx2)
|
||||
raise ValueError("Data out of range", tx2)
|
||||
if tx3 > self.valid[2] or tx3 < 0:
|
||||
raise ValueError('Toggle out of range', tx3)
|
||||
raise ValueError("Toggle out of range", tx3)
|
||||
self.aptr = 0 # Inital conditions for tx: index into array
|
||||
self.carrier = False
|
||||
await self.tx(tx1, tx2, tx3) # Subclass populates ._arr
|
||||
asyncio.create_task(self.trigger()) # Initiate transmission
|
||||
if self.timeit:
|
||||
dt = ticks_diff(ticks_us(), t)
|
||||
print('Time = {}μs'.format(dt))
|
||||
print("Time = {}μs".format(dt))
|
||||
|
||||
while self.busy():
|
||||
await asyncio.sleep_ms(1)
|
||||
#sleep_ms(1) # Ensure ._busy is set prior to return
|
||||
await asyncio.sleep_ms(1)
|
||||
# sleep_ms(1) # Ensure ._busy is set prior to return
|
||||
|
||||
# Subclass interface
|
||||
async def trigger(self): # Used by NEC to initiate a repeat frame
|
||||
@ -125,10 +128,10 @@ class IR:
|
||||
self._arr[self.aptr] = t
|
||||
self.aptr += 1
|
||||
self.carrier = not self.carrier # Keep track of carrier state
|
||||
self.verbose and print('append', t, 'carrier', self.carrier)
|
||||
self.verbose and print("append", t, "carrier", self.carrier)
|
||||
|
||||
def add(self, t): # Increase last time value (for biphase)
|
||||
assert t > 0
|
||||
self.verbose and print('add', t)
|
||||
self.verbose and print("add", t)
|
||||
# .carrier unaffected
|
||||
self._arr[self.aptr - 1] += t
|
||||
self._arr[self.aptr - 1] += t
|
||||
|
@ -1,34 +1,34 @@
|
||||
# Encoder for OpenLaserTag IR transmitter using synchronous code
|
||||
# Sony SIRC protocol.
|
||||
# on Sony SIRC protocol.
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
from micropython import const
|
||||
from olt_lib.ir_tx import IR
|
||||
|
||||
|
||||
# Bit reverse a 32 bit value
|
||||
def rbit32(v):
|
||||
v = (v & 0x0000ffff) << 16 | (v & 0xffff0000) >> 16
|
||||
v = (v & 0x00ff00ff) << 8 | (v & 0xff00ff00) >> 8
|
||||
v = (v & 0x0f0f0f0f) << 4 | (v & 0xf0f0f0f0) >> 4
|
||||
v = (v & 0x33333333) << 2 | (v & 0xcccccccc) >> 2
|
||||
return (v & 0x55555555) << 1 | (v & 0xaaaaaaaa) >> 1
|
||||
class LT_ABC(IR):
|
||||
v = (v & 0x0000FFFF) << 16 | (v & 0xFFFF0000) >> 16
|
||||
v = (v & 0x00FF00FF) << 8 | (v & 0xFF00FF00) >> 8
|
||||
v = (v & 0x0F0F0F0F) << 4 | (v & 0xF0F0F0F0) >> 4
|
||||
v = (v & 0x33333333) << 2 | (v & 0xCCCCCCCC) >> 2
|
||||
return (v & 0x55555555) << 1 | (v & 0xAAAAAAAA) >> 1
|
||||
|
||||
|
||||
class LT_ABC(IR):
|
||||
def __init__(self, pin, bits, freq, verbose):
|
||||
super().__init__(pin, freq, 3 + bits * 2, 40, verbose) # 30 -> 40
|
||||
super().__init__(pin, freq, 3 + bits * 2, 40, verbose) # 30 -> 40
|
||||
if bits != 24:
|
||||
raise ValueError('OLT only support 24 bits.')
|
||||
#if bits not in (20, 24):
|
||||
raise ValueError("OLT only support 24 bits.")
|
||||
# if bits not in (20, 24):
|
||||
# raise ValueError('bits must be 20 or 24.')
|
||||
self.bits = bits
|
||||
|
||||
|
||||
|
||||
async def tx(self, tx1, tx2, tx3):
|
||||
bits = self.bits
|
||||
v = tx3 & 0xff
|
||||
v |= (tx2 & 0xff) << 8
|
||||
v |= (tx1 & 0xff) << 16
|
||||
v = tx3 & 0xFF
|
||||
v |= (tx2 & 0xFF) << 8
|
||||
v |= (tx1 & 0xFF) << 16
|
||||
|
||||
v = rbit32(v)
|
||||
v = v >> 8
|
||||
@ -38,8 +38,10 @@ class LT_ABC(IR):
|
||||
self.append(1200 if v & 1 else 600, 600)
|
||||
v >>= 1
|
||||
|
||||
|
||||
# OLT specifies 56KHz
|
||||
class LT_24(LT_ABC):
|
||||
valid = (0xff, 0xff, 0xff) # Max tx1, tx2, tx3
|
||||
valid = (0xFF, 0xFF, 0xFF) # Max tx1, tx2, tx3
|
||||
|
||||
def __init__(self, pin, freq=56000, verbose=False):
|
||||
super().__init__(pin, 24, freq, verbose)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# A RMT-like class for the RP2.
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
|
||||
# There are two asm_pio programs, pulsetrain and irqtrain. Only the second is used.
|
||||
# Both operate on a FIFO containing times in μs. The first toggles a pin when a
|
||||
@ -14,6 +14,7 @@
|
||||
from machine import Pin, PWM
|
||||
import rp2
|
||||
|
||||
|
||||
# See above: this function is unused by the IR class.
|
||||
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW, autopull=True, pull_thresh=32)
|
||||
def pulsetrain():
|
||||
@ -60,7 +61,9 @@ class RP2_RMT:
|
||||
if pin_pulse is None:
|
||||
self.sm = rp2.StateMachine(sm_no, irqtrain, freq=sm_freq)
|
||||
else:
|
||||
self.sm = rp2.StateMachine(sm_no, pulsetrain, freq=sm_freq, set_base=pin_pulse)
|
||||
self.sm = rp2.StateMachine(
|
||||
sm_no, pulsetrain, freq=sm_freq, set_base=pin_pulse
|
||||
)
|
||||
self.apt = 0 # Array index
|
||||
self.arr = None # Array
|
||||
self.ict = None # Current IRQ count
|
||||
|
@ -1,12 +1,13 @@
|
||||
# ir_tx.test Test for nonblocking OpenLaserTag/SONY IR transmitter.
|
||||
# Sony SIRC protocol.
|
||||
# Tomas Krejci [Njord]
|
||||
|
||||
|
||||
# Implements a 2-button remote control on a Pyboard with auto repeat.
|
||||
from sys import platform
|
||||
ESP32 = platform == 'esp32'
|
||||
RP2 = platform == 'rp2'
|
||||
PYBOARD = platform == 'pyboard'
|
||||
|
||||
ESP32 = platform == "esp32"
|
||||
RP2 = platform == "rp2"
|
||||
PYBOARD = platform == "pyboard"
|
||||
if ESP32 or RP2:
|
||||
from machine import Pin
|
||||
else:
|
||||
@ -14,16 +15,19 @@ else:
|
||||
import uasyncio as asyncio
|
||||
from primitives.switch import Switch
|
||||
from primitives.delay_ms import Delay_ms
|
||||
|
||||
# Import all implemented classes
|
||||
from olt_lib.ir_tx.olt import LT_24, SONY_12, SONY_15, SONY_20
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
|
||||
# If button is held down normal behaviour is to retransmit
|
||||
# but most NEC models send a REPEAT code
|
||||
class Rbutton:
|
||||
toggle = 1 # toggle is ignored in NEC mode
|
||||
|
||||
def __init__(self, irb, pin, addr, data, proto):
|
||||
self.irb = irb
|
||||
self.sw = Switch(pin)
|
||||
@ -53,27 +57,28 @@ class Rbutton:
|
||||
tog = 0 # NEC, sony 12, 15: toggle==0
|
||||
self.irb.transmit(self.addr, self.data, tog, True) # Test validation
|
||||
|
||||
|
||||
async def main(proto):
|
||||
# Test uses a 56KHz carrier.
|
||||
if ESP32: # Pins for IR LED gate
|
||||
pin = Pin(23, Pin.OUT, value = 0)
|
||||
pin = Pin(23, Pin.OUT, value=0)
|
||||
elif RP2:
|
||||
pin = Pin(17, Pin.OUT, value = 0)
|
||||
pin = Pin(17, Pin.OUT, value=0)
|
||||
else:
|
||||
pin = Pin('X1')
|
||||
pin = Pin("X1")
|
||||
classes = (LT_24, SONY_12, SONY_15, SONY_20)
|
||||
irb = classes[proto](pin, 56000) # My decoder chip is 56KHz
|
||||
# Uncomment the following to print transmit timing
|
||||
irb.timeit = True
|
||||
|
||||
b = [] # Rbutton instances
|
||||
px3 = Pin('X3', Pin.IN, Pin.PULL_UP) if PYBOARD else Pin(18, Pin.IN, Pin.PULL_UP)
|
||||
px4 = Pin('X4', Pin.IN, Pin.PULL_UP) if PYBOARD else Pin(19, Pin.IN, Pin.PULL_UP)
|
||||
px3 = Pin("X3", Pin.IN, Pin.PULL_UP) if PYBOARD else Pin(18, Pin.IN, Pin.PULL_UP)
|
||||
px4 = Pin("X4", Pin.IN, Pin.PULL_UP) if PYBOARD else Pin(19, Pin.IN, Pin.PULL_UP)
|
||||
b.append(Rbutton(irb, px3, 0x1, 0x7, proto))
|
||||
b.append(Rbutton(irb, px4, 0x10, 0xb, proto))
|
||||
b.append(Rbutton(irb, px4, 0x10, 0xB, proto))
|
||||
if ESP32:
|
||||
while True:
|
||||
print('Running')
|
||||
print("Running")
|
||||
await asyncio.sleep(5)
|
||||
elif RP2:
|
||||
led = Pin(25, Pin.OUT)
|
||||
@ -86,39 +91,41 @@ async def main(proto):
|
||||
await asyncio.sleep_ms(500) # Obligatory flashing LED.
|
||||
led.toggle()
|
||||
|
||||
|
||||
# Greeting strings. Common:
|
||||
s = '''Test for IR transmitter. Run:
|
||||
s = """Test for IR transmitter. Run:
|
||||
from ir_tx.test import test
|
||||
test() for LT-24 protocol
|
||||
test(1) for Sony SIRC 12 bit
|
||||
test(2) for Sony SIRC 15 bit
|
||||
test(3) for Sony SIRC 20 bit
|
||||
'''
|
||||
"""
|
||||
|
||||
# Pyboard:
|
||||
spb = '''
|
||||
spb = """
|
||||
IR LED on pin X1
|
||||
Ground pin X3 to send addr 1 data 7
|
||||
Ground pin X4 to send addr 0x10 data 0x0b.'''
|
||||
Ground pin X4 to send addr 0x10 data 0x0b."""
|
||||
|
||||
# ESP32
|
||||
sesp = '''
|
||||
sesp = """
|
||||
IR LED gate on pin 23
|
||||
Ground pin 18 to send addr 1 data 7
|
||||
Ground pin 19 to send addr 0x10 data 0x0b.'''
|
||||
Ground pin 19 to send addr 0x10 data 0x0b."""
|
||||
|
||||
# RP2
|
||||
srp2 = '''
|
||||
srp2 = """
|
||||
IR LED gate on pin 17
|
||||
Ground pin 18 to send addr 1 data 7
|
||||
Ground pin 19 to send addr 0x10 data 0x0b.'''
|
||||
Ground pin 19 to send addr 0x10 data 0x0b."""
|
||||
|
||||
if ESP32:
|
||||
print(''.join((s, sesp)))
|
||||
print("".join((s, sesp)))
|
||||
elif RP2:
|
||||
print(''.join((s, srp2)))
|
||||
print("".join((s, srp2)))
|
||||
else:
|
||||
print(''.join((s, spb)))
|
||||
print("".join((s, spb)))
|
||||
|
||||
|
||||
def test(proto=0):
|
||||
loop.run_until_complete(main(proto))
|
||||
|
Loading…
Reference in New Issue
Block a user