d-Drive and 30DV50/300
This page covers the d-Drive modular amplifier family, its features, and how to use it with psj-lib.
Overview
The d-Drive is piezosystem jena’s modular piezo amplifier series, designed for precision nanopositioning and high-dynamic control applications. Each d-Drive unit can contain 1-6 independent amplifier channels in a compact enclosure.
The 30DV50/300 is a single-channel amplifier that shares the same command set and capability model as d-Drive. It is ideal for compact, single-axis setups.
Hardware Specifications
Digital Control System
Resolution: 20-bit DAC and ADC (1,048,576 steps)
Sample Rate: 50 kHz (20 µs control loop period)
Control Loop: Digital PID with feedforward compensation (PCF)
Channel Capabilities
Each d-Drive channel provides comprehensive control capabilities:
Status and Monitoring
Status Register: Real-time hardware state flags
Temperature: Internal amplifier temperature monitoring
Actuator Description: Connected piezo description readout
Fan Control: Active cooling fan management
Position Control
Setpoint: Voltage and position target setting
Position: Actor position readback
Closed-Loop Controller: Enable/disable feedback control
Slew Rate: Maximum rate of change limiting
Control System
PID Controller: Proportional-Integral-Derivative tuning
Pre-Control Factor (PCF): Feedforward compensation
Notch Filter: Resonance suppression
Low-Pass Filter: Signal noise reduction
Error LPF: PID error signal filtering
Signal Generation
Waveform Generator: Function generation (sine, triangle, sweep, etc.)
Modulation Source: External or internal signal modulation
Monitor Output: Configurable analog output routing
Data Acquisition
Data Recorder: Two-channel data capture (500k samples)
Trigger Out: Hardware trigger generation (TTL output)
Accessing Capabilities
All capabilities are accessed as channel attributes. The d-Drive provides both standard piezo capabilities and device-specific implementations.
from psj_lib import DDriveDevice, TransportType
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
# Access any capability as a channel property
status = await channel.status_register.get()
position = await channel.position.get()
await channel.setpoint.set(50.0)
Using PSJ 30DV series
The 30DV50/300 exposes a single channel (ID 0) with the same capabilities as a d-Drive channel:
from psj_lib import PSJ30DVDevice, TransportType
device = PSJ30DVDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
await channel.closed_loop_controller.set(True)
await channel.setpoint.set(10.0)
Channel Capabilities Reference
All d-Drive channel capabilities with API references:
Property |
API Reference |
Description |
|---|---|---|
|
|
Hardware status with d-Drive specific flags (actuator detection, sensor type, waveform status) |
|
Actuator identification and specifications |
|
|
Target position control (write-only, readback is cached client-side) |
|
|
Actual position readback (read-only, updates every 500ms) |
|
|
Amplifier electronics temperature monitoring |
|
|
Cooling fan enable/disable control (Presence of fan is hardware dependent) |
|
|
Feedback control enable/disable |
|
|
Maximum rate of change limiting |
|
|
Pre-control factor (feedforward compensation) |
|
|
PID controller configuration (P, I, D, diff filter) |
|
|
Notch filter for resonance suppression |
|
|
Low-pass filter for signal conditioning |
|
|
Error signal low-pass filter |
|
|
Modulation input source selection (expects |
|
|
Analog monitor output routing (expects |
|
|
Multi-waveform generator with 5 types (sine, triangle, rectangle, noise, sweep) and automated scan function |
|
|
Two-channel recorder: position + voltage, 500k samples max, 50 kHz sample rate |
|
|
Hardware trigger output with d-Drive specific offset parameter |
d-Drive Status Register
The DDriveStatusRegister provides d-Drive specific hardware state information:
from psj_lib import DDriveDevice, TransportType
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
status = await channel.status_register.get()
# d-Drive specific status flags
print(f"Actuator plugged: {status.actor_plugged}")
print(f"Sensor type: {status.sensor_type.name}")
print(f"Voltage enabled: {status.piezo_voltage_enabled}")
print(f"Closed-loop: {status.closed_loop}")
print(f"Active waveform: {status.waveform_generator_status.name}")
print(f"Notch filter: {status.notch_filter_active}")
print(f"Low-pass filter: {status.low_pass_filter_active}")
Key d-Drive Status Flags:
actor_plugged: Actuator physically connected and detectedsensor_type: Position sensor type (SensorTypeenum)piezo_voltage_enabled: High voltage output enabledclosed_loop: Closed-loop feedback control activewaveform_generator_status: Active waveform type (DDriveWaveformGeneratorStatusenum)notch_filter_active: Notch filter enabled statuslow_pass_filter_active: Low-pass filter enabled status
d-Drive Waveform Generator
The DDriveWaveformGenerator provides 5 waveform types and automated scanning:
Waveform Types (DDriveWaveformType):
SINE: Sinusoidal waveformTRIANGLE: Triangular waveform with adjustable duty cycleRECTANGLE: Square/rectangular waveform with duty cycleNOISE: Random noise for ditheringSWEEP: Linear sweep/ramp (time in seconds for full cycle)
Basic Usage:
from psj_lib import DDriveDevice, DDriveWaveformType, TransportType
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
wfg = channel.waveform_generator
# Configure sine wave
await wfg.sine.set(
amplitude=20.0, # 20 µm peak-to-peak
offset=50.0, # Center at 50 µm
frequency=10.0 # 10 Hz
)
# Activate sine waveform
await wfg.set_waveform_type(DDriveWaveformType.SINE)
# Stop waveform
await wfg.set_waveform_type(DDriveWaveformType.NONE)
Automated Scan Function:
The d-Drive supports automated single or double scan cycles:
from psj_lib import DDriveScanType
# Start automated single triangle scan
await wfg.start_scan(DDriveScanType.TRIANGLE_ONCE)
# Check if scan is still running
while await wfg.is_scan_running():
await asyncio.sleep(0.1)
print("Scan completed")
Scan Types (DDriveScanType):
SINE_ONCE: Single sine cycleTRIANGLE_ONCE: Single triangle cycle (up and down)SINE_TWICE: Two sine cyclesTRIANGLE_TWICE: Two triangle cyclesOFF: No automated scan
See Base Capabilities for base waveform generator documentation.
d-Drive Data Recorder
The DataRecorder records two channels simultaneously at up to 50 kHz:
Channel Mapping:
Channel 1: Position sensor signal
Channel 2: Actuator voltage
Key Specifications:
Maximum 500,000 samples per channel
50 kHz sample rate (20 µs period)
Stride (decimation) support for longer duration at lower rate
Both channels always record same length
Basic Usage:
from psj_lib import DDriveDevice, DDriveDataRecorderChannel, TransportType
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
recorder = channel.data_recorder
# Configure for 1 second at 50 kHz
await recorder.set(
memory_length=50000, # 50k samples at 50 kHz = 1 sec
stride=1 # No decimation
)
# Start recording
await recorder.start()
# ... perform motion or waveform ...
# Retrieve data
position_data = await recorder.get_all_data(
DDriveDataRecorderChannel.POSITION
)
voltage_data = await recorder.get_all_data(
DDriveDataRecorderChannel.VOLTAGE
)
See Base Capabilities for base data recorder documentation.
d-Drive Data Format:
The d-Drive recorder returns data that is automatically parsed by DDriveDataRecorder:
Position Channel: Returns percentage of full closed-loop motion range (includes ±30% overshoot capability)
Voltage Channel: Returns output voltage in Volts
Configuration Notes:
get_memory_length()returns 500000 (maximum hardware capacity)get_stride()returns 0 (d-Drive doesn’t support reading this back)
d-Drive Closed-Loop Controller
The DDriveClosedLoopController extends the base controller with d-Drive specific status reading:
from psj_lib import DDriveDevice, TransportType
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
controller = channel.closed_loop_controller
# Enable closed-loop control
await controller.set(True)
# Check status via status register (d-Drive specific)
is_enabled = await controller.get_enabled()
print(f"Closed-loop active: {is_enabled}")
# Get control loop frequency
period = controller.sample_period # 20 µs for d-Drive
frequency = 1000000 / period # 50 kHz
print(f"Control loop: {frequency:.0f} Hz")
Key Features:
Reads closed-loop state from hardware status register (bit 7)
50 kHz control loop (20 µs sample period)
Integrated with PID controller for precise position control
d-Drive Setpoint
The DDriveSetpoint provides setpoint control with client-side caching:
from psj_lib import DDriveDevice, TransportType
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
channel = device.channels[0]
# Set target position
await channel.setpoint.set(50.0) # 50 µm
# Read back cached value (not from hardware)
target = await channel.setpoint.get()
print(f"Target: {target} µm")
# Compare with actual position
actual = await channel.position.get()
error = target - actual
print(f"Position error: {error:.3f} µm")
Important Notes:
get()returns the cached value, not a hardware readd-Drive hardware does not support reading back setpoint
Cache is updated only when
set()is calledIf setpoint is changed by another application, cache will be stale
Initial cache value is 0.0 before first
set()call
Multi-Channel Coordination
d-Drive devices support 1-6 channels. Use parallel operations for efficient multi-channel control:
from psj_lib import DDriveDevice, TransportType
import asyncio
device = DDriveDevice(TransportType.SERIAL, "COM3")
async with device:
# Enable closed-loop on all channels in parallel
await asyncio.gather(*[
ch.closed_loop_controller.set(True)
for ch in device.channels
])
# Move all channels simultaneously
positions = [30.0, 50.0, 70.0]
await asyncio.gather(*[
ch.setpoint.set(pos)
for ch, pos in zip(device.channels, positions)
])
Next Steps
Explore detailed capability documentation:
Getting Started: Getting Started - Basic device control and position feedback
Base Capabilities: Base Capabilities - Control system, filtering, data acquisition, and signal generation
Examples: Examples - Real-world use cases and complete applications