Warm-Up no.07, Seeing (Infra)red

Introduction

This will be the last Warm-Up that we do. Instead of questions for homework, due to the nature of what we're learning, we'll do a collaborative exercise. What we'll be learning about is the IR sensor(s) on the CPX.

IR?! I heardly know-R

IR stands for Infrared. This is a wavelength of light beyond the visible part of the spectrum. This allows us to transmit and receive light in pulses that we don't see. This is the same technology that you see in a remote control for a television. One thing to note is that you need a direct line of sight between the two objects (sending and receiving respectfully)

Example (in 2 CPX's)

We'll need 2 CPX's for the below example. One person will be the sender. Their CPX will use the "ir_send()" function in order to send an arbitrary signal.

First you'll need to put this library into your CPX (open the drive and drop it into the "lib" folder):

Adafruit Infrared Module

It is possible there might be some incompatibility issues there, if so I'll walk you through updating your CPX, if we need to you'll also need this file:

Adafruit Circuit Python Interpreter for Circuit Playground Express, v.10.0.0

Here's the code for the "sender" CPX and the "receiver" CPX, this is about the simplest that we can do:

  • Sender sends an arbitrary code
  • Lights a light to show we sent
  • Receiver waits for any code
  • When it gets something it shows the code it got
  • It also flashes a light to let us know what's up
# --------------------------
# IR EXAMPLE
# THE SENDER 
# --------------------------

# based heavily on an example from the adafruit website
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT

# imports
import time
from adafruit_circuitplayground.express import cpx
import adafruit_irremote
import pulseio
import board

# Create a 'pulseio' output, to send infrared signals on the IR transmitter @ 38KHz
pulseout = pulseio.PulseOut(board.IR_TX, 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)
print("\n-----------------")
print("\nSENDER")
print("\n-----------------\n")

while True:
    # send different codes for button A and B
    if cpx.button_a:
        print("Button A pressed! \n")

        # light up A side
        for i in range(5):
            cpx.pixels[i] = (255,0,255)
        encoder.transmit(pulseout, [255, 2, 255, 0])
        cpx.pixels.fill((0,0,0))

        # wait so the receiver can get the full message
        time.sleep(0.2)
    if cpx.button_b:
        print("Button B pressed! \n")

        # light up B side
        for i in range(5,10):
            cpx.pixels[i] = (255,0,255)
        encoder.transmit(pulseout, [255, 2, 191, 0])
        cpx.pixels.fill((0,0,0))
        time.sleep(0.2)

# --------------------------
# IR EXAMPLE
# THE RECEIVER
# --------------------------

# based on an example from the adafruit website
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT

# imports 
import pulseio
import board
import adafruit_irremote
from adafruit_circuitplayground import cp
import time

# Create a 'pulseio' input, to listen to 
# infrared signals on the IR receiver
pulsein = pulseio.PulseIn(board.IR_RX, maxlen=120, idle_state=True)
# Create a decoder that will 
# take pulses and turn them into numbers
decoder = adafruit_irremote.GenericDecode()

# let them know we have the receiver right now
print("\n -------------")
print("\n RECEIVER")
print("\n ------------- \n")

while True:
    # receive pulse and put into a format we can read
    pulses = decoder.read_pulses(pulsein)
    try:
        # Attempt to convert received pulses into numbers
        received_code = decoder.decode_bits(pulses)
    except adafruit_irremote.IRNECRepeatException:
        # We got an unusual short code, probably a 'repeat' signal
        # print("NEC repeat!")
        continue
    except adafruit_irremote.IRDecodeException as e:
        # Something got distorted or maybe its not an NEC-type remote?
        # print("Failed to decode: ", e.args)
        continue

    # show the code we received
    # NEC is the company these codes are based on
    # remote control standards
    print("NEC Infrared code received: ", received_code)
    received_code = list(decoder.decode_bits(pulses))

    # show feedback for expected pulses

    # A BUTTON
    if received_code == [255, 2, 255, 0]:
        for i in range(5):
            cp.pixels[i] = (255,0,255)
        time.sleep(0.2)
        cp.pixels.fill((0,0,0))

        received_code = [0]

    #  button
    if received_code == [255, 2, 191, 0]:
        for i in range(5, 10):
            cp.pixels[i] = (255,0,255)
        time.sleep(0.2)
        cp.pixels.fill((0,0,0))
        received_code = [0]

In-Class Exercise

What we'll do in class is the following, is create a kind of primitive "laser tag" type deal

  • select 5 arbitrary (hex)codes for each person in class

  • share the codes with each other

  • select 5 arbitrary color codes for each person in class

  • share the color values with each other

  • set each of our individual CPX's to send our specific code with button A

  • set each individual CPX to properly "decode" each other person's code

  • create a little "hit" animation that shows the coe of who hit you.

  • test that this works

  • add some functionality:

    • give each person some amount of "life" (3, 5?)
    • each person's life's reduces on hit
    • play sounds for shooting and hitting
    • play a sound for "dying" (life = 0)
    • use button B to "respawn"
    • play sound for "respawning"