📡 Level 3 – Advanced Communication

Project 3.2: "IR Transmission Between R32"

 

 

🚀 Project 3.2 – IR Transmission Between R32

🎯 What you’ll learn

  • ✅ Goal 1: Send an IR command from one D1 R32 to another and see it in the serial monitor
  • ✅ Goal 2: Confirm reception with clean messages and build a simple “START/STOP” protocol
  • ✅ Goal 3: Send multiple values and make a two‑way confirmation (handshake)

Key ideas

  • Short definition: IR communication sends small codes using invisible light.
  • Real‑world link: TV remotes use IR to change channels or volume.

🧱 Blocks glossary (used in this project)

  • IR send: Transmits an infrared code (like pressing a remote button).
  • IR receive: Listens for IR codes and reads them when they arrive.
  • Serial print: Shows status and data on your computer screen.
  • Variable: Stores a number like a command code.
  • if / else: Makes a choice based on what was received.
  • Loop: Keeps checking or sending again and again.

🧰 What you need

PartHow many?Pin connection
D1 R32 (Sender)1USB cable
D1 R32 (Receiver)1USB cable
IR Transmitter Module1Pin 26 (Sender)
IR Receiver Module1Pin 26 (Receiver)

🔌 Wiring tip: Point the transmitter at the receiver, 20–50 cm apart, with a clear line of sight.
📍 Pin map snapshot: Pin 26 reserved for IR in this project. Other pins remain free.


✅ Before you start

  • Open two serial monitors (one per board): label them “Sender” and “Receiver”.
  • Test print shows:
print("Ready!")  # Confirm serial is working

🎮 Microprojects (5 mini missions)

🎮 Microproject 3.2.1 – Sending a simple IR command (Sender)

Goal: Transmit one IR command (hex) from the sender board.

Blocks used:

  • IR send: Transmit one code
  • Serial print: Announce the send

Block sequence:

  1. Setup IR transmitter on Pin 26
  2. Choose a command (0x45 = “1”)
  3. Transmit the command
  4. Print confirmation

MicroPython code (Sender):

# Microproject 3.2.1 – Sender: Send one IR command

import irremote               # Load IR communication library
import time                   # Load time library for delays

ir_tx = irremote.NEC_TX(26, False, 100)   # Create IR transmitter on Pin 26, not inverted, power 100%
print("[Sender] IR TX ready on Pin 26")   # Confirm transmitter ready

cmd = 0x45                                # Choose command code: 0x45 (IR remote '1')
addr = 0x00                               # Use simple address 0 for demo
ctrl = 0x00                               # Use simple control 0 for demo

print("[Sender] Sending CMD=0x45")        # Announce the command to send
ir_tx.transmit(addr, cmd, ctrl)           # Transmit (address, command, control)
print("[Sender] Command sent!")           # Confirm send
time.sleep_ms(1000)                       # Wait to avoid spamming

Reflection: You sent a number using invisible light—just like a TV remote.
Challenge:

  • Easy: Change the command to 0x46 (“2”).
  • Harder: Send the command every 2 seconds inside a loop.

🎮 Microproject 3.2.2 – Reception and confirmation (Receiver)

Goal: Detect the incoming IR code and show it on the serial monitor.

Blocks used:

  • IR receive: Listen for codes
  • Serial print: Show received value

Block sequence:

  1. Setup IR receiver on Pin 26
  2. Check for any incoming code
  3. If available, read and print it
  4. Repeat in a loop

MicroPython code (Receiver):

# Microproject 3.2.2 – Receiver: Listen and print incoming IR code

import irremote                    # Load IR communication library
import time                        # Load time library for delays

ir_rx = irremote.NEC_RX(26, 8)     # Create IR receiver on Pin 26 with buffer size 8
print("[Receiver] IR RX ready on Pin 26")   # Confirm receiver ready

while True:                                      # Start continuous listening loop
    if ir_rx.any():                               # Check if any IR code has arrived
        received_code = ir_rx.code[0]             # Read the first code from the buffer
        print("[Receiver] Received:", hex(received_code))  # Show code in hex
    else:                                         # If no code available
        print("[Receiver] Waiting...")            # Print waiting status
    time.sleep_ms(400)                            # Delay for readable updates

Reflection: Your receiver board “heard” the sender’s code—teamwork!
Challenge:

  • Easy: Only print when data arrives (remove “Waiting…”).
  • Harder: Add a counter that increments every time a code is received.

🎮 Microproject 3.2.3 – Basic communication protocol (START/STOP)

Goal: Map specific codes to actions: START (0x45) and STOP (0x46).

Blocks used:

  • IR send: Transmit labeled actions
  • IR receive: Decode and map
  • if / else: Decide action

Block sequence:

  1. Sender sends START (0x45) then STOP (0x46)
  2. Receiver reads and prints action labels
  3. Repeat with timing
  4. Clear logs to stay readable

MicroPython code (Sender):

# Microproject 3.2.3 – Sender: Send START and STOP with IR

import irremote                     # Load IR communication library
import time                         # Load time library for delays

ir_tx = irremote.NEC_TX(26, False, 100)    # Create IR transmitter on Pin 26
print("[Sender] Protocol TX ready")        # Confirm transmitter ready

addr = 0x00                                # Use simple address for demo
ctrl = 0x00                                # Use simple control for demo

print("[Sender] START=0x45, STOP=0x46")    # Show mapping for clarity

ir_tx.transmit(addr, 0x45, ctrl)           # Send START code
print("[Sender] Sent START (0x45)")        # Confirm START sent
time.sleep_ms(1200)                        # Wait 1.2 seconds

ir_tx.transmit(addr, 0x46, ctrl)           # Send STOP code
print("[Sender] Sent STOP (0x46)")         # Confirm STOP sent
time.sleep_ms(1200)                        # Wait 1.2 seconds

MicroPython code (Receiver):

# Microproject 3.2.3 – Receiver: Decode START/STOP

import irremote                          # Load IR communication library
import time                              # Load time library for delays

ir_rx = irremote.NEC_RX(26, 8)           # Create IR receiver on Pin 26
print("[Receiver] Protocol RX ready")    # Confirm receiver ready

while True:                                        # Start decoding loop
    if ir_rx.any():                                 # If a code arrived
        code_value = ir_rx.code[0]                  # Read the first buffered code
        print("[Receiver] Raw:", hex(code_value))   # Show raw hex code
        if code_value == 0x45:                      # If equals START code
            print("[Receiver] ACTION: START")       # Announce START
        elif code_value == 0x46:                    # If equals STOP code
            print("[Receiver] ACTION: STOP")        # Announce STOP
        else:                                       # Otherwise unknown
            print("[Receiver] ACTION: UNKNOWN")     # Mark unknown
    else:                                           # No code this cycle
        print("[Receiver] Listening...")            # Keep listening message
    time.sleep_ms(400)                              # Delay for readability

Reflection: You turned numbers into clear actions—your first IR protocol.
Challenge:

  • Easy: Add PAUSE with 0x47 and print it.
  • Harder: Ignore duplicate codes by spacing sends at least 500 ms.

🎮 Microproject 3.2.4 – Sending multiple data (sequence)

Goal: Send a small sequence [0x45, 0x46, 0x47] and print each one received.

Blocks used:

  • IR send: Transmit codes in a loop
  • Loop: Iterate over the sequence
  • Serial print: Show progress on both boards

Block sequence:

  1. Sender loops through list of codes
  2. Send each code with delay
  3. Receiver prints each arrival with a counter
  4. Keep logs short

MicroPython code (Sender):

# Microproject 3.2.4 – Sender: Send sequence [0x45, 0x46, 0x47]

import irremote                       # Load IR communication library
import time                           # Load time library for delays

ir_tx = irremote.NEC_TX(26, False, 100)    # Create IR transmitter on Pin 26
print("[Sender] TX ready for sequence")    # Confirm transmitter ready

addr = 0x00                                # Use simple address
ctrl = 0x00                                # Use simple control
seq = [0x45, 0x46, 0x47]                   # Define sequence codes

print("[Sender] Sequence:", [hex(x) for x in seq])  # Show sequence in hex

for item in seq:                          # Loop through each code
    print("[Sender] Sending:", hex(item)) # Announce current code
    ir_tx.transmit(addr, item, ctrl)      # Send the code
    time.sleep_ms(700)                     # Wait 0.7 seconds between sends

MicroPython code (Receiver):

# Microproject 3.2.4 – Receiver: Count received sequence items

import irremote                         # Load IR communication library
import time                             # Load time library for delays

ir_rx = irremote.NEC_RX(26, 8)          # Create IR receiver on Pin 26
print("[Receiver] RX ready for sequence")   # Confirm receiver ready

count = 0                               # Initialize counter of received items

while True:                                         # Start listening loop
    if ir_rx.any():                                  # If a code arrived
        code_item = ir_rx.code[0]                    # Read the first buffered code
        count = count + 1                            # Increase count by 1
        print("[Receiver] #", count, "code:", hex(code_item))  # Show count and code
    else:                                            # If nothing yet
        print("[Receiver] Waiting for next...")      # Print waiting message
    time.sleep_ms(350)                               # Delay for readable updates

Reflection: You sent and tracked a tiny “message” made of three IR codes.
Challenge:

  • Easy: Change delay to 300 ms and test reliability.
  • Harder: Require the receiver to detect all three, then print “Sequence OK”.

🎮 Microproject 3.2.5 – Two‑way communication (handshake)

Goal: Receiver replies with CONFIRM (0x1C), and sender waits for ACK.

Blocks used:

  • IR receive: Listen for incoming request
  • IR send: Reply with CONFIRM
  • if / else: Check for the expected ACK

Block sequence:

  1. Sender sends REQUEST (e.g., 0x45)
  2. Receiver gets REQUEST and sends CONFIRM (0x1C)
  3. Sender waits for CONFIRM and prints “ACK received”
  4. Add timeout

MicroPython code (Receiver → confirms back):

# Microproject 3.2.5 – Receiver: Send confirmation (0x1C) after receiving any code

import irremote                          # Load IR communication library
import time                              # Load time library for delays

ir_rx = irremote.NEC_RX(26, 8)           # Create IR receiver on Pin 26
ir_tx = irremote.NEC_TX(26, False, 100)  # Create IR transmitter on Pin 26
print("[Receiver] Ready: RX+TX on Pin 26")   # Confirm both RX and TX ready

addr = 0x00                               # Use simple address
ctrl = 0x00                               # Use simple control
confirm_cmd = 0x1C                        # Confirmation code (IR remote 'OK')

while True:                                           # Start handshake loop
    if ir_rx.any():                                    # If any code arrived
        incoming = ir_rx.code[0]                       # Read first buffered code
        print("[Receiver] Got:", hex(incoming))        # Show received code
        print("[Receiver] Reply:", hex(confirm_cmd))   # Announce confirmation code
        ir_tx.transmit(addr, confirm_cmd, ctrl)        # Send confirmation via IR
    else:                                              # If no code now
        print("[Receiver] Waiting for request...")     # Print waiting message
    time.sleep_ms(500)                                 # Delay for timing and readability

MicroPython code (Sender → waits for ACK):

# Microproject 3.2.5 – Sender: Send request and wait for confirmation (ACK)

import irremote                          # Load IR communication library
import time                              # Load time library for delays

ir_tx = irremote.NEC_TX(26, False, 100)  # Create IR transmitter on Pin 26
ir_rx = irremote.NEC_RX(26, 8)           # Create IR receiver on Pin 26
print("[Sender] Ready: TX+RX on Pin 26") # Confirm both TX and RX ready

addr = 0x00                               # Use simple address
ctrl = 0x00                               # Use simple control
request_cmd = 0x45                        # Request code (e.g., '1')
ack_cmd = 0x1C                            # Expected confirmation ('OK')

print("[Sender] Request:", hex(request_cmd))   # Announce request code
ir_tx.transmit(addr, request_cmd, ctrl)        # Send request via IR

wait_steps = 0                                  # Initialize wait counter
while wait_steps < 10:                          # Check up to 10 times
    if ir_rx.any():                              # If any code was received
        received = ir_rx.code[0]                 # Read first buffered code
        print("[Sender] Received:", hex(received))  # Show received code
        if received == ack_cmd:                  # If matches expected ACK
            print("[Sender] ACK received!")      # Print success message
            break                                # Exit loop on success
    else:                                        # If no code this cycle
        print("[Sender] Waiting for ACK...")     # Print waiting status
    time.sleep_ms(300)                           # Delay between checks
    wait_steps = wait_steps + 1                  # Increase wait counter

Reflection: You built a handshake: request → confirm → success—real protocol design.
Challenge:

  • Easy: Change CONFIRM to 0x18 (UP) and retest.
  • Harder: Add a timeout message if no ACK after 3 seconds.

✨ Main project – Basic IR communication protocol between two R32

🔧 Blocks steps (with glossary)

  • IR send: Sender transmits “START” then “STOP”.
  • IR receive: Receiver decodes and prints actions.
  • Serial print: Clear logs of send/receive.
  • if / else: Map codes to labels and handle confirmation.

Block sequence:

  1. Sender: Setup IR TX (Pin 26) → send 0x45 (“START”).
  2. Receiver: Setup IR RX (Pin 26) → read and print action.
  3. Sender: Send 0x46 (“STOP”).
  4. Receiver: Read and print action.
  5. Extend with confirmation (0x1C) as optional handshake.

🐍 MicroPython code (mirroring blocks)

# Project 3.2 – IR Transmission Between R32: Mini Protocol Demo

import irremote                               # Load IR communication library
import time                                   # Load time library for delays

# Setup IR transmitter on Sender
ir_tx = irremote.NEC_TX(26, False, 100)       # Create IR transmitter on Pin 26
print("[Sender] IR TX ready on 26")           # Confirm TX ready

# Setup IR receiver on Receiver
ir_rx = irremote.NEC_RX(26, 8)                # Create IR receiver on Pin 26
print("[Receiver] IR RX ready on 26")         # Confirm RX ready

# Sender: Transmit START (0x45)
print("[Sender] TX START (0x45)")             # Announce sending START
ir_tx.transmit(0x00, 0x45, 0x00)              # Send address=0x00, command=0x45, control=0x00
time.sleep_ms(800)                            # Wait for receiver

# Receiver: Read first code if available
if ir_rx.any():                                # Check if a code is available
    code1 = ir_rx.code[0]                      # Read the first buffered code
    print("[Receiver] Got:", hex(code1))       # Show code in hex
    if code1 == 0x45:                          # If equals START
        print("[Receiver] ACTION: START")      # Announce START
    else:                                      # Otherwise unknown
        print("[Receiver] ACTION: UNKNOWN")    # Announce unknown
else:                                          # If nothing arrived yet
    print("[Receiver] No data")                # Inform no data

# Sender: Transmit STOP (0x46)
print("[Sender] TX STOP (0x46)")              # Announce sending STOP
ir_tx.transmit(0x00, 0x46, 0x00)              # Send address=0x00, command=0x46, control=0x00
time.sleep_ms(800)                            # Wait for receiver

# Receiver: Read second code if available
if ir_rx.any():                                # Check if a code is available
    code2 = ir_rx.code[0]                      # Read the first buffered code
    print("[Receiver] Got:", hex(code2))       # Show code in hex
    if code2 == 0x46:                          # If equals STOP
        print("[Receiver] ACTION: STOP")       # Announce STOP
    else:                                      # Otherwise unknown
        print("[Receiver] ACTION: UNKNOWN")    # Announce unknown
else:                                          # If nothing arrived yet
    print("[Receiver] No data")                # Inform no data

📖 External explanation

  • What it teaches: How to send and receive IR codes and label them as actions.
  • Why it works: The sender encodes a number; the receiver reads it and maps it to a known meaning (START/STOP).
  • Key concept: Small, clear codes (hex values) make reliable communication.

✨ Story time

Two robots, one message beam. Your sender whispers “START” and “STOP” in light, and the receiver acts—like mission control.


🕵️ Debugging (2 common problems)

🐞 Debugging 3.2.A – IR signal not arriving

Problem: Receiver prints “No data” even though the sender is transmitting.
Clues: No “[Receiver] Got:” messages appear.

Broken code:

ir_rx = irremote.NEC_RX(23, 8)  # Wrong pin (receiver wired to 26)

Fixed code:

ir_rx = irremote.NEC_RX(26, 8)  # Correct pin (use Pin 26 as wired)

Why it works: The code must match the physical pin the IR module uses.
Avoid next time: Check pin numbers and aim the modules directly at each other.


🐞 Debugging 3.2.B – Corrupt or unknown codes

Problem: “[Receiver] ACTION: UNKNOWN” appears for expected sends.
Clues: Raw hex values don’t match 0x45 or 0x46.

Broken code:

if ir_rx.any():
    print(ir_rx.code)  # Prints whole buffer without checking a valid entry

Fixed code:

if ir_rx.any():
    rx_code = ir_rx.code[0]          # Read first valid code from buffer
    if rx_code == 0x45: print("START")  # Compare against known hex codes

Why it works: Reading a single valid entry avoids noise or old buffer values.
Avoid next time: Use small delays and compare to known hex codes.


✅ Final checklist

  • I sent at least one IR command and saw it on the receiver
  • I mapped codes to actions like START and STOP
  • I created a handshake with a confirmation code or tested the sequence

📚 Extras

  • 🧠 Student tip: Test in a dim room and keep modules close—IR is light.
  • 🧑‍🏫 Instructor tip: Pair students as sender/receiver teams and rotate.
  • 📖 Glossary:
    • IR (infrared): Invisible light used for remote controls.
    • Hex code: A number in base‑16 (like 0x45) used in protocols.
    • Handshake: Request then acknowledgment to confirm communication.
  • 💡 Mini tips:
    • Space your sends (500–1200 ms) to avoid collisions.
    • Print hex with hex(value) for easier reading.
    • Keep the line of sight clear; avoid sunlight or strong lamps.
On this page