Skip to main content

Overview

Kinematrix provides powerful LED control capabilities through the PCF8574Module, allowing you to control up to 8 LEDs per I2C expander chip. This guide covers basic LED control, patterns, and integration with sensors.

Hardware Setup

PCF8574 I2C Expander

  • Address: 0x20 (default, configurable with A0-A2 pins)
  • Interface: I2C (SDA, SCL)
  • Outputs: 8 digital outputs (PCF_PIN0 to PCF_PIN7)
  • Voltage: 5V compatible

Wiring

ESP32/Arduino    PCF8574
--------------------------
SDA (21)    -->  SDA
SCL (22)    -->  SCL
VCC (5V)    -->  VCC
GND         -->  GND
                 P0-P7 --> LEDs (with resistors)

Basic LED Control

1

Include Library

#include "Arduino.h"
#include "PCF8574Module.h"
2

Create Module Instance

PCF8574Module pcfModule(0x20);  // I2C address 0x20

// Define LED pins
#define LED1 PCF_PIN0
#define LED2 PCF_PIN1
#define LED3 PCF_PIN2
#define LED4 PCF_PIN3
#define LED5 PCF_PIN4
#define LED6 PCF_PIN5
#define LED7 PCF_PIN6
#define LED8 PCF_PIN7
3

Initialize Module

void setup() {
    Serial.begin(115200);
    delay(1000);
    
    if (!pcfModule.begin()) {
        Serial.println("PCF8574 Error!");
        while(1);
    }
    
    // Setup all LEDs
    pcfModule.setupLED(LED1);
    pcfModule.setupLED(LED2);
    pcfModule.setupLED(LED3);
    pcfModule.setupLED(LED4);
    pcfModule.setupLED(LED5);
    pcfModule.setupLED(LED6);
    pcfModule.setupLED(LED7);
    pcfModule.setupLED(LED8);
    
    // Turn all LEDs off
    pcfModule.digitalWriteAll(0x00);
}
4

Control LEDs

void loop() {
    // Turn on LED1
    pcfModule.turnOnLED(LED1);
    delay(500);
    
    // Turn off LED1
    pcfModule.turnOffLED(LED1);
    delay(500);
    
    // Toggle LED2
    pcfModule.toggleLED(LED2);
    delay(500);
}

LED Patterns and Effects

Sequential Chase Pattern

LEDs light up one after another in sequence:
void loop() {
    // Chase forward
    for (int i = 0; i < 8; i++) {
        pcfModule.turnOnLED(i);
        delay(200);
        pcfModule.turnOffLED(i);
        delay(50);
    }
    
    delay(500);
}

Knight Rider / Cylon Effect

A single LED sweeps back and forth:
void loop() {
    // Sweep forward
    for (int i = 0; i < 7; i++) {
        pcfModule.digitalWriteAll(1 << i);
        delay(150);
    }
    
    // Sweep backward
    for (int i = 6; i >= 0; i--) {
        pcfModule.digitalWriteAll(1 << i);
        delay(150);
    }
    
    delay(500);
}
Flash all LEDs on and off:
void loop() {
    for (int i = 0; i < 3; i++) {
        pcfModule.digitalWriteAll(0xFF);  // All on
        delay(300);
        pcfModule.digitalWriteAll(0x00);  // All off
        delay(300);
    }
    
    delay(500);
}

Alternating Pattern

Odd and even LEDs alternate:
void loop() {
    for (int i = 0; i < 5; i++) {
        pcfModule.digitalWriteAll(0b01010101);  // Odd LEDs on
        delay(300);
        pcfModule.digitalWriteAll(0b10101010);  // Even LEDs on
        delay(300);
    }
    
    delay(1000);
}

Complete Example: All Patterns

Here’s the complete example demonstrating multiple LED patterns:
#include "Arduino.h"
#include "PCF8574Module.h"

PCF8574Module pcfModule(0x20);

#define LED1 PCF_PIN0
#define LED2 PCF_PIN1
#define LED3 PCF_PIN2
#define LED4 PCF_PIN3
#define LED5 PCF_PIN4
#define LED6 PCF_PIN5
#define LED7 PCF_PIN6
#define LED8 PCF_PIN7

void setup() {
    Serial.begin(115200);
    delay(1000);
    
    if (!pcfModule.begin()) {
        Serial.println("PCF8574 Error!");
        while(1);
    }
    
    pcfModule.setupLED(LED1);
    pcfModule.setupLED(LED2);
    pcfModule.setupLED(LED3);
    pcfModule.setupLED(LED4);
    pcfModule.setupLED(LED5);
    pcfModule.setupLED(LED6);
    pcfModule.setupLED(LED7);
    pcfModule.setupLED(LED8);
    
    pcfModule.digitalWriteAll(0x00);
}

void loop() {
    // Pattern 1: Sequential chase
    for (int i = 0; i < 8; i++) {
        pcfModule.turnOnLED(i);
        delay(200);
        pcfModule.turnOffLED(i);
        delay(50);
    }
    
    delay(500);
    
    // Pattern 2: Knight Rider effect
    for (int i = 0; i < 7; i++) {
        pcfModule.digitalWriteAll(1 << i);
        delay(150);
    }
    
    for (int i = 6; i >= 0; i--) {
        pcfModule.digitalWriteAll(1 << i);
        delay(150);
    }
    
    delay(500);
    
    // Pattern 3: Blink all
    for (int i = 0; i < 3; i++) {
        pcfModule.digitalWriteAll(0xFF);
        delay(300);
        pcfModule.digitalWriteAll(0x00);
        delay(300);
    }
    
    delay(500);
    
    // Pattern 4: Alternating
    for (int i = 0; i < 5; i++) {
        pcfModule.digitalWriteAll(0b01010101);
        delay(300);
        pcfModule.digitalWriteAll(0b10101010);
        delay(300);
    }
    
    delay(1000);
}

Sensor-Triggered LED Control

Combine LED control with sensor readings:
#define ENABLE_SENSOR_MODULE_V2
#define ENABLE_SENSOR_DHT_V2
#define ENABLE_SENSOR_UTILITY_V2
#include "Kinematrix.h"
#include "PCF8574Module.h"

SensorModuleV2 sensors;
PCF8574Module leds(0x20);

#define LED_COLD   PCF_PIN0  // Blue LED for cold
#define LED_NORMAL PCF_PIN1  // Green LED for normal
#define LED_WARM   PCF_PIN2  // Yellow LED for warm
#define LED_HOT    PCF_PIN3  // Red LED for hot

void setup() {
    Serial.begin(115200);
    
    // Initialize LEDs
    leds.begin();
    leds.setupLED(LED_COLD);
    leds.setupLED(LED_NORMAL);
    leds.setupLED(LED_WARM);
    leds.setupLED(LED_HOT);
    leds.digitalWriteAll(0x00);
    
    // Initialize sensors
    sensors.addSensor("temp", new DHTSensV2(2, DHT22));
    sensors.init();
}

void loop() {
    sensors.update();
    
    if (sensors.isUpdated("temp")) {
        float temperature = sensors.getValue<float>("temp", "temperature");
        
        // Turn off all LEDs
        leds.digitalWriteAll(0x00);
        
        // Light appropriate LED based on temperature
        if (temperature < 20.0) {
            leds.turnOnLED(LED_COLD);
            Serial.println("Status: COLD");
        } else if (temperature < 25.0) {
            leds.turnOnLED(LED_NORMAL);
            Serial.println("Status: NORMAL");
        } else if (temperature < 30.0) {
            leds.turnOnLED(LED_WARM);
            Serial.println("Status: WARM");
        } else {
            leds.turnOnLED(LED_HOT);
            Serial.println("Status: HOT");
        }
        
        Serial.print("Temperature: ");
        Serial.print(temperature);
        Serial.println("°C");
    }
    
    delay(1000);
}

Advanced Techniques

Using Multiple PCF8574 Modules

Control up to 64 LEDs (8 modules) on the same I2C bus:
PCF8574Module pcf1(0x20);  // First module
PCF8574Module pcf2(0x21);  // Second module
PCF8574Module pcf3(0x22);  // Third module

void setup() {
    pcf1.begin();
    pcf2.begin();
    pcf3.begin();
    
    // Setup LEDs on each module
    for (int i = 0; i < 8; i++) {
        pcf1.setupLED(i);
        pcf2.setupLED(i);
        pcf3.setupLED(i);
    }
}

Binary Counter Display

Display binary numbers on 8 LEDs:
void loop() {
    for (uint8_t count = 0; count < 256; count++) {
        pcfModule.digitalWriteAll(count);
        delay(100);
        Serial.print("Binary: ");
        Serial.println(count, BIN);
    }
}

PWM-like Brightness Control

Simulate PWM by rapidly toggling LEDs:
void setLEDBrightness(uint8_t led, uint8_t brightness) {
    // brightness: 0-100
    for (int i = 0; i < 100; i++) {
        if (i < brightness) {
            pcfModule.turnOnLED(led);
        } else {
            pcfModule.turnOffLED(led);
        }
        delayMicroseconds(100);
    }
}

PCF8574 API Reference

Initialization

bool begin();                    // Initialize I2C communication

LED Setup

void setupLED(uint8_t pin);      // Configure pin as LED output

Individual LED Control

void turnOnLED(uint8_t pin);     // Turn on single LED
void turnOffLED(uint8_t pin);    // Turn off single LED
void toggleLED(uint8_t pin);     // Toggle single LED

Bulk Control

void digitalWriteAll(uint8_t value);  // Set all 8 pins at once
// Example: 0b10101010 or 0xAA

Troubleshooting

  • Verify I2C address using I2C scanner
  • Check SDA/SCL connections
  • Ensure pull-up resistors on I2C lines (usually built-in)
  • Try different I2C address (0x20-0x27)
  • Check LED polarity (anode to resistor, cathode to GND)
  • Verify appropriate resistor value (220Ω - 1kΩ)
  • Test with digitalWriteAll(0xFF) to turn all on
  • Check power supply can handle current draw
  • Increase resistor values if LEDs too bright
  • Check power supply capacity
  • Reduce number of LEDs lit simultaneously
  • Add capacitor (100µF) across power supply

Next Steps

IoT Data Logger

Log data and trigger LED alerts

Multi-Platform Development

Deploy LED control across platforms

Debugging

Debug LED and I2C issues

Basic Sensor Reading

Integrate sensors with LED feedback

Build docs developers (and LLMs) love