자작 파워서플라이 개조 아두이노 프로젝트

아두이노/프로젝트

대학교 기말고사기간이 되니 공부는 하기싫어지고 평소에는 별로 하지도 않던것에 관심이 가기 시작해서 구상한 파워서플라이 개조.  


안쓰는 컴퓨터파워로 3.3V 5V 12V 출력과 USB충전(퀵차지 포함)을 만들 생각이였다.

여기서 아두이노를 더해 전압체크와 전류체크, 소비전력(W)계산 모니터링 및 고온알림 기능을 추가하였습니다.



사용부품:
하이박스, ON/OFF 스위치 4개, USB 2구 암단자 2개, 가변저항 100k 및 노브, 0.96인치 OLED, I2C 16*2 LCD, TFX 파워 서플라이, 바나나 플러그 5개, 아두이노 나노, 7805 레귤레이터, ACS712 전류센서 5A 3개, 100k옴 및 10k옴 4개, 만능기판, 터미널 블록, 적색 LED 2개, 스탭다운 USB 퀵 차지 모듈 2개, 2채널 릴레이, 1채널 릴레이, ADS1115 16비트 ADC, 방열판, MT3608 스탭업 전원모듈, DHT11 온습도센서, 수동부저, RTC모듈, 80mm 팬 2개


* 파란색은 알리익스프레스에서 구입한 제품

* 빨간색은 국내에서 구입한 제품


총 가격: 20달러 + 21,000원 = 약 42,000원



여기다 계속 쓰기위해서 산 납땜도구들, 니퍼 플라이어, 롱노우즈 플라이어, 와이어 스트리퍼 등을 다 합하면 10만원정도 든것 같지만... 이건 계속 쓸거니 초기투자로 생각합니다 ^^...



*주의*

파워서플라이를 사용한 프로젝트로 고전류가 흐를수 있으니, 개조시 전기에 대해 해박한 분의 조언을 받으시길 바랍니.


- 4년전쯤 친구 컴퓨터에서 가져온 FSP 240W TFX 파워서플라이 -



- 파워스펙, 각 출력별로 6A이상 쓸 생각이 없으므로 이정도면 충분합니다 -



위의 파워를 이용해 3.3V 5V 12V의 각 출력을 바나나플러그를 이용해 일반 직류전원 공급기처럼 만들고 MT3608 스탭업모듈과 가변저항을 이용해 5V~24V의 전압을 따로 공급할수 있게 할 예정입니다.


또한 파워에 여러가지 색깔의 선이 있는데 여기에 어떤 색이 어떤 전압이 있는지 알 수 있습니다. 

주황색은 3.3V, 빨간색은 5V, 노란색은 12V1 12V2(듀얼레일), 검은색은 GND입니다.

초록색의 PS_ON은 GND와 연결시켜주면 전원이 켜지는 방식입니다.

보라색의 5VSB는 5V StandBy로써, 전원이 꺼진상태에서도 5V를 출력시켜줍니다. 보통 전원이 꺼진 컴퓨터에서 USB충전목적으로 쓰입니다.



- 일반적인 직류전원 공급기의 모습(OPE-303QI) -




본론으로 넘어가, 본격적으로 만드는 과정을 시작하겠습니다.


우선 이번 프로젝트에서 가장 중요한 아두이노 나노의 핀맵사진입니다.



3.3V, 5V 12V, ADJ(Adjustable) 의 전압을 확인하기 위해 A0, A1, A2, A7포트를 이용했습니다. 아두이노의 아날로그핀은 0~5V까지만 확인가능하므로, 전압분배회로를 만들어 전압을 낮춘 뒤 아두이노에서 읽어들여 다시 계산해야합니다. 


위 사진이 전압분배회로입니다. R1과 R2가 같다면, Vout은 Vin의 절반이 출력됩니다. 전 100k옴과 10k옴 저항을 이용해 1/10으로 낮춰서 사용했습니다. 

예를들어 12V가 Vin에 입력되면 Vout으로 1.2V가 출력됩니다. 아두이노에서 이 값을 불러들여 *10을 해주면 됩니다.


I2C 프로토콜을 사용하는 LCD, OLED, ADS1115는 주소만 다르게 지정해주면 A4 A5단자에 모두 연결가능합니다. 릴레이는 총 3개로, 5V충전, 퀵차지 충전, 5VSB에 연결되있습니다. 앞의 2개는 내부온도가 55도 이상으로 올라가면 차단되게 만들었고, 5VSB는 추후 이야기하겠습니다.


-TIP- 아두이노 나노의 아날로그핀을 디지털핀처럼 사용할 수 있는 건 A0~A5까지입니다. A6에 5VSB 릴레이를 사용하려고 했지만 적용이 안돼 알아보니 A6, A7은 아날로그핀 전용으로만 사용할 수 있습니다.





메인기판은 아두이노 나노를 꼽을수 있는 핀헤더 + ADS1115 ADC + ACS712전류센서에 정확한 5V값을 주기위한 7805레귤레이터 + DHT11 온습도센서 + 수동부저 로 이루어져 있습니다.


제가 산 ACS712전류센서는 션트저항을 통해서 전류를 측정하는게 아닌 비접촉 홀 이펙트기반 모듈이라 정밀도가 낮은데, 아두이노의 아날로그핀도 10bit의 분해능밖에 가지지 못해 16bit(실제론 15bit)의 분해능을 가진 ADS1115 아날로그 디지털 컨버터모듈을 사용했습니다. 또한 ACS712전류센서는 특성상 주위 노이즈에 약하고 입력전압에 따라 값이 변동하므로 필터 커패시터를 추가해주고 7805선형레귤레이터로 전원공급을 했습니다.


-TIP- ADS1115 아날로그 to 디지털 컨버터는 정품모듈이 아닌경우 오차가 심합니다. 이경우 초기 보정을 시켜줘야 원하는 값을 구할 수 있습니다.


위 사진에선 안나와있지만, 12V를 메인기판에서 받아 7805레귤레이터와 아두이노의 VIN에 나눠주는데, 선형레귤레이터특성상 7V의 손실이 열로 바뀝니다. 이를 줄여주고자 중간에 다이오드 5개정도를 직렬로 연결해 8.5V로 낮춰서 공급해주게 만들었습니다.


USB충전모듈은 전원리플을 줄이기 위한 전해커패시터와 고주파를 줄이기 위한 세라믹 커패시터를 추가했습니다. 이건 없어도 무방합니다. 스탭다운 USB 퀵 차지 모듈은 12V입력을 받아 퀄컴 퀵차지, 삼성 어댑티브 패스트 차징을 지원하는 모듈을입니다. 알리에서 개당 1.3달러정도에 구입했습니다. 이 모듈이 방열처리가 안돼있어 따로 추가해줬습니다.


전압분배모듈은 위에서 설명한것과 같이 100k옴과 10k옴을 이용해 출력 전압을 1/10으로 낮췄습니다.


MT3608 스탭업 모듈은 3.3V의 입력을 받아 최대 24V의 출력을 낼 수 있는 모듈입니다. 가변저항으로 연결해 저항을 높히면 전압도 높아지는 형식입니다. 최대 2A까지 가능하지만, 0.3A이상 넘어가면 고주파음이 발생합니다.





파워와 각종 모듈들을 담을 수 있게 가공한 하이박스입니다. 이게 프로그래밍이나 모듈 납땜하는것보다 더 힘들었습니다. 타공위치를 그리는것도 힘들지만, 특히나 사각형을 만드는게 여간 쉬운게 아니더군요... 드릴로 뚫은뒤에 칼이나 사포같은걸로 정리해주었습니다. 그래도 좀 많이 엉성하게 보입니다.




전면 조립과정입니다. 얼추 잘 맞아서 다행이네요. ㅎㅎ




      


내부 모습과 누드테스트 장면입니다. 다행히 잘 작동합니다.


-TIP- DS1302 RTC모듈을 사용할때, 시간출력이 정상적으로 나오다가 갑자기 이상한 값이 섞여서 나오는 경우가 있습니다. 이럴땐 VCC핀을 빼서 자체 건전지로만 구동되게 하면 정상적으로 출력이 됩니다.





완성된 모습입니다. 선들이 좀 많이 어지럽혀져 있는데, 쇼트날일 없게 모두 수축튜브 처리해주고 이후에 캡톤테이프랑 케이블타이로 정리해주었습니다. 문제는 공기순환이 잘 안된다는것인데, 아두이노 나노와 다른 모듈들이 원래 저전력지향이라 발열이 심하지 않아 사용에 문제는 없었습니다.




      





3.35V 5.13V 12.4V 9.65V(가변)출력 확인 모습입니다. 아두이노로 측정된 내부 LCD에서 3.3V 5.10V, 12.4V 9.71V 오차범위 5%내로 거의 똑같음을 알수있습니다.


-TIP- 완벽한 12V출력을 내기 위해서는 5V출력에 10~40옴가량의 시멘트 저항을 걸어주면 됩니다. 




 


퀵차지 모듈은 충전 전압, 전류를 잴 수 없어, 입력단 전원인 12V의 전압, 전류를 측정하였습니다. 때문에 전력부분만 확인하면 됩니다. (전력 = 전압 * 전류) OLED에선 4.9W, USB테스터에선 4.35W로, 퀵차지모듈의 변환효율 90%를 생각하면 얼추 맞습니다. 이부분은 아두이노 프로그래밍을 다시해서 보정해주었습니다.


5V충전은 거의 완벽하게 들어맞네요. OLED: 5V 1.15A 5.8W, USB테스터: 4.94V 1.176A 5.809W





LCD 옆 버튼을 올리면 현재시간도 나옵니다. 일종의 부가기능인데, 평소에는 USB만 쓰니까 시간확인용으로 쓰기위해서 달아놨습니다. 그 왼쪽빨간색버튼은 LCD on/off 스위치입니다.



아래는 제가 코딩한 소스코드입니다. 필요하신분 있으실까 해서 올립니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include "DHT.h"
#include "U8glib.h"
#include <Wire.h> 
#include <DS1302.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_ADS1015.h>
Adafruit_ADS1115 ads(0x48);
 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
LiquidCrystal_I2C lcd(0x3F162);
 
DHT dht(2, DHT11); //DHT11 온습도 모듈 - D2
 
DS1302 rtc(8910); //RTC모듈 - D8,D9,D10
 
float input3 = 0float input5 = 0float input12 = 0float inputadj = 0;
float vout3 = 0float vout5 = 0float vout12 = 0float voutadj = 0;
 
int16_t adc0; int16_t adc1; int16_t adc2; int16_t adc3;
float adcv0 = 0.0float adcv1 = 0.0float adcv2 = 0.0float adcv3 = 0.0;
float Amps0 = 0.0float Amps1 = 0.0float Amps2 = 0.0;
 
float watt0 = 0.0float watt1 = 0.0;
 
 
void setup() {
  
  pinMode(3,OUTPUT); //ALP1205S 피에조 부저 - D3
  pinMode(4,OUTPUT); //릴레이1 - D4
  pinMode(5,OUTPUT); //릴레이2 - D5
  pinMode(6,INPUT_PULLUP); //LCD 화면 변경  on할때 0, off하면 1
  pinMode(7,INPUT_PULLUP); //화면 딜레이  on할때 0.4초, off하면 3초
  pinMode(11,OUTPUT); //5V LED - D11
  pinMode(12,OUTPUT); //QC LED - D12
  pinMode(A3,OUTPUT);  //5V StandBy 릴레이 제어
 
  ads.begin();
 //ads.setSPS(ADS1115_DR_128SPS); 
 
  lcd.begin();
  lcd.backlight();
  
  u8g.setFont(u8g_font_unifont);
  
  digitalWrite(A3, HIGH); //5V StandBy 릴레이 OFF
}
 
 
 
void loop() {
  //3.3V 5V 12V 전압 측정
  input3 = analogRead(A0); input5 = analogRead(A1); input12 = analogRead(A2); inputadj = analogRead(A7);
  vout3 = input3*5.0/1024.0/0.091; vout5 = input5*5.0/1024.0/0.091; vout12 = input12*5.0/1024.0/0.091;
  voutadj = inputadj*5.0/1024.0/0.091;
 
  //ADS1115 ADC모듈 측정 1ch:5V전류, 2ch:QC전류, 3ch:ADJ 전류, 4ch:ADJ 전압
  adc0 = ads.readADC_SingleEnded(0+ 2830; adc1 = ads.readADC_SingleEnded(1+ 2820;
  adc2 = ads.readADC_SingleEnded(2+ 2830//adc3 = ads.readADC_SingleEnded(3) + 2950;
  adcv0 = adc0 * 0.1875; adcv1 = adc1 * 0.1875;
  adcv2 = adc2 * 0.1875//adcv3 = (adc3 * 0.1875)/100; //전류를 구하는 adcv0~2는 mV가 필요하므로 /1000안함.
  Amps0 = ((adcv0 - 2500/ 185); Amps1 = ((adcv1 - 2500/ 185); Amps2 = ((adcv2 - 2500/ 185);
  if(Amps0<0) {Amps0 = 0;} if(Amps1<0) {Amps1 = 0;} if(Amps2<0) {Amps2 = 0;} //0미만은 0으로
 
  //전력계산
  watt0 = vout5 * Amps0; watt1 = vout12 * Amps1;
 
  //DHT11 온습도 측정
  int temp = dht.readTemperature();  // 변수 temp에 온도 값을 저장
  int humid = dht.readHumidity();  // 변수 humid에 습도 값을 저장 
 
 
  
  //LCD 출력
  if (digitalRead(6== HIGH) {   //LCD 기본화면: 전압 및 전류
    lcd.clear();
    lcd.print(vout3,1); lcd.print("V ");
    lcd.print(vout5,2); lcd.print("V ");
    lcd.print(vout12,1); lcd.print("V");
    lcd.setCursor(0,1); //2번째줄
    lcd.print("ADJ: ");
      if (voutadj >= 10) {
        lcd.print(voutadj,1); lcd.print("V ");
      }
      else {
        lcd.print(voutadj,2); lcd.print("V ");
      }
    lcd.print(Amps2,2); lcd.print("A ");
    lcd.print(temp); lcd.print("'");
  } 
  else {   //LCD 다른화면: 시계
    lcd.clear();
 
    lcd.print(rtc.getDOWStr());
    lcd.setCursor(12,0); lcd.print(temp); lcd.print((char)223); lcd.print("C");
    lcd.setCursor(4,1); lcd.print(rtc.getTimeStr());
  }
 
 
  //OLED 출력
  u8g.firstPage();  
    do {
    //1번째 줄
    u8g.drawStr( 015"A:");
    u8g.setPrintPos(2015); 
    u8g.print(vout12,1);
    u8g.drawStr( 5315"V ");
    u8g.setPrintPos(7215); 
    u8g.print(Amps1,2);
    u8g.drawStr( 10515"A");
      
    //2번째 줄
    u8g.setPrintPos(2030);
    u8g.print(watt1,1);
    u8g.drawStr( 5330"W");
    u8g.setPrintPos(8530);
    u8g.print(temp);
    u8g.drawStr( 10030"'C");
      
    //3번째 줄
    u8g.drawStr( 045"B:");
    u8g.setPrintPos(2045); 
    u8g.print(vout5,1);
    u8g.drawStr( 5345"V ");
    u8g.setPrintPos(7245); 
    u8g.print(Amps0,2);
    u8g.drawStr( 10545"A");
      
    //4번째 줄
    u8g.setPrintPos(2060);
    u8g.print(watt0,1);
    u8g.drawStr( 5360"W");
    u8g.setPrintPos(8560);
    u8g.print(humid);
    u8g.drawStr( 10060"%");
    } while( u8g.nextPage() );
  
 
  //온도 상승알림
  if (temp >= 60) {
    digitalWrite(4,HIGH); //릴레이1 OFF
    digitalWrite(5,HIGH); //릴레이2 OFF
    
    lcd.clear();
    lcd.print("Temp is too high");
    lcd.setCursor(0,1);
    lcd.print("Temp: "); lcd.print(temp); lcd.print("'C");
    
    analogWrite(3,256);
    delay(1000);
    analogWrite(3,128);
    delay(100);
  }
  else {   //LCD 다른화면: 시계
    digitalWrite(4,LOW); //릴레이1 ON
    digitalWrite(5,LOW); //릴레이2 ON
 
  }
 
 
  //5V LED (0.35A이하시 OFF)
  if (Amps0 >= 0.35) {
    digitalWrite(11,HIGH); 
  }
  else { 
    digitalWrite(11,LOW); 
  }
  
  //QC LED (0.15A이하시 OFF)
  if (Amps1 >= 0.15) {
    digitalWrite(12,HIGH); 
  }
  else { 
    digitalWrite(12,LOW); 
  }
 
 
  //화면딜레이
  if (digitalRead(7== HIGH) {
  digitalWrite(A3, HIGH); //5V StandBy 릴레이 OFF
  delay(3000); 
  } 
  else {
  digitalWrite(A3, LOW); //5V StandBy 릴레이 ON
  delay(400); 
  }
}
 
 
/*
SETUP에 넣기
  rtc.halt(false);
  rtc.writeProtect(false);
  rtc.setDOW(THURSDAY);
  rtc.setTime(21,48,0);
  rtc.setDate(27,2,2019); 
*/
 
cs





+) 전원을 끈 상태에서 파워서플라이 고주파음이 들리는 경우가 있습니다.

파워코드만 꼽아도 고주파음이 들리는 상태인데 원인을 못찾고 파워코드에 on/off스위치를 달까 생각도 해보고 코일에 글루건을 쏴서 떨림을 없얼까도 생각해봤습니다.


하지만 해결책은 의외로 간단했습니다.

5VSB에 10W 40옴의 저항을 연결해주니 고주파음이 사라졌습니다. 아마 파워코드를 꼽으면 커패시터에 충전된 전압이 코일을 거쳐 계속해서 고주파를 만들어낸게 아닌가... 생각합니다. 

40옴의 저항에서 사용하는 전력은 0.675W로 최대 버틸수 잇는 10W의 1/15정도지만, 충분한 방열대책을 세우기 위해 방열판을 붙이고 철제 파워케이스에 서멀구리스로 접착시켰습니다. 



- 5년전에 한번사서 계속해서 쓰고있는 녹투아 H1 서멀구리스 -





- 40옴 10W 시멘트 저항에 방열판과 서멀구리스를 발라 파워에 붙였습니다 -





일반 서멀구리스는 접착력이 낮으므로 순간접착제를 주위에 발라 고정시켰습니다. 또한 릴레이를 연결해 전원이 켜지면 자동으로 5VSB와 저항의 연결을 끊어 불필요한 전력소모를 없애도록 하였습니다.


깨끗한 12V출력을 위해서는 5V에 저항을 걸어주면 된다는 말을 앞에서 했는데, 이를 위해서 OLED 옆에있는 스위치

에 이 릴레이를 연결시켜 스위치를 켜면 5VSB에 연결되도록 만들었습니다.



완성된 모습입니다. 이제 단자에 설명만 적어주면 되는데 귀찮아서 안하고 있습니다 ㅋㅋㅋ....


MT3608을 빼고 CC CV기능이 있는 모듈을 넣을지 고민입니다. 


궁금한것 있으시면 댓글로 남겨주세요 아는범위내에서 답변드리겠습니다.