Skip to content

Hidden-Layer-Media/driftone

Repository files navigation

🎵 DRIFTONE MINI - ESP32 Lo-Fi Beat Sequencer

A handheld 6-track step sequencer inspired by the Elektron Model:Samples workflow. Create lo-fi beats with touch control, real-time BPM adjustment, and custom sample loading from SD card.

Status Platform License

Features

  • 6 audio tracks with individual step sequences
  • 16-step sequencer with visual grid interface
  • PWM audio output via ESP32 internal DAC (GPIO25)
  • Resistive touchscreen control with stylus support
  • microSD card sample loading (8-bit unsigned mono .raw files)
  • Real-time BPM control (60-200 BPM)
  • Minimalist black/red UI design
  • Modular code architecture for easy expansion

📦 Bill of Materials (BOM)

Core Components

Part Description Qty Example Part # Approx. Cost
ESP32 Dev Board ESP32-DevKitC or compatible 1 ESP32-DevKitC-32D $8-15
TFT Display Adafruit 2.8" ILI9341 TFT + Resistive Touch 1 Adafruit 1770 / 2478 $35-40
microSD Card 2GB-32GB FAT32 formatted 1 SanDisk 8GB $5
Breadboard 830 point solderless breadboard 1 - $5
Jumper Wires Male-to-male breadboard wires (20 pack) 1 - $3
Stylus Capacitive/resistive stylus (optional) 1 - $2

Audio Output Components

Part Description Qty Notes
3.5mm Audio Jack Panel mount or PCB mount 1 Stereo jack (use tip + sleeve)
10μF Capacitor Electrolytic or ceramic, 16V+ 1 For DC blocking
1kΩ Resistor 1/4W, through-hole 1 Current limiting

Optional Components (for permanent build)

Part Description Qty Notes
Prototype PCB Universal perfboard 1 For permanent soldering
Power Bank 5V USB power bank 1 For portable operation
Enclosure 3D printed or project box 1 Protect electronics
Power Switch SPST toggle or slide switch 1 For power control

Total Estimated Cost: $60-80 USD (excluding optional components)

Where to Buy

Wiring Diagram

TFT Display (SPI)

ESP32     | ILI9341
----------|----------
GPIO23    | MOSI
GPIO18    | CLK
GPIO19    | MISO
GPIO5     | CS
GPIO2     | DC
GPIO4     | RST
3.3V      | VCC
GND       | GND

Resistive Touchscreen

ESP32     | Touch Pin
----------|----------
GPIO34    | Y+ (YP) - Must be analog input capable
GPIO33    | X- (XM) - Must be digital I/O capable
GPIO14    | Y- (YM) - Must be digital I/O capable
GPIO32    | X+ (XP) - Must be analog input capable

Note: On ESP32, GPIO34-39 are input-only pins. GPIO34 is used for YP as it needs analog reading capability.

SD Card

ESP32     | SD Card
----------|----------
GPIO23    | MOSI
GPIO18    | CLK
GPIO19    | MISO
GPIO15    | CS
3.3V      | VCC
GND       | GND

Audio Output

ESP32     | Audio Circuit
----------|----------
GPIO25    | Signal → [1kΩ] → [10μF] → 3.5mm Jack Tip
GND       | 3.5mm Jack Sleeve

Audio Circuit Explanation:

  • The 1kΩ resistor limits current from GPIO25
  • The 10μF capacitor blocks DC offset and passes audio signal
  • Connect capacitor with correct polarity (negative side to jack)
  • Use tip and sleeve of stereo jack (ring can be left unconnected)

🔧 Step-by-Step Assembly Guide

Step 1: Prepare the ESP32

  1. Inspect the ESP32 board for any damage
  2. Identify GPIO pins using the pinout diagram for your specific board
  3. Connect ESP32 to computer via USB to verify it powers on
  4. Test basic communication using Arduino IDE's Serial Monitor

Step 2: Connect the TFT Display

  1. Power off the ESP32 (disconnect USB)
  2. Connect SPI pins from ESP32 to TFT display:
    • GPIO23 (MOSI) → TFT MOSI
    • GPIO18 (CLK) → TFT CLK
    • GPIO19 (MISO) → TFT MISO
    • GPIO5 → TFT CS (Chip Select)
    • GPIO2 → TFT DC (Data/Command)
    • GPIO4 → TFT RST (Reset)
  3. Connect power: ESP32 3.3V → TFT VCC, GND → TFT GND
  4. Double-check connections before powering on

⚠️ Warning: Ensure 3.3V (NOT 5V) is used for the TFT to avoid damage.

Step 3: Connect the Touchscreen

  1. Locate touch pins on the TFT shield (Y+, X-, Y-, X+)
  2. Connect touchscreen pins:
    • Touch Y+ → ESP32 GPIO34
    • Touch X- → ESP32 GPIO33
    • Touch Y- → ESP32 GPIO14
    • Touch X+ → ESP32 GPIO32
  3. Note: GPIO34 is input-only on ESP32 (perfect for analog touch reading)

Step 4: Connect the SD Card

  1. Insert formatted SD card into TFT shield (if built-in) OR use separate SD module
  2. Connect SD card pins (shares SPI bus with TFT):
    • Same MOSI, CLK, MISO as TFT
    • GPIO15 → SD CS (separate chip select)
    • 3.3V → SD VCC, GND → SD GND

Step 5: Build Audio Output Circuit

  1. Solder components in this order:
    GPIO25 → [1kΩ resistor] → [10μF capacitor +] → [3.5mm jack tip]
                                       [cap −] → GND
    ESP32 GND → [3.5mm jack sleeve]
    
  2. Check polarity on electrolytic capacitor (stripe = negative)
  3. Test connections with multimeter (check for shorts)

Step 6: Final Assembly

  1. Organize wiring to prevent shorts and tangles
  2. Secure components to breadboard
  3. Label connections with tape/labels for future reference
  4. Take photos of your wiring for troubleshooting later

Step 7: Power Test

  1. Visual inspection of all connections
  2. Connect USB power and check for:
    • ESP32 power LED should light up
    • TFT backlight should turn on
    • No burning smell or excessive heat
  3. If any issues, power off immediately and check wiring

💻 Software Setup

Arduino IDE Configuration

  1. Install ESP32 board package in Arduino IDE
  2. Install required libraries:
    • Adafruit GFX Library
    • Adafruit ILI9341
    • TouchScreen
    • SD

Project Structure

DriftRiffMini/
├── main.cpp           # Main application loop
├── sequencer.h/cpp    # Sequencer logic and step management
├── ui.h/cpp          # User interface and display handling
├── audioengine.h/cpp # PWM audio output and sample playback
├── sdloader.h/cpp    # SD card sample loading
└── touchscreen.h/cpp # Touch input processing

SD Card Setup

Create the following folder structure on your SD card:

/samples/
├── kick.raw
├── snare.raw
├── hihat.raw
├── perc.raw
├── bass.raw
└── lead.raw

Sample Format

  • Format: 8-bit unsigned mono
  • Sample Rate: 22,050 Hz
  • File Extension: .raw
  • Max Size: 32KB per sample

Converting Audio to Raw Format

Using Audacity:

  1. Import your audio file
  2. Convert to Mono (Tracks → Mix → Mix and Render)
  3. Set Project Rate to 22050 Hz
  4. Export → Export OtherRaw (header-less)
  5. Choose Unsigned 8-bit PCM

🚀 Quick Start Guide

First Time Setup (5 minutes)

  1. Format SD card to FAT32 format
  2. Create folder /samples/ on the SD card root
  3. Add sample files (kick.raw, snare.raw, hihat.raw, perc.raw, bass.raw, lead.raw)
    • Use the provided sample files OR convert your own (see "Converting Audio" below)
  4. Insert SD card into the TFT shield
  5. Upload code to ESP32 via Arduino IDE
  6. Open Serial Monitor (115200 baud) to view startup messages
  7. Wait for "DRIFTONE MINI Ready!" message
  8. Touch the grid to start creating beats!

🎹 Usage

Basic Operation

  1. Power on - Device initializes and loads samples
  2. Touch grid squares to toggle steps on/off
  3. Red squares = active steps
  4. White outline = current playing step
  5. Touch +/- buttons to adjust BPM
  6. Touch PLAY/PAUSE to control playback

Default Pattern

The sequencer starts with a basic demo pattern:

  • Track 0 (KICK): Steps 1, 5, 9, 13
  • Track 1 (SNARE): Steps 5, 13
  • Track 2 (HIHAT): Every other step

Track Assignment

  • Track 0: KICK - kick.raw
  • Track 1: SNARE - snare.raw
  • Track 2: HIHAT - hihat.raw
  • Track 3: PERC - perc.raw
  • Track 4: BASS - bass.raw
  • Track 5: LEAD - lead.raw

Customization

Adding New Samples

  1. Convert audio to 8-bit unsigned mono .raw format
  2. Copy to /samples/ folder on SD card
  3. Rename to match expected filenames
  4. Restart device to reload samples

Modifying UI Colors

Edit color definitions in ui.h:

#define COLOR_BG        ILI9341_BLACK
#define COLOR_STEP_ON   ILI9341_RED
#define COLOR_CURRENT   ILI9341_WHITE

Adjusting Audio Output

Modify audio parameters in audioengine.h:

#define SAMPLE_RATE         22050
#define MAX_CONCURRENT_SAMPLES 4

🔧 Troubleshooting

Problem: "SD CARD ERROR" on startup

Symptoms: Red error message on screen, device halts at startup

Solutions:

  1. Verify SD card is inserted correctly
  2. Format SD card as FAT32 (not exFAT or NTFS)
    • Windows: Right-click drive → Format → FAT32
    • Mac: Disk Utility → Erase → MS-DOS (FAT)
  3. Check SD card wiring:
    • CS pin must be GPIO15 (not shared with TFT)
    • Verify SPI bus connections (MOSI, MISO, CLK)
  4. Try different SD card (some cards have compatibility issues)
  5. Check Serial Monitor for detailed error messages

Problem: Touch Not Responding / Inaccurate

Symptoms: Touches register in wrong location or not at all

Solutions:

  1. Run touch calibration:
    • Call touchHandler.calibrate() in setup()
    • Follow on-screen prompts to touch 5 calibration points
    • Copy the calibration values to touchscreen.h:
    #define TS_MINX 150  // Replace with your values
    #define TS_MINY 120
    #define TS_MAXX 920
    #define TS_MAXY 940
  2. Verify touch wiring:
    • GPIO34 (Y+) - Must be input-capable pin
    • GPIO33 (X-)
    • GPIO14 (Y-)
    • GPIO32 (X+)
  3. Use stylus instead of finger for better precision
  4. Check Serial Monitor for touch coordinate readings

Problem: No Audio Output

Symptoms: Device works but no sound from headphones/speakers

Solutions:

  1. Check audio circuit:
    • GPIO25 → 1kΩ resistor → 10μF capacitor → jack tip
    • ESP32 GND → jack sleeve
    • Verify capacitor polarity (negative to GND)
  2. Check Serial Monitor for "Audio engine initialized" message
  3. Verify samples loaded:
    • Serial should show "Loaded sample 0 (XXXX bytes): /samples/kick.raw"
    • If not, samples failed to load from SD card
  4. Test output:
    • Use headphones (line-level output, not amplified)
    • Volume may be low - increase with setMasterVolume()
  5. Check PWM output:
    • Use multimeter on GPIO25 (should show ~1.65V DC)
    • Use oscilloscope to verify PWM signal

Problem: Samples Not Loading

Symptoms: "Warning: Some samples failed to load" in Serial Monitor

Solutions:

  1. Verify folder structure on SD card:
    /samples/
      kick.raw
      snare.raw
      hihat.raw
      perc.raw
      bass.raw
      lead.raw
    
  2. Check file names are EXACTLY as shown (case-sensitive)
  3. Verify sample format:
    • Must be RAW PCM format (no WAV header)
    • 8-bit unsigned mono
    • 22,050 Hz sample rate
    • .raw extension
  4. Check file size - must be < 32KB each
  5. Re-export samples using Audacity (see "Converting Audio")

Problem: Memory Issues / Crashes

Symptoms: Device resets, "Guru Meditation Error", or random crashes

Solutions:

  1. Reduce sample sizes:
    • Keep samples under 32KB each
    • Shorter samples = less memory usage
  2. Adjust max sample size in sdloader.h:
    #define MAX_SAMPLE_SIZE 16384  // Reduce from 32768 to 16KB
  3. Monitor memory via Serial output
  4. Simplify patterns - fewer concurrent samples

Problem: Display Not Working

Symptoms: Blank screen, garbled display, or backlight only

Solutions:

  1. Check power: Ensure 3.3V (NOT 5V) to TFT
  2. Verify SPI connections:
    • MOSI, MISO, CLK must be correct
    • CS, DC, RST pins critical for communication
  3. Test with simple sketch:
    • Use Adafruit GFX library test examples
    • Verify display works before running Driftone code
  4. Check screen rotation: Code uses tft.setRotation(3) for landscape

Problem: Touch Calibration Not Working

Symptoms: Calibration routine doesn't complete or values seem wrong

Solutions:

  1. Use stylus for precise calibration
  2. Touch firmly but not too hard
  3. Wait for visual feedback (green circle) after each point
  4. Restart calibration if values seem incorrect
  5. Manual calibration:
    • Open Serial Monitor
    • Touch corners and note raw X/Y values
    • Calculate min/max for each axis
    • Update touchscreen.h manually

Problem: "No available sample slots" Warning

Symptoms: Some samples don't play when many triggers happen at once

Explanation: This is expected behavior! The audio engine supports maximum 4 concurrent samples (polyphony limit). When more than 4 tracks trigger simultaneously, some samples will be dropped.

Solutions:

  • Adjust patterns to avoid too many simultaneous triggers
  • Increase MAX_CONCURRENT_SAMPLES in audioengine.h (may impact performance):
    #define MAX_CONCURRENT_SAMPLES 6  // Increase from 4 to 6
  • Use shorter samples so they finish playing before next trigger

Still Having Issues?

  1. Check Serial Monitor at 115200 baud for detailed debug messages
  2. Verify ESP32 board is functioning (try basic LED blink test)
  3. Check all physical connections - loose wires are common culprit
  4. Try known-good components to isolate faulty parts
  5. Take photos of your setup and compare to wiring diagrams
  6. Open an issue on GitHub with:
    • Full error message from Serial Monitor
    • Photos of your wiring
    • SD card contents
    • ESP32 board model

Future Enhancements

Planned Features

  • Pattern chaining and song mode
  • Real-time effects (bitcrush, delay, reverb)
  • Sample recording via I2S microphone
  • MIDI sync input/output
  • Parameter automation
  • Multiple pattern banks

Hardware Expansions

  • Rotary encoders for parameter control
  • Hardware buttons for track mute/solo
  • LED indicators for visual feedback
  • External audio input for sampling
  • Battery power with charging circuit

License

Open source hardware/software project. Feel free to modify and share!

Credits

Inspired by Elektron Model:Samples workflow and designed for lo-fi beat making enthusiasts.


Happy beat making! 🎵

About

handheld super lofi sampler/sequencer on esp32 + tft resistive touchscreen

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages