Skip to main content

Overview

AutoLight V3 includes 16 built-in LED sequence patterns, each implemented as optimized C++ methods. This guide shows you how to use these patterns and customize them for your needs.

Built-in Sequence Patterns

All LEDs blink simultaneously with configurable timing:
void BaseChannel::taskSequence2BlinkAll() {
    // Full blink cycle
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 15; ++j) {
            // Turn all LEDs on
            for (int k = 0; k < config_data_ptr_->header.pin_size_; k++) {
                set(config_data_ptr_->header.pin_ptr_[k], HIGH);
            }
            sleep(channel_data_.delay_time_);
            
            // Turn all LEDs off
            for (int k = 0; k < config_data_ptr_->header.pin_size_; k++) {
                set(config_data_ptr_->header.pin_ptr_[k], LOW);
            }
            sleep(channel_data_.delay_time_);
        }
        sleep(500);
    }
    off();
    
    // Half blink patterns follow...
}
Use Case: Status indicators, attention-grabbing effects

Mode 3: Fill Two Point

LEDs fill from two points (center and edges) simultaneously:
void BaseChannel::taskSequence3FillTwoPoint() {
    for (int i = 0; i < config_data_ptr_->header.pin_size_ / 2; i += 2) {
        // Blink current pair
        for (int j = 0; j < 8; ++j) {
            set(config_data_ptr_->header.pin_ptr_[i], HIGH);
            set(config_data_ptr_->header.pin_ptr_[i + 1], HIGH);
            sleep(channel_data_.delay_time_);
            set(config_data_ptr_->header.pin_ptr_[i], LOW);
            set(config_data_ptr_->header.pin_ptr_[i + 1], LOW);
            sleep(channel_data_.delay_time_);
        }
        
        // Keep LEDs on
        set(config_data_ptr_->header.pin_ptr_[i], HIGH);
        set(config_data_ptr_->header.pin_ptr_[i + 1], HIGH);
        sleep(300);
        
        // Mirror from the other end
        if (i < (config_data_ptr_->header.pin_size_ / 2) - 1) {
            for (int j = 0; j < 8; ++j) {
                set(config_data_ptr_->header.pin_ptr_[
                    (config_data_ptr_->header.pin_size_ - 1) - i], HIGH);
                set(config_data_ptr_->header.pin_ptr_[
                    (config_data_ptr_->header.pin_size_ - 1) - (i + 1)], HIGH);
                sleep(channel_data_.delay_time_);
                set(config_data_ptr_->header.pin_ptr_[
                    (config_data_ptr_->header.pin_size_ - 1) - i], LOW);
                set(config_data_ptr_->header.pin_ptr_[
                    (config_data_ptr_->header.pin_size_ - 1) - (i + 1)], LOW);
                sleep(channel_data_.delay_time_);
            }
        }
    }
    
    // Clear from end to start
    for (int i = config_data_ptr_->header.pin_size_; i > 0; --i) {
        set(config_data_ptr_->header.pin_ptr_[i - 1], LOW);
        sleep(channel_data_.delay_time_ * 2);
    }
    off();
    sleep(500);
}
Use Case: Progress indicators, symmetrical lighting effects

Mode 4: Fill Right

Sequential fill from right to left:
void BaseChannel::taskSequence4FillRight() {
    for (int i = config_data_ptr_->header.pin_size_; i > 0; --i) {
        // Animate movement
        for (int j = 0; j < i; j++) {
            set(config_data_ptr_->header.pin_ptr_[j], HIGH);
            sleep(channel_data_.delay_time_ * 2);
            set(config_data_ptr_->header.pin_ptr_[j], LOW);
        }
        // Keep last LED on
        set(config_data_ptr_->header.pin_ptr_[i - 1], HIGH);
    }
    
    // Clear all
    for (int i = config_data_ptr_->header.pin_size_; i > 0; --i) {
        set(config_data_ptr_->header.pin_ptr_[i - 1], LOW);
        sleep(channel_data_.delay_time_ * 2);
    }
    off();
    sleep(500);
}
Use Case: Loading bars, directional indicators

Sequence Mapping System

Filter and reorder available sequences to create custom sequence sets:
1

Enable Sequence Mapping

void setup() {
    // ... initialization ...
    
    // Enable the mapping system
    led.enableSequenceMapping(true);
}
2

Define Active Sequences

Specify which sequences are available:
// Method 1: Using variadic function
led.setActiveSequences(4, 2, 5, 7, 10);
// Only modes 2, 5, 7, and 10 are accessible

// Method 2: Using array
uint8_t sequences[] = {2, 5, 7, 10};
led.setActiveSequences(sequences, 4);

// Method 3: Using macro
SET_ACTIVE_SEQUENCES(led, 2, 5, 7, 10);
3

Navigate Filtered Sequences

void loop() {
    led.runAutoLight();
    
    // nextMode() now cycles through 2 → 5 → 7 → 10 → 2
    if (buttonPressed) {
        led.nextMode();
    }
}

Complete Mapping Example

#define ENABLE_ADDONS_AUTOLIGHT_V3
#include "Kinematrix.h"

using namespace AutoLight;

BaseChannel led;
BaseConfig config;

void setup() {
    Serial.begin(115200);
    
    config.setDynamicConfig(12, 2);
    led.attachConfig(config.getConfigData());
    
    // Enable sequence mapping
    led.enableSequenceMapping(true);
    
    // Filter to specific modes for automotive turn signals
    SET_ACTIVE_SEQUENCES(led, 2, 3, 4, 6);
    // Mode 2: Blink All
    // Mode 3: Fill Two Point
    // Mode 4: Fill Right
    // Mode 6: Blink One
    
    // Start with first mapped sequence
    led.setInitSequence(2);
    led.initialize();
    
    // Debug: Print active mapping
    led.printSequenceMapping();
}

void loop() {
    led.runAutoLight();
    
    static unsigned long lastChange = 0;
    if (millis() - lastChange > 5000) {
        led.nextMode();  // Cycles: 2 → 3 → 4 → 6 → 2
        Serial.println("Active Mode: " + led.getActiveMappingString());
        lastChange = millis();
    }
    
    delay(10);
}

Reordering Sequences

Change the order of mapped sequences:
void setup() {
    // ... initialization ...
    
    led.enableSequenceMapping(true);
    SET_ACTIVE_SEQUENCES(led, 2, 5, 7, 10);
    
    // Reorder: start with mode 7, then 2, then 10, then 5
    uint8_t newOrder[] = {7, 2, 10, 5};
    led.reorderActiveSequences(newOrder, 4);
    
    led.initialize();
}

Pattern Timing Control

All sequences respect the delay_time parameter:
void setup() {
    // ... initialization ...
    
    // Fast animations (30ms)
    led.setInitDelay(30);
    
    led.initialize();
}

void loop() {
    led.runAutoLight();
    
    // Dynamic speed control via potentiometer
    int speed = analogRead(A0);
    int newDelay = map(speed, 0, 4095, 30, 300);
    led.setInitDelay(newDelay);
    
    delay(10);
}

Creating Pattern Presets

Define preset configurations for different use cases:
enum LightingPreset {
    PRESET_EMERGENCY,
    PRESET_PARTY,
    PRESET_CALM,
    PRESET_AUTOMOTIVE
};

void applyPreset(LightingPreset preset) {
    led.enableSequenceMapping(true);
    
    switch (preset) {
        case PRESET_EMERGENCY:
            SET_ACTIVE_SEQUENCES(led, 2, 6);  // Fast blink patterns
            led.setInitDelay(30);  // Very fast
            break;
            
        case PRESET_PARTY:
            SET_ACTIVE_SEQUENCES(led, 3, 5, 8, 9);  // Complex patterns
            led.setInitDelay(50);  // Medium speed
            break;
            
        case PRESET_CALM:
            SET_ACTIVE_SEQUENCES(led, 4, 5, 10);  // Smooth transitions
            led.setInitDelay(150);  // Slow
            break;
            
        case PRESET_AUTOMOTIVE:
            SET_ACTIVE_SEQUENCES(led, 2, 3, 4);  // Directional fills
            led.setInitDelay(80);
            break;
    }
    
    led.setInitSequence(2);  // Start at first mapped sequence
}

void setup() {
    Serial.begin(115200);
    config.setDynamicConfig(24, 3);
    led.attachConfig(config.getConfigData());
    
    // Apply automotive preset
    applyPreset(PRESET_AUTOMOTIVE);
    
    led.initialize();
}

Pattern Analysis Functions

void loop() {
    led.runAutoLight();
    
    // Get current pattern information
    int currentMode = led.getSequenceIndex();
    int currentDelay = led.getDelayTime();
    String activeMapping = led.getActiveMappingString();
    
    // Print status every 2 seconds
    static unsigned long lastPrint = 0;
    if (millis() - lastPrint > 2000) {
        Serial.println("=== AutoLight Status ===");
        Serial.println("Mode: " + String(currentMode));
        Serial.println("Delay: " + String(currentDelay) + "ms");
        Serial.println("Active Mapping: " + activeMapping);
        lastPrint = millis();
    }
    
    delay(10);
}

Advanced: Direct LED Control

For custom patterns, access LEDs directly:
void customPattern() {
    ConfigData* cfg = config.getConfigData();
    
    // Access individual channels
    for (int i = 0; i < cfg->header.pin_size_; i++) {
        // Turn on LED
        led.set(cfg->header.pin_ptr_[i], HIGH);
        delay(50);
        
        // Turn off LED
        led.set(cfg->header.pin_ptr_[i], LOW);
    }
}

void loop() {
    // Run custom pattern instead of built-in sequences
    customPattern();
    delay(10);
}
Direct LED control bypasses the sequence system. Use led.runAutoLight() for built-in patterns or customPattern() for manual control, but not both simultaneously.

Sequence Reference Table

ModeFunction NamePattern TypeBest For
0OFFStaticPower saving
1ONStaticFull illumination
2taskSequence2BlinkAllSynchronousAlerts, warnings
3taskSequence3FillTwoPointSymmetricalLoading, progress
4taskSequence4FillRightDirectionalIndicators, arrows
5taskSequence5FillInConvergingCenter attention
6taskSequence6BlinkOneSequentialStatus display
7taskSequence7BlinkTwoFillComplexDynamic effects
8taskSequence8SnakeAnimatedEntertainment
9taskSequence9RandomRandomParty mode
10taskSequence10WaveWaveAmbient lighting
11-15taskSequence11-15CombinedAdvanced effects

Next Steps

Web Integration

Control LED patterns remotely via WiFi and REST API

Basic LED Control

Review the fundamentals of AutoLight setup

Build docs developers (and LLMs) love