Text Editor
Adafruit recommends using the Mu editor for editing your CircuitPython code. You can get more info in this guide.
Alternatively, you can use any text editor that saves simple text files.
Download the Project Bundle
Your project will use a specific set of CircuitPython libraries, .txt files, and the code.py file. To get everything you need, click on the Download Project Bundle link below, and uncompress the .zip file.
Plug the Circuit Playground into your computer via a known good data+power USB cable. Your board should show up in your File Explorer/Finder (depending on your Operating System) as a thumb drive named CIRCUITPY.
Drag the contents of the uncompressed bundle directory onto your board's CIRCUITPY drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.
# SPDX-FileCopyrightText: 2018 Limor Fried for Adafruit Industries # # SPDX-License-Identifier: MIT # Circuit Playground Bluefruit version 2022 John Park import array import time import board import pulseio from digitalio import DigitalInOut, Direction, Pull from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService from adafruit_bluefruit_connect.packet import Packet from adafruit_bluefruit_connect.button_packet import ButtonPacket # pylint: disable=eval-used # Switch to select 'stealth-mode' switch = DigitalInOut(board.SLIDE_SWITCH) switch.direction = Direction.INPUT switch.pull = Pull.UP # Button to see output debug led = DigitalInOut(board.D13) led.direction = Direction.OUTPUT # which pin for IR LED/blaster ir_pin = board.A2 # JST IR Blaster board # Speaker as haptic feedback spkr_en = DigitalInOut(board.SPEAKER_ENABLE) spkr_en.direction = Direction.OUTPUT spkr_en.value = True spkr = DigitalInOut(board.SPEAKER) spkr.direction = Direction.OUTPUT # Allow any button to trigger activity! button_a = DigitalInOut(board.BUTTON_A) button_a.direction = Direction.INPUT button_a.pull = Pull.DOWN button_b = DigitalInOut(board.BUTTON_B) button_b.direction = Direction.INPUT button_b.pull = Pull.DOWN # BLE setup ble = BLERadio() uart_service = UARTService() advertisement = ProvideServicesAdvertisement(uart_service) def ir_code_send(code): f = open(code, "r") for line in f: code = eval(line) print(code) if switch.value: led.value = True else: spkr.value = True # If this is a repeating code, extract details try: repeat = code["repeat"] delay = code["repeat_delay"] except KeyError: # by default, repeat once only! repeat = 1 delay = 0 # The table holds the on/off pairs table = code["table"] pulses = [] # store the pulses here # Read through each indexed element for i in code["index"]: pulses += table[i] # and add to the list of pulses pulses.pop() # remove one final 'low' pulse with pulseio.PulseOut( ir_pin, frequency=code["freq"], duty_cycle=2**15 ) as pulse: for i in range(repeat): pulse.send(array.array("H", pulses)) time.sleep(delay) led.value = False spkr.value = False time.sleep(code["delay"]) f.close() while True: ble.name = 'TVRemote' ble.start_advertising(advertisement) while not ble.connected: # Wait for a connection. if button_a.value or button_b.value: print("All codes") time.sleep(0.1) # wait a moment ir_code_send("/full_codes.txt") while ble.connected: if button_a.value or button_b.value: print("all") time.sleep(0.1) # wait a moment ir_code_send("/full_codes.txt") if uart_service.in_waiting: # Packet is arriving. packet = Packet.from_stream(uart_service) if isinstance(packet, ButtonPacket) and packet.pressed: if packet.button == ButtonPacket.UP: print("Select codes") time.sleep(0.1) # wait a moment ir_code_send("/codes.txt") if packet.button == ButtonPacket.DOWN: print("All codes") time.sleep(0.1) # wait a moment ir_code_send("/full_codes.txt") elif packet.button == ButtonPacket.BUTTON_1: print("Sony power") time.sleep(0.1) # wait a moment ir_code_send("/sony_pwr.txt") elif packet.button == ButtonPacket.BUTTON_2: print("Toshiba power") time.sleep(0.1) # wait a moment ir_code_send("/toshiba_pwr.txt")
Use the TV Zapper
To use the Zapper, you can simply press either button on the Circuit Playground Bluefruit and point the emitter at the target TVs. Once the proper code is sent, ZAP! The TV will power off! (Or on, if it was already off).
To use it in BLE mode, connected from the Bluefruit mobile app, and use the controller buttons. See this guide for step-by-step instructions on using the Bluefruit Connect app.
- Up sends the codes in codes.txt
- Down sends the codes defined in the file full_codes.txt
- Left sends the Sony power code.
- Right sends a Toshiba power code.
See the alert box below on how to make your own custom code assignments.
This section of the main TV Zapper guide shows how most of the code works in this project. The main differences here are the use of the IR breakout board, and the Bluetooth functionality.
from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService from adafruit_bluefruit_connect.packet import Packet from adafruit_bluefruit_connect.button_packet import ButtonPacket
IR Code Send Function
The ir_code_send()
function is used to open up the requested text file and then emit the relevant code pulses. It will be called by the button presses and Bluefruit buttons to run different code text files.
def ir_code_send(code): f = open(code, "r") for line in f: code = eval(line) print(code) if switch.value: led.value = True else: spkr.value = True # If this is a repeating code, extract details try: repeat = code["repeat"] delay = code["repeat_delay"] except KeyError: # by default, repeat once only! repeat = 1 delay = 0 # The table holds the on/off pairs table = code["table"] pulses = [] # store the pulses here # Read through each indexed element for i in code["index"]: pulses += table[i] # and add to the list of pulses pulses.pop() # remove one final 'low' pulse with pulseio.PulseOut( ir_pin, frequency=code["freq"], duty_cycle=2**15 ) as pulse: for i in range(repeat): pulse.send(array.array("H", pulses)) time.sleep(delay) led.value = False spkr.value = False time.sleep(code["delay"]) f.close()
Main Loop
Then main loop advertises the BLE and then waits for a connection. While it is waiting, you can still use the buttons to send all codes.
while True: ble.name = 'TVRemote' ble.start_advertising(advertisement) while not ble.connected: # Wait for a connection. if button_a.value or button_b.value: print("All codes") time.sleep(0.1) # wait a moment ir_code_send("/full_codes.txt") pass
Once connected, the physical buttons on the Circuit Playground Bluefruit still work, but now the button packets from the Bluefruit app are also used to call different IR code send text files.
while ble.connected: if button_a.value or button_b.value: print("all") time.sleep(0.1) # wait a moment ir_code_send("/full_codes.txt") if uart_service.in_waiting: # Packet is arriving. packet = Packet.from_stream(uart_service) if isinstance(packet, ButtonPacket) and packet.pressed: if packet.button == ButtonPacket.UP: print("Select codes") time.sleep(0.1) # wait a moment ir_code_send("/codes.txt") if packet.button == ButtonPacket.DOWN: print("All codes") time.sleep(0.1) # wait a moment ir_code_send("/full_codes.txt") elif packet.button == ButtonPacket.BUTTON_1: print("Sony power") time.sleep(0.1) # wait a moment ir_code_send("/sony_pwr.txt") elif packet.button == ButtonPacket.BUTTON_2: print("Toshiba power") time.sleep(0.1) # wait a moment ir_code_send("/toshiba_pwr.txt")
Text editor powered by tinymce.