From 12683170548778e5d933f2f2052164547cc15113 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Tue, 23 Feb 2021 15:03:48 +0000 Subject: [PATCH] Transmitter: ESP32 uses RMT to generate carrier. Test program updated for uasyncio V3 --- TRANSMITTER.md | 49 ++++++++++++++++++++++------------------------- ir_tx/__init__.py | 7 ++----- ir_tx/test.py | 7 ++++--- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/TRANSMITTER.md b/TRANSMITTER.md index 3e3290e..7a70cca 100644 --- a/TRANSMITTER.md +++ b/TRANSMITTER.md @@ -13,8 +13,8 @@ On the Pyboard the transmitter test script assumes pin X1 for IR output. It can be changed, but it must support Timer 2 channel 1. Pins for pushbutton inputs are arbitrary: X3 and X4 are used. The driver uses timers 2 and 5. -On ESP32 the demo uses pins 21 and 23 for IR output and pins 18 and 19 for -pushbuttons. These pins may be changed. +On ESP32 the demo uses pin 23 for IR output and pins 18 and 19 for pushbuttons. +These pins may be changed. The only device resource used is `RMT(0)`. ## 1.1 Pyboard Wiring @@ -30,20 +30,16 @@ increase power. The transistor type is not critical. The driver assumes circuits as shown. Here the carrier "off" state is 0V, -which is the driver default. If using a circuit where "off" is required to be -3.3V, the class variable `active_high` should be set `False`. +which is the driver default. If using an alternative circuit where "off" is +required to be 3.3V, the class variable `active_high` should be set `False`. ## 1.2 ESP32 Wiring -The ESP32 RMT device does not currently support the carrier option. A simple -hardware gate is required to turn the IR LED on when both the carrier pin and -the RMT pin are high. A suitable circuit is below; the transistor type is not -critical. -![Image](images/gate.png) - -This simpler alternative uses MOSFETS, but the device type needs attention. The -chosen type has a low gate-source threshold voltage and low Rdson. -![Image](images/gate_mosfet.png) +The ESP32 RMT device now supports the carrier option, and this driver has been +updated to use it. The same circuits as above may be used to connect to pin 23 +(or other pin, if the code has been adapted). The `active_high` option is not +available on the ESP32 `RMT` object, so any alternative circuit must illuminate +the LED if the pin state is high. # 2. Dependencies and installation @@ -51,11 +47,17 @@ chosen type has a low gate-source threshold voltage and low Rdson. The device driver has no dependencies. -On ESP32 a firmware version >= V1.12 is required. The Loboris port is not -supported owing to the need for the RMT device. +On ESP32 a firmware version >= V1.14 is required. The Loboris port is not +supported owing to the need for the RMT device and other issues. -The demo program requires `uasyncio` from the official library and `aswitch.py` -from [this repo](https://github.com/peterhinch/micropython-async). +The demo program uses `uasyncio` primitives from +[this repo](https://github.com/peterhinch/micropython-async). Clone the repo to +a directory on your PC: +```bash +$ git clone https://github.com/peterhinch/micropython-async +``` +move to its `v3` directory, and copy the `primitives` directory with its +contents to the filesystem. ## 2.2 Installation @@ -96,8 +98,7 @@ Basic usage on ESP32: ```python from machine import Pin from ir_tx.nec import NEC -pins = (Pin(23, Pin.OUT, value = 0), Pin(21, Pin.OUT, value = 0)) -nec = NEC(pins) +nec = NEC(Pin(23, Pin.OUT, value = 0)) nec.transmit(1, 2) # address == 1, data == 2 ``` @@ -269,13 +270,9 @@ transmission by calling the Timer5 callback. ## 4.2 ESP32 -The carrier is output continuously at the specified duty ratio. A pulse train -generated by the RMT instance drives a hardware gate such that the IR LED is -lit only when both carrier and RMT are high. - -The carrier is generated by PWM instance `.pwm` running continuously. The ABC -constructor converts the 0-100 duty ratio specified by the subclass to the -0-1023 range used by ESP32. +The RMT class now supports `carrier_freq` and `carrier_duty_percent` +constructor args, so the base class `IR` (in `__init__.py`) uses these to +enable the OOK (on-off keying) waveform. The `.trigger` method calls `RMT.write_pulses` and returns with `RMT` operating in the background. diff --git a/ir_tx/__init__.py b/ir_tx/__init__.py index ab16627..d6c8429 100644 --- a/ir_tx/__init__.py +++ b/ir_tx/__init__.py @@ -40,11 +40,8 @@ class IR: def __init__(self, pin, cfreq, asize, duty, verbose): if ESP32: - self._pwm = PWM(pin[0]) # Continuous 36/38/40KHz carrier - self._pwm.deinit() - # ESP32: 0 <= duty <= 1023 - self._pwm.init(freq=cfreq, duty=round(duty * 10.23)) - self._rmt = RMT(0, pin=pin[1], clock_div=80) # 1μs resolution + self._rmt = RMT(0, pin=pin, clock_div=80, carrier_freq=cfreq, + carrier_duty_percent=duty) # 1μs resolution else: # Pyboard if not IR._active_high: duty = 100 - duty diff --git a/ir_tx/test.py b/ir_tx/test.py index c3a0ab8..c1961fd 100644 --- a/ir_tx/test.py +++ b/ir_tx/test.py @@ -12,7 +12,8 @@ if ESP32: else: from pyb import Pin, LED import uasyncio as asyncio -from aswitch import Switch, Delay_ms +from primitives.switch import Switch +from primitives.delay_ms import Delay_ms # Import all implemented classes from ir_tx.nec import NEC from ir_tx.sony import SONY_12, SONY_15, SONY_20 @@ -59,7 +60,7 @@ class Rbutton: async def main(proto): # Test uses a 38KHz carrier. if ESP32: # Pins for IR LED gate - pin = (Pin(23, Pin.OUT, value = 0), Pin(21, Pin.OUT, value = 0)) + pin = Pin(23, Pin.OUT, value = 0) else: pin = Pin('X1') classes = (NEC, SONY_12, SONY_15, SONY_20, RC5, RC6_M0) @@ -101,7 +102,7 @@ Ground pin X4 to send addr 0x10 data 0x0b.''' # ESP32 sesp = ''' -IR LED gate on pins 23, 21 +IR LED gate on pin 23 Ground pin 18 to send addr 1 data 7 Ground pin 19 to send addr 0x10 data 0x0b.''' -- 2.47.3