Hello everyone,
I’m currently working on a fully programmable centrifuge using an Arduino board to control a Delta ASDA-B3 servo drive and a Delta ECM-B3 servo motor. My goal is to control acceleration, velocity, and stopping using position (PT) mode or PT-S or PT-T (position and speed or position and torque) via Arduino. However, I’m running into multiple issues and could really use some help troubleshooting.
1. Hardware:
- Microcontroller: Arduino Uno Rev4 WiFi
- Servo Motor: Delta ECM-B3M-C20604RS1 (400W, 3000 RPM, 1.27Nm, 220VAC)
- Servo Drive: Delta ASD-B3A-0421-E
- Power Supply: DRL-24V75W1AZ, DC 24V for control signals
User Manual for servo motor and servo drive (if using it, make sure to look for info for B3A-E drives): https://filecenter.deltaww.com/Products/download/06/060201/Manual/DELTA_IA-ASD_ASDA-B3_UM_EN_20230428.pdf
2. Wiring:
[Servo Drive CN1] to [Arduino or Power Supply or CN1]
- COM+ (pin 5) ---> +24V (+ end of power supply)
- GND (pin 10) ---> 0V (- end of power supply)
- DI1- (pin 6) ---> disconnected (when connected to GND, it disables the drive)
- PULL HI_S (pin 13) ---> COM+ (pin 5 of CN1)
- PULL HI_P (pin 14) ---> COM+ (pin 5 of CN1)
- SIGN- (pin 24) ---> Arduino pin 12 (direction control)
- PULSE- (pin 26) ---> Arduino pin 13 (pulse control)
- GND (pin 10) ---> Arduino GND (common ground)
3. Behaviour:
- The motor only runs when DI1- is disconnected.
- When DI1- is connected to GND, the drive disables the motor.
My goal:
- Control acceleration & velocity for two different motion profiles:
- Linear Acceleration → up to 250g
- Angular Acceleration → up to 10,000 rad/s²
- Stop the motor completely after running both acceleration cycles.
- Ensure correct speed scaling (right now, it’s much slower than expected).
Problems I'm facing:
- Motor Does Not Reach Expected Speed
- When running the program, the drive screen displays:
- ~480 when running slower phase
- ~1200 when running faster phase
- Based on my calculations, the motor should be much faster.
- I suspect the pulse rate calculation or gear ratio settings might be wrong.
- Motor Does Not Fully Stop
- After both 10-second acceleration cycles, the motor keeps spinning indefinitely.
- The screen displays values around 100-200 during this phase.
- The only way to stop it is manually connecting DI1- to GND.
Current drive configuration:
| Parameter | Value | Purpose |
|---|---|---|
| P1.000 | 0142 | PT Mode (Pulse + Direction) |
| P1.001 | 0000 | Enable PT Mode |
| P1.044 | 20000 | Electronic Gear Ratio Numerator |
| P1.045 | 10000 | Electronic Gear Ratio Denominator |
| P1.046 | 00000 | Pulse Input Filter (disabled) |
| P1.047 | 00300 | Max Pulse Frequency (Hz) (it's the maximum value it will let me select) |
| P1.055 | 03000 | Maximum Speed Limit (3000 RPM) |
Summary of problems:
- the motor speed is much lower than expected
- the motor does both 10s cycles and changes speed when it has to, but it never stops
- Maybe I should configure other parameters differently?
I would appreciate any help and insights anyone might have in solving these problems. Thank you in advance ![]()
Code:
This is the code I'm using.
// Control pins for Delta Servo Drive (PT Mode - Pulse + Direction)
const int dirPin = 12; // Direction control
const int pulsePin = 13; // Pulse train signal
// Constants
float g = 9.81; // Gravity (m/s^2)
float r_lin = 0.15; // Arm radius for linear acceleration (m)
float r_ang = 0.04; // Arm radius for angular acceleration (m)
// Input target accelerations
float lin_acc_target = 250 * g; // Linear acceleration (m/s^2)
float ang_acc_target = 10000; // Angular acceleration (rad/s^2)
// Motor parameters
int speed_rated = 3000; // Max rated speed (RPM)
float torque_rated = 1.27; // Max rated torque (Nm)
// Timing
int duration = 10000; // Each phase runs for 10s
void setup() {
pinMode(dirPin, OUTPUT);
pinMode(pulsePin, OUTPUT);
Serial.begin(115200);
}
void loop() {
// Phase 1: Achieve linear acceleration
float omega_lin = sqrt(lin_acc_target / r_lin); // Angular velocity (rad/s)
float rpm_lin = (omega_lin * 60) / (2 * PI); // Convert to RPM
float pulseRate_lin = (rpm_lin * 10000) / 60; // Convert RPM to pulses/sec
Serial.println("--- Running Linear Acceleration Phase ---");
Serial.print("Target RPM: "); Serial.println(rpm_lin);
runMotor(pulseRate_lin, duration);
// Phase 2: Achieve angular acceleration
float torque_required = ang_acc_target * r_ang; // Torque (Nm)
float omega_ang = sqrt(ang_acc_target / r_ang);
float rpm_ang = (omega_ang * 60) / (2 * PI);
float pulseRate_ang = (rpm_ang * 10000) / 60; // Convert RPM to pulses/sec
Serial.println("--- Running Angular Acceleration Phase ---");
Serial.print("Target RPM: "); Serial.println(rpm_ang);
Serial.print("Required Torque: "); Serial.println(torque_required);
runMotor(pulseRate_ang, duration);
// Stop the motor
Serial.println("--- Stopping Motor ---");
while (true) {
digitalWrite(pulsePin, LOW);
}
Serial.println("--- Motor Stopped---");
}
void runMotor(float pulseRate, int duration) {
unsigned long startTime = millis();
digitalWrite(dirPin, HIGH); // Set direction
while ((millis() - startTime) < duration) {
digitalWrite(pulsePin, HIGH);
delayMicroseconds(500000 / pulseRate); // Adjust pulse width
digitalWrite(pulsePin, LOW);
delayMicroseconds(500000 / pulseRate);
}
}