045 - MicroPython TechNotes: Infrared Transmitter
Introduction
In this article, I will tackle how you can use an Infrared transmitter module with ESP32 using MicroPython. GorillaCell Infrared Transmitter module from GorillaCell ESP32 development kits uses an infrared transmitter LED. It is low cost and easy to use.
Bill Of Materials
-
ESP32 development board.
-
Gorillacell ESP32 shield.
-
3-pin female-female dupont wires.
-
Gorillacell Infrared Transmitter module.
Pinout
It has 3 pins namely: 1. G – for the ground pin. 2. V – for the supply voltage. 3. S – for the infrared transmitter signal pin.
Hardware Instruction
-
First, attach the ESP32 development board on top of the ESP32 shield and make sure that both the USB port are on the same side.
-
Next, attach the dupont wires to the Infrared Transmitter module by following the color coding that is black for the ground, red for the VCC, and yellow for the signal pin.
-
Next, attach the other end of the dupont wires to the ESP32 shield by matching the colors of the wires to the colors of the pin headers that is black is to black, red is to red, and yellow is to yellow pin headers. For this lesson, I choose GPIO 26 to serve as the output pin for the Infrared Transmitter module.
-
Next, power the ESP32 shield with an external power supply with a type-C USB connector and make sure that the power switch is set to ON state.
-
Lastly, connect the ESP32 to the computer using a micro-USB connector cable.
Software Instruction
-
Copy the ir_tx.py from the SOURCE CODE section and paste it to Thonny IDE.
-
Save it to MicroPython root directory by clicking the File menu and select Save As.
-
Select MicroPython Device.
-
And save it as ir_tx.py.
-
Copy other examples to Thonny IDE and run it accordingly.
-
Feel free to modify and adapt according to your needs.
Video Demonstration
Call To Action
If you have any concern regarding this video, please write your question in the comment box.
You might also liked to support my journey on Youtube by subscribing on my channel, TechToTinker. Click this to Subscribe.
Thank you and have a good days ahead.
See you, – George Bantique | tech.to.tinker@gmail.com
Source Code
1. Example # 1, basics of transferring Infrared data:
1# More details can be found in TechToTinker.blogspot.com
2# George Bantique | tech.to.tinker@gmail.com
3
4from machine import Pin
5from ir_tx import NEC
6
7nec = NEC(Pin(26, Pin.OUT, value = 0))
8
9#nec.transmit(<addr>, <data>)
2. Example # 2, basic application of Infrared transmitter:
1# George Bantique | tech.to.tinker@gmail.com
2
3from machine import Pin
4from ir_tx import NEC
5from time import sleep_ms
6
7nec = NEC(Pin(26, Pin.OUT, value = 0))
8sw = Pin(0, Pin.IN)
9
10while True:
11 if sw.value()==0:
12 nec.transmit(0x0000, 0x09)
13 sleep_ms(100)
3. micropython_ir Library of Peter Hinch, save it as ir_tx.py:
1# MIT License
2#
3# Copyright (c) 2020 Peter Hinch
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy
6# of this software and associated documentation files (the "Software"), to deal
7# in the Software without restriction, including without limitation the rights
8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9# copies of the Software, and to permit persons to whom the Software is
10# furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in all
13# copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE.
22
23# Author: Peter Hinch
24# Copyright Peter Hinch 2020-2021 Released under the MIT license
25# http://github.com/peterhinch/micropython_ir
26
27# __init__.py Nonblocking IR blaster
28# Runs on Pyboard D or Pyboard 1.x (not Pyboard Lite), ESP32 and RP2
29
30# Released under the MIT License (MIT). See LICENSE.
31
32# Copyright (c) 2020-2021 Peter Hinch
33from sys import platform
34from micropython import const
35ESP32 = platform == 'esp32' # Loboris not supported owing to RMT
36RP2 = platform == 'rp2'
37if ESP32:
38 from machine import Pin, PWM
39 from esp32 import RMT
40elif RP2:
41 from .rp2_rmt import RP2_RMT
42else:
43 from pyb import Pin, Timer # Pyboard does not support machine.PWM
44from esp32 import RMT
45from array import array
46from time import ticks_us
47from time import ticks_diff
48# import micropython
49# micropython.alloc_emergency_exception_buf(100)
50
51
52# Shared by NEC
53STOP = const(0) # End of data
54
55# IR abstract base class. Array holds periods in μs between toggling 36/38KHz
56# carrier on or off. Physical transmission occurs in an ISR context controlled
57# by timer 2 and timer 5. See TRANSMITTER.md for details of operation.
58class IR:
59 _active_high = True # Hardware turns IRLED on if pin goes high.
60 _space = 0 # Duty ratio that causes IRLED to be off
61 timeit = False # Print timing info
62
63 @classmethod
64 def active_low(cls):
65 if ESP32:
66 raise ValueError('Cannot set active low on ESP32')
67 cls._active_high = False
68 cls._space = 100
69
70 def __init__(self, pin, cfreq, asize, duty, verbose):
71 if ESP32:
72 self._rmt = RMT(0, pin=pin, clock_div=80, carrier_freq=cfreq,
73 carrier_duty_percent=duty) # 1μs resolution
74 elif RP2: # PIO-based RMT-like device
75 self._rmt = RP2_RMT(pin_pulse=None, carrier=(pin, cfreq, duty)) # 1μs resolution
76 else: # Pyboard
77 if not IR._active_high:
78 duty = 100 - duty
79 tim = Timer(2, freq=cfreq) # Timer 2/pin produces 36/38/40KHz carrier
80 self._ch = tim.channel(1, Timer.PWM, pin=pin)
81 self._ch.pulse_width_percent(self._space) # Turn off IR LED
82 # Pyboard: 0 <= pulse_width_percent <= 100
83 self._duty = duty
84 self._tim = Timer(5) # Timer 5 controls carrier on/off times
85 self._tcb = self._cb # Pre-allocate
86 self._arr = array('H', 0 for _ in range(asize)) # on/off times (μs)
87 self._mva = memoryview(self._arr)
88 # Subclass interface
89 self.verbose = verbose
90 self.carrier = False # Notional carrier state while encoding biphase
91 self.aptr = 0 # Index into array
92
93 def _cb(self, t): # T5 callback, generate a carrier mark or space
94 t.deinit()
95 p = self.aptr
96 v = self._arr[p]
97 if v == STOP:
98 self._ch.pulse_width_percent(self._space) # Turn off IR LED.
99 return
100 self._ch.pulse_width_percent(self._space if p & 1 else self._duty)
101 self._tim.init(prescaler=84, period=v, callback=self._tcb)
102 self.aptr += 1
103
104 # Public interface
105 # Before populating array, zero pointer, set notional carrier state (off).
106 def transmit(self, addr, data, toggle=0, validate=False): # NEC: toggle is unused
107 t = ticks_us()
108 if validate:
109 if addr > self.valid[0] or addr < 0:
110 raise ValueError('Address out of range', addr)
111 if data > self.valid[1] or data < 0:
112 raise ValueError('Data out of range', data)
113 if toggle > self.valid[2] or toggle < 0:
114 raise ValueError('Toggle out of range', toggle)
115 self.aptr = 0 # Inital conditions for tx: index into array
116 self.carrier = False
117 self.tx(addr, data, toggle) # Subclass populates ._arr
118 self.trigger() # Initiate transmission
119 if self.timeit:
120 dt = ticks_diff(ticks_us(), t)
121 print('Time = {}μs'.format(dt))
122
123 # Subclass interface
124 def trigger(self): # Used by NEC to initiate a repeat frame
125 if ESP32:
126 self._rmt.write_pulses(tuple(self._mva[0 : self.aptr]), start = 1)
127 elif RP2:
128 self.append(STOP)
129 self._rmt.send(self._arr)
130 else:
131 self.append(STOP)
132 self.aptr = 0 # Reset pointer
133 self._cb(self._tim) # Initiate physical transmission.
134
135 def append(self, *times): # Append one or more time peiods to ._arr
136 for t in times:
137 self._arr[self.aptr] = t
138 self.aptr += 1
139 self.carrier = not self.carrier # Keep track of carrier state
140 self.verbose and print('append', t, 'carrier', self.carrier)
141
142 def add(self, t): # Increase last time value (for biphase)
143 assert t > 0
144 self.verbose and print('add', t)
145 # .carrier unaffected
146 self._arr[self.aptr - 1] += t
147
148
149# Given an iterable (e.g. list or tuple) of times, emit it as an IR stream.
150class Player(IR):
151
152 def __init__(self, pin, freq=38000, verbose=False): # NEC specifies 38KHz
153 super().__init__(pin, freq, 68, 33, verbose) # Measured duty ratio 33%
154
155 def play(self, lst):
156 for x, t in enumerate(lst):
157 self._arr[x] = t
158 self.aptr = x + 1
159 self.trigger()
160
161
162_TBURST = const(563)
163_T_ONE = const(1687)
164
165class NEC(IR):
166 valid = (0xffff, 0xff, 0) # Max addr, data, toggle
167
168 def __init__(self, pin, freq=38000, verbose=False): # NEC specifies 38KHz
169 super().__init__(pin, freq, 68, 33, verbose) # Measured duty ratio 33%
170
171 def _bit(self, b):
172 self.append(_TBURST, _T_ONE if b else _TBURST)
173
174 def tx(self, addr, data, _): # Ignore toggle
175 self.append(9000, 4500)
176 if addr < 256: # Short address: append complement
177 addr |= ((addr ^ 0xff) << 8)
178 for _ in range(16):
179 self._bit(addr & 1)
180 addr >>= 1
181 data |= ((data ^ 0xff) << 8)
182 for _ in range(16):
183 self._bit(data & 1)
184 data >>= 1
185 self.append(_TBURST)
186
187 def repeat(self):
188 self.aptr = 0
189 self.append(9000, 2250, _TBURST)
190 self.trigger() # Initiate physical transmission.
References And Credits
-
Purchase your Gorillacell ESP32 development kits from: https://gorillacell.kr/
-
Peter Hinch micropython IR library: http://github.com/peterhinch/micropython_ir
Posts in this series
- 049 - MicroPython TechNotes: MP3 Player
- 048 - MicroPython TechNotes: Analog Touch Sensor
- 047 - MicroPython TechNotes: E108 GPS
- 046 - MicroPython TechNotes: RF433 Transceivers
- 044 - MicroPython TechNotes: Infrared Receiver
- 043 - MicroPython TechNotes: ESP12E WiFi | External WiFi module
- 042 - MicroPython TechNotes: JDY-32 | Bluetooth Low Energy BLE
- 041 - MicroPython TechNotes: Bluetooth HC-06
- 040 - MicroPython TechNotes: Relay
- 039 - MicroPython TechNotes: Electromagnet
- 038 - MicroPython TechNotes: Buzzer
- 037 - MicroPython TechNotes: Servo Motor
- 036 - MicroPython TechNotes: Stepper Motor
- 035 - MicroPython TechNotes: Dual Motor Driver
- 034 - MicroPython TechNotes: DC Motors | Gear Motor and Fan Motor
- 033 - MicroPython TechNotes: TCS34725 RGB Color Sensor
- 032 - MicroPython TechNotes: BMP280 Sensor
- 031 - MicroPython TechNotes: TOF Distance Sensor
- 030 - MicroPython TechNotes: DS3231 RTC
- 029 - MicroPython TechNotes: HC-SR04 Ultrasonic Sensor
- 028 - MicroPython TechNotes: DHT11 Temperature and Humidity Sensor
- 027 - MicroPython TechNotes: Rotary Encoder
- 026 - MicroPython TechNotes: Light Dependent Resistor (LDR)
- 025 - MicroPython TechNotes: Joystick
- 024 - MicroPython TechNotes: Slider Switch
- 023 - MicroPython TechNotes: Continuous Rotation Potentiometer
- 022 - MicroPython TechNotes: Potentiometer | Reading an Analog Input
- 021 - MicroPython TechNotes: Color Touch Sensor
- 020 - MicroPython TechNotes: Touch Sensor
- 019 - MicroPython TechNotes: Switch Module
- 018 - MicroPython TechNotes: Button | Reading an Input
- 017 - MicroPython TechNotes: LASER Module
- 016 - MicroPython TechNotes: RGB LED Matrix
- 015 - MicroPython TechNotes: Neopixel 16
- 014 - MicroPython TechNotes: 8x8 Dot Matrix Display (I2C)
- 013 - MicroPython TechNotes: 8x16 Dot Matrix Display (SPI)
- 012 - MicroPython TechNotes: 8x8 Dot Matrix Display (SPI)
- 011 - MicroPython TechNotes: 1.3 OLED Display
- 010 - MicroPython TechNotes: 0.96 OLED Display
- 009 - MicroPython TechNotes: 7 Segment Display
- 008 - MicroPython TechNotes: 16x2 LCD
- 007 - MicroPython TechNotes: RGB LED
- 006 - MicroPython TechNotes: Traffic Light LED Module
- 005 - MicroPython TechNotes: Gorilla Cell LED | MicroPython Hello World
- 004 - MicroPython TechNotes: Gorilla Cell I/O Devices
- 003 - MicroPython TechNotes: Gorillacell ESP32 Shield
- 002 - MicroPython TechNotes: Introduction for Gorillacell ESP32 Dev Kit
- 001 - MicroPython TechNotes: Get Started with MicroPython
- 000 - MicroPython TechNotes: Unboxing Gorillacell ESP32 Development Kit
No comments yet!