Tuesday, June 12, 2012

Overriding PSU Safety Features


So I have one of those computer PSUs that I converted into a "bench power supply;" not really that elegant, but it does the job. However, when I pull too much amps from it, it shuts off. This is a good thing, but one annoying part of it is that I have to disconnect the green wire from ground to reset the safety feature. Especially annoying when both my hands are occupied, holding wires to a capacitor.

I did the only sensible thing and overrode that safety feature, with the help of a certain programmable chip.


(Courtesy of ~underitall from DeviantArt. http://fav.me/d4hkxml)


My very professional-looking schematic of the circuit.




Pin 1 - D/C
Pin 2 - Input - Button with pull-down resistor (1KΩ Brown Black Red)
Pin 3 - Input - Red Wire (+5 VDC from PSU)
Pin 4 - Ground
Pin 5 - D/C
Pin 6 - Output - Status LED
Pin 7 - Output - Green Wire (PSU Power control)
Pin 8 - Vcc - Purple Wire (It provides +5 VDC even if the PSU is "off")


Prototype stage




Perfboard stage







  • When I just press the button, the PSU turns on, no safety features overridden. (State 1)
  • When I press and hold the button while the unit is on, the safety features are overridden. In this stage, the LED continually fades in and out, notifying the user of the possible danger that could occur. (State 2)
  • When the button is pressed again, the unit reverts back to ON. (State 1)
  • When the button is pressed once again, the unit turns off. (State 0)
When the green wire is provided +5 VDC (current sourcing), the PSU views it as disconnected, as when it isn't connected to anything, the voltage on the green wire is +5 VDC.
When it is pulled down to ground (current sinking), the PSU turns on.


And finally, here is the code:
(Get the Bounce Library here: http://www.arduino.cc/playground/Code/Bounce)

#include <Bounce.h>

#define pinLED 1
#define pinCtrl 2
#define pinButton 3
#define pinPower 4
int brightness = 0;
int state = 0; //0 is off, 1 is on, 2 is power


long timecurr = 0;
long timelater = 0;
#define period 500
#define holddown 1000


Bounce button = Bounce(pinButton,5);

void setup(){
  pinMode(pinLED, OUTPUT);
  pinMode(pinCtrl, OUTPUT);
  pinMode(pinButton, INPUT);
  pinMode(pinPower, INPUT);
}

void loop(){

  timecurr = millis();
 

  if(state == 0){
    digitalWrite(pinCtrl, HIGH);
    digitalWrite(pinLED, LOW);
   
    button.update();
    while(button.read() == HIGH){
      button.update();
      if(button.read() == LOW){
        state = 1;
      }
    }
  }
 
  else if(state == 1){
   
    digitalWrite(pinCtrl, LOW);
    digitalWrite(pinLED, HIGH);
   
    button.update();
    timelater = timecurr;
    while(button.read() == HIGH){
     
      timecurr = millis();
     
      if(timecurr - timelater > holddown){
        brightness = 128+127*cos((2*PI*millis())/period);
        analogWrite(pinLED, brightness);
        state = 2;
      }
     
      button.update();
      if(button.read() == LOW && state == 1){
          state = 0;
      }
    }
  }
 
  else{
   
    brightness = 128+127*cos((2*PI*timecurr)/period);
    analogWrite(pinLED, brightness);
   
    digitalWrite(pinCtrl, LOW);
    timelater = timecurr;
    while(digitalRead(pinPower) == LOW){
      digitalWrite(pinCtrl, HIGH);
     
      timecurr = millis();
      do{
        timelater = millis();
        brightness = 128+127*cos((2*PI*millis())/period);
        analogWrite(pinLED, brightness);
      }
      while(timelater - timecurr < 500);
     
      digitalWrite(pinCtrl, LOW);
     
      timecurr = millis();
      do{
        timelater = millis();
        brightness = 128+127*cos((2*PI*millis())/period);
        analogWrite(pinLED, brightness);
      }
      while(timelater - timecurr < 500);
       
    }
   
    button.update();
    while(button.read() == HIGH){
      button.update();
      if(button.read() == LOW){
        state = 1;
      }
    }
   
  }

}

Special Thanks to:

My computer science major friend for helping me debug the code

MIT's High Low Tech for their tutorial on putting Arduino on the Attiny.
My brother for buying me an Arduino for Christmas!
Hack-a-Day for featuring me! Click here.

11 comments:

  1. Hello, this is very interesting, but why are you printing Serial data? I didn't know you could use this fuction in the Attiny core. I just tried and it compiles but according of what i've read online it doesn't really works. I've read too that the Software serial works but with a bit of hacking.
    Thanks, great hack!

    ReplyDelete
  2. ...So, I copied your code to try it out, all the Serial printing is commented... then, my question is self-answered ;)

    ReplyDelete
    Replies
    1. Sorry, I should have stated:
      The serial print outs were for debugging when I was testing on an Arduino Uno.

      I will edit them out.

      Delete
  3. Nice hack.

    I love the 8-pin ATTinys for one off projects like this, have done a few myself.

    I notice you're using double sided pad-per-hole proto boards, and you've bridged some pads. Can I ask where you get the board you used? I have some I got from digikey but they are high quality ones with a solder mask which means its very hard to bridge pads to make ghetto tracks. I'm having trouble finding the cheap no-mask PPH boards suitable for this kind of prototyping.

    (I'm in Australia, so I need a source that will ship to there)

    ReplyDelete
    Replies
    1. This board also has a solder mask. All bridges you see are assisted by some type of wire. I chose to reuse the LED and capacitor leads, and splicing wires longer than usual.

      I believe I got that board from digikey as well.

      Delete
    2. Thanks (and dang).

      I got some nice cheap single-sided PPH boards from futurlec.com, but they don't have double-side-plated ones.

      Delete
  4. What value cap are you using?

    ReplyDelete
    Replies
    1. 100 uF. It's just to smooth out the power for the chip.

      Delete
    2. 100 uF. It's just to smooth out the power for the chip.

      Delete
  5. Hey everyone, here is a tidy version fo the shcematic I made in eagle cad:

    http://i988.photobucket.com/albums/af1/XOIIO/Eagle%20Cad/screenshot3.jpg

    And here is the board with as idea spacing and traces as I could make, note that the top layer trace is meant to be a jumper.

    http://i988.photobucket.com/albums/af1/XOIIO/Eagle%20Cad/screenshot4.jpg

    ReplyDelete
    Replies
    1. Thanks!

      Unfortunately, the schematic you posted does not match mine. It's my fault; I didn't have an eraser on hand!

      The capacitor is just between the purple, constant on 5V and ground, not really part of the circuit.

      One leg of the switch is directly connected to the constant on 5V, and the other connected to pin 2 of the attiny. It's just a simple button with a pull-down resistor.

      Thanks again for the schematic! If you fix it, may I use it to replace my awful drawing?

      Delete