[아이씨뱅큐 ICbanQ 파워블로거 2기] MPD를 사용하여 곡 정보 CLCD에 표현하기

 

[본 컨텐츠는 ICbanQ (아이씨뱅큐)에서 진행하는 파워블로거 활동의 일환으로아이씨뱅큐의 지원을 받아 작성되었습니다]


[ 사용한 품목 ]

 

라즈베리파이 B+, 로터리 엔코더 


 

[ CONTENTS ]


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::[ Hardware ]::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

LCD ================ GPIO

VSS (pin 1) —————- GND

VDD (pin 2)—————- +5V (pin 2)

D7   (pin 14)—————— GPIO14 (pin 8) [previously GPIO18]

D6   (pin 13) —————— GPIO23 (pin 16)

D5    (pin 12)—————— GPIO24 (pin 18)

D4    (pin 11)—————— GPIO25 (pin 22)

E      (pin 6) ——————– GPIO08 (pin 24)

RS    (pin 4)—————— GPIO07 (pin 26)

RW    (pin 5)—————— GND


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::[ Software ]::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


1. GPIO설치
sudo dpkg -i python-rpi.gpio_0.5.11-1_armhf.deb

2. MPD설치
sudo apt-get install python-mpd

2.1 CharLCD.py

[참고]  Adafruit_CharLCD.py를 이용하여 만들었다. (라이브러리로 활용)

  sudo nano CharLCD.py
  아래내용 복사-붙여넣기
  Ctrl + X선택 후 y 선택 후 Enter


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
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/usr/bin/python
 
#
# based on code from lrvick and LiquidCrystal
#
 
from time import sleep
 
class CharLCD(object):
 
    # commands
    LCD_CLEARDISPLAY        = 0x01
    LCD_RETURNHOME          = 0x02
    LCD_ENTRYMODESET        = 0x04
    LCD_DISPLAYCONTROL      = 0x08
    LCD_CURSORSHIFT         = 0x10
    LCD_FUNCTIONSET         = 0x20
    LCD_SETCGRAMADDR        = 0x40
    LCD_SETDDRAMADDR        = 0x80
 
    # flags for display entry mode
    LCD_ENTRYRIGHT          = 0x00
    LCD_ENTRYLEFT           = 0x02
    LCD_ENTRYSHIFTINCREMENT = 0x01
    LCD_ENTRYSHIFTDECREMENT = 0x00
 
    # flags for display on/off control
    LCD_DISPLAYON           = 0x04
    LCD_DISPLAYOFF          = 0x00
    LCD_CURSORON            = 0x02
    LCD_CURSOROFF           = 0x00
    LCD_BLINKON             = 0x01
    LCD_BLINKOFF            = 0x00
 
    # flags for display/cursor shift
    LCD_DISPLAYMOVE         = 0x08
    LCD_CURSORMOVE          = 0x00
 
    # flags for display/cursor shift
    LCD_DISPLAYMOVE         = 0x08
    LCD_CURSORMOVE          = 0x00
    LCD_MOVERIGHT           = 0x04
    LCD_MOVELEFT            = 0x00
 
    # flags for function set
    LCD_8BITMODE            = 0x10
    LCD_4BITMODE            = 0x00
    LCD_2LINE               = 0x08
    LCD_1LINE               = 0x00
    LCD_5x10DOTS            = 0x04
    LCD_5x8DOTS             = 0x00
 
    def __init__(self, pin_rs=7, pin_e=8, pins_db=[25242314], GPIO=None):
        # Emulate the old behavior of using RPi.GPIO if we haven't been given
        # an explicit GPIO interface to use
        if not GPIO:
            import RPi.GPIO as GPIO
            GPIO.setwarnings(False)
        self.GPIO = GPIO
        self.pin_rs = pin_rs
        self.pin_e = pin_e
        self.pins_db = pins_db
 
        self.GPIO.setmode(GPIO.BCM)
        self.GPIO.setup(self.pin_e, GPIO.OUT)
        self.GPIO.setup(self.pin_rs, GPIO.OUT)
 
        for pin in self.pins_db:
            self.GPIO.setup(pin, GPIO.OUT)
 
        self.write4bits(0x33)  # initialization
        self.write4bits(0x32)  # initialization
        self.write4bits(0x28)  # 2 line 5x7 matrix
        self.write4bits(0x0C)  # turn cursor off 0x0E to enable cursor
        self.write4bits(0x06)  # shift cursor right
 
        self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
 
        self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
        self.displayfunction |= self.LCD_2LINE
 
        # Initialize to default text direction (for romance languages)
        self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)  # set the entry mode
 
        self.clear()
 
    def begin(self, cols, lines):
        if (lines > 1):
            self.numlines = lines
            self.displayfunction |= self.LCD_2LINE
 
    def home(self):
        self.write4bits(self.LCD_RETURNHOME)  # set cursor position to zero
        self.delayMicroseconds(3000)  # this command takes a long time!
 
    def clear(self):
        self.write4bits(self.LCD_CLEARDISPLAY)  # command to clear display
        self.delayMicroseconds(3000)  # 3000 microsecond sleep, clearing the display takes a long time
 
    def setCursor(self, col, row):
        self.row_offsets = [0x000x400x140x54]
        if row > self.numlines:
            row = self.numlines - 1  # we count rows starting w/0
        self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
 
    def noDisplay(self):
        """ Turn the display off (quickly) """
        self.displaycontrol &= ~self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
 
    def display(self):
        """ Turn the display on (quickly) """
        self.displaycontrol |= self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
 
    def noCursor(self):
        """ Turns the underline cursor off """
        self.displaycontrol &= ~self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
 
    def cursor(self):
        """ Turns the underline cursor on """
        self.displaycontrol |= self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
 
    def noBlink(self):
        """ Turn the blinking cursor off """
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
 
    def blink(self):
        """ Turn the blinking cursor on """
        self.displaycontrol |= self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
 
    def DisplayLeft(self):
        """ These commands scroll the display without changing the RAM """
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
 
    def scrollDisplayRight(self):
        """ These commands scroll the display without changing the RAM """
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT)
 
    def leftToRight(self):
        """ This is for text that flows Left to Right """
        self.displaymode |= self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
 
    def rightToLeft(self):
        """ This is for text that flows Right to Left """
        self.displaymode &= ~self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
 
    def autoscroll(self):
        """ This will 'right justify' text from the cursor """
        self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
 
    def noAutoscroll(self):
        """ This will 'left justify' text from the cursor """
        self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
 
    def write4bits(self, bits, char_mode=False):
        """ Send command to LCD """
        self.delayMicroseconds(1000)  # 1000 microsecond sleep
        bits = bin(bits)[2:].zfill(8)
        self.GPIO.output(self.pin_rs, char_mode)
        for pin in self.pins_db:
            self.GPIO.output(pin, False)
        for i in range(4):
            if bits[i] == "1":
                self.GPIO.output(self.pins_db[::-1][i], True)
        self.pulseEnable()
        for pin in self.pins_db:
            self.GPIO.output(pin, False)
        for i in range(48):
            if bits[i] == "1":
                self.GPIO.output(self.pins_db[::-1][i-4], True)
        self.pulseEnable()
 
    def delayMicroseconds(self, microseconds):
        seconds = microseconds / float(1000000)  # divide microseconds by 1 million for seconds
        sleep(seconds)
 
    def pulseEnable(self):
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)       # 1 microsecond pause - enable pulse must be > 450ns
        self.GPIO.output(self.pin_e, True)
        self.delayMicroseconds(1)       # 1 microsecond pause - enable pulse must be > 450ns
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)       # commands need > 37us to settle
 
    def message(self, text):
        """ Send string to LCD. Newline wraps to second line"""
        for char in text:
            if char == '\n':
                self.write4bits(0xC0)  # next line
            else:
                self.write4bits(ord(char), True)
 
 
if __name__ == '__main__':
    lcd = CharLCD()
    lcd.clear()
    lcd.message("  CLCD 16x2\n  Standard LCD")
 
cs




2.2 CLCD 출력 테스트 

아래 명령어를 입력

sudo python CharLCD.py
++++++++++++++++++   출력화면 ++++++++++++++++++++++++

    lcd.clear()
    lcd.message("  CLCD 16x2\n  Standard LCD")

+++++++++++++++++++++++++++++++++++++++++++++++++++

위헤 해당된 글이 CLCD에 출력이 되어야 한다.



2.3 곡정보 표시를 위한 clcd_test.py 만들기

  sudo nano clcd_test.py
  아래내용 복사-붙여넣기
  Ctrl + X선택 후 y 선택 후 Enter
  그리고 아래를 실행하여 확인
 
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
 
#!/usr/bin/python
 
from CharLCD import CharLCD
from subprocess import *
from time import sleep, strftime
from datetime import datetime
 
from mpd import MPDClient
client = MPDClient()               # create client object
client.timeout = 10                # network timeout in seconds (floats allowed), default: None
client.idletimeout = None          # timeout for fetching the result of the idle command is handled seperately, default:$
client.connect("localhost"6600)  # connect to localhost:6600
 
 
lcd = CharLCD()
 
 
lcd.begin(16,2)
 
 
while 1:
    
    title = client.currentsong()['title']
    last_status = client.status()['state']
    volume = client.status()['volume']
    id = client.currentsong()['id']
    currentsong = client.currentsong()['file']
    status = client.status()['state']
    
    lcd.clear()
    
    try:
        if status == "play":
            lcd.message( "[" + id + "] " + title + "\n" + "PLAY     VOL:" + volume)
            
        elif status == "pause":
            lcd.message( "[" + id + "] " + title + "\n" + "PAUSED   VOL:" + volume)
            
        else:
            lcd.message( "[" + id + "] " + title + "\n" + "STOPED   VOL:" + volume)
                
        last_status = client.status()['state']
            
    except:
        pass
        
        
    sleep(2)
 
cs


2.4 Music Player Daemon (MPD) 정보 스크립트 만들기 
mpd데몬이 설치가 되어있다면 다음 파일을 만들어 보자

  sudo nano mpd_info.py
  아래내용 복사-붙여넣기
  Ctrl + X선택 후 y 선택 후 Enter
  그리고 아래를 실행하여 확인

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
 
#!/usr/bin/env python 
from mpd import MPDClient
client = MPDClient()               # create client object
client.timeout = 10                # network timeout in seconds (floats allowed), default: None
client.idletimeout = None          # timeout for fetching the result of the idle command is handled seperately, default:$
client.connect("localhost"6600)  # connect to localhost:6600
currentsong = client.currentsong()
print ""
print 'CURRENT----------------------------------------------------------------'
if len(currentsong) > 0:
   for text in currentsong:
      print text + ": " + str(currentsong.get(text))
   current_id = int(currentsong.get("pos")) + 1
else:
   print "No current song (empty playlist)"
print ""
print 'STATUS-----------------------------------------------------------------'
status = client.status()
for text in status:
   print text + ": " + str(status.get(text))
print ""
print 'STATS------------------------------------------------------------------'
stats = client.stats()
for text in stats:
   print text + ": " + str(stats.get(text))
client.close()                     # send the close command
client.disconnect()                # disconnect from the server
 
cs

2.5 위의 파일 실행 및 확인

 아래 명령을 실행하면 화면에 다양한 정보를 볼 수 있다. 저 정보를 사용하여 위의 clcd_test.py를 꾸미면 된다.

sudo python mpd_info.py



3. 실행 및 확인 

sudo python clcd_test.py
위와 같이 실행하면 아래와 같이 곡아이디, 곡명, 플레이상태, 볼륨정보등을 확인할 수 있다. 



 

4. 동영상 확인


 
5. 관련상품