adafruit / Adafruit_Learning_System_Guides

Programs and scripts to display "inline" in Adafruit Learning System guides
MIT License
1.01k stars 769 forks source link

IR Transceiver for STEMMA_IR_Transceiver_Examples CircuitPython throws errors #2853

Open EAGrahamJr opened 3 months ago

EAGrahamJr commented 3 months ago

Ref:

As written, the transceiver seems to have developed a feedback loop wherein the receiver is actually also receiving the transmitted code, which then re-transmits, etc. until a bit is dropped and the decode fails.

If the example code is modified as below, there are no errors and the receive/transmit functions seem to work as expected (on a lab bench).

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

import time
import array
import pulseio
import board
import adafruit_irremote

# Create a 'PulseOut' to send infrared signals on the IR transmitter @ 38KHz
pulseout = pulseio.PulseOut(board.SCL1, frequency=38000, duty_cycle=2**15)
# Create an encoder that will take numbers and turn them into NEC IR pulses
encoder = adafruit_irremote.GenericTransmit(header=[9000, 4500],
                                            one=[560, 1700],
                                            zero=[560, 560],
                                            trail=0)
# IR receiver setup
ir_receiver = pulseio.PulseIn(board.SDA1, maxlen=120, idle_state=True)
decoder = adafruit_irremote.GenericDecode()

skip_next = False
while True:
    pulses = decoder.read_pulses(ir_receiver)
    try:
        if not skip_next:
            # Attempt to decode the received pulses
            received_code = decoder.decode_bits(pulses)
            if received_code:
                hex_code = ''.join(["%02X" % x for x in received_code])
                print(f"Received: {hex_code}")
                # Convert pulses to an array of type 'H' (unsigned short)
                pulse_array = array.array('H', pulses)
                # send code back using original pulses
                pulseout.send(pulse_array)
                print(f"Sent: {pulse_array}")
                skip_next = True
        else:
            skip_next = False
    except adafruit_irremote.IRNECRepeatException:  # Signal was repeated, ignore
        pass
    except adafruit_irremote.IRDecodeException:  # Failed to decode signal
        print("Error decoding")
    ir_receiver.clear()  # Clear the receiver buffer
    time.sleep(1)  # Delay to allow the receiver to settle
    print()

Note that if the read and write functions are "decoupled" (e.g. record and playback), the device works as each of the counterparts.

EAGrahamJr commented 3 months ago

Additional note: this is running on an ESP32S3