Skip to main content

HyperStudy TTL

An RP2040-based TTL pulse generator for HyperStudy experiments with electrical isolation via optocoupler.

Overview​

The HyperStudy TTL device generates precisely-timed TTL (Transistor-Transistor Logic) pulses that can trigger external equipment such as MRI scanners, EEG amplifiers, or other research hardware. It connects to HyperStudy experiments through the HyperStudy Bridge.

Signal Flow​

HyperStudy TriggerComponent → HyperStudy Bridge → RP2040 Firmware → TTL Output

Features​

  • Fast & Reliable: Sub-millisecond latency via USB serial communication
  • Electrical Isolation: HCPL-2211 optocoupler protects both devices
  • Bridge Compatible: Response format matches HyperStudy Bridge parser expectations
  • Easy Setup: PlatformIO-based firmware with comprehensive documentation
  • Configurable: Pulse duration adjustable at runtime (default 10ms) via serial command or Bridge settings

Hardware Requirements​

Components​

ComponentPart NumberPurpose
MicrocontrollerAdafruit Feather RP2040Main controller
OptocouplerHCPL-2211Electrical isolation
ResistorsVarious (see wiring)Current limiting
EnclosureOptionalProtection

Specifications​

  • Communication: USB serial, 115200 baud
  • Pulse Output: GPIO Pin 6 / D4 (active HIGH)
  • Pulse Duration: Configurable (default 10ms, range 1–10000ms)
  • USB Identification: VID 0x239A, PID 0x80F1
  • Unique Serial Number: Auto-generated from RP2040 flash chip ID
  • Firmware Version: 1.4.0+
  • Input Voltage: 5V (USB powered)
  • Output Voltage: 3.3V or 5V (depending on optocoupler configuration)

Firmware Installation​

  1. Install PlatformIO

    pip install platformio
  2. Clone the Repository

    git clone https://github.com/hyperstudyio/hyperstudy-ttl.git
    cd hyperstudy-ttl
  3. Upload Firmware

    cd firmware
    pio run --target upload
  4. Verify Installation

    pio device monitor

    Type TEST and press Enter. You should see OK:Test successful.

Alternative: Arduino IDE​

Alternative firmwares are provided in /examples for reference, but PlatformIO is recommended for production use.

Serial Commands​

The firmware accepts case-insensitive serial commands via USB:

CommandResponseDescription
PULSEOK:Pulse sentTriggers a TTL pulse using the default duration (10ms)
PULSE <ms>OK:Pulse sentTriggers a TTL pulse with the specified duration (1–10000ms)
SETDURATION <ms>OK:Duration set to <ms>msSets the default pulse duration (persists until reboot)
TIMINGOK:Timing us:<N>,dur:<ms>Reports last pulse's serial-to-GPIO latency in microseconds
SERIALOK:Serial <hex>Returns the board's unique serial number (from flash chip ID)
TESTOK:Test successfulValidates the serial connection
VERSIONOK:Version 1.4.0Returns firmware version
LONGPULSEOK:Long pulse sentTriggers a 3-second pulse for testing/visibility

Response Format​

All responses follow the pattern OK:<message> or ERROR:<message> for easy parsing by the HyperStudy Bridge.

Pulse Duration Configuration​

Pulse duration can be configured in three ways:

  1. Per-pulse override: PULSE 5 sends a 5ms pulse without changing the default
  2. Set default: SETDURATION 20 changes the default to 20ms (until device reboot)
  3. Via HyperStudy Bridge: Configure pulse_duration_ms in TTL device settings — the Bridge sends the duration with each PULSE command automatically

Wiring Diagrams​

Basic Wiring (Without Optocoupler)​

For testing or when isolation is not required:

Adafruit Feather RP2040
│
│ GPIO 6
▼
┌───────┐
│ 100Ω │ (current limiting resistor)
└───┬───┘
│
▼
TTL Output → External Device
│
▼
GND

Isolated Wiring (With Optocoupler)​

Recommended for production use to protect both the computer and connected equipment:

                    HCPL-2211
┌─────────────────┐
│ │
GPIO 6 ──────┤ 1 (Anode) 8 (Vcc2) ├──── +5V (external)
│ LED │
GND ─────┬───┤ 2 (Cathode) 7 (Vo1) ├──── TTL Output
│ │ │
│ │ ─┬─ │
│ │ /│\ │
│ │ ──┴── │
│ │ │
│ │ 3 (NC) 6 (Vo2) ├──── (not used)
│ │ │
└───┤ 4 (GND) 5 (GND2) ├──── GND (external)
│ │
└─────────────────┘

Component Values:
- R1 (GPIO to Anode): 330Ω (limits LED current to ~5mA)
- R2 (Pullup on Vo1): 4.7kΩ (optional, for faster rise time)

Detailed Optocoupler Wiring​

For step-by-step assembly instructions with photos, see OPTOCOUPLER_WIRING.md in the repository.

Key Points:

  • The optocoupler provides galvanic isolation between the RP2040 and external equipment
  • External equipment can use a different ground reference
  • Maximum isolation voltage: 3750V RMS (HCPL-2211 specification)

Usage with HyperStudy​

Setup​

  1. Connect the TTL Device to a USB port on the Bridge computer
  2. Open HyperStudy Bridge and configure the TTL device:
    • Port will be auto-detected by VID/PID
    • Verify connection status shows green
  3. Enable Kernel Integration in your experiment (Metadata tab)
  4. Add TriggerComponent to your experiment states

TriggerComponent Configuration​

In the Experiment Designer, add a TriggerComponent to send TTL pulses:

{
"type": "trigger",
"config": {
"triggerType": "ttl",
"label": "Trial Start"
}
}

Device Discovery​

The Bridge automatically detects HyperStudy TTL devices by their USB VID/PID. You can also manually find the port:

# macOS
ls /dev/tty.usbmodem*

# Linux
ls /dev/ttyACM*

# Or use the discovery script
python3 testing/find_ttl_port.py

Troubleshooting​

Device Not Detected​

  1. Check USB Connection

    • Try a different USB cable (some are power-only)
    • Try a different USB port
    • Avoid USB hubs if possible
  2. Verify Device is Recognized

    # macOS
    system_profiler SPUSBDataType | grep -A5 "RP2040"

    # Linux
    lsusb | grep 239a
  3. Check Permissions (Linux)

    sudo usermod -a -G dialout $USER
    # Log out and back in for changes to take effect

No Response to Commands​

  1. Check Baud Rate - must be 115200
  2. Verify Line Endings - use \n or \r\n
  3. Try the TEST command first to validate connection

Pulse Not Triggering External Device​

  1. Verify Wiring - check optocoupler connections
  2. Check Voltage Levels - ensure external device expects 3.3V or 5V
  3. Measure Output - use oscilloscope or multimeter to verify pulse
  4. Check Polarity - some devices expect active-LOW signals

Firmware Issues​

  1. Re-flash Firmware

    cd firmware
    pio run --target upload --upload-port /dev/tty.usbmodem*
  2. Enter Bootloader Mode

    • Hold BOOTSEL button while connecting USB
    • Device appears as USB mass storage
    • Drag .uf2 file to device

Technical Reference​

Timing Specifications​

ParameterValue
Pulse Duration10ms default (configurable 1–10000ms)
Rise Time<1μs
Fall Time<1μs
On-Device LatencyTypically <100μs (serial-available to GPIO toggle)
End-to-End Command Latency<1ms (Bridge to GPIO output)
Optocoupler Propagation~150–300ns
Minimum Inter-Pulse IntervalPulse duration + ~1ms

Pin Mapping​

FunctionGPIONotes
TTL Output6 (D4)3.3V logic level
Status LEDBuilt-inFlashes on pulse
USBNative115200 baud

Latency Measurement​

Understanding the Latency Chain​

When a TTL pulse is triggered from a HyperStudy experiment, the signal passes through several stages:

HyperStudy Web App
│
│ ① WebSocket message (~0.1–0.5ms)
▼
HyperStudy Bridge
│
│ ② USB serial write + bus transfer (~125μs–1ms)
▼
RP2040 Firmware
│
│ ③ Serial parse → GPIO toggle (<100μs, measured by TIMING command)
▼
HCPL-2211 Optocoupler
│
│ ④ Optical propagation (~150–300ns, negligible)
▼
TTL Output
StageWhat's MeasuredTypical Latency
① Bridge latencyWebSocket receive → serial write0.1–0.5ms
② USB bus latencySerial write → device receives125μs–1ms
③ On-device latencySerial available → GPIO toggle<100μs
④ Optocoupler propagationLED on → output transition~200ns

Total end-to-end latency (① through ④) is typically <1ms.

Querying On-Device Timing​

After sending a PULSE command, you can query the on-device measured latency with the TIMING command:

> PULSE
OK:Pulse sent
> TIMING
OK:Timing us:42,dur:10

This reports:

  • us:42 — 42 microseconds from serial data available to GPIO going HIGH
  • dur:10 — the pulse duration was 10ms

The Bridge also logs its own internal latency (stage ①) for each command.

Interpreting Results​

  • <1ms total: Expected performance with firmware v1.4.0+
  • 1–2ms total: Acceptable; may indicate USB hub or system load issues
  • >2ms total: Investigate — check for USB hubs, high CPU load, or other serial port consumers

Resources​


Release Notes​

v1.4.0​

Released: 2026-02-17

What's Changed​

New Features​

  • Configurable pulse duration: PULSE <ms> for per-pulse override, SETDURATION <ms> to change the default (range 1–10000ms)
  • On-device timing measurement: TIMING command reports serial-to-GPIO latency in microseconds
  • Unique board serial numbers: Each device auto-generates a unique USB serial descriptor from its RP2040 flash chip ID
  • SERIAL command: Query the board's unique identifier at runtime

Performance​

  • Removed delay(1) polling bottleneck: Tight polling loop reduces on-device latency from up to 1ms to typically <100μs
  • GPIO toggle happens immediately on command receipt — duration parsing occurs after the pin goes HIGH

Compatibility​

  • Requires HyperStudy Bridge v0.8.21+ (bridge now sends PULSE <duration> format)
  • Fully backward-compatible serial protocol (OK:/ERROR: response format unchanged)

Release notes are automatically synced from GitHub releases.