blinky_button

Example of the component ozanoner/freeact-esp32 v0.1.1
# BlinkyButton Example

This example demonstrates the FreeAct Active Object pattern with LED blinking and button handling on ESP32.

## Overview

The BlinkyButton example showcases:
- **Event-Driven Architecture**: Using FreeAct Active Objects for clean separation of concerns
- **Time Events**: Demonstration of FreeRTOS timer integration through TimeEvents
- **LED Blinking**: Automated LED1 blinking with asymmetric timing (200ms ON, 800ms OFF)
- **Button Handling**: Immediate LED0 response to button press/release events

## Hardware Requirements

- ESP32 development board (any variant)
- 2 LEDs connected to GPIO pins (configured in BSP)
- 1 button connected to GPIO pin (configured in BSP)
- Pull-up/pull-down resistors as needed

## GPIO Configuration

The example uses configurable GPIO assignments through ESP-IDF's menuconfig system:

**Default GPIO Assignments:**
- **LED0 (Red)**: GPIO 18 - Button feedback LED
- **LED1 (Blue)**: GPIO 19 - Blinking pattern LED  
- **Button**: GPIO 22 - User input (active low with internal pull-up)

**Configuration:**
GPIO pins can be customized via `idf.py menuconfig` under "Blinky Button Example" menu.

**Hardware Setup:**
- LEDs: Connect with appropriate current limiting resistors
- Button: Connected between GPIO and GND (internal pull-up enabled)

## Behavior

### LED1 (Blinking)
- **Pattern**: Asymmetric blinking
- **ON period**: 200ms (short flash)
- **OFF period**: 800ms (long pause)
- **Automatic**: Starts immediately when the application launches

### LED0 (Button Feedback) 
- **ON**: When button is pressed
- **OFF**: When button is released
- **Debounced**: Uses ESP-IDF iot_button component for reliable operation

### Button Events
- **BUTTON_PRESSED_SIG**: Generated on button press using iot_button component
- **BUTTON_RELEASED_SIG**: Generated on button release using iot_button component
- **Debouncing**: Automatic debouncing handled by ESP-IDF iot_button component

## Code Structure

### Active Object Design

```c
typedef struct {
    Active super;      // Inherit Active base class
    TimeEvent te;      // Time event for LED blinking
    bool isLedOn;      // Current LED1 state tracking
} BlinkyButton;
```

### Event Handling

The `BlinkyButton_dispatch()` function processes:

1. **INIT_SIG**: Initial event to start LED blinking
2. **TIMEOUT_SIG**: Timer expiry to toggle LED1 and re-arm timer
3. **BUTTON_PRESSED_SIG**: Turn LED0 ON immediately
4. **BUTTON_RELEASED_SIG**: Turn LED0 OFF immediately

### Memory Allocation

- **Stack**: `configMINIMAL_STACK_SIZE * 2` (static allocation)
- **Queue**: 10 events (static allocation)
- **Priority**: 1 (lowest user priority above idle)

### Dependencies

- **ESP-IDF**: v5.0 or higher
- **FreeAct ESP32**: Main component
- **ESP-IDF iot_button**: v4.1.4+ for reliable button handling

## Building and Running

### Prerequisites

- ESP-IDF v5.0 or higher
- FreeAct ESP32 component installed

### Build Commands

```bash
# Navigate to the example directory
cd examples/blinky_button

# Update the component version
vi main/idf_component.yml

# Configure GPIOs 
idf.py menuconfig
# Navigate to: Component config -> Blinky Button Example

# Build the project
idf.py build

# Flash and monitor
idf.py flash monitor
```

### Component Configuration

The example uses component dependencies defined in `main/idf_component.yml`:
- **FreeAct ESP32**: Main Active Object framework  
- **ESP-IDF iot_button**: Professional button handling with debouncing

### Expected Output

```
I (xxx) app: BlinkyButton example start
I (xxx) bsp: BSP initialized
I (xxx) bsp: Button interrupt enabled
```

You should observe:
- LED1 blinking with the specified pattern
- LED0 responding to button presses
- No console output after initialization (normal behavior)

## Key Learning Points

### 1. Active Object Pattern
- Encapsulation of state, behavior, and execution context
- Thread-safe communication via message passing
- Clean separation of event handling logic

### 2. Time Events
- Integration with FreeRTOS timers
- One-shot timer re-arming for periodic behavior
- ISR-safe timer operations

### 3. Professional Button Handling
- ESP-IDF iot_button component integration with Active Objects
- Automatic debouncing and noise filtering
- Task-context event posting (not ISR) using `Active_post()`
- Event-driven callback mechanism


## Customization

### Timing Adjustment

Modify the timing in `BlinkyButton_dispatch()`:

```c
TimeEvent_arm(&me->te, 200);  // ON period (ms)
TimeEvent_arm(&me->te, 800);  // OFF period (ms)
```

### Adding More Events

1. Define new signals in the enum
2. Add cases to the dispatch function
3. Post events from appropriate contexts

### Hardware Configuration

```bash
idf.py menuconfig
# Navigate to: Component config -> Blinky Button Example
# Configure: Red LED GPIO, Blue LED GPIO, Button GPIO
```

## Troubleshooting

### LEDs Not Working
- Check GPIO pin assignments in BSP
- Verify LED polarity and current limiting resistors
- Ensure adequate power supply

### Button Not Responding
- Verify button wiring (connect between GPIO and GND)
- Check GPIO configuration in menuconfig
- Ensure button is active-low (pressed = connected to GND)
- Verify iot_button component is working in logs

### Build Errors
- Ensure ESP-IDF v5.0+ is installed
- Verify FreeAct component is properly installed  
- Check component dependencies in `main/idf_component.yml`
- Ensure iot_button component v4.1.4+ is available

## Advanced Features

This example can be extended to demonstrate:
- **Multiple Active Objects**: Add more AOs for complex interactions
- **State Machines**: Implement hierarchical state machines within the dispatch function
- **Inter-AO Communication**: Show how Active Objects communicate with each other

## License

This example is part of the FreeAct ESP32 port and follows the same MIT License as the main component.

To create a project from this example, run:

idf.py create-project-from-example "ozanoner/freeact-esp32=0.1.1:blinky_button"

or download archive (~7.32 KB)