Advertisement
OhioJoe

oled_I2C.py

Mar 22nd, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.32 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- encoding:utf8 -*-
  3. #
  4. #   apt-get install fonts-takao-pgothic
  5. #   apt-get install python-mutagen python3-mutagen
  6.  
  7. import os
  8. import sys
  9. import time
  10. import signal
  11. import socket
  12. import subprocess
  13. import smbus
  14. import math
  15. from PIL import Image
  16. from PIL import ImageFont
  17. from PIL import ImageDraw
  18.  
  19. # to get IP address
  20. gw = os.popen("ip -4 route show default").read().split()
  21. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  22. s.connect((gw[2], 0))
  23. ipaddr = s.getsockname()[0]
  24.  
  25.  
  26. mpd_music_dir   = "/home/pi/Music/"
  27. #mpd_music_dir  = "/media/"
  28. title_height    = 18
  29. scroll_unit     = 3
  30.  
  31. oled_width      = 128
  32. oled_height     =  64
  33. cover_size      = oled_height - title_height - 2
  34.  
  35. # SSD1306 --> 0
  36. # SH1106  --> 2
  37. oled_offset_x   = 0
  38.  
  39. font_title      = ImageFont.truetype('TakaoGothic.ttf', int(title_height*11/12), encoding='unic')
  40. #font_title     = ImageFont.truetype('aqua_pfont.ttf', title_height, encoding='unic')
  41. #font_title     = ImageFont.truetype('MEIRYOB.TTC', int(title_height*10/12), encoding='unic')
  42.  
  43. font_info       = ImageFont.truetype('TakaoGothic.ttf', 14, encoding='unic')
  44. #font_info      = ImageFont.truetype('aqua_pfont.ttf', 16, encoding='unic')
  45. #font_info      = ImageFont.truetype('MEIRYO.TTC', 14, encoding='unic')
  46.  
  47. font_audio      = ImageFont.load_default()
  48.  
  49. font_time       = ImageFont.truetype('TakaoGothic.ttf', 28);
  50. #font_time      = ImageFont.truetype('aqua_pfont.ttf', 32);
  51. font_date       = ImageFont.truetype('TakaoGothic.ttf', 16);
  52. #font_date      = ImageFont.truetype('aqua_pfont.ttf', 18);
  53.  
  54.  
  55. mpd_host        = 'localhost'
  56. mpd_port        = 6600
  57. mpd_bufsize     = 8192
  58.  
  59.  
  60.  
  61.  
  62.  
  63. bus = smbus.SMBus(1)
  64. OLED_address     = 0x3c
  65. OLED_CommandMode = 0x00
  66. OLED_DataMode    = 0x40
  67.  
  68.  
  69. def oled_init():
  70.  
  71.     cmd = []
  72.  
  73.     cmd += [0xAE]   #display off
  74.  
  75.     cmd += [0x40]   #set display start line
  76.  
  77.     cmd += [0x81]   # Contrast
  78.     cmd += [0x80]   # 0 - 255, default=0x80
  79.    
  80.     cmd += [0xA1]   #set segment remap
  81.  
  82.     cmd += [0xA6]   #normal / reverse
  83.  
  84.     cmd += [0xA8]   #multiplex ratio
  85.     cmd += [0x3F]   #duty = 1/64
  86.  
  87.     cmd += [0xC8]   #Com scan direction
  88.  
  89.     cmd += [0xD3]   #set display offset
  90.     cmd += [0x00]  
  91.     cmd += [0xD5]   #set osc division
  92.     cmd += [0x80]
  93.  
  94.     cmd += [0xD9]   #set pre-charge period
  95.     cmd += [0xF1]
  96.  
  97.     cmd += [0xDA]   #set COM pins
  98.     cmd += [0x12]
  99.  
  100.     cmd += [0xDB]   #set vcomh
  101.     cmd += [0x40]
  102.  
  103.     cmd += [0x8D]   #set charge pump enable
  104.     cmd += [0x14]
  105.  
  106.     cmd += [0x20]   #set addressing mode
  107.     cmd += [0x02]   #set page addressing mode
  108.  
  109.     cmd += [0xAF]   #display ON
  110.  
  111. #   bus.write_i2c_block_data(OLED_address,OLED_CommandMode,cmd)
  112.  
  113.     for byte in cmd:
  114.         try:
  115.             bus.write_byte_data(OLED_address,OLED_CommandMode,byte)
  116.         except IOError:
  117.             print("IOError")
  118.             return -1
  119.  
  120.  
  121. def oled_drawImage(image):
  122.  
  123.     if image.mode != '1' and image.mode != 'L':
  124.         raise ValueError('Image must be in mode 1.')
  125.  
  126.     imwidth, imheight = image.size
  127.     if imwidth != oled_width or imheight != oled_height:
  128.         raise ValueError('Image must be same dimensions as display ({0}x{1}).' \
  129.         .format(oled_width, oled_height))
  130.  
  131.     # Grab all the pixels from the image, faster than getpixel.
  132.     pix     = image.load()
  133.  
  134.     pages   = oled_height / 8;
  135.     block   = oled_width / 32;
  136.  
  137.     for page in range(pages):
  138.  
  139.         addr    = [];
  140.         addr    += [0xB0 | page];   # Set Page Address
  141.         addr    += [0x10];  # Set Higher Column Address
  142.         addr    += [0x00 | oled_offset_x];  # Set Lower Column Address
  143.  
  144.         try:
  145.             bus.write_i2c_block_data(OLED_address,OLED_CommandMode,addr)
  146.         except IOError:
  147.             print("IOError")
  148.             return -1
  149.  
  150.         for blk in range(block):
  151.             data=[]
  152.             for b in range(32):
  153.                 x   = blk * 32 + b;
  154.                 y   = page * 8
  155.  
  156.                 data.append(
  157.                     ((pix[(x, y+0)] >> 7) << 0) | \
  158.                     ((pix[(x, y+1)] >> 7) << 1) | \
  159.                     ((pix[(x, y+2)] >> 7) << 2) | \
  160.                     ((pix[(x, y+3)] >> 7) << 3) | \
  161.                     ((pix[(x, y+4)] >> 7) << 4) | \
  162.                     ((pix[(x, y+5)] >> 7) << 5) | \
  163.                     ((pix[(x, y+6)] >> 7) << 6) | \
  164.                     ((pix[(x, y+7)] >> 7) << 7) );
  165.  
  166.             try:
  167.                 bus.write_i2c_block_data(OLED_address,OLED_DataMode,data)
  168.             except IOError:
  169.                 print("IOError")
  170.                 return -1
  171.  
  172.  
  173.  
  174. # initialize OLED
  175. oled_init()
  176.  
  177. # OLED images
  178. image           = Image.new('L', (oled_width, oled_height))
  179. draw            = ImageDraw.Draw(image)
  180. draw.rectangle((0,0,oled_width,oled_height), outline=0, fill=0)
  181.  
  182.  
  183. music_file      = ""
  184. cover_image     = Image.new('L', (cover_size, cover_size))
  185. title_image     = Image.new('L', (oled_width, title_height))
  186. title_offset    = 0
  187.  
  188. # Draw opening image
  189. try:
  190.     oled_drawImage(Image.open('opening.png').resize((oled_width,oled_height)).convert('L'))
  191.     time.sleep(3)
  192. except:
  193.     oled_drawImage(image)
  194.  
  195.  
  196. # Socket
  197. soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  198. soc.connect((mpd_host, mpd_port))
  199. soc.recv(mpd_bufsize)
  200.  
  201. soc.send('commands\n')
  202. rcv = soc.recv(mpd_bufsize)
  203. print("commands:")
  204. print("----- start ----------")
  205. print( rcv )
  206. print("----- end ----------\n")
  207.  
  208.  
  209. while True:
  210.  
  211.     soc.send('currentsong\n')
  212.     buff        = soc.recv(mpd_bufsize)
  213.     song_list   = buff.splitlines()
  214.  
  215. #   print("currentsong:")
  216. #   print("----- start ----------")
  217. #   print( buff )
  218. #   print("----- end ----------\n")
  219.  
  220.     soc.send('status\n')
  221.     buff        = soc.recv(mpd_bufsize)
  222.     state_list  = buff.splitlines()
  223.  
  224. #   print("status:")
  225. #   print("----- start ----------")
  226. #   print( buff )
  227. #   print("----- end ----------\n")
  228.  
  229.     info_state      = ""
  230.     info_audio      = ""
  231.     info_elapsed    = 0
  232.     info_duration   = 0
  233.     info_title      = ""
  234.     info_artist     = ""
  235.     info_album      = ""
  236.     info_file       = ""
  237.  
  238.     for line in range(0,len(state_list)):
  239.         if state_list[line].startswith("state: "):     info_state      = state_list[line].replace("state: ", "")
  240.         if state_list[line].startswith("audio: "):     info_audio      = state_list[line].replace("audio: ", "")
  241.         if state_list[line].startswith("elapsed: "):   info_elapsed    = float(state_list[line].replace("elapsed: ", ""))
  242.         if state_list[line].startswith("time: "):      info_duration   = float(state_list[line].split(":")[2])
  243.  
  244.     for line in range(0,len(song_list)):
  245.         if song_list[line].startswith("file: "):       info_file       = song_list[line].replace("file: ", "")
  246.         if song_list[line].startswith("Artist: "):     info_artist     = song_list[line].replace("Artist: ", "")
  247.         if song_list[line].startswith("Album: "):      info_album      = song_list[line].replace("Album: ", "")
  248.         if song_list[line].startswith("Title: "):      info_title      = song_list[line].replace("Title: ", "")
  249.  
  250.     # clear the image
  251.     draw.rectangle((0,0,oled_width,oled_height), outline=0, fill=0)
  252.  
  253.     if info_state != "stop":
  254.  
  255.         if info_title == "" :
  256.             name    = info_file.split('/')
  257.             name.reverse()
  258.             info_title  = name[0]
  259.    
  260.             try:
  261.                 info_album  = name[1]
  262.             except:
  263.                 info_album  = ""
  264.    
  265.             try:   
  266.                 info_artist = name[2]
  267.             except:
  268.                 info_artist = ""
  269.  
  270.         if info_file != music_file :
  271.    
  272.             music_file  = info_file;
  273.             file_path   = mpd_music_dir + info_file
  274.             cover_path  = mpd_music_dir + os.path.split(music_file)[0] + "/front.jpg"
  275.    
  276.             print('--------------------------------------------')
  277.             print(file_path)
  278.            
  279.             # Generate title image
  280.             title_width, dmy_y   = font_title.getsize(unicode(info_title,'utf-8'))
  281.             title_offset    = oled_width / 2;
  282.             title_image     = Image.new('L', (title_width, title_height))
  283.             title_draw      = ImageDraw.Draw(title_image)
  284.             title_draw.rectangle((0,0, title_width, title_height), outline=0, fill=0)
  285.             title_draw.text((0,0), unicode(info_title,'utf-8'), font=font_title, fill=255)
  286.  
  287.         # Title
  288.         x   = 0
  289.         y   = 0
  290.         if oled_width < title_image.width :
  291.             if title_image.width < -title_offset : 
  292.                 title_offset    = oled_width / 2
  293.    
  294.             if title_offset < 0 :
  295.                 x   = title_offset
  296.            
  297.             title_offset    = title_offset - scroll_unit
  298.    
  299.         image.paste(title_image, (x,y))
  300.         x   = 0;
  301.    
  302.         # Current playback position
  303.         y   += title_height;
  304.         r   = (oled_width * info_elapsed / info_duration) if 0 < info_duration else oled_width
  305.         draw.line((x, y, r, y ), fill=255)
  306.      
  307.         # Cover Image
  308.         y   += 2;
  309.         image.paste( cover_image, (x,y))
  310.  
  311.         # artist name, album name, audio format
  312.         x   = + 3; #cover_size + 3; moves Album title over for image - removed
  313.         y   += 1
  314.         draw.text((x, y), unicode(info_artist,'utf-8'), font=font_info, fill=255)
  315.         draw.text((x, y + (oled_height - 10 - 1 - y) / 2), unicode(info_album,'utf-8'), font=font_info, fill=255)
  316.         draw.text((x, oled_height - 10), unicode(info_audio,'utf-8'), font=font_audio, fill=255)
  317.  
  318.     else:
  319.  
  320.         music_file  = ""
  321.  
  322. #       draw.text((2, 2),time.strftime("%A"),       font=font_date,fill=255)
  323.         draw.text((0, 2),    ipaddr,  font=font_date, fill=255)
  324.         draw.text((2,18),time.strftime("%e %b %Y"), font=font_date,fill=255)
  325.         draw.text((2,32),time.strftime("%X"),       font=font_time,fill=255)
  326.  
  327.     oled_drawImage(image)
  328. #   image.save( 'oled_image.png')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement