ATX PSU On/Off State Changing

Hello all,

I’m currently working on trying to control an ATX power supply (that will power two linear actuators) with an Arduino. I have the power supply all hooked up and whatnot and have confirmed that the Arduino can turn it on and off, I just don’t know how to control it under certain conditions.

  1. I want for the power supply to turn on right as I flip the switches for the linear actuators to activate. This is easy because I can just say the following
digitalWrite(psuOnOff, HIGH);
delay(5000);

before I tell my motors to run. This will enable the transistor that I have inside of the PSU, which will in turn allow it to power on. I also have the 5 second delay in there to ensure that the PSU turns on completely before any other commands are carried out.

  1. I want for the PSU to turn off after 30 seconds of no commands being sent to the actuators. This is really where I’m having trouble. I’m unsure of how to integrate keeping time with this requirement, and also with the next.

  2. I want for the counter to reset back to 0 if I issue a command before it reaches 30 seconds.

I’ve looked into finite state machines, but I’m unsure of whether or not this is what I need. Most FSMs that I have seen use the millis() function… but all that does is keep track of how long the program has been running, from what I understand. My program will be running continuously, so I don’t think that’s what I’m looking for.

Any help or suggestions would be appreciated. Thanks!

Hello,

millis() is used to keep track of time. If you save the value of millis() at one moment, and later compare this saved value with the actual value of millis(), you can calculate the time difference and do something if this difference reach a value.

When you issue a command, save the current value of millis() in a variable "previousTime". Constantly check if millis() minus "previousTime" is greater or equal 30 seconds, if yes, turn off PSU.

Here is a basic example:

const uint8_t buttonPin = 2;
const uint8_t ledPin = 13;

void setup()
{
  pinMode( buttonPin, INPUT_PULLUP );
  pinMode( ledPin, OUTPUT );
  
  // turn on LED
  digitalWrite( ledPin, HIGH );
}

void loop()
{
  uint32_t currentTime = millis();
  static uint32_t previousTime = currentTime;

  // if button is pressed, turn on LED, and record time
  if ( digitalRead( buttonPin ) == LOW )
  {
    digitalWrite( ledPin, HIGH );
    previousTime = currentTime;
  }

  // if time difference is greater than 2 seconds, turn off the LED
  if ( currentTime - previousTime >= 2000 )
    digitalWrite( ledPin, LOW );
}

The LED will turn on at start. If the button is not pressed within 2 seconds, the LED will turn off. If the button is pressed, the "timeout" is reset.

guix:
millis() is used to keep track of time. If you save the value of millis() at one moment, and later compare this saved value with the actual value of millis(), you can calculate the time difference and do something if this difference reach a value.

I can’t believe I didn’t think of that! So simple. I do like that idea, so if what I have doesn’t work, I’ll be using your method, surely. I just came up with a simple function that I call upon when all of my switches are set to LOW (actuators are off). Here it is:

int psuControl(){
    millis();
    count = millis();
    while (count < 30000){
        digitalWrite(psuOnOff, HIGH);
        if ((digitalRead(onOffSwitch1) != onOffSwitch1State) || (digitalRead(directionSwitch1) != directionSwitch1State) 
        || (digitalRead(onOffSwitch2) != onOffSwitch2State) || (digitalRead(directionSwitch2) != directionSwitch2State)){     //checks to see if any state changes have occurred
            count = 0;    //reset timer back to 0 
        }   
    }
    if (count == 30000){    //when the timer reaches 30 seconds, this statement will turn the PSU off
        digitalWrite(psuOnOff, LOW);
    }
}

I haven’t gotten the chance to test it yet, but I’m hoping that since I’m calling the millis() function at a specific time, instead of at the beginning of the entire program, that it will only count from when I called it.