Getting Started
Basic Concepts
CtrlAer is built around three main concepts:
- Signal Generators: Python generators that yield timing patterns
 - Signal Multiplexing: Combining multiple generators to control multiple pins
 - PIO Execution: Running the program on RP2040/RP2350 hardware
 
Creating Signal Patterns
Simple Patterns
The simplest way to create a signal pattern is to yield pairs of (state, duration):
def blink_led():
    while True:
        yield HIGH, 1000  # Constant HIGH for 1 second
        yield LOW, 1000   # Constant LOW for 1 second
Square Waves
For high-frequency applications, use PULSE10 or PULSE01:
def ultrasonic_burst():
    # Generate 40kHz square wave for 100ms, then off for 900ms
    while True:
        yield PULSE10, 100   # Square wave at freq Hz
        yield OFF, 900       # Off for 900ms
The square wave frequency is set when creating the controller:
Multiple Pins
Each generator in a multiplexed program controls one pin:
def motor_phase1():
    while True:
        yield PULSE10, 50
        yield OFF, 50
def motor_phase2():
    while True:
        yield PULSE01, 50  # 180° out of phase
        yield OFF, 50
# First pin controlled by phase1, second pin by phase2
progs = [motor_phase1(), motor_phase2()]
prog = mux(progs)
Hardware Setup
Pin Assignment
- Pins are assigned sequentially starting from 
base_pin - Each generator in a multiplexed program controls one pin
 - Example with 
base_pin=2and three generators: 
State Machine Selection
- RP2040 has 8 state machines (0-7)
 - RP2350 has 12 state machines (0-11)
 - State machines are grouped in blocks of 4
 - All state machines in a block share the same frequency
 - Use different blocks for different frequencies
 
Common Patterns
Blocking vs Non-blocking
# Blocking (wait for completion)
controller.run(prog)
# Non-blocking with later synchronization
controller.run(prog, block=False)
# Do other things
controller.block()  # Wait for completion
Frequency Control
# Create controller at initial frequency
controller = CtrlAer(sm_number=0, base_pin=0, n_pins=2, freq=10000)
# Change frequency later (affects all pins in same PIO block)
controller.set_freq(20000)
Finite vs Infinite Programs
# Finite program (runs 10 times then stops)
def finite_pattern():
    for _ in range(10):
        yield ON, 100
        yield OFF, 100
# Infinite program (runs until stopped)
def infinite_pattern():
    while True:
        yield ON, 100
        yield OFF, 100
See the API Reference for detailed documentation of all features.