Files
rpi-tulivision/protocol_development_guide.md
2025-09-27 22:35:56 +02:00

5.6 KiB

Custom IR Protocol Development Guide

This guide will help you develop a custom decoder for an unknown IR protocol using the tools provided.

Step 1: Capture Raw Signal Data

First, use the IR signal analyzer to capture raw timing data from your unknown remote:

python3 ir_signal_analyzer.py --gpio-pin 18 --verbose

Instructions:

  1. Point your unknown remote at the IR receiver
  2. Press buttons to capture signals
  3. Press the same button multiple times to check consistency
  4. Press different buttons to understand the protocol structure
  5. Press Ctrl+C to stop and save analysis

The analyzer will save a JSON file with all captured signals and generate an analysis summary.

Step 2: Analyze the Captured Data

Examine the generated JSON file and analysis summary to understand:

Key Questions to Answer:

  1. How many pulses does each signal have?

    • Consistent pulse count indicates a structured protocol
    • Variable pulse count might indicate variable-length data
  2. What are the common timing values?

    • Look for repeated timing values across different buttons
    • These likely represent bit 0, bit 1, header, footer, etc.
  3. Is there a header pattern?

    • First few pulses often form a header
    • Headers are usually longer than data bits
  4. How are bits encoded?

    • Pulse Width Modulation: Different pulse lengths for 0/1
    • Space Width Modulation: Different space lengths for 0/1
    • Both: Different combinations of pulse and space lengths
  5. Is there a repeat code?

    • Usually 2 pulses with specific timing
    • Much shorter than normal frames

Step 3: Customize the Protocol Decoder

Edit custom_ir_protocol.py and update the timing constants based on your analysis:

Example Analysis Results:

# If your analysis shows these common timings:
# 9000μs, 4500μs, 560μs, 1690μs, 560μs

# Update the constants:
self.HEADER_PULSE = 9000    # Long pulse at start
self.HEADER_SPACE = 4500    # Long space after header
self.BIT_1_PULSE = 560      # Short pulse for all bits
self.BIT_1_SPACE = 1690     # Long space for bit 1
self.BIT_0_PULSE = 560      # Short pulse for all bits
self.BIT_0_SPACE = 560      # Short space for bit 0

Common Protocol Patterns:

NEC-like Protocol:

  • 34 pulses total (header + 32 data bits)
  • Header: 9000μs pulse + 4500μs space
  • Data: 560μs pulse + (560μs or 1690μs) space
  • Repeat: 9000μs pulse + 2250μs space

RC5-like Protocol:

  • 14 bits total
  • Manchester encoding
  • 889μs bit time
  • Start bits: 11

Custom Protocol Example:

  • 20 pulses total
  • Header: 8000μs pulse + 4000μs space
  • Data: 500μs pulse + (500μs or 1500μs) space
  • Footer: 500μs pulse + 100000μs space

Step 4: Test Your Decoder

Test your custom decoder with the captured signals:

python3 custom_ir_protocol.py

This will attempt to decode all captured signals using your custom protocol.

Step 5: Integrate with IR System

Once your decoder works, integrate it into your IR system:

  1. Add to protocol list in your IR listeners
  2. Update IR mapping to include your custom protocol codes
  3. Test with real remote to ensure it works correctly

Troubleshooting

Common Issues:

  1. No signals decoded:

    • Check timing constants match your analysis
    • Verify pulse count expectations
    • Check tolerance settings (try increasing to 0.3)
  2. Inconsistent decoding:

    • Remote might have timing variations
    • Increase tolerance or add timing ranges
    • Check for different button types (some might be repeats)
  3. Wrong data extracted:

    • Verify bit order (LSB vs MSB)
    • Check address vs command bit allocation
    • Ensure proper bit indexing

Debug Tips:

  1. Enable debug logging:
    logging.basicConfig(level=logging.DEBUG)
    

/home/tulivision/rpi-tulivision 3. Compare with known protocols to understand similarities

  1. Use the analyzer's timing analysis to identify patterns

Advanced Features

Variable-Length Protocols:

Some protocols have variable data lengths. Modify the decoder to handle this:

def _determine_data_length(self, pulse_times):
    # Analyze pulse count to determine data length
    # Return appropriate bit counts
    pass

Multiple Protocol Variants:

If your remote uses multiple similar protocols:

class CustomIRProtocolVariant1(CustomIRProtocol):
    def __init__(self):
        super().__init__("CUSTOM_V1")
        # Different timing constants
        
class CustomIRProtocolVariant2(CustomIRProtocol):
    def __init__(self):
        super().__init__("CUSTOM_V2")
        # Different timing constants

Checksum Validation:

Some protocols include checksums:

def _validate_checksum(self, address, command):
    # Calculate and validate checksum
    # Return True if valid, False otherwise
    pass

Example: Complete Custom Protocol

Here's an example of a complete custom protocol based on analysis:

class MyCustomProtocol(CustomIRProtocol):
    def __init__(self):
        super().__init__("MY_CUSTOM")
        
        # Based on analysis of captured signals
        self.HEADER_PULSE = 8500
        self.HEADER_SPACE = 4200
        self.BIT_1_PULSE = 580
        self.BIT_1_SPACE = 1650
        self.BIT_0_PULSE = 580
        self.BIT_0_SPACE = 580
        self.REPEAT_PULSE = 8500
        self.REPEAT_SPACE = 2100
        
        self.EXPECTED_PULSE_COUNT = 36  # 2 header + 34 data
        self.DATA_BITS = 32
        self.ADDRESS_BITS = 16
        self.COMMAND_BITS = 16

This protocol would decode signals as MY_CUSTOM_1234_5678 format.