zaterdag 23 maart 2013

Raspberry Hoofdunit deel 1.

Het scherm dat ik in mijn hoofdunit wil gaan gebruiken is een 4*20 lcd.
Dat houd in 4 lijnen aan 20 tekens per lijn.





Om dit scherm op mijn I2C van mijn Raspberry Pi te laten werken heb ik een print gemaakt die hiermee kan communiceren.

Omdat men diverse adressen kan aanmaken bij sommige ic's probeer ik dus mijn prints zodanig te maken dat ik de adressen zelf kan kiezen d.m.v. jumpers.

In bovenstaand geval heb ik dit reeds al gedaan bij het scherm wat ik eerder heb genoemd.
Tevens heb ik gekozen om de I2Cop 5V te laten lopen omdat meerder deel van de te verkrijgen hardware hier op werkt.
Zou een stukje hardware op een lager voltage werken is dit dan ook geen probleem.

Het printje om bovenstaande lcd te laten werken ziet er als volgt uit.


Zoals je kunt zien op de layout heb ik hier gebruik van 2 PCF8574's.
Waarom 2 ? de reden hiervan is dat 1 ervan is om de lcd aan te sturen en 1 om de knop bediening.
Die van de knopbediening zit links en voor de lcd midden boven.

De adressen die mogelijk zijn te kiezen bij de PCF8574 zijn.:


Het adres dat mijn print heeft op de I2C lijn is 0x26.

Om het scherm aan te sturen maak ik gebruik van een libery pylcdlib.
Code van deze libery is.:
import smbus
from time import *

# General i2c device class so that other devices can be added easily
class i2c_device:
 def __init__(self, addr, port):
  self.addr = addr
  self.bus = smbus.SMBus(port)

 def write(self, byte):
  self.bus.write_byte(self.addr, byte)

 def read(self):
  return self.bus.read_byte(self.addr)

 def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
  return self.bus.read_i2c_block_data(self.addr, data, n)


class lcd:
 #initializes objects and lcd
 '''
 Reverse Codes:
 0: lower 4 bits of expander are commands bits
 1: top 4 bits of expander are commands bits AND P0-4 P1-5 P2-6
 2: top 4 bits of expander are commands bits AND P0-6 P1-5 P2-4
 '''
 def __init__(self, addr, port, reverse=0):
  self.reverse = reverse
  self.lcd_device = i2c_device(addr, port)
  if self.reverse:
   self.lcd_device.write(0x30)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_device.write(0x20)
   self.lcd_strobe()
   sleep(0.0005)
  else:
   self.lcd_device.write(0x03)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_device.write(0x02)
   self.lcd_strobe()
   sleep(0.0005)

  self.lcd_write(0x28)
  self.lcd_write(0x08)
  self.lcd_write(0x01)
  self.lcd_write(0x06)
  self.lcd_write(0x0C)
  self.lcd_write(0x0F)

 # clocks EN to latch command
 def lcd_strobe(self):
  if self.reverse == 1:
   self.lcd_device.write((self.lcd_device.read() | 0x04))
   self.lcd_device.write((self.lcd_device.read() & 0xFB))
  if self.reverse == 2:
   self.lcd_device.write((self.lcd_device.read() | 0x01))
   self.lcd_device.write((self.lcd_device.read() & 0xFE))
  else:
   self.lcd_device.write((self.lcd_device.read() | 0x10))
   self.lcd_device.write((self.lcd_device.read() & 0xEF))

 # write a command to lcd
 def lcd_write(self, cmd):
  if self.reverse:
   self.lcd_device.write((cmd >> 4)<<4 data-blogger-escaped-0x0f="" data-blogger-escaped-cmd="" data-blogger-escaped-else:="" data-blogger-escaped-self.lcd_device.write="" data-blogger-escaped-self.lcd_strobe="" data-blogger-escaped-x0="">> 4))
   self.lcd_strobe()
   self.lcd_device.write((cmd & 0x0F))
   self.lcd_strobe()
   self.lcd_device.write(0x0)

 # write a character to lcd (or character rom)
 def lcd_write_char(self, charvalue):
  if self.reverse == 1:
   self.lcd_device.write((0x01 | (charvalue >> 4)<<4 data-blogger-escaped-0x0f="" data-blogger-escaped-2:="" data-blogger-escaped-charvalue="" data-blogger-escaped-if="" data-blogger-escaped-self.lcd_device.write="" data-blogger-escaped-self.lcd_strobe="" data-blogger-escaped-self.reverse="=" data-blogger-escaped-x01="" data-blogger-escaped-x04="" data-blogger-escaped-x0="">> 4)<<4 data-blogger-escaped-0x0f="" data-blogger-escaped-charvalue="" data-blogger-escaped-else:="" data-blogger-escaped-self.lcd_device.write="" data-blogger-escaped-self.lcd_strobe="" data-blogger-escaped-x04="" data-blogger-escaped-x0="" data-blogger-escaped-x40="">> 4)))
   self.lcd_strobe()
   self.lcd_device.write((0x40 | (charvalue & 0x0F)))
   self.lcd_strobe()
   self.lcd_device.write(0x0)

 # put char function
 def lcd_putc(self, char):
  self.lcd_write_char(ord(char))

 # put string function
 def lcd_puts(self, string, line):
  if line == 1:
   self.lcd_write(0x80)
  if line == 2:
   self.lcd_write(0xC0)
  if line == 3:
   self.lcd_write(0x94)
  if line == 4:
   self.lcd_write(0xD4)

  for char in string:
   self.lcd_putc(char)

 # clear lcd and set to home
 def lcd_clear(self):
  self.lcd_write(0x1)
  self.lcd_write(0x2)

 # add custom characters (0 - 7)
 def lcd_load_custon_chars(self, fontdata):
  self.lcd_device.bus.write(0x40);
  for char in fontdata:
   for line in char:
    self.lcd_write_char(line)


En het resultaat van hierboven genoemde in test opstelling is dus dat het werkt.
Om bovenstaand werkend te krijgen heb ik deze code in Python gemaakt.:
#!/usr/bin/python
# Raspberryboard Mainunit V0.1
#
# Author : Pascal Schuffelers
# Site   : http://www.vbib.be
# 
# Date   : 15/03/2013 tijd.: 00:01
#
# Main unit interne vast adressen.:
# -Display groot is adres 0x26
 
#Doe imports
import smbus
import time
import pylcdlib
import os
import random
 
from time import sleep
from datetime import datetime
from subprocess import *
 
#Ken PCF8575 adressen toe aan variabelen
i2c_addr4x20 = 0x26
i2c = smbus.SMBus(1)
 
lcd = pylcdlib.lcd(i2c_addr4x20,1)
lcd.lcd_puts("   I2C bussysteem   ",1) #toon op lijn 1
lcd.lcd_puts("       test 1       ",2) #toon op lijn 2
lcd.lcd_puts("       test 2       ",3) #toon op lijn 3
lcd.lcd_puts("       test 3       ",4) #toon op lijn 4

Voor meer video's en foto's van deze lcd's te zien kun je deze vinden op www.vbib.be.

Geen opmerkingen:

Een reactie posten