File [scripts/mpd_lcd.py]
1 |
#!/usr/bin/python |
2 |
import smbus |
3 |
import time |
4 |
from mpd import MPDClient |
5 |
import socket |
6 |
# Server for MPD |
7 |
SERVER = "lounge-pi" |
8 |
client = MPDClient() # create client object |
9 |
client.timeout = 10 # network timeout in seconds (floats allowed), default: None |
10 |
client.idletimeout = None # timeout for fetching the result of the idle command is handled seperately, default: None |
11 |
# Host lookup for determining Internet connectivity |
12 |
INET_SERVER = "www.google.com" |
13 |
# Define some device parameters |
14 |
I2C_ADDR = 0x27 # I2C device address |
15 |
LCD_WIDTH = 20 # Maximum characters per line |
16 |
# Define some device constants |
17 |
LCD_CHR = 1 # Mode - Sending data |
18 |
LCD_CMD = 0 # Mode - Sending command |
19 |
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line |
20 |
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line |
21 |
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line |
22 |
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line |
23 |
LCD_BACKLIGHT = 0x08 # On |
24 |
#LCD_BACKLIGHT = 0x00 # Off |
25 |
ENABLE = 0b00000100 # Enable bit |
26 |
# Timing constants |
27 |
E_PULSE = 0.0005 |
28 |
E_DELAY = 0.0005 |
29 |
ZERO_DISP = 3 |
30 |
#Open I2C interface |
31 |
#bus = smbus.SMBus(0) # Rev 1 Pi uses 0 |
32 |
bus = smbus.SMBus(1) # Rev 2 Pi uses 1 |
33 |
def lcd_init(): |
34 |
# Initialist display |
35 |
lcd_byte(0x33,LCD_CMD) # 110011 Initialise |
36 |
lcd_byte(0x32,LCD_CMD) # 110010 Initialise |
37 |
lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction |
38 |
lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off |
39 |
lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size |
40 |
lcd_byte(0x01,LCD_CMD) # 000001 Clear display |
41 |
time.sleep(E_DELAY) |
42 |
def lcd_byte(bits, mode): |
43 |
# Send byte to data pins |
44 |
# bits = the data |
45 |
# mode = 1 for data |
46 |
# 0 for command |
47 |
bits_high = mode | (bits &; 0xF0) | LCD_BACKLIGHT |
48 |
bits_low = mode | ((bits<<4) &; 0xF0) | LCD_BACKLIGHT |
49 |
# High bits |
50 |
bus.write_byte(I2C_ADDR, bits_high) |
51 |
lcd_toggle_enable(bits_high) |
52 |
# Low bits |
53 |
bus.write_byte(I2C_ADDR, bits_low) |
54 |
lcd_toggle_enable(bits_low) |
55 |
def lcd_toggle_enable(bits): |
56 |
# Toggle enable |
57 |
time.sleep(E_DELAY) |
58 |
bus.write_byte(I2C_ADDR, (bits | ENABLE)) |
59 |
time.sleep(E_PULSE) |
60 |
bus.write_byte(I2C_ADDR,(bits &; ~ENABLE)) |
61 |
time.sleep(E_DELAY) |
62 |
def lcd_string(message,line): |
63 |
# Send string to display |
64 |
message = message.ljust(LCD_WIDTH," ") |
65 |
lcd_byte(line, LCD_CMD) |
66 |
for i in range(LCD_WIDTH): |
67 |
lcd_byte(ord(message[i]),LCD_CHR) |
68 |
def music_details(): |
69 |
# Set defaults just in case of errors |
70 |
artist = "Cannot connect to" |
71 |
album = SERVER |
72 |
song = "" |
73 |
length = 0 |
74 |
position = 0 |
75 |
# Connect to MPD on the server |
76 |
server_up = 1 |
77 |
try: |
78 |
client.connect(SERVER, 6600) |
79 |
# Catch socket errors |
80 |
except IOError: |
81 |
server_up = 0 |
82 |
print("Car_Server_LCD.py: Could not connect to " + SERVER) |
83 |
# Catch Other MPD Errors |
84 |
except MPDError: |
85 |
server_up = 0 |
86 |
print("Car_Server_LCD.py: Could not connect to " + SERVER) |
87 |
if server_up == 1: |
88 |
status = client.status() |
89 |
if status['state'] == "play": |
90 |
position = int(float(status['elapsed'])) |
91 |
track = client.currentsong() |
92 |
if len(track) > 0: |
93 |
artist = track['artist'] |
94 |
if len(artist) > LCD_WIDTH: |
95 |
artist += " " |
96 |
album = track['album'] |
97 |
if len(album) > LCD_WIDTH: |
98 |
album += " " |
99 |
song = track['title'] |
100 |
if len(song) > LCD_WIDTH: |
101 |
song += " " |
102 |
length = int(track['time']) |
103 |
else: |
104 |
artist = "Unknown" |
105 |
album = "Unknown" |
106 |
song = "Unknown" |
107 |
# Close and disconnect from the server |
108 |
client.close() |
109 |
client.disconnect() |
110 |
return (artist, album, song, length, position) |
111 |
def format_string(old_string, cur_string, pos): |
112 |
if old_string != cur_string: |
113 |
# We need to reset the position on a new string |
114 |
pos = 0 |
115 |
if len(cur_string) > LCD_WIDTH: |
116 |
return cur_string[pos:pos + 20] |
117 |
else: |
118 |
return cur_string |
119 |
def string_pos(cur_string, pos, zero_count): |
120 |
return_pos = 0 |
121 |
if (pos + 20) < len(cur_string): |
122 |
if (zero_count < ZERO_DISP) and (pos == 0): |
123 |
zero_count = zero_count + 1 |
124 |
else: |
125 |
zero_count = 0 |
126 |
return_pos = pos + 1 |
127 |
return (return_pos, zero_count) |
128 |
def is_connected(hostname): |
129 |
try: |
130 |
# see if we can resolve the host name -- tells us if there is |
131 |
# a DNS listening |
132 |
host = socket.gethostbyname(hostname) |
133 |
# connect to the host -- tells us if the host is actually |
134 |
# reachable |
135 |
s = socket.create_connection((host, 80), 2) |
136 |
s.close() |
137 |
return True |
138 |
except: |
139 |
pass |
140 |
return False |
141 |
def main(): |
142 |
# Main program block |
143 |
# Initialise display |
144 |
lcd_init() |
145 |
# Define old variables to speed up display updates |
146 |
old_artist = "" |
147 |
old_album = "" |
148 |
old_song = "" |
149 |
# Define old displays to speed up display updates |
150 |
disp_artist = "" |
151 |
disp_album = "" |
152 |
disp_song = "" |
153 |
disp_timer = "" |
154 |
# Define the start positions of text strings |
155 |
start_artist = 0 |
156 |
start_album = 0 |
157 |
start_song = 0 |
158 |
# Define the number of times a scrolling message has been at pos=0 |
159 |
zero_artist = 0 |
160 |
zero_album = 0 |
161 |
zero_song = 0 |
162 |
# Define an internet check timer |
163 |
inet_timer = 0 |
164 |
while True: |
165 |
# Query the MPD server |
166 |
the_music = music_details() |
167 |
artist = the_music[0] |
168 |
album = the_music[1] |
169 |
song = the_music[2] |
170 |
length = the_music[3] |
171 |
position = the_music[4] |
172 |
# Convert the times into HH:SS |
173 |
song_len = time.strftime('%M:%S', time.gmtime(length)) |
174 |
song_pos = time.strftime('%M:%S', time.gmtime(position)) |
175 |
# Work out if we need to display part of a string |
176 |
artist_string = format_string(old_artist, artist, start_artist) |
177 |
old_artist = artist |
178 |
pos_artist = string_pos(artist, start_artist, zero_artist) |
179 |
start_artist = pos_artist[0] |
180 |
zero_artist = pos_artist[1] |
181 |
album_string = format_string(old_album, album, start_album) |
182 |
old_album = album |
183 |
pos_album = string_pos(album, start_album, zero_album) |
184 |
start_album = pos_album[0] |
185 |
zero_album = pos_album[1] |
186 |
song_string = format_string(old_song, song, start_song) |
187 |
old_song = song |
188 |
pos_song = string_pos(song, start_song, zero_song) |
189 |
start_song = pos_song[0] |
190 |
zero_song = pos_song[1] |
191 |
# Now work out if we have Internet connection, but only |
192 |
# do it every 10 seconds to save bandwidth |
193 |
if time.time() - inet_timer >= 10: |
194 |
if is_connected(INET_SERVER): |
195 |
inet = "*" |
196 |
else: |
197 |
inet = "-" |
198 |
inet_timer = time.time() |
199 |
timer = song_pos + " - " + song_len + " " + inet |
200 |
# Send some test |
201 |
if artist_string != disp_artist: |
202 |
disp_artist = artist_string |
203 |
lcd_string(artist_string, LCD_LINE_1) |
204 |
if album_string != disp_album: |
205 |
disp_album = album_string |
206 |
lcd_string(album_string, LCD_LINE_2) |
207 |
if song_string != disp_song: |
208 |
disp_song = song_string |
209 |
lcd_string(song_string, LCD_LINE_3) |
210 |
if timer != disp_timer: |
211 |
disp_timer = timer |
212 |
lcd_string(timer, LCD_LINE_4) |
213 |
time.sleep(0.2) |
214 |
if __name__ == '__main__': |
215 |
try: |
216 |
main() |
217 |
except KeyboardInterrupt: |
218 |
pass |
219 |
finally: |
220 |
lcd_byte(0x01, LCD_CMD) |
Computing Power
- Acer Aspire R3700
- Acknowledgements
- BOINC
- Desktop PC
- Eee PC 4G (701)
- Eee PC 901
- Gigabit Network
- Inspiron 14 5485 Laptop
- Kids PC 1
- Kids PC 2
- Media PC
- Mini-ITX PC
- My Useful Scripts
- Nano ITX PC
- Nook Simple Touch
- Processing Power
- Raspberry Pi
- Sharp Zaurus SL-C3200
- Storage Capacity
- The Server
- What Is Firmware
Galleries
(* updated in last 14 days)