Once you've finished setting up your QT Py RP2040 with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the Download Project Bundle button in the window below. It will download as a zipped folder.

# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT

import array
import pulseio
import board
from digitalio import DigitalInOut, Direction, Pull
from adafruit_debouncer import Debouncer
import neopixel

#  button setup with Debouncer
pin = DigitalInOut(board.A2)
pin.direction = Direction.INPUT
pin.pull = Pull.UP
button = Debouncer(pin)

#  button LED
led = DigitalInOut(board.A1)
led.direction = Direction.OUTPUT

#  onboard neopixel
pix = board.NEOPIXEL
num_pixels = 1
pixel = neopixel.NeoPixel(pix, num_pixels, brightness=0.8, auto_write=False)

#  PWM setup for IR LEDs
remote = pulseio.PulseOut(board.TX, frequency=38000, duty_cycle=2**15)
#  power on pulse array
# Prevent black from reformatting the arrays.
# fmt: off
power_on = array.array('H', [9027, 4490, 577, 563, 549, 1677, 579, 1674, 582, 558,
                             554, 559, 553, 561, 551, 562, 551, 1675, 580, 1674, 572,
                             567, 555, 1672, 573, 567, 556, 558, 554, 559, 553, 560,
                             552, 562, 550, 1675, 581, 560, 552, 561, 552, 561, 551,
                             563, 549, 1677, 579, 1674, 581, 560, 552, 561, 552, 1674,
                             581, 1673, 573, 1680, 575, 1679, 577, 563, 549, 565, 547,
                             1679, 577])
#  power off pulse array
power_off = array.array('H', [9028, 4491, 576, 563, 549, 1678, 578, 1701, 554, 533,
                              579, 561, 551, 562, 551, 536, 576, 1703, 552, 1700, 556,
                              558, 554, 1698, 547, 540, 582, 558, 554, 532, 580, 560,
                              552, 561, 552, 562, 550, 563, 549, 564, 548, 565, 547,
                              566, 546, 1707, 549, 1704, 551, 562, 550, 1703, 553, 1699,
                              556, 1697, 548, 1705, 551, 1701, 554, 560, 553, 560, 552,
                              1701, 554])
# fmt: on
#  array of the pulses
signals = [power_on, power_off]
#  neopixel colors
RED = (255, 0, 0)
GREEN = (0, 255, 0)
#  array of colors
colors = [GREEN, RED]
#  index variable
s = 0

while True:
    #  scan button for update
    button.update()
    #  if the button is pressed..
    if button.fell:
        #  send the pulse
        remote.send(signals[s])
        #  update onboard neopixel
        pixel.fill(colors[s])
        pixel.show()
        #  turn on button LED
        led.value = True
        #  advance the index variable
        s = (s + 1) % 2
    #  if the button is released..
    if button.rose:
        #  turn off the button LED
        led.value = False

Upload the Code and Libraries to the QT Py RP2040

After downloading the Project Bundle, plug your QT Py RP2040 into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the QT Py RP2040's CIRCUITPY drive. 

  • lib folder
  • code.py

Your QT Py RP2040 CIRCUITPY drive should look like this after copying the lib folder and the code.py file.

CIRCUITPY
The default IR pulse arrays in the code will probably not work with your TV. You will need to decode your TV remote's IR pulse arrays and update the CircuitPython code.

Decode Your Pulses

Each remote command for your TV is stored in an array of IR pulses. Follow along with this guide page for the IR sensor to decode your remote's pulses. Once you decode the arrays that you want your owl to send from your TV remote, then you can update the CircuitPython code to work with your TV.

How the CircuitPython Code Works

The code stores two IR pulse arrays: one for powering on the TV and one for powering it off. These arrays are stored in the signals list for use in the loop. The colors array is setup with GREEN and RED NeoPixel colors. The onboard NeoPixel will change color depending on which IR command was sent.

You'll edit the power_on and power_off arrays with your decoded IR pulses so that the code will work with your TV.

remote = pulseio.PulseOut(pwm)
#  power on pulse array
power_on = array.array('H', [9027, 4490, 577, 563, 549, 1677, 579, 1674, 582, 558,
                             554, 559, 553, 561, 551, 562, 551, 1675, 580, 1674, 572,
                             567, 555, 1672, 573, 567, 556, 558, 554, 559, 553, 560,
                             552, 562, 550, 1675, 581, 560, 552, 561, 552, 561, 551,
                             563, 549, 1677, 579, 1674, 581, 560, 552, 561, 552, 1674,
                             581, 1673, 573, 1680, 575, 1679, 577, 563, 549, 565, 547,
                             1679, 577])
#  power off pulse array
power_off = array.array('H', [9028, 4491, 576, 563, 549, 1678, 578, 1701, 554, 533,
                              579, 561, 551, 562, 551, 536, 576, 1703, 552, 1700, 556,
                              558, 554, 1698, 547, 540, 582, 558, 554, 532, 580, 560,
                              552, 561, 552, 562, 550, 563, 549, 564, 548, 565, 547,
                              566, 546, 1707, 549, 1704, 551, 562, 550, 1703, 553, 1699,
                              556, 1697, 548, 1705, 551, 1701, 554, 560, 553, 560, 552,
                              1701, 554])
#  array of the pulses
signals = [power_on, power_off]
#  neopixel colors
RED = (255, 0, 0)
GREEN = (0, 255, 0)
#  array of colors
colors = [GREEN, RED]

The Loop

In the loop, s is used as the index variable and either has a value of 0 or 1. When the button is pressed, the IR LEDs alternate between sending out the power_on or power_off pulse arrays. The onboard NeoPixel is green when power_on has been sent and red when power_off has been sent.

#  if the button is pressed..
    if button.fell:
        #  send the pulse
        remote.send(signals[s])
        #  update onboard neopixel
        pixel.fill(colors[s])
        pixel.show()
        #  turn on button LED
        led.value = True
        #  advance the index variable
        s = (s + 1) % 2

This guide was first published on Jul 13, 2022. It was last updated on Mar 27, 2024.

This page (Code the Owl IR TV Remote) was last updated on Mar 27, 2024.

Text editor powered by tinymce.