Can I Safely Use a PC ATX Power Supply to Directly Power an Arduino for Sequential Control of a 12V BLDC Motor and Actuator?

I am planning to control a 12V BLDC motor and a 12V actuator with an Arduino, using a PC ATX Power Supply for power. Each motor will be operated using a motor driver, and I aim to control the speed of the motors via the Arduino UNO. The two motors will not run at the same time but will operate sequentially, with a delay between their operations. I am considering powering both motors and the Arduino directly from the ATX supply. The power output required is 60W for the BLDC motor and 20W for the actuator, while the ATX 12V can deliver up to 15A. Can I safely connect the ATX's 12V directly to the Arduino's DC barrel jack to power it?

Did you measure the 12 V with your volt meter? Is the voltage actually 12 volts?

1 Like

Is there any 5 volt available? That could power the 5 volt pin on the Arduino.
Applying 12 volt to Vin noting should use the 5 volt pin.

1 Like

When using desktop PC sources we have to protect the outputs with fuses suitable for our circuit as they are "powerful" and can supply high currents which in certain cases can even generate "fire".

1 Like

With appropriate protection they should work just fine. Use fuses to limit the current to what your circuits can support. You can power it with a 12V source but do not connect much of a load to the Arduino the regulator will be at max.

2 Likes

Older ATX power supplies required a certain amount of load on the +12V to properly regulate. I don't know if newer units require a load

2 Likes

Are you sure it is the 12V that needs the load? I had to add a 10 Ohm power resistor to the 5V line to make the 12V start regulating.

4 Likes

I checked 12V, 5V output terminals of power source. I think they are all at an appropriate level.

Then just do it.

1 Like

Thank you for your opinions and feedback. To add to my previous explanation, I had concerns about the possibility of power insufficiency when powering the Arduino with the 5V supply from an ATX power source. My plan involves using a BLDC motor driver to control the speed with a potentiometer, taking the speed signal from the motor driver to display it on an I2C LCD screen, and showing the motor startup time on a TM1637 segment display. The actuator will be controlled with a joystick in an up/down manner and is designed to operate only after the BLDC motor has stopped. Upon researching in forums, I learned that applying a constant load to the ATX 5V can stabilize the 12V output, so I am planning to use a 10W block resistor for this purpose. If the Arduino can be sufficiently powered with just a 5V input in this setup, I will certainly consider using the 5V supply. Thank you

It also has a 5V power source. i have also considering 12V to 9V using the LM2596 module.

Totally, works great. Adapt this to your needs.
https://www.dimensionengineering.com/appnotes/atxguide/atxguide.htm

2 Likes

Thank you for your valuable opinions.
I have never experienced working on such a project with Arduino before, but I have gained confidence with your help.

I plan to attach a 10 ohm, 10W fixed load to the 5V line of the ATX power and connect the 12V to a BLDC motor and an actuator, while the 5V will be connected to an Arduino and the hall sensor of the BLDC motor driver. I'm considering using a breadboard with the Arduino to supply power to an LCD and a segment display from the 5V output line, and connect the motor driver, actuator motor driver, potentiometer, and joystick to the common ground (GND). The code has been written with the help of ChatGPT.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TM1637Display.h>

// LCD configuration
LiquidCrystal_I2C lcd(0x27, 16, 2);

// TM1637 configuration
TM1637Display tmDisplay(6, 7);

// Pins for BLDC motor and actuator control
const int potPin = A0; // Potentiometer pin for motor speed control
const int motorPin = 9; // PWM pin for BLDC motor control
const int upButtonPin = 4; // Up button pin
const int downButtonPin = 5; // Down button pin
const int actuatorDirectionPin = 10; // Actuator direction control pin
const int actuatorPowerPin = 12; // Additional actuator power control pin

// FG signal and timing variables
const int fgPin = 2; // FG signal pin
volatile unsigned int pulseCount = 0;
const float motorPoles = 2.0;
unsigned long lastUpdateTime = 0;
unsigned long motorStartTime = 0;
bool motorRunning = false;

// Variables for dot blinking
bool dotState = false;
unsigned long lastBlinkTime = 0;
const long blinkInterval = 500;

void countPulse() {
  pulseCount++;
}

void setup() {
  Serial.begin(9600);
  pinMode(potPin, INPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(upButtonPin, INPUT_PULLUP);
  pinMode(downButtonPin, INPUT_PULLUP);
  pinMode(actuatorDirectionPin, OUTPUT);
  pinMode(actuatorPowerPin, OUTPUT); // Set the power control pin to output

  attachInterrupt(digitalPinToInterrupt(fgPin), countPulse, RISING);

  lcd.init();
  lcd.backlight();
  tmDisplay.setBrightness(0x0f);
}

void loop() {
  int potValue = analogRead(potPin);
  int motorSpeed = map(potValue, 0, 1023, 0, 255);
  analogWrite(motorPin, motorSpeed);

  if (motorSpeed > 0 && !motorRunning) {
    motorStartTime = millis();
    motorRunning = true;
  } else if (motorSpeed == 0 && motorRunning) {
    motorRunning = false;
    unsigned long motorRunTime = millis() - motorStartTime;
    displayRunTime(motorRunTime); // Display motor run time on TM1637
  }

  unsigned long currentMillis = millis();
  if (currentMillis - lastUpdateTime >= 1000) {
    lastUpdateTime = currentMillis;

    noInterrupts();
    float frequency = pulseCount / 1.0; // Frequency in Hz
    pulseCount = 0;
    interrupts();

    float rpm = (frequency / motorPoles) * 60.0; // Calculate RPM

    // Calculate actual shaft RPM (with gearbox)
    float shaftRPM = rpm / 101.0; // Applying gear ratio of 1/101

    // Display actual shaft RPM on LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Motor RPM:");
    lcd.setCursor(0, 1);
    lcd.print(shaftRPM, 2); // Display with two decimal places
  }

  // Actuator direction and power control
  if (digitalRead(upButtonPin) == LOW) {
    digitalWrite(actuatorDirectionPin, HIGH); // Forward direction
    analogWrite(actuatorPowerPin, 255); // Turn on actuator power (switch to PWM signal)
  } else if (digitalRead(downButtonPin) == LOW) {
    digitalWrite(actuatorDirectionPin, LOW); // Reverse direction
    analogWrite(actuatorPowerPin, 255); // Turn on actuator power (switch to PWM signal)
  } else {
    analogWrite(actuatorPowerPin, 0); // Turn off actuator power
  }

  // Dot blinking processing and runtime display logic
  if (currentMillis - lastBlinkTime > blinkInterval) {
    lastBlinkTime = currentMillis;
    dotState = !dotState;

    if (motorRunning) {
      displayRunTime(currentMillis - motorStartTime);
    }
  }
}

void displayRunTime(unsigned long runTime) {
  int minutes = (runTime / 60000) % 60;
  int seconds = (runTime % 60000) / 1000;

  // Re-encode for displaying minutes and seconds
  uint8_t displayData[4] = {
    tmDisplay.encodeDigit(minutes / 10),
    tmDisplay.encodeDigit(minutes % 10) | (dotState ? 0x80 : 0), // Add a dot between minutes
    tmDisplay.encodeDigit(seconds / 10),
    tmDisplay.encodeDigit(seconds % 10)
  };

  tmDisplay.setSegments(displayData);
}

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.