texy
Forum Moderator
Forum Moderator
Posts: 5155
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England

Nokia Pi LCD + Switch Shield board v2 code

Sun Mar 24, 2013 11:14 am

Hi,
code for version 2 of my Nokia Pi Shield board.
Prerequisites :
wiringpi installation -

Code: Select all

sudo apt-get install git-core python-dev
sudo apt-get install python-pip
sudo pip install wiringpi
spidev installation -

Code: Select all

sudo apt-get install spidev
modify the blacklist -

Code: Select all

sudo nano /etc/modprobe.d/raspi-blacklist.conf
and make there there is a # in front of the

Code: Select all

blacklist spi-bcm2708
line.
You'll need to restart the Pi after that.

Now create a main program python script using your favourite editor, eg nano :

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# LCD SHIELD v2a
# 23/3/2013

import time
import wiringpi
import spidev

CONTRAST=0xb4
PWM=512 # mid level

ROWS = 6
COLUMNS = 14
PIXELS_PER_ROW = 6
IN = OFF = 0
OUT = ON = 1

#gpio's :
DC   = 3 # gpio pin 15 = wiringpi no. 3 (BCM 22)
RST  = 0 # gpio pin 11 = wiringpi no. 0 (BCM 17)
LED  = 1 # gpio pin 12 = wiringpi no. 1 (BCM 18)

# SPI connection
SCE  = 10 # gpio pin 24 = wiringpi no. 10 (CE0 BCM 8)
SCLK = 14 # gpio pin 23 = wiringpi no. 14 (SCLK BCM 11)
DIN  = 12 # gpio pin 19 = wiringpi no. 12 (MOSI BCM 10)

UP  = 13 # gpio pin 21 = UP
DOWN  = 11 # gpio pin 26 = DOWN
LEFT  = 5  # gpio pin 18 = LEFT
RIGHT  = 4  # gpio pin 16 = RIGHT
SELECT  = 2  # gpio pin 13 = SELECT

CLSBUF=[0]*(ROWS * COLUMNS * PIXELS_PER_ROW)

FONT = {
  ' ': [0x00, 0x00, 0x00, 0x00, 0x00],
  '!': [0x00, 0x00, 0x5f, 0x00, 0x00],
  '"': [0x00, 0x07, 0x00, 0x07, 0x00],
  '#': [0x14, 0x7f, 0x14, 0x7f, 0x14],
  '$': [0x24, 0x2a, 0x7f, 0x2a, 0x12],
  '%': [0x23, 0x13, 0x08, 0x64, 0x62],
  '&': [0x36, 0x49, 0x55, 0x22, 0x50],
  "'": [0x00, 0x05, 0x03, 0x00, 0x00],
  '(': [0x00, 0x1c, 0x22, 0x41, 0x00],
  ')': [0x00, 0x41, 0x22, 0x1c, 0x00],
  '*': [0x14, 0x08, 0x3e, 0x08, 0x14],
  '+': [0x08, 0x08, 0x3e, 0x08, 0x08],
  ',': [0x00, 0x50, 0x30, 0x00, 0x00],
  '-': [0x08, 0x08, 0x08, 0x08, 0x08],
  '.': [0x00, 0x60, 0x60, 0x00, 0x00],
  '/': [0x20, 0x10, 0x08, 0x04, 0x02],
  '0': [0x3e, 0x51, 0x49, 0x45, 0x3e],
  '1': [0x00, 0x42, 0x7f, 0x40, 0x00],
  '2': [0x42, 0x61, 0x51, 0x49, 0x46],
  '3': [0x21, 0x41, 0x45, 0x4b, 0x31],
  '4': [0x18, 0x14, 0x12, 0x7f, 0x10],
  '5': [0x27, 0x45, 0x45, 0x45, 0x39],
  '6': [0x3c, 0x4a, 0x49, 0x49, 0x30],
  '7': [0x01, 0x71, 0x09, 0x05, 0x03],
  '8': [0x36, 0x49, 0x49, 0x49, 0x36],
  '9': [0x06, 0x49, 0x49, 0x29, 0x1e],
  ':': [0x00, 0x36, 0x36, 0x00, 0x00],
  ';': [0x00, 0x56, 0x36, 0x00, 0x00],
  '<': [0x08, 0x14, 0x22, 0x41, 0x00],
  '=': [0x14, 0x14, 0x14, 0x14, 0x14],
  '>': [0x00, 0x41, 0x22, 0x14, 0x08],
  '?': [0x02, 0x01, 0x51, 0x09, 0x06],
  '@': [0x32, 0x49, 0x79, 0x41, 0x3e],
  'A': [0x7e, 0x11, 0x11, 0x11, 0x7e],
  'B': [0x7f, 0x49, 0x49, 0x49, 0x36],
  'C': [0x3e, 0x41, 0x41, 0x41, 0x22],
  'D': [0x7f, 0x41, 0x41, 0x22, 0x1c],
  'E': [0x7f, 0x49, 0x49, 0x49, 0x41],
  'F': [0x7f, 0x09, 0x09, 0x09, 0x01],
  'G': [0x3e, 0x41, 0x49, 0x49, 0x7a],
  'H': [0x7f, 0x08, 0x08, 0x08, 0x7f],
  'I': [0x00, 0x41, 0x7f, 0x41, 0x00],
  'J': [0x20, 0x40, 0x41, 0x3f, 0x01],
  'K': [0x7f, 0x08, 0x14, 0x22, 0x41],
  'L': [0x7f, 0x40, 0x40, 0x40, 0x40],
  'M': [0x7f, 0x02, 0x0c, 0x02, 0x7f],
  'N': [0x7f, 0x04, 0x08, 0x10, 0x7f],
  'O': [0x3e, 0x41, 0x41, 0x41, 0x3e],
  'P': [0x7f, 0x09, 0x09, 0x09, 0x06],
  'Q': [0x3e, 0x41, 0x51, 0x21, 0x5e],
  'R': [0x7f, 0x09, 0x19, 0x29, 0x46],
  'S': [0x46, 0x49, 0x49, 0x49, 0x31],
  'T': [0x01, 0x01, 0x7f, 0x01, 0x01],
  'U': [0x3f, 0x40, 0x40, 0x40, 0x3f],
  'V': [0x1f, 0x20, 0x40, 0x20, 0x1f],
  'W': [0x3f, 0x40, 0x38, 0x40, 0x3f],
  'X': [0x63, 0x14, 0x08, 0x14, 0x63],
  'Y': [0x07, 0x08, 0x70, 0x08, 0x07],
  'Z': [0x61, 0x51, 0x49, 0x45, 0x43],
  '[': [0x00, 0x7f, 0x41, 0x41, 0x00],
  '\\': [0x02, 0x04, 0x08, 0x10, 0x20],
  ']': [0x00, 0x41, 0x41, 0x7f, 0x00],
  '^': [0x04, 0x02, 0x01, 0x02, 0x04],
  '_': [0x40, 0x40, 0x40, 0x40, 0x40],
  '`': [0x00, 0x01, 0x02, 0x04, 0x00],
  'a': [0x20, 0x54, 0x54, 0x54, 0x78],
  'b': [0x7f, 0x48, 0x44, 0x44, 0x38],
  'c': [0x38, 0x44, 0x44, 0x44, 0x20],
  'd': [0x38, 0x44, 0x44, 0x48, 0x7f],
  'e': [0x38, 0x54, 0x54, 0x54, 0x18],
  'f': [0x08, 0x7e, 0x09, 0x01, 0x02],
  'g': [0x0c, 0x52, 0x52, 0x52, 0x3e],
  'h': [0x7f, 0x08, 0x04, 0x04, 0x78],
  'i': [0x00, 0x44, 0x7d, 0x40, 0x00],
  'j': [0x20, 0x40, 0x44, 0x3d, 0x00],
  'k': [0x7f, 0x10, 0x28, 0x44, 0x00],
  'l': [0x00, 0x41, 0x7f, 0x40, 0x00],
  'm': [0x7c, 0x04, 0x18, 0x04, 0x78],
  'n': [0x7c, 0x08, 0x04, 0x04, 0x78],
  'o': [0x38, 0x44, 0x44, 0x44, 0x38],
  'p': [0x7c, 0x14, 0x14, 0x14, 0x08],
  'q': [0x08, 0x14, 0x14, 0x18, 0x7c],
  'r': [0x7c, 0x08, 0x04, 0x04, 0x08],
  's': [0x48, 0x54, 0x54, 0x54, 0x20],
  't': [0x04, 0x3f, 0x44, 0x40, 0x20],
  'u': [0x3c, 0x40, 0x40, 0x20, 0x7c],
  'v': [0x1c, 0x20, 0x40, 0x20, 0x1c],
  'w': [0x3c, 0x40, 0x30, 0x40, 0x3c],
  'x': [0x44, 0x28, 0x10, 0x28, 0x44],
  'y': [0x0c, 0x50, 0x50, 0x50, 0x3c],
  'z': [0x44, 0x64, 0x54, 0x4c, 0x44],
  '{': [0x00, 0x08, 0x36, 0x41, 0x00],
  '|': [0x00, 0x00, 0x7f, 0x00, 0x00],
  '}': [0x00, 0x41, 0x36, 0x08, 0x00],
  '~': [0x10, 0x08, 0x08, 0x10, 0x08],
  '\x7f': [0x00, 0x7e, 0x42, 0x42, 0x7e],
}

ORIGINAL_CUSTOM = FONT['\x7f']

bitreverse =[
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
]

def bit_reverse(value, width=8):
  result = 0
  for _ in xrange(width):
    result = (result << 1) | (value & 1)
    value >>= 1

    return result


BITREVERSE = map(bit_reverse, xrange(256))

spi = spidev.SpiDev()

def setup():
  # Set pin directions.
  wiringpi.wiringPiSetup()
  for pin in [DC, RST]:
    wiringpi.pinMode(pin, OUT) # set to output

  for pin in [UP, RIGHT, DOWN, LEFT, SELECT]:
    wiringpi.pinMode(pin, IN) # set to input
    wiringpi.pullUpDnControl(pin, wiringpi.PUD_DOWN) # enable pull down resistor

  wiringpi.pinMode(LED,2)
  wiringpi.pwmWrite(LED,PWM) # output pwm, range 0 - 1023

  spi.open(0,0)
  spi.max_speed_hz=5000000


def lcd_cmd(value):
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([value])


def lcd_data(value):
  wiringpi.digitalWrite(DC, ON)
  spi.writebytes([value])


def gotoxy(x, y):
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([x+128,y+64])


def cls():
  gotoxy(0, 0)
  wiringpi.digitalWrite(DC, ON)
  spi.writebytes(CLSBUF)
  


def begin(contrast):
  setup()
  # Toggle RST low to reset.
  wiringpi.digitalWrite(RST, OFF)
  wiringpi.digitalWrite(LED, ON)
  time.sleep(0.100)
  wiringpi.digitalWrite(RST, ON)
  # Extended mode, bias, vop, basic mode, non-inverted display.
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([0x21, 0x14, contrast, 0x20, 0x0c])
  # cls()

def init():
  begin(CONTRAST)

def led(led_value):
  wiringpi.digitalWrite(LED, led_value)


def load_bitmap(filename, reverse=False):
  mask = 0xff if reverse else 0x00
  gotoxy(0, 0)
  with open(filename, 'rb') as bitmap_file:
    for x in xrange(6):
      for y in xrange(84):
        bitmap_file.seek(0x3e + y * 8 + x)
        lcd_data(BITREVERSE[ord(bitmap_file.read(1))] ^ mask)


def show_custom(font=FONT):
  display_char('\x7f', font)


def define_custom(values):
  FONT['\x7f'] = values


def restore_custom():
  define_custom(ORIGINAL_CUSTOM)


def alt_custom():
  define_custom([0x00, 0x50, 0x3C, 0x52, 0x44])


def pi_custom():
  define_custom([0x19, 0x25, 0x5A, 0x25, 0x19])

def display_char(char, font=FONT):
  try:
    wiringpi.digitalWrite(DC, ON)
    spi.writebytes(font[char]+[0])

  except KeyError:
    pass # Ignore undefined characters.

def text(string, font=FONT):
  for char in string:
    display_char(char, font)


def gotorc(r, c):
  lcd_cmd(c * 6 + 128)
  lcd_cmd(r + 64)


def centre_word(r, word):
  gotorc(r, max(0, (COLUMNS - len(word)) // 2))
  text(word)

def load_bitmap(file):
  gotoxy(0,0)
  f = open(file,'r')
  for x in range(6):
    for y in range(84):
      f.seek(0x3e + y*8 + x)
      b = ord(f.read(1))
      rev = bitreverse[b]
      lcd_data(rev ^ 0xff)
  f.close()

def main():
  start, end = 32, 116
  print 'LCD Display Test: ASCII %d to %d' % (start, end)
  start_time = time.time()
  init()
  led(1)
  for i in xrange(start, end + 1):
    display_char(chr(i))
    
  finish_time = time.time()
  print 'Init, LED on, %d chars, total time = %.2f' % (
    end - start, finish_time - start_time
    )
  print
  time.sleep(1)

  load_bitmap('r.bmp')   
  PWM = 0
  while 1==1:

    input_value1 = wiringpi.digitalRead(UP)
    input_value2 = wiringpi.digitalRead(DOWN)
    input_value3 = wiringpi.digitalRead(LEFT)
    input_value4 = wiringpi.digitalRead(RIGHT)
    input_value5 = wiringpi.digitalRead(SELECT)

    print "UP = ",input_value1
    print "DOWN = ",input_value2
    print "LEFT = ",input_value3
    print "RIGHT = ",input_value4
    print "SELECT = ",input_value5
    PWM = PWM + 50
    wiringpi.pwmWrite(LED,PWM) # output pwm, range 0 - 1023
    time.sleep(.5)


if __name__ == '__main__':
  main()
Also download, unzip and save the attached bitmap file to the same directory as the main program above.
Run the main python code with

Code: Select all

sudo python myprog.py
Image

Texy
Attachments
r.zip
(471 Bytes) Downloaded 214 times
Various male/female 40- and 26-way GPIO header for sale here ( IDEAL FOR YOUR PiZero ):
https://www.raspberrypi.org/forums/viewtopic.php?f=93&t=147682#p971555

johnnyvdberg
Posts: 6
Joined: Mon Mar 25, 2013 9:47 pm

Re: Nokia Pi LCD + Switch Shield board v2 code

Wed Apr 03, 2013 4:13 pm

For people being confused why spidev won't install

Code: Select all

sudo apt-get install spidev
Should be:

Code: Select all

sudo pip install spidev
edit:
Wiringpi isn't playing nice with the buttons. For instance, I thought the Select button was broken because I couldn't get any input from it. Only when I tested it with wiringpi2 I realised it was a software problem. I don't know if it's because I have a rev2 board, but I couldn't make it work in wiringpi (1). Changing all references to wiringpi2 and replacing PUD_DOWN with 1 seems to fix it.

Love the screen though ;)

texy
Forum Moderator
Forum Moderator
Posts: 5155
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England

Re: Nokia Pi LCD + Switch Shield board v2 code

Tue Apr 16, 2013 8:38 pm

Hi,
thanks for spotting my deliberate mistake with the spidev installation ;)

Also for noticing that the cod wasn't compatible with revision 2 Pi's with wiringpi. I have now updated the program to use wiringpi2 and tested it with rev 1 and 2 Pi's :

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# LCD SHIELD v2b
# now uses wiringpi2 and is compatible with v1 and v2 Pi's
# 16/4/2013

import time
import wiringpi2 as wiringpi
import spidev

CONTRAST = 0xb5
PWM = 0 # LED backlight initial value
#Offset = 50
PUD_DOWN = 1

ROWS = 6
COLUMNS = 14
PIXELS_PER_ROW = 6
IN = OFF = 0
OUT = ON = 1

#gpio's :
DC   = 3 # gpio pin 15 = wiringpi no. 3 (BCM 22)
RST  = 0 # gpio pin 11 = wiringpi no. 0 (BCM 17)
LED  = 1 # gpio pin 12 = wiringpi no. 1 (BCM 18)

# SPI connection
SCE  = 10 # gpio pin 24 = wiringpi no. 10 (CE0 BCM 8)
SCLK = 14 # gpio pin 23 = wiringpi no. 14 (SCLK BCM 11)
DIN  = 12 # gpio pin 19 = wiringpi no. 12 (MOSI BCM 10)

UP  = 13 # gpio pin 21 = UP
DOWN  = 11 # gpio pin 26 = DOWN
LEFT  = 5  # gpio pin 18 = LEFT
RIGHT  = 4  # gpio pin 16 = RIGHT
SELECT  = 2  # gpio pin 13 = SELECT

CLSBUF=[0]*(ROWS * COLUMNS * PIXELS_PER_ROW)

FONT = {
  ' ': [0x00, 0x00, 0x00, 0x00, 0x00],
  '!': [0x00, 0x00, 0x5f, 0x00, 0x00],
  '"': [0x00, 0x07, 0x00, 0x07, 0x00],
  '#': [0x14, 0x7f, 0x14, 0x7f, 0x14],
  '$': [0x24, 0x2a, 0x7f, 0x2a, 0x12],
  '%': [0x23, 0x13, 0x08, 0x64, 0x62],
  '&': [0x36, 0x49, 0x55, 0x22, 0x50],
  "'": [0x00, 0x05, 0x03, 0x00, 0x00],
  '(': [0x00, 0x1c, 0x22, 0x41, 0x00],
  ')': [0x00, 0x41, 0x22, 0x1c, 0x00],
  '*': [0x14, 0x08, 0x3e, 0x08, 0x14],
  '+': [0x08, 0x08, 0x3e, 0x08, 0x08],
  ',': [0x00, 0x50, 0x30, 0x00, 0x00],
  '-': [0x08, 0x08, 0x08, 0x08, 0x08],
  '.': [0x00, 0x60, 0x60, 0x00, 0x00],
  '/': [0x20, 0x10, 0x08, 0x04, 0x02],
  '0': [0x3e, 0x51, 0x49, 0x45, 0x3e],
  '1': [0x00, 0x42, 0x7f, 0x40, 0x00],
  '2': [0x42, 0x61, 0x51, 0x49, 0x46],
  '3': [0x21, 0x41, 0x45, 0x4b, 0x31],
  '4': [0x18, 0x14, 0x12, 0x7f, 0x10],
  '5': [0x27, 0x45, 0x45, 0x45, 0x39],
  '6': [0x3c, 0x4a, 0x49, 0x49, 0x30],
  '7': [0x01, 0x71, 0x09, 0x05, 0x03],
  '8': [0x36, 0x49, 0x49, 0x49, 0x36],
  '9': [0x06, 0x49, 0x49, 0x29, 0x1e],
  ':': [0x00, 0x36, 0x36, 0x00, 0x00],
  ';': [0x00, 0x56, 0x36, 0x00, 0x00],
  '<': [0x08, 0x14, 0x22, 0x41, 0x00],
  '=': [0x14, 0x14, 0x14, 0x14, 0x14],
  '>': [0x00, 0x41, 0x22, 0x14, 0x08],
  '?': [0x02, 0x01, 0x51, 0x09, 0x06],
  '@': [0x32, 0x49, 0x79, 0x41, 0x3e],
  'A': [0x7e, 0x11, 0x11, 0x11, 0x7e],
  'B': [0x7f, 0x49, 0x49, 0x49, 0x36],
  'C': [0x3e, 0x41, 0x41, 0x41, 0x22],
  'D': [0x7f, 0x41, 0x41, 0x22, 0x1c],
  'E': [0x7f, 0x49, 0x49, 0x49, 0x41],
  'F': [0x7f, 0x09, 0x09, 0x09, 0x01],
  'G': [0x3e, 0x41, 0x49, 0x49, 0x7a],
  'H': [0x7f, 0x08, 0x08, 0x08, 0x7f],
  'I': [0x00, 0x41, 0x7f, 0x41, 0x00],
  'J': [0x20, 0x40, 0x41, 0x3f, 0x01],
  'K': [0x7f, 0x08, 0x14, 0x22, 0x41],
  'L': [0x7f, 0x40, 0x40, 0x40, 0x40],
  'M': [0x7f, 0x02, 0x0c, 0x02, 0x7f],
  'N': [0x7f, 0x04, 0x08, 0x10, 0x7f],
  'O': [0x3e, 0x41, 0x41, 0x41, 0x3e],
  'P': [0x7f, 0x09, 0x09, 0x09, 0x06],
  'Q': [0x3e, 0x41, 0x51, 0x21, 0x5e],
  'R': [0x7f, 0x09, 0x19, 0x29, 0x46],
  'S': [0x46, 0x49, 0x49, 0x49, 0x31],
  'T': [0x01, 0x01, 0x7f, 0x01, 0x01],
  'U': [0x3f, 0x40, 0x40, 0x40, 0x3f],
  'V': [0x1f, 0x20, 0x40, 0x20, 0x1f],
  'W': [0x3f, 0x40, 0x38, 0x40, 0x3f],
  'X': [0x63, 0x14, 0x08, 0x14, 0x63],
  'Y': [0x07, 0x08, 0x70, 0x08, 0x07],
  'Z': [0x61, 0x51, 0x49, 0x45, 0x43],
  '[': [0x00, 0x7f, 0x41, 0x41, 0x00],
  '\\': [0x02, 0x04, 0x08, 0x10, 0x20],
  ']': [0x00, 0x41, 0x41, 0x7f, 0x00],
  '^': [0x04, 0x02, 0x01, 0x02, 0x04],
  '_': [0x40, 0x40, 0x40, 0x40, 0x40],
  '`': [0x00, 0x01, 0x02, 0x04, 0x00],
  'a': [0x20, 0x54, 0x54, 0x54, 0x78],
  'b': [0x7f, 0x48, 0x44, 0x44, 0x38],
  'c': [0x38, 0x44, 0x44, 0x44, 0x20],
  'd': [0x38, 0x44, 0x44, 0x48, 0x7f],
  'e': [0x38, 0x54, 0x54, 0x54, 0x18],
  'f': [0x08, 0x7e, 0x09, 0x01, 0x02],
  'g': [0x0c, 0x52, 0x52, 0x52, 0x3e],
  'h': [0x7f, 0x08, 0x04, 0x04, 0x78],
  'i': [0x00, 0x44, 0x7d, 0x40, 0x00],
  'j': [0x20, 0x40, 0x44, 0x3d, 0x00],
  'k': [0x7f, 0x10, 0x28, 0x44, 0x00],
  'l': [0x00, 0x41, 0x7f, 0x40, 0x00],
  'm': [0x7c, 0x04, 0x18, 0x04, 0x78],
  'n': [0x7c, 0x08, 0x04, 0x04, 0x78],
  'o': [0x38, 0x44, 0x44, 0x44, 0x38],
  'p': [0x7c, 0x14, 0x14, 0x14, 0x08],
  'q': [0x08, 0x14, 0x14, 0x18, 0x7c],
  'r': [0x7c, 0x08, 0x04, 0x04, 0x08],
  's': [0x48, 0x54, 0x54, 0x54, 0x20],
  't': [0x04, 0x3f, 0x44, 0x40, 0x20],
  'u': [0x3c, 0x40, 0x40, 0x20, 0x7c],
  'v': [0x1c, 0x20, 0x40, 0x20, 0x1c],
  'w': [0x3c, 0x40, 0x30, 0x40, 0x3c],
  'x': [0x44, 0x28, 0x10, 0x28, 0x44],
  'y': [0x0c, 0x50, 0x50, 0x50, 0x3c],
  'z': [0x44, 0x64, 0x54, 0x4c, 0x44],
  '{': [0x00, 0x08, 0x36, 0x41, 0x00],
  '|': [0x00, 0x00, 0x7f, 0x00, 0x00],
  '}': [0x00, 0x41, 0x36, 0x08, 0x00],
  '~': [0x10, 0x08, 0x08, 0x10, 0x08],
  '\x7f': [0x00, 0x7e, 0x42, 0x42, 0x7e],
}

ORIGINAL_CUSTOM = FONT['\x7f']

bitreverse =[
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
]

def bit_reverse(value, width=8):
  result = 0
  for _ in xrange(width):
    result = (result << 1) | (value & 1)
    value >>= 1

    return result


BITREVERSE = map(bit_reverse, xrange(256))

spi = spidev.SpiDev()

def setup():
  # Set pin directions.
  wiringpi.wiringPiSetup()
  for pin in [DC, RST]:
    wiringpi.pinMode(pin, OUT) # set to output

  for pin in [UP, RIGHT, DOWN, LEFT, SELECT]:
    wiringpi.pinMode(pin, IN) # set to input
    wiringpi.pullUpDnControl(pin, PUD_DOWN) # enable pull down resistor

  wiringpi.pinMode(LED,2)
  wiringpi.pwmWrite(LED,PWM) # output pwm, range 0 - 1023

  spi.open(0,0)
  spi.max_speed_hz=5000000


def lcd_cmd(value):
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([value])


def lcd_data(value):
  wiringpi.digitalWrite(DC, ON)
  spi.writebytes([value])


def gotoxy(x, y):
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([x+128,y+64])


def cls():
  gotoxy(0, 0)
  wiringpi.digitalWrite(DC, ON)
  spi.writebytes(CLSBUF)
  


def begin(contrast):
  setup()
  # Toggle RST low to reset.
  wiringpi.digitalWrite(RST, OFF)
  wiringpi.digitalWrite(LED, ON)
  time.sleep(0.100)
  wiringpi.digitalWrite(RST, ON)
  # Extended mode, bias, vop, basic mode, non-inverted display.
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([0x21, 0x14, contrast, 0x20, 0x0c])
  # cls()

def init():
  begin(CONTRAST)

def led(led_value):
  wiringpi.digitalWrite(LED, led_value)


def load_bitmap(filename, reverse=False):
  mask = 0xff if reverse else 0x00
  gotoxy(0, 0)
  with open(filename, 'rb') as bitmap_file:
    for x in xrange(6):
      for y in xrange(84):
        bitmap_file.seek(0x3e + y * 8 + x)
        lcd_data(BITREVERSE[ord(bitmap_file.read(1))] ^ mask)


def show_custom(font=FONT):
  display_char('\x7f', font)


def define_custom(values):
  FONT['\x7f'] = values


def restore_custom():
  define_custom(ORIGINAL_CUSTOM)


def alt_custom():
  define_custom([0x00, 0x50, 0x3C, 0x52, 0x44])


def pi_custom():
  define_custom([0x19, 0x25, 0x5A, 0x25, 0x19])

def display_char(char, font=FONT):
  try:
    wiringpi.digitalWrite(DC, ON)
    spi.writebytes(font[char]+[0])

  except KeyError:
    pass # Ignore undefined characters.

def text(string, font=FONT):
  for char in string:
    display_char(char, font)


def gotorc(r, c):
  lcd_cmd(c * 6 + 128)
  lcd_cmd(r + 64)


def centre_word(r, word):
  gotorc(r, max(0, (COLUMNS - len(word)) // 2))
  text(word)

def load_bitmap(file):
  gotoxy(0,0)
  f = open(file,'r')
  for x in range(6):
    for y in range(84):
      f.seek(0x3e + y*8 + x)
      b = ord(f.read(1))
      rev = bitreverse[b]
      lcd_data(rev ^ 0xff)
  f.close()

def main():
  start, end = 32, 116
  print 'LCD Display Test: ASCII %d to %d' % (start, end)
  start_time = time.time()
  init()
  led(1)
  for i in xrange(start, end + 1):
    display_char(chr(i))
    
  finish_time = time.time()
  print 'Init, LED on, %d chars, total time = %.2f' % (
    end - start, finish_time - start_time
    )
  print
  time.sleep(1)

  load_bitmap('r.bmp')   
  PWM = 0
  Offset = 50
  while 1==1:

    input_value1 = wiringpi.digitalRead(UP)
    input_value2 = wiringpi.digitalRead(DOWN)
    input_value3 = wiringpi.digitalRead(LEFT)
    input_value4 = wiringpi.digitalRead(RIGHT)
    input_value5 = wiringpi.digitalRead(SELECT)

    print "UP = ",input_value1
    print "DOWN = ",input_value2
    print "LEFT = ",input_value3
    print "RIGHT = ",input_value4
    print "SELECT = ",input_value5
    PWM +=  Offset
    if PWM > 1024:
      Offset = -Offset
    if PWM < 50:
      Offset = -Offset
    wiringpi.pwmWrite(LED,PWM) # output pwm, range 0 - 1023
    time.sleep(.25)


if __name__ == '__main__':
  main()

Thanks,
Texy
Various male/female 40- and 26-way GPIO header for sale here ( IDEAL FOR YOUR PiZero ):
https://www.raspberrypi.org/forums/viewtopic.php?f=93&t=147682#p971555

oceny
Posts: 5
Joined: Sat Mar 09, 2013 10:16 am

Re: Nokia Pi LCD + Switch Shield board v2 code

Wed Jun 12, 2013 3:12 pm

This is the python script for running my Nokia Pi LCD + Switch Shield board v2 based internet radio and airplay speaker.
Still a work in progress, suggestions are welcome.

Gr.

Laurent
IMG_1553.jpg
IMG_1553.jpg (46.4 KiB) Viewed 3314 times
IMG_1555.jpg
IMG_1555.jpg (33.44 KiB) Viewed 3314 times

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# LCD SHIELD v2b
# now uses wiringpi2 and is compatible with v1 and v2 Pi's
# 16/4/2013

import time
import wiringpi2 as wiringpi
import spidev
import os
import subprocess

CONTRAST = 0xb0
PWM = 0 # LED backlight initial value
#Offset = 50
PUD_DOWN = 1

ROWS = 6
COLUMNS = 14
PIXELS_PER_ROW = 6
IN = OFF = 0
OUT = ON = 1

#gpio's :
DC   = 3 # gpio pin 15 = wiringpi no. 3 (BCM 22)
RST  = 0 # gpio pin 11 = wiringpi no. 0 (BCM 17)
LED  = 1 # gpio pin 12 = wiringpi no. 1 (BCM 18)

# SPI connection
SCE  = 10 # gpio pin 24 = wiringpi no. 10 (CE0 BCM 8)
SCLK = 14 # gpio pin 23 = wiringpi no. 14 (SCLK BCM 11)
DIN  = 12 # gpio pin 19 = wiringpi no. 12 (MOSI BCM 10)

UP  = 13 # gpio pin 21 = UP
DOWN  = 11 # gpio pin 26 = DOWN
LEFT  = 5  # gpio pin 18 = LEFT
RIGHT  = 4  # gpio pin 16 = RIGHT
SELECT  = 2  # gpio pin 13 = SELECT

CLSBUF=[0]*(ROWS * COLUMNS * PIXELS_PER_ROW)

FONT = {
  ' ': [0x00, 0x00, 0x00, 0x00, 0x00],
  '!': [0x00, 0x00, 0x5f, 0x00, 0x00],
  '"': [0x00, 0x07, 0x00, 0x07, 0x00],
  '#': [0x14, 0x7f, 0x14, 0x7f, 0x14],
  '$': [0x24, 0x2a, 0x7f, 0x2a, 0x12],
  '%': [0x23, 0x13, 0x08, 0x64, 0x62],
  '&': [0x36, 0x49, 0x55, 0x22, 0x50],
  "'": [0x00, 0x05, 0x03, 0x00, 0x00],
  '(': [0x00, 0x1c, 0x22, 0x41, 0x00],
  ')': [0x00, 0x41, 0x22, 0x1c, 0x00],
  '*': [0x14, 0x08, 0x3e, 0x08, 0x14],
  '+': [0x08, 0x08, 0x3e, 0x08, 0x08],
  ',': [0x00, 0x50, 0x30, 0x00, 0x00],
  '-': [0x08, 0x08, 0x08, 0x08, 0x08],
  '.': [0x00, 0x60, 0x60, 0x00, 0x00],
  '/': [0x20, 0x10, 0x08, 0x04, 0x02],
  '0': [0x3e, 0x51, 0x49, 0x45, 0x3e],
  '1': [0x00, 0x42, 0x7f, 0x40, 0x00],
  '2': [0x42, 0x61, 0x51, 0x49, 0x46],
  '3': [0x21, 0x41, 0x45, 0x4b, 0x31],
  '4': [0x18, 0x14, 0x12, 0x7f, 0x10],
  '5': [0x27, 0x45, 0x45, 0x45, 0x39],
  '6': [0x3c, 0x4a, 0x49, 0x49, 0x30],
  '7': [0x01, 0x71, 0x09, 0x05, 0x03],
  '8': [0x36, 0x49, 0x49, 0x49, 0x36],
  '9': [0x06, 0x49, 0x49, 0x29, 0x1e],
  ':': [0x00, 0x36, 0x36, 0x00, 0x00],
  ';': [0x00, 0x56, 0x36, 0x00, 0x00],
  '<': [0x08, 0x14, 0x22, 0x41, 0x00],
  '=': [0x14, 0x14, 0x14, 0x14, 0x14],
  '>': [0x00, 0x41, 0x22, 0x14, 0x08],
  '?': [0x02, 0x01, 0x51, 0x09, 0x06],
  '@': [0x32, 0x49, 0x79, 0x41, 0x3e],
  'A': [0x7e, 0x11, 0x11, 0x11, 0x7e],
  'B': [0x7f, 0x49, 0x49, 0x49, 0x36],
  'C': [0x3e, 0x41, 0x41, 0x41, 0x22],
  'D': [0x7f, 0x41, 0x41, 0x22, 0x1c],
  'E': [0x7f, 0x49, 0x49, 0x49, 0x41],
  'F': [0x7f, 0x09, 0x09, 0x09, 0x01],
  'G': [0x3e, 0x41, 0x49, 0x49, 0x7a],
  'H': [0x7f, 0x08, 0x08, 0x08, 0x7f],
  'I': [0x00, 0x41, 0x7f, 0x41, 0x00],
  'J': [0x20, 0x40, 0x41, 0x3f, 0x01],
  'K': [0x7f, 0x08, 0x14, 0x22, 0x41],
  'L': [0x7f, 0x40, 0x40, 0x40, 0x40],
  'M': [0x7f, 0x02, 0x0c, 0x02, 0x7f],
  'N': [0x7f, 0x04, 0x08, 0x10, 0x7f],
  'O': [0x3e, 0x41, 0x41, 0x41, 0x3e],
  'P': [0x7f, 0x09, 0x09, 0x09, 0x06],
  'Q': [0x3e, 0x41, 0x51, 0x21, 0x5e],
  'R': [0x7f, 0x09, 0x19, 0x29, 0x46],
  'S': [0x46, 0x49, 0x49, 0x49, 0x31],
  'T': [0x01, 0x01, 0x7f, 0x01, 0x01],
  'U': [0x3f, 0x40, 0x40, 0x40, 0x3f],
  'V': [0x1f, 0x20, 0x40, 0x20, 0x1f],
  'W': [0x3f, 0x40, 0x38, 0x40, 0x3f],
  'X': [0x63, 0x14, 0x08, 0x14, 0x63],
  'Y': [0x07, 0x08, 0x70, 0x08, 0x07],
  'Z': [0x61, 0x51, 0x49, 0x45, 0x43],
  '[': [0x00, 0x7f, 0x41, 0x41, 0x00],
  '\\': [0x02, 0x04, 0x08, 0x10, 0x20],
  ']': [0x00, 0x41, 0x41, 0x7f, 0x00],
  '^': [0x04, 0x02, 0x01, 0x02, 0x04],
  '_': [0x40, 0x40, 0x40, 0x40, 0x40],
  '`': [0x00, 0x01, 0x02, 0x04, 0x00],
  'a': [0x20, 0x54, 0x54, 0x54, 0x78],
  'b': [0x7f, 0x48, 0x44, 0x44, 0x38],
  'c': [0x38, 0x44, 0x44, 0x44, 0x20],
  'd': [0x38, 0x44, 0x44, 0x48, 0x7f],
  'e': [0x38, 0x54, 0x54, 0x54, 0x18],
  'f': [0x08, 0x7e, 0x09, 0x01, 0x02],
  'g': [0x0c, 0x52, 0x52, 0x52, 0x3e],
  'h': [0x7f, 0x08, 0x04, 0x04, 0x78],
  'i': [0x00, 0x44, 0x7d, 0x40, 0x00],
  'j': [0x20, 0x40, 0x44, 0x3d, 0x00],
  'k': [0x7f, 0x10, 0x28, 0x44, 0x00],
  'l': [0x00, 0x41, 0x7f, 0x40, 0x00],
  'm': [0x7c, 0x04, 0x18, 0x04, 0x78],
  'n': [0x7c, 0x08, 0x04, 0x04, 0x78],
  'o': [0x38, 0x44, 0x44, 0x44, 0x38],
  'p': [0x7c, 0x14, 0x14, 0x14, 0x08],
  'q': [0x08, 0x14, 0x14, 0x18, 0x7c],
  'r': [0x7c, 0x08, 0x04, 0x04, 0x08],
  's': [0x48, 0x54, 0x54, 0x54, 0x20],
  't': [0x04, 0x3f, 0x44, 0x40, 0x20],
  'u': [0x3c, 0x40, 0x40, 0x20, 0x7c],
  'v': [0x1c, 0x20, 0x40, 0x20, 0x1c],
  'w': [0x3c, 0x40, 0x30, 0x40, 0x3c],
  'x': [0x44, 0x28, 0x10, 0x28, 0x44],
  'y': [0x0c, 0x50, 0x50, 0x50, 0x3c],
  'z': [0x44, 0x64, 0x54, 0x4c, 0x44],
  '{': [0x00, 0x08, 0x36, 0x41, 0x00],
  '|': [0x00, 0x00, 0x7f, 0x00, 0x00],
  '}': [0x00, 0x41, 0x36, 0x08, 0x00],
  '~': [0x10, 0x08, 0x08, 0x10, 0x08],
  '\x7f': [0x00, 0x7e, 0x42, 0x42, 0x7e],
}

ORIGINAL_CUSTOM = FONT['\x7f']

bitreverse =[
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
]

def bit_reverse(value, width=8):
  result = 0
  for _ in xrange(width):
    result = (result << 1) | (value & 1)
    value >>= 1

    return result


BITREVERSE = map(bit_reverse, xrange(256))

spi = spidev.SpiDev()

def setup():
  # Set pin directions.
  wiringpi.wiringPiSetup()
  for pin in [DC, RST]:
    wiringpi.pinMode(pin, OUT) # set to output

  for pin in [UP, RIGHT, DOWN, LEFT, SELECT]:
    wiringpi.pinMode(pin, IN) # set to input
    wiringpi.pullUpDnControl(pin, PUD_DOWN) # enable pull down resistor

  wiringpi.pinMode(LED,2)
  wiringpi.pwmWrite(LED,PWM) # output pwm, range 0 - 1023

  spi.open(0,0)
  spi.max_speed_hz=5000000


def lcd_cmd(value):
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([value])


def lcd_data(value):
  wiringpi.digitalWrite(DC, ON)
  spi.writebytes([value])


def gotoxy(x, y):
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([x+128,y+64])


def cls():
  gotoxy(0, 0)
  wiringpi.digitalWrite(DC, ON)
  spi.writebytes(CLSBUF)
  


def begin(contrast):
  setup()
  # Toggle RST low to reset.
  wiringpi.digitalWrite(RST, OFF)
  wiringpi.digitalWrite(LED, ON)
  time.sleep(0.100)
  wiringpi.digitalWrite(RST, ON)
  # Extended mode, bias, vop, basic mode, non-inverted display.
  wiringpi.digitalWrite(DC, OFF)
  spi.writebytes([0x21, 0x14, contrast, 0x20, 0x0c])
  # cls()

def init():
  begin(CONTRAST)

def led(led_value):
  wiringpi.digitalWrite(LED, led_value)


def load_bitmap(filename, reverse=False):
  mask = 0xff if reverse else 0x00
  gotoxy(0, 0)
  with open(filename, 'rb') as bitmap_file:
    for x in xrange(6):
      for y in xrange(84):
        bitmap_file.seek(0x3e + y * 8 + x)
        lcd_data(BITREVERSE[ord(bitmap_file.read(1))] ^ mask)


def show_custom(font=FONT):
  display_char('\x7f', font)


def define_custom(values):
  FONT['\x7f'] = values


def restore_custom():
  define_custom(ORIGINAL_CUSTOM)


def alt_custom():
  define_custom([0x00, 0x50, 0x3C, 0x52, 0x44])


def pi_custom():
  define_custom([0x19, 0x25, 0x5A, 0x25, 0x19])

def display_char(char, font=FONT):
  try:
    wiringpi.digitalWrite(DC, ON)
    spi.writebytes(font[char]+[0])

  except KeyError:
    pass # Ignore undefined characters.

def text(string, font=FONT):
  for char in string:
    display_char(char, font)


def gotorc(r, c):
  lcd_cmd(c * 6 + 128)
  lcd_cmd(r + 64)


def centre_word(r, word):
  gotorc(r, max(0, (COLUMNS - len(word)) // 2))
  text(word)

def load_bitmap(file):
  gotoxy(0,0)
  f = open(file,'r')
  for x in range(6):
    for y in range(84):
      f.seek(0x3e + y*8 + x)
      b = ord(f.read(1))
      rev = bitreverse[b]
      lcd_data(rev ^ 0xff)
  f.close()

def main():
  init()
  led(1)
  cls()
  PWM=800
  wiringpi.pwmWrite(LED,PWM) 
  # make sure the audio card is started, as well as MPD
  os.system("sudo mpc clear")
  os.system("sudo mpc load playlistlol.pls")
  # setup variables
  count = 0 
  up = 0
  down = 0
  left = 0
  right = 0
  vol = 10
  #gets the playlist to count and set the length of the list
  cmd = subprocess.Popen("sudo mpc playlist",shell=True, stdout=subprocess.PIPE)
  stations = cmd.stdout.readlines()
  channelCount = len(stations)
  #play Channel 1
  os.system("sudo amixer cset numid=4 10%")
  os.system("sudo mpc play 4")
  currentChannel = 4
  cls()
  time.sleep(1)
  gotoxy(2,0)
  text (str(currentChannel) + ": " + cmd.stdout.readline())


  while 0==0:
    if(down==1):
      if(wiringpi.digitalRead(UP)==0):
        #change station
        if(currentChannel<channelCount):
          currentChannel = currentChannel + 1
        else:
          currentChannel = 1			
        cmd = subprocess.Popen("sudo mpc play " + str(currentChannel),shell=True, stdout=subprocess.PIPE)
        cls()
        gotoxy(2,0)
        text (str(currentChannel) + ": " + cmd.stdout.readline())

    down = wiringpi.digitalRead(UP)
	

    if(up==1):
      if(wiringpi.digitalRead(DOWN)==0):
        #change station
        if(currentChannel>1):
          currentChannel = currentChannel - 1
        else:
          currentChannel = channelCount			
        cmd = subprocess.Popen("sudo mpc play " + str(currentChannel),shell=True, stdout=subprocess.PIPE) 
        cls()
        gotoxy(2,0)
        text (str(currentChannel) + ": " + cmd.stdout.readline()) 
    
    up = wiringpi.digitalRead(DOWN)

    
    if(left==1):
      if(wiringpi.digitalRead(LEFT)==0):
        #change volume
        vol = vol - 5
        if(vol<0):
          vol = 0		
        volstr=str(vol)+"%"		
        os.system("sudo amixer cset numid=4 -- "+volstr)        
        cls()
        gotoxy(4,2)
        text ("volume down     "+volstr)
        time.sleep(.75)
        cls()
        f = os.popen('echo "currentsong" | nc localhost 6600 | grep -e "^Name: "')
        text (f.read()) 
    
    left = wiringpi.digitalRead(LEFT)

    if(right==1):
      if(wiringpi.digitalRead(RIGHT)==0):
        #change volume
        vol = vol + 5
        if(vol>100):
          vol = 100
        volstr=str(vol)+"%"		
        os.system("sudo amixer cset numid=4 -- "+volstr)
        cls()
        gotoxy(4,2)
        text ("Volume up       "+volstr)
        time.sleep(.75)
        cls()
        f = os.popen('echo "currentsong" | nc localhost 6600 | grep -e "^Name: "')
        text (f.read())

    right = wiringpi.digitalRead(RIGHT)

    if(wiringpi.digitalRead(SELECT)==1):
      #Stop system if button pressed more then 2 seconds else start airplay mode
      os.system("sudo mpc stop")
      cls()
      gotoxy(4,2)
      text ("Airplay mode")
      time.sleep(2)
      if(wiringpi.digitalRead(SELECT)==1):
        os.system("sudo halt")

if __name__ == '__main__':
  main()

johnnyvdberg
Posts: 6
Joined: Mon Mar 25, 2013 9:47 pm

Re: Nokia Pi LCD + Switch Shield board v2 code

Wed Jun 12, 2013 6:08 pm

Might as well post my code :). You need to save a playlist named 'radiolist' and add the image in the attachment in the same folder as the script. The code is extremely messy but it works for me :D

Image

Code: Select all

#!/usr/bin/python
# Radio
# Edited by John, all screen interface code is from the internet
# 13/4/2013

import time
import wiringpi2
import spidev
import subprocess
import datetime
import sys
import os
from threading import Thread

CONTRAST=0xb2
PWM=512 # mid level

ROWS = 6
COLUMNS = 14
PIXELS_PER_ROW = 6
IN = OFF = 0
OUT = ON = 1

radioSelection = 0
channelCount = 0
stations = []
playing = False

guiThread = Thread()
resetGUI = False
running = True

#Radio info
stationText = "Init"
stationTitle = "Init"
stationName = "Init"


##############################
###   Screen interface     ###
##############################

#gpio's :
DC   = 3 # gpio pin 15 = wiringpi no. 3 (BCM 22)
RST  = 0 # gpio pin 11 = wiringpi no. 0 (BCM 17)
LED  = 1 # gpio pin 12 = wiringpi no. 1 (BCM 18)

# SPI connection
SCE  = 10 # gpio pin 24 = wiringpi no. 10 (CE0 BCM 8)
SCLK = 14 # gpio pin 23 = wiringpi no. 14 (SCLK BCM 11)
DIN  = 12 # gpio pin 19 = wiringpi no. 12 (MOSI BCM 10)

UP  = 13 # gpio pin 21 = UP
DOWN  = 11 # gpio pin 26 = DOWN
LEFT  = 5  # gpio pin 18 = LEFT
RIGHT  = 4  # gpio pin 16 = RIGHT
SELECT  = 2  # gpio pin 13 = SELECT

CLSBUF=[0]*(ROWS * COLUMNS * PIXELS_PER_ROW)

FONT = {
  ' ': [0x00, 0x00, 0x00, 0x00, 0x00],
  '!': [0x00, 0x00, 0x5f, 0x00, 0x00],
  '"': [0x00, 0x07, 0x00, 0x07, 0x00],
  '#': [0x14, 0x7f, 0x14, 0x7f, 0x14],
  '$': [0x24, 0x2a, 0x7f, 0x2a, 0x12],
  '%': [0x23, 0x13, 0x08, 0x64, 0x62],
  '&': [0x36, 0x49, 0x55, 0x22, 0x50],
  "'": [0x00, 0x05, 0x03, 0x00, 0x00],
  '(': [0x00, 0x1c, 0x22, 0x41, 0x00],
  ')': [0x00, 0x41, 0x22, 0x1c, 0x00],
  '*': [0x14, 0x08, 0x3e, 0x08, 0x14],
  '+': [0x08, 0x08, 0x3e, 0x08, 0x08],
  ',': [0x00, 0x50, 0x30, 0x00, 0x00],
  '-': [0x08, 0x08, 0x08, 0x08, 0x08],
  '.': [0x00, 0x60, 0x60, 0x00, 0x00],
  '/': [0x20, 0x10, 0x08, 0x04, 0x02],
  '0': [0x3e, 0x51, 0x49, 0x45, 0x3e],
  '1': [0x00, 0x42, 0x7f, 0x40, 0x00],
  '2': [0x42, 0x61, 0x51, 0x49, 0x46],
  '3': [0x21, 0x41, 0x45, 0x4b, 0x31],
  '4': [0x18, 0x14, 0x12, 0x7f, 0x10],
  '5': [0x27, 0x45, 0x45, 0x45, 0x39],
  '6': [0x3c, 0x4a, 0x49, 0x49, 0x30],
  '7': [0x01, 0x71, 0x09, 0x05, 0x03],
  '8': [0x36, 0x49, 0x49, 0x49, 0x36],
  '9': [0x06, 0x49, 0x49, 0x29, 0x1e],
  ':': [0x00, 0x36, 0x36, 0x00, 0x00],
  ';': [0x00, 0x56, 0x36, 0x00, 0x00],
  '<': [0x08, 0x14, 0x22, 0x41, 0x00],
  '=': [0x14, 0x14, 0x14, 0x14, 0x14],
  '>': [0x00, 0x41, 0x22, 0x14, 0x08],
  '?': [0x02, 0x01, 0x51, 0x09, 0x06],
  '@': [0x32, 0x49, 0x79, 0x41, 0x3e],
  'A': [0x7e, 0x11, 0x11, 0x11, 0x7e],
  'B': [0x7f, 0x49, 0x49, 0x49, 0x36],
  'C': [0x3e, 0x41, 0x41, 0x41, 0x22],
  'D': [0x7f, 0x41, 0x41, 0x22, 0x1c],
  'E': [0x7f, 0x49, 0x49, 0x49, 0x41],
  'F': [0x7f, 0x09, 0x09, 0x09, 0x01],
  'G': [0x3e, 0x41, 0x49, 0x49, 0x7a],
  'H': [0x7f, 0x08, 0x08, 0x08, 0x7f],
  'I': [0x00, 0x41, 0x7f, 0x41, 0x00],
  'J': [0x20, 0x40, 0x41, 0x3f, 0x01],
  'K': [0x7f, 0x08, 0x14, 0x22, 0x41],
  'L': [0x7f, 0x40, 0x40, 0x40, 0x40],
  'M': [0x7f, 0x02, 0x0c, 0x02, 0x7f],
  'N': [0x7f, 0x04, 0x08, 0x10, 0x7f],
  'O': [0x3e, 0x41, 0x41, 0x41, 0x3e],
  'P': [0x7f, 0x09, 0x09, 0x09, 0x06],
  'Q': [0x3e, 0x41, 0x51, 0x21, 0x5e],
  'R': [0x7f, 0x09, 0x19, 0x29, 0x46],
  'S': [0x46, 0x49, 0x49, 0x49, 0x31],
  'T': [0x01, 0x01, 0x7f, 0x01, 0x01],
  'U': [0x3f, 0x40, 0x40, 0x40, 0x3f],
  'V': [0x1f, 0x20, 0x40, 0x20, 0x1f],
  'W': [0x3f, 0x40, 0x38, 0x40, 0x3f],
  'X': [0x63, 0x14, 0x08, 0x14, 0x63],
  'Y': [0x07, 0x08, 0x70, 0x08, 0x07],
  'Z': [0x61, 0x51, 0x49, 0x45, 0x43],
  '[': [0x00, 0x7f, 0x41, 0x41, 0x00],
  '\\': [0x02, 0x04, 0x08, 0x10, 0x20],
  ']': [0x00, 0x41, 0x41, 0x7f, 0x00],
  '^': [0x04, 0x02, 0x01, 0x02, 0x04],
  '_': [0x40, 0x40, 0x40, 0x40, 0x40],
  '`': [0x00, 0x01, 0x02, 0x04, 0x00],
  'a': [0x20, 0x54, 0x54, 0x54, 0x78],
  'b': [0x7f, 0x48, 0x44, 0x44, 0x38],
  'c': [0x38, 0x44, 0x44, 0x44, 0x20],
  'd': [0x38, 0x44, 0x44, 0x48, 0x7f],
  'e': [0x38, 0x54, 0x54, 0x54, 0x18],
  'f': [0x08, 0x7e, 0x09, 0x01, 0x02],
  'g': [0x0c, 0x52, 0x52, 0x52, 0x3e],
  'h': [0x7f, 0x08, 0x04, 0x04, 0x78],
  'i': [0x00, 0x44, 0x7d, 0x40, 0x00],
  'j': [0x20, 0x40, 0x44, 0x3d, 0x00],
  'k': [0x7f, 0x10, 0x28, 0x44, 0x00],
  'l': [0x00, 0x41, 0x7f, 0x40, 0x00],
  'm': [0x7c, 0x04, 0x18, 0x04, 0x78],
  'n': [0x7c, 0x08, 0x04, 0x04, 0x78],
  'o': [0x38, 0x44, 0x44, 0x44, 0x38],
  'p': [0x7c, 0x14, 0x14, 0x14, 0x08],
  'q': [0x08, 0x14, 0x14, 0x18, 0x7c],
  'r': [0x7c, 0x08, 0x04, 0x04, 0x08],
  's': [0x48, 0x54, 0x54, 0x54, 0x20],
  't': [0x04, 0x3f, 0x44, 0x40, 0x20],
  'u': [0x3c, 0x40, 0x40, 0x20, 0x7c],
  'v': [0x1c, 0x20, 0x40, 0x20, 0x1c],
  'w': [0x3c, 0x40, 0x30, 0x40, 0x3c],
  'x': [0x44, 0x28, 0x10, 0x28, 0x44],
  'y': [0x0c, 0x50, 0x50, 0x50, 0x3c],
  'z': [0x44, 0x64, 0x54, 0x4c, 0x44],
  '{': [0x00, 0x08, 0x36, 0x41, 0x00],
  '|': [0x00, 0x00, 0x7f, 0x00, 0x00],
  '}': [0x00, 0x41, 0x36, 0x08, 0x00],
  '~': [0x10, 0x08, 0x08, 0x10, 0x08],
  '\x7f': [0x00, 0x1f, 0x0e, 0x04, 0x00],
}

ORIGINAL_CUSTOM = FONT['\x7f']

bitreverse =[
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
]

def bit_reverse(value, width=8):
  result = 0
  for _ in xrange(width):
    result = (result << 1) | (value & 1)
    value >>= 1

    return result


BITREVERSE = map(bit_reverse, xrange(256))

spi = spidev.SpiDev()

def setup():
  # Set pin directions.
  wiringpi2.wiringPiSetup()
  for pin in [DC, RST]:
    wiringpi2.pinMode(pin, OUT) # set to output

  for pin in [UP, RIGHT, DOWN, LEFT, SELECT]:
    wiringpi2.pinMode(pin, IN) # set to input
    wiringpi2.pullUpDnControl(pin, 1) # enable pull down resistor

  wiringpi2.pinMode(LED,2)
  wiringpi2.pwmWrite(LED,PWM) # output pwm, range 0 - 1023

  spi.open(0,0)
  spi.max_speed_hz=5000000


def lcd_cmd(value):
  wiringpi2.digitalWrite(DC, OFF)
  spi.writebytes([value])


def lcd_data(value):
  wiringpi2.digitalWrite(DC, ON)
  spi.writebytes([value])


def gotoxy(x, y):
  wiringpi2.digitalWrite(DC, OFF)
  spi.writebytes([x+128,y+64])


def cls():
  gotoxy(0, 0)
  wiringpi2.digitalWrite(DC, ON)
  spi.writebytes(CLSBUF)
  


def begin(contrast):
  setup()
  # Toggle RST low to reset.
  wiringpi2.digitalWrite(RST, OFF)
  wiringpi2.digitalWrite(LED, ON)
  time.sleep(0.1)
  wiringpi2.digitalWrite(RST, ON)
  # Extended mode, bias, vop, basic mode, non-inverted display.
  wiringpi2.digitalWrite(DC, OFF)
  spi.writebytes([0x21, 0x14, contrast, 0x20, 0x0c])
  # cls()

def init():
  begin(CONTRAST)

def led(led_value):
  wiringpi2.digitalWrite(LED, led_value)


def load_bitmap(filename, reverse=False):
  mask = 0xff if reverse else 0x00
  gotoxy(0, 0)
  with open(filename, 'rb') as bitmap_file:
    for x in xrange(6):
      for y in xrange(84):
        bitmap_file.seek(0x3e + y * 8 + x)
        lcd_data(BITREVERSE[ord(bitmap_file.read(1))] ^ mask)


def show_custom(font=FONT):
  display_char('\x7f', font)


def define_custom(values):
  FONT['\x7f'] = values

def restore_custom():
  define_custom(ORIGINAL_CUSTOM)


def alt_custom():
  define_custom([0x00, 0x50, 0x3C, 0x52, 0x44])


def pi_custom():
  define_custom([0x19, 0x25, 0x5A, 0x25, 0x19])

def display_char(char, font=FONT):
  try:
    wiringpi2.digitalWrite(DC, ON)
    spi.writebytes(font[char]+[0])

  except KeyError:
    pass # Ignore undefined characters.

def text(string, font=FONT):
  for char in string:
    display_char(char, font)


def gotorc(r, c):
  lcd_cmd(c * 6 + 128)
  lcd_cmd(r + 64)


def centre_word(r, word):
  gotorc(r, max(0, (COLUMNS - len(word)) // 2))
  text(word)

def load_bitmap(file):
  gotoxy(0,0)
  f = open(file,'r')
  for x in range(6):
    for y in range(84):
      f.seek(0x3e + y*8 + x)
      b = ord(f.read(1))
      rev = bitreverse[b]
      lcd_data(rev ^ 0xff)
  f.close()
  
##############################
###   Wifi Scanner Logic   ###
##############################

def main():
  #Script runs at boot, need to wait for Wi-Fi interface
  #time.sleep(10)
  init()
  led(1)
  
  #Loading screen
  load_bitmap('./radio.bmp')
  time.sleep(2)
  
  #Init sound and mpc
  cls()
  initRadio()
  
    
  
  #Start reading input
  t = Thread(target=inputKeys)
  t.start()

def inputKeys():
  global running
  shutdownCounter = 0
  screenTimeout = 0
  while running:
    #Assign tasks to buttons
    if wiringpi2.digitalRead(DOWN) == 1:
      #Screen timeout reset
      enableBacklight()
      screenTimeout = 0
      
      #Give desired screen output for every button press
      downPlaylist()
    elif wiringpi2.digitalRead(UP) == 1:
      #Screen timeout reset
      enableBacklight()
      screenTimeout = 0
      
      upPlaylist()
    elif wiringpi2.digitalRead(LEFT) == 1:
      #Screen timeout reset
      enableBacklight()
      screenTimeout = 0
    elif wiringpi2.digitalRead(RIGHT) == 1:
      #Screen timeout reset
      enableBacklight()
      screenTimeout = 0
      
      toggleRadio()
    elif wiringpi2.digitalRead(SELECT) == 1:
      #Shutdown if button pressed long enough
      if shutdownCounter > 4:
        #Return to launcher
        running = False
        os.system("sudo halt")        
      shutdownCounter = shutdownCounter + 1
      print "Select"
      #Screen timeout reset
      screenTimeout = 0
    else :
      # Disable duration keys and increase screen timeout
      shutdownCounter = 0
      screenTimeout = screenTimeout + 1
    #Turn off backlight after 10 seconds to preserve power
    if screenTimeout > 40 :
      wiringpi2.pwmWrite(LED,0)
    
    time.sleep(0.25)
    
############################################
######     Button actions             ######
############################################

def downPlaylist():
  global radioSelection
  global playing
  
  if radioSelection > 1:
    radioSelection = radioSelection - 1
  else:
    radioSelection = channelCount
  print radioSelection
  os.system("sudo mpc play " + str(radioSelection))
  playing = True
  updateInfo()
      
def upPlaylist():
  global radioSelection
  global playing
  
  if radioSelection < channelCount:
    radioSelection = radioSelection + 1
  else:
    radioSelection = 1
  print radioSelection
  os.system("sudo mpc play " + str(radioSelection))
  playing = True
  updateInfo()
  
def toggleRadio():
  global playing
  os.system("sudo mpc toggle")
  if playing:
    playing = False
  else:
    playing = True
  
def initRadio():
  global channelCount
  global radioSelection
  global stations
  global playing
  
  os.system("sudo modprobe snd_bcm2835")
  os.system("sudo mpd")
  os.system("sudo mpc clear")
  os.system("sudo mpc repeat on")
  os.system("sudo mpc load radiolist")
  
  #gets the playlist to count and set the length of the list
  cmd = subprocess.Popen("sudo mpc playlist",shell=True, stdout=subprocess.PIPE)
  cmd.wait()
  stations = cmd.stdout.readlines()
  channelCount = len(stations)
  
  # Start default station
  if(channelCount>0):
    os.system("sudo mpc play 1")
    radioSelection = 1
    playing = True
    updateRadio()
    
def updateRadio():
  global guiThread
  global resetGUI
  resetGUI = True
  #time.sleep(0.6)
  
  guiThread = Thread(target=showRadio)
  guiThread.daemon=True
  guiThread.start()

def showRadio():
  global resetGUI
  global running
  global stationText
  global stationName
  global stationTitle
  
  now = datetime.datetime.now()
  resetGUI = False
  
  updateInfo()
  
  #Text marquee
  countName = 0
  countTitle = 0
  refreshCounter = 0
  
  while resetGUI == False and running:
    time.sleep(.5)
    
    #Print inexpensive elements
    centre_word(0, "Radio")
    
    #Show playing status
    gotorc(5,0)
    if playing:
      text("Playing")
    else:
      text("Paused ")
    
    #Radio
    now = datetime.datetime.now()
    gotorc(5,9)
    text(now.strftime("%H:%M"))
    
    #Show playlist count
    gotorc(4,0)
    text("{0}/{1} ".format(radioSelection, channelCount))
    
    #Check if data is outdated
    if refreshCounter > 2:
      cmd = subprocess.Popen("sudo mpc current",shell=True, stdout=subprocess.PIPE)
      cmd.wait()
      newStationText = cmd.stdout.readlines()[0]
      newStationText = filter_non_printable(newStationText)
      if stationText != newStationText:
        updateInfo()
        
        #Reset all counters
        countName = 0
        countTitle = 0
        refreshCounter = 0
        continue
      else:
        refreshCounter = 0
    else:
      refreshCounter = refreshCounter + 1
    #Show title and name
    if len(stationName) == 0 and len(stationTitle) == 0:
      gotorc(1, 0)
      text("                            ")
      gotorc(1, 0)
      centre_word(1,"No info")
      continue
    if len(stationName) < 14:
      #Clear line
      gotorc(1, 0)
      text("              ")
      gotorc(1, 0)
      text(stationName)
    else:
      #Get and show marquee name
      marqueeName = getMarqueeText(countName, stationName, 14)
      if marqueeName[0] == False :
        countName = countName + 1
      else :
        countName = 0
      #Show scrolling name
      gotorc(1,0)
      text(marqueeName[1])
    if len(stationTitle) < 14:
      #Clear line
      gotorc(2, 0)
      text("              ")
      gotorc(2, 0)
      text(stationTitle)
    else:   
      #Get and show marquee title
      marqueeTitle = getMarqueeText(countTitle, stationTitle, 14)
      if marqueeTitle[0] == False :
        countTitle = countTitle + 1
      else :
        countTitle = 0
      #Show scrolling title
      gotorc(2,0)
      text(marqueeTitle[1])
    
def getMarqueeText(count, text, width) :
  reset = False
  length = len(text)
  
  if length < width:
    return [True, text]
  
  oldText = text + " | "
  oldText = oldText[count:]
  text = oldText + text
  
  if count > length + 1:
      reset = True
  
  #Catch full string return
  return [reset, text[:width]]
  
def updateInfo() :
  global stationText
  global stationName
  global stationTitle

  #Get player status
  cmd = subprocess.Popen("sudo mpc current",shell=True, stdout=subprocess.PIPE)
  cmd.wait()
  
  #Full info for update checking
  stationText = cmd.stdout.readlines()[0]
  stationText = filter_non_printable(stationText)
  
  #Get title and station name
  #Name
  cmd = subprocess.Popen("sudo mpc -f  \"%name%\"",shell=True, stdout=subprocess.PIPE)
  cmd.wait()
  stationName = cmd.stdout.readlines()[0]
  stationName = filter_non_printable(stationName)
  
  #Title
  cmd = subprocess.Popen("sudo mpc -f  \"%title%\"",shell=True, stdout=subprocess.PIPE)
  cmd.wait()
  stationTitle = cmd.stdout.readlines()[0]
  stationTitle = filter_non_printable(stationTitle)
  
def enableBacklight() :
  wiringpi2.pwmWrite(LED,PWM)
    
def filter_non_printable(str):
  return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9])
    
if __name__ == '__main__':
  main()
Attachments
radio_script.rar
(4.98 KiB) Downloaded 118 times

Return to “Python”