Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

라즈베리 파이를 이용해 원격 컴퓨터의 전원 스위치 제어

개발자라면 다들 공감하시겠지만, 사실 업무와 공부의 경계가 많이 모호한 면이 있습니다. 이 때문에 회사 컴퓨터를 켜놓고 집에서 접속해야 할 경우가 종종 있는데요, 그렇다 해도 많지는 않아서 항상 켜놓기에는 전기 사용이 좀 아깝습니다. 하지만, 꺼놓고 퇴근하자니 또 집에서 필요해지면 아쉽기 때문에 그러는 것도 좀 망설여지는데요.

그래서 ^^ 만들었습니다. 회사 컴퓨터의 전원을 원격으로 제어가 가능하도록 하는 것입니다.




이를 구현하기 위해, 6년 전에 구매했던 - 먼지가 내려앉은 넷두이노를 꺼냈습니다. ^^

.NET Micro Framework - 넷두이노 플러스
; https://www.sysnet.pe.kr/2/0/1392

(이제는 지원도 끊겨 버렸지만) 마지막 firmware 버전인 4.2.0.1로 업그레이드까지 하고 네트워크 구현까지 완료했지만... 아쉽게도 이더넷 LAN 포트가 접촉 불량 문제가 발생했습니다. 납땜의 문제는 아닌 것 같고 랜 소켓 자체가 내부에 이더넷 케이블과 접촉되는 공간이 유격이 발생한 듯 케이블을 살짝 움직일 때마다 네트워크 접속이 끊어져 버리는 것입니다.

할 수 없이 ^^; 다시 먼지가 쌓이도록 창고에 두고.

그다음 제가 가지고 있는 보드 중,


후보로 떠오른 것이 "라즈베리 파이 제로 W"입니다. WiFi를 기본 제공하고 RPi의 특성상 PC 환경에 준하는 개발 환경을 가지고 있기 때문에 프로그램 작성도 매우 용이합니다.

한 가지 아쉬운 것은 제가 가지고 있는 "라즈베리 파이 제로 W"가 Data Pin 쪽에 헤더가 납땜되어 있지 않은 모델이라는 점입니다. (혹시, 제로 W 모델을 구매하시려는 분이 있다면 "with Headers" 모델을 추천합니다.)

[그림 - 출처 http://www.icbanq.com/P008219607]
raspberry_pi_zero_w_with_no_pin_header_1.jpg

그래서 저걸로 Data Pin을 제어하려면 핀 헤더를 납땜해야 하는 불편함이 있습니다.

How to solder header pins to the Raspberry Pi Zero (W) 
; https://www.youtube.com/watch?v=UDdbaMk39tM

가벼운 문제라면, 제가 인두기가 없습니다. ^^ 고민하던 차에 생각난 것이 바로 FTDI 장치입니다.

PC에 연결해 동작하는 자신만의 USB 장치 만들어 보기
; https://www.sysnet.pe.kr/2/0/11606

FTDI 장치를 rpi에 연결하면 이후부터는 Serial port를 제어하는 방식으로 코딩할 수 있기 때문에 다음의 글에서 설명한 데로,

Raspberry PI Zero (W)에 FTDI 장치 연결 후 C/C++로 DTR 제어
; https://www.sysnet.pe.kr/2/0/11716

간단하게 해결할 수 있습니다.




남은 작업은 FTDI의 GND 선과 DTR 신호를 컴퓨터에 연결하는 것입니다. 참고로 제가 가지고 있는 "GIGABYTE GA-Z87-HD3" 메인 보드는,

GIGABYTE GA-Z87-HD3
; https://www.gigabyte.com/Motherboard/GA-Z87-HD3-rev-1x#ov

다음과 같은 PW+, PW- 핀 배열을 가지고 있습니다.

turn_on_the_device_1.png

따라서, FTDI의 GND를 PW-에 연결하고 DTR 선을 PW+에 연결하면 됩니다.

turn_on_the_device_2.png

참고로, PW+와 PW-간의 전압을 측정해 보면 약 3.347V가 나옵니다. FTDI의 DTR 라인은 아두이노의 데이터 핀처럼 별도의 전원을 제공하는 것이 아닌, 단순히 선을 연결해 주는 동작만 하는 것이기 때문에 컴퓨터 전원 스위치를 켜는 용도로 사용할 수 있습니다.

이렇게 연결을 한 후, FtdiApp 프로젝트의 소스 코드를 다음과 같이 변경해 DTR 신호를 사람이 Power 스위치를 누르는 동안 정도의 시간만큼 ON 시켜 주는 것으로 바꿔줍니다.

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>

using namespace std;

int main(int argc, char *argv[])
{
    // http://xanthium.in/Controlling-RTS-and-DTR-pins-SerialPort-in-Linux

    string portNumber = "0";
    string portName = "/dev/ttyUSB";

    if (argc < 2)
    {
        cout << "FtdiApp [portNumber]" << endl;
        cout << "ex - set DTR on /dev/ttyUSB0" << endl;
        cout << "\t" << "FtdiApp 0" << endl;
        return 1;
    }

    portNumber = argv[1];
    portName.append(portNumber);

    int fd = open(portName.c_str(), O_RDWR | O_NOCTTY);
    if (fd == -1)
    {
        cout << "NO Port: " << portName << endl;
        return 1;
    }

    int dtrFlag = TIOCM_DTR;
    ioctl(fd, TIOCMBIS, &dtrFlag);

    usleep(500 * 1000); // 500ms

    ioctl(fd, TIOCMBIC, &dtrFlag);
    close(fd);

    return 0;
}

자.. 이제 ^^ 컴퓨터 케이스를 열고 DTR, GND를 각각 PW+, PW- 선과 연결한 다음 Raspberry PI 콘솔에서 다음과 같이 실행해 주면,

$ ./FtdiApp.out 0

컴퓨터가 켜지는 것을 볼 수 있습니다. 마찬가지로 한 번 더 실행해 주면, 운영체제가 (제어판의 전원관리에서 설정한 동작에 따라) Shutdown이나 최대 절전 모드로 들어가게 됩니다.




주의할 것은, 반드시 DTR과 PW+를 연결하고 GND와 PW-를 연결해야 합니다. 컴퓨터 케이스의 Power Switch는 물리적으로 접점이 끊긴 것을 연결하는 것이기 때문에 +/- 극을 맞출 필요가 없지만 FTDI 장치는 극이 맞아야 합니다. 저도 내부적인 FTDI 장치의 배선을 몰라 자세하게 설명할 수는 없지만, 현상 자체는 DTR을 PW-, GND를 PW+에 연결하는 경우 그 순간 컴퓨터 전원이 들어오게 됩니다. 계측기로 + 단자를 DTR에 - 단자를 GND에 놓고 측정하면 저항이 무한대가 되지만, 그 반대로 하는 경우에는 약 250K 정도의 저항이 측정되는 걸로 봐서 선이 연결된 것과 유사한 역할을 하는 것 같습니다.

이제 나머지 문제는, "마감"을 훌륭하게 하는 것입니다. 대충 해 놓으면 동작은 하겠지만 실 사용 환경에서라면 좀 더 완성도를 높이는 게 좋습니다. 일단 FTDI와 라즈베리 파이를 연결하는 것은 USB 케이블로 깔끔하게 해결은 됩니다. 하지만 FTDI의 DTR, GND와 메인 보드 간의 연결을 하는 것은 그다지 매끄럽게 해결이 안 됩니다. 우선, 기존의 컴퓨터 케이스에 있는 Power Switch를 안 쓰는 걸로 가정하고 다음의 케이블을 사용할 수 있습니다.

PC 파워 전원 스위치 케이블/메인보드연결
; http://item.gmarket.co.kr/detailview/item.asp?goodscode=995567752

computer_power_cable_1.png

Female Header 부분이 메인 보드의 Power Pin에 정확히 연결할 수 있기 때문에 편리하긴 한데 문제는 반대쪽 스위치를 잘라내고 FTDI의 DTR, GND에 연결하는 것이 불편합니다. 이 케이블의 선은 단선이 아닌 연선인데다 제가 가지고 있는 와이어 스트리퍼 기준으로,

Vessel 3500E-2
; https://www.eleparts.co.kr/goods/view?no=5803

24AWG(0.5mm)로 피복이 벗겨지는데 따라서 FTDI의 DTR, GND 소켓에 끼우기에는 너무 얇습니다. (악어 클립으로 집는 것도 그다지 권장할 수 없습니다.)

차라리 그보다는 22AWG 단선으로 "PC 파워 전원 스위치 케이블"과 납땜으로 연결하거나, 아니면 Female-Female 케이블22AWG 단선으로 FTDI와 납땜 없이 연결하는 것이 좋습니다.




그런데 결론적으로는, 라즈베리 파이도 사용하지 않았습니다. 왜냐하면 이게 영... 마감이 좋지 않습니다. ^^; 라즈베리 파이 용 케이스도 구매해야 하고 라즈베리 파이 쪽에 별도의 휴대폰 어댑터로부터 5VDC도 공급해야 합니다. 당연히 필요한 것이 아니냐??? 라고 할 텐데, 제가 다른 방법을 하나 더 찾아냈습니다. 바로 회사 컴퓨터 외에 늘 켜져 있는 NAS 장비를 이용하는 것입니다.

Synology NAS(DS216+II)에 docker 설치 후 .NET Core 2.1 응용 프로그램 실행하는 방법
; https://www.sysnet.pe.kr/2/0/11713

이건 다음에 다시 정리해서 올리겠습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]





[최초 등록일: ]
[최종 수정일: 10/7/2018 ]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer@outlook.com

비밀번호

댓글 쓴 사람
 




1  2  3  4  5  6  7  8  9  [10]  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
12114정성태1/13/2020924디버깅 기술: 156. C# - PDB 파일로부터 심벌(Symbol) 및 타입(Type) 정보 열거 [1]파일 다운로드3
12113정성태1/12/20201301오류 유형: 590. Visual C++ 빌드 오류 - fatal error LNK1104: cannot open file 'atls.lib' [1]
12112정성태1/12/2020564오류 유형: 589. PowerShell - 원격 Invoke-Command 실행 시 "WinRM cannot complete the operation" 오류 발생
12111정성태3/23/20201430디버깅 기술: 155. C# - KernelMemoryIO 드라이버를 이용해 실행 프로그램을 숨기는 방법(DKOM: Direct Kernel Object Modification) [11]
12110정성태6/23/2020933디버깅 기술: 154. Patch Guard로 인해 블루 스크린(BSOD)가 발생하는 사례 [3]파일 다운로드1
12109정성태1/10/2020777오류 유형: 588. Driver 프로젝트 빌드 오류 - Inf2Cat error -2: "Inf2Cat, signability test failed."
12108정성태1/10/2020618오류 유형: 587. Kernel Driver 시작 시 127(The specified procedure could not be found.) 오류 메시지 발생
12107정성태1/10/2020710.NET Framework: 877. C# - 프로세스의 모든 핸들을 열람 - 두 번째 이야기
12106정성태1/8/2020799VC++: 136. C++ - OSR Driver Loader와 같은 Legacy 커널 드라이버 설치 프로그램 제작 [1]
12105정성태1/8/2020702디버깅 기술: 153. C# - PEB를 조작해 로드된 DLL을 숨기는 방법
12104정성태1/9/20201147DDK: 9. 커널 메모리를 읽고 쓰는 NT Legacy driver와 C# 클라이언트 프로그램 [4]
12103정성태4/23/20201927DDK: 8. Visual Studio 2019 + WDK Legacy Driver 제작- Hello World 예제 [1]파일 다운로드2
12102정성태1/6/20201289디버깅 기술: 152. User 권한(Ring 3)의 프로그램에서 _ETHREAD 주소(및 커널 메모리를 읽을 수 있다면 _EPROCESS 주소) 구하는 방법
12101정성태1/8/2020820.NET Framework: 876. C# - PEB(Process Environment Block)를 통해 로드된 모듈 목록 열람
12100정성태1/3/2020571.NET Framework: 875. .NET 3.5 이하에서 IntPtr.Add 사용
12099정성태1/3/2020802디버깅 기술: 151. Windows 10 - Process Explorer로 확인한 Handle 정보를 windbg에서 조회
12098정성태9/10/2020803.NET Framework: 874. C# - 커널 구조체의 Offset 값을 하드 코딩하지 않고 사용하는 방법 [3]
12097정성태1/2/2020608디버깅 기술: 150. windbg - Wow64, x86, x64에서의 커널 구조체(예: TEB) 구조체 확인
12096정성태1/2/2020821디버깅 기술: 149. C# - DbgEng.dll을 이용한 간단한 디버거 제작
12095정성태12/27/2019967VC++: 135. C++ - string_view의 동작 방식
12094정성태12/26/2019832.NET Framework: 873. C# - 코드를 통해 PDB 심벌 파일 다운로드 방법
12093정성태12/26/20191021.NET Framework: 872. C# - 로딩된 Native DLL의 export 함수 목록 출력파일 다운로드1
12092정성태12/25/2019877디버깅 기술: 148. cdb.exe를 이용해 (ntdll.dll 등에 정의된) 커널 구조체 출력하는 방법
12091정성태12/25/20191219디버깅 기술: 147. pdb 파일을 다운로드하기 위한 symchk.exe 실행에 필요한 최소 파일 [1]
12090정성태12/24/2019823.NET Framework: 871. .NET AnyCPU로 빌드된 PE 헤더의 로딩 전/후 차이점
12089정성태12/23/2019712디버깅 기술: 146. gflags와 _CrtIsMemoryBlock을 이용한 Heap 메모리 손상 여부 체크
1  2  3  4  5  6  7  8  9  [10]  11  12  13  14  15  ...