Home [IR light] 전등 리모컨 제작기 - 3
Post
Cancel

[IR light] 전등 리모컨 제작기 - 3

관련 포스팅


3. PC 프로그램 제작

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
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QGridLayout, QLabel, QComboBox, QPushButton, QDesktopWidget)
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QIcon
import serial.tools.list_ports as sp
import serial

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.ports = sorted(sp.comports())
        self.myserial = serial.Serial(port='COM1', baudrate=9600)
        self.cb_serial = QComboBox(self)
        self.cb_serial.currentIndexChanged.connect(self.onActivated)
        for port, desc, _ in self.ports:
            self.cb_serial.addItem("{}: {}".format(port, desc))
        self.timer = QTimer(self)
        self.timer.start(1000)
        self.timer.timeout.connect(self.control_cb_data)
        
        btn_on = QPushButton('&On', self)
        btn_on.clicked.connect(lambda: self.btn_clicked('1'))
        btn_off = QPushButton('&Off', self)
        btn_off.clicked.connect(lambda: self.btn_clicked('0'))
        
        btn_sleep = QPushButton('&Sleep light', self)
        btn_sleep.clicked.connect(lambda: self.btn_clicked('d'))
        btn_bright = QPushButton('&20% / 50% / 100%', self)
        btn_bright.clicked.connect(lambda: self.btn_clicked('b'))
        
        self.cb_timer = QComboBox(self)
        self.cb_timer.addItems(["1 min", "10 min", "20 min", "30 min"])
        btn_timer = QPushButton('&Set timer', self)
        btn_timer.clicked.connect(self.btn_timer_clicked)
        
        
        grid = QGridLayout()
        self.setLayout(grid)
        
        grid.addWidget(QLabel('Serial port'), 0, 0, 1, 4)
        grid.addWidget(self.cb_serial, 1, 0, 1, 4)

        grid.addWidget(QLabel('On/Off'), 2, 0, 1, 2)
        grid.addWidget(btn_on, 3, 0)
        grid.addWidget(btn_off, 3, 1)
        
        grid.addWidget(QLabel('Control brightness'), 4, 0, 1, 2)
        grid.addWidget(btn_sleep, 5, 0, 1, 2)
        grid.addWidget(btn_bright, 6, 0, 1, 2)
        
        grid.addWidget(QLabel('Timer'), 2, 2, 1, 2)
        grid.addWidget(self.cb_timer, 3, 2, 1, 2)
        grid.addWidget(btn_timer, 6, 2, 1, 2)


        self.setWindowTitle('Light remote')
        self.setWindowIcon(QIcon('./remote.png'))
        self.setGeometry(300, 300, 300, 200)
        self.show()

    def onActivated(self):
        self.myserial.setPort(self.ports[self.cb_serial.currentIndex()][0])
        print(self.ports[self.cb_serial.currentIndex()][0])
    
    def control_cb_data(self):
        now_ports = sorted(sp.comports())
        if self.ports != now_ports:
            self.ports = now_ports
            self.cb_serial.clear()
            for port, desc, _ in self.ports:
                self.cb_serial.addItem("{}: {}".format(port, desc))
                
    def btn_clicked(self, chr):
        self.myserial.write(str.encode(chr))
        
    def btn_timer_clicked(self):
        if self.cb_timer.currentIndex() == 0:
            self.myserial.write(str.encode('v'))
        elif self.cb_timer.currentIndex() == 1:
            self.myserial.write(str.encode('s'))
        elif self.cb_timer.currentIndex() == 2:
            self.myserial.write(str.encode('m'))
        elif self.cb_timer.currentIndex() == 3:
            self.myserial.write(str.encode('l'))
    
    def location_on_the_screen(self):    
        screen = QDesktopWidget().screenGeometry()
        widget = self.geometry()
        x = screen.width() - widget.width()
        y = 0
        self.move(x, y)
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    ex.location_on_the_screen()
    sys.exit(app.exec_())

Program_window IR remote program window

pyqt5 모듈을 사용하여 구현하였습니다. GUI 프로그램을 개발하는건 이번 기회가 처음이라 공부하면서 제작하였습니다. 다음 wikidocs를 주로 참고하였습니다.

PyQt5 Tutorial - 파이썬으로 만드는 나만의 GUI 프로그램

이하 내용은 기능과 사용한 위젯을 중심으로 기술해 보았습니다.


3.1 시리얼 포트 설정

serial.tools.list_ports.comports()를 이용하여 현재 컴퓨터에서 열려 있는 시리얼 포트를 받아올 수 있습니다. 받아온 시리얼 포트 정보는 콤보 박스 위젯을 통해 사용자에게 전달되며 사용자는 어떤 포트와 통신할지 선택할 수 있습니다. QTImer 클래스를 사용하여 1초마다 포트 상태를 체크하는데, 만약 상태가 달라졌다면 콤보 박스의 아이템을 갱신합니다.

3.2 전등 전원

버튼 위젯을 사용하여 On, Off 전원을 구현하였습니다. On/Off 버튼 클릭 시 미리 선택된 시리얼 포트로 '1'/'0' 1byte 신호를 보냅니다. IR 송신 모듈은 시리얼 값을 읽어와 대응하는 IR command를 송신합니다.

3.3 전등 밝기 조절

마찬가지로 버튼 위젯을 사용하여 구현하였습니다. 가장 어두운 밝기인 취침등(Sleep light) 설정과 20%/50%/100% 밝기를 순차적으로 선택할 수 있는 설정이 있습니다.

3.4 타이머 조절

전등이 꺼지는 시각을 미리 설정해놓는 타이머 기능이 있습니다. 1분, 10분, 20분, 30분 이렇게 4가지 설정이 가능하고, 콤보 박스 상에서 선택한 후 Set timer 버튼을 클릭 시 시리얼 신호가 송신됩니다.

3.5 그 외

  • 그리드 레이아웃을 사용하여 각 위젯를 배치하였습니다.
  • 프로그램 실행 시 자동으로 모니터의 우측 상단에서 열리도록 하였습니다.
  • pyinstaller를 사용하여 실행파일로 만들었습니다. 콘솔창이 출력되지 않게 하고, 프로그램 아이콘을 설정하기 위해 다음과 같은 명령어를 콘솔창에 입력해줍니다.
1
pyinstaller -w --icon=./remote.ico IR_light.py


4. 결과

IR_remote_result IR remote program result

잘 작동합니다!!

추가로 저는 프로그램 단축키를 등록해주었습니다. 단축키 등록 방법은

  1. 바탕화면에 바로가기 만들기
  2. 아이콘 우클릭 후 ‘속성’
  3. ‘바로 가기’ 탭에서 ‘바로 가기’ 키를 누른 다음 원하는 단축키를 입력

순서로 진행하면 됩니다. 저는 ctrl + alt + R 키로 등록하였습니다.


지금까지 리모컨도 필요 없는 완전한 무선 전등 제어 시스템을 구축해 보았습니다 :D

This post is licensed under CC BY 4.0 by the author.