Arduino Controlling Delta ASDA-B3 Servo Drive – Motor Won't Stop & Incorrect Speed Scaling

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:

  1. 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.
  1. 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 :folded_hands:

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);
    }
}

One thing jumps right out to me is you are doing a lot of time consuming calculations in the loop that runs the motor. Almost all of those are redundant and could be done before the "while" is begun. The same problem may be causing some of your other problems.