GitHub - monkeyToneCircuits/BlinkyTree

An interactive ATtiny85-powered Christmas tree with LED candle effects and breath-controlled music playback.

BlinkyTree in Action

Get your kit at BlinkyParts.com!

Demo

πŸŽ₯ Watch the demo video - Shows candle effect, breath detection, and melody playback with LED visualization

Features

  • πŸ•―οΈ Realistic Candle Effect - Four LED rings flicker independently
  • 🎀 Breath Detection - Blow to trigger songs or increase flicker intensity
  • 🎡 Music Playback - Built-in buzzer plays Christmas melodies
  • 🎨 LED Light Show - LEDs react to note frequencies
  • βš™οΈ Fully Customizable - Add your own songs via GitHub Actions (no coding required!)

🎡 Customize Your Songs (No Setup Required!)

Customize songs directly on GitHub - no local development environment needed!

  1. Fork this repository on GitHub
  2. Edit config.yaml to enable/disable songs and adjust settings
  3. Add MusicXML files to the songs/ folder (export from MuseScore, Finale, etc.)
  4. Push changes - GitHub Actions automatically builds your firmware
  5. Download the .hex file from Actions β†’ Artifacts
  6. Flash to your BlinkyTree - See FLASHING_GUIDE.md

Song Configuration

Edit config.yaml to customize each song:

songs:
  JINGLE_BELLS:
    enabled: true
    duty_cycle: 80      # Volume (10-100)
    speed: 150          # Tempo (25-200, 100=original)
    transpose: 0        # Pitch shift (-12 to +12 semitones)

Adding New Songs

  1. Export your melody as MusicXML (MuseScore: File β†’ Export β†’ MusicXML)
    • ⚠️ Important: In MuseScore, export as Uncompressed MusicXML (not .mxl)
    • File extension should be .musicxml
  2. Upload the .musicxml file to the songs/ folder
  3. Add an entry in config.yaml with the same filename (without extension)
  4. Commit and push - GitHub Actions builds your custom firmware!

Requirements: Single melody line, note range G3-B5, standard durations

Hardware

ATtiny85 Pinout:

      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 RESETβ”‚1  β€’      8 β”‚ VCC (+3-5V)
  MIC β”‚2         7 β”‚ LED_1ER
BUZZERβ”‚3         6 β”‚ LED_5ER (PWM)
  GND β”‚4         5 β”‚ LED_4ER (PWM)
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Pin Mapping:
Pin 1: PB5 (RESET) - ISP Programming
Pin 2: PB3 (MIC/LED_3ER) - Shared/Time-multiplexed
Pin 3: PB4 (BUZZER)
Pin 5: PB0 (LED_4ER) - Hardware PWM
Pin 6: PB1 (LED_5ER) - Hardware PWM  
Pin 7: PB2 (LED_1ER) - Software PWM

Components:

  • ATtiny85 microcontroller (8MHz internal)
  • 4 LED rings (1, 3, 4, 5 LEDs)
  • Electret microphone with peak detector
  • Piezo buzzer
  • Power: 3-5V (battery or USB)

Quick Start

Option 1: Flash Pre-Built Firmware

  1. Download the latest firmware from Releases
  2. Follow the FLASHING_GUIDE.md
  3. Use the included flash_firmware.bat (Windows) or flash_firmware.sh (Linux/macOS)

Option 2: Build Locally

Prerequisites:

  • PlatformIO Core or VS Code with PlatformIO extension
  • Python 3.11+ with PyYAML (pip install pyyaml)

Build and Upload:

pio run                    # Build firmware
pio run --target upload    # Upload to ATtiny85 (requires ISP programmer)

Flashing

Quick Flash

Windows: Double-click flash_firmware.bat
Linux/macOS: Run ./flash_firmware.sh

The scripts auto-detect your ISP programmer and flash automatically.

Manual Flash

# USBasp
avrdude -c usbasp -p attiny85 -U flash:w:firmware.hex:i

# AVRISPv2  
avrdude -c avrisp2 -P usb -p attiny85 -U flash:w:firmware.hex:i

Need help? See the complete FLASHING_GUIDE.md for:

  • ISP programmer setup and connections
  • Driver installation (Windows)
  • Fuse configuration
  • Detailed troubleshooting

How It Works

Startup

  1. Hardware initialization (LEDs, microphone, buzzer)
  2. Microphone calibration
  3. Candle effect starts automatically

Operation

Idle: Four LED rings flicker independently with realistic candle simulation

Light Breath: Candle flicker intensity increases proportionally

Strong Breath: Triggers a random song from your enabled playlist

Configuration

Song Settings (config.yaml)

Edit config.yaml to customize songs - this is what most users will need:

songs:
  JINGLE_BELLS:
    enabled: true
    duty_cycle: 80      # Volume/tone (10-100)
    speed: 150          # Tempo (25-200, 100=original)
    transpose: 0        # Pitch shift (-12 to +12 semitones)

Hardware Settings (config.yaml)

All hardware behavior can now be customized through config.yaml:

hardware:
  # LED system
  led_brightness_default: 30     # Base LED brightness (10-100)
  candle_flicker_speed: 150      # Candle flicker rate in ms (50-500, lower=faster)
  candle_flicker_intensity: 70   # Flicker intensity percentage (20-100)
  
  # Audio system  
  song_cooldown: 3000           # Time between songs in ms (1000-10000)
  note_separation: 50           # Gap between notes in ms (0-200)
  startup_melody: false         # Play song at startup (true/false)
  
  # Sensor settings
  breath_sensitivity: 1          # Breath detection threshold (1-50, lower=more sensitive)
  sensor_update_rate: 5         # Sensor check interval in ms (1-50, lower=more responsive)

These settings are automatically converted to firmware configuration during compilation.

Project Structure

BlinkyTree/
β”œβ”€β”€ config.yaml                    # Song configuration (edit this!)
β”œβ”€β”€ songs/*.musicxml               # MusicXML song files
β”œβ”€β”€ src/main.cpp                   # Main application
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ Audio/                     # Audio system
β”‚   β”‚   β”œβ”€β”€ audio.h/cpp           # Core audio engine
β”‚   β”‚   └── audio_songs_generated.* # Auto-generated from MusicXML
β”‚   β”œβ”€β”€ Lighting/                  # LED effects
β”‚   β”œβ”€β”€ Hardware/                  # GPIO/PWM/ADC abstraction
β”‚   └── Sensors/                   # Microphone processing
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ generate_audio_code.py    # MusicXML β†’ C converter
β”‚   └── pre_build.py              # Build automation
β”œβ”€β”€ flash_firmware.bat/.sh         # Automated flashing scripts
└── FLASHING_GUIDE.md             # Detailed flashing instructions

Troubleshooting

LEDs not working:

  • Check power supply (3-5V)
  • Verify LED polarity

Microphone not responding:

  • Adjust BREATH_STRONG_THRESHOLD in config/config.h (lower = more sensitive)
  • Check microphone circuit connection (Pin 2)
  • Verify calibration during startup

Upload fails:

  • Verify ISP connections (all 6 pins)
  • Check programmer COM port in platformio.ini

See FLASHING_GUIDE.md for more details.

Default Memory Usage

  • Flash: ~5KB / 8KB (60-70%)
  • RAM: ~150 bytes / 512 bytes (25-30%)

Resources

License

CC-BY-NC 4.0 - Non-commercial use only

You may share and adapt this project with attribution to monkeyToneCircuits.
See LICENSE for details.


Made with ❀️ by monkeyToneCircuits