Wednesday, May 1, 2013

Raspberry PI 16X2 LCD

HI

So this is my first ever blog so i don't really know what to start with except hi.

anyway..

I ordered a Raspberry PI a while back and revived it a couple of months ago. Before i even had it in my hands i thought of stuff to do with it, but when it arrived i could not find time to really sit down and implement some of those ideas. my first idea was to use it a a media server: that lasted about 15 minutes and i used a proper PC with more disk space and better processing as i wanted something permanent and did not want to give up my PI.

So i went on to my original idea/plan. ->


  1. Order a PI -> done
  2. learn Python -> can never say done, but Google proves very helpful as well as codeacademy.com
  3. Get a 16x2 LCD -> done
  4. Use Python to interface with the LCD -> well i did get it to display some info but still have alot ot learn.
  5. connect it to my car OBD -> have not even started.
So in my quest to connect a LCD i realized there are lots of guys with guides on how to connect your LCD to you PI. I decided that another one might bring a different perspective to someone so they can better understand how what and why.

First of all i got almost all of my info from various websites and i do not want to get credit for something i got from someone else, my main source of info was :  http://www.raspberrypi-spy.co.uk/2012/07/16x2-lcd-module-control-using-python/ , this is a real good tutorial i only made one change and that was to put a potentiometer on pin VO to manage the contrast. but the rest is the same even the python script.

I also made some changes to be able to display the ip address on the LCD so here is what you need:

  1. obviously you will need a PI
  2. a breadboard
  3. 1 X 560 ohm resistor(green,blue,brown)
  4. a 16X2 HD47780 compatible LCD
  5. i also got some header pins to connect the LCD to the breadboard without any hassels, but you can solder wires onto the LCD
  6. some jumper cables to connect the pi to the breadboard
  7. a 10k potentiometer.
First thing you need to do is load your PI with an OS i used Wheezy. you can get info on how to install this on http://www.raspberrypi.org/downloads . this is fairly easy.

As far as i know the latest version of Wheezy already has Python ,with everything else you will need to use the GPIO, installed. if this is not the case get it here : https://pypi.python.org/pypi/RPi.GPIO .

so the pinouts for the LCD is a follow:
1 -> VSS 
2 -> VDD
3 -> VO
4 -> RS
5 -> RW
6 -> E
7 to 14 -> data pins
15 -> LED +
16 -> LED-

we will connect them in the following way to the PI:

The basic idea is :
LCD to PI ->
1 VSS - PI-06 (ground)
2 VDD - PI-02 (5v)
3 VO- potentiometer 
4 RS- PI-26 (IO7)
5 RW - PI-06 (ground)
6 E - PI-24 (IO8)
7 - n/c
8 - n/c
9 - n/c
10 - n/c
11 D4 - PI-22(IO25)
12 D5 - PI-18(IO24)
13 D6 - PI-16(IO23)
14 D7 - PI-12(IO18)
15 LED+ - PI-02(560Ohm resistor)
16 LED- - PI-06 (ground)

Once you have done this the rest is quite easy.

Copy the Python script to your PI (I used winscp) and run it with as root ie sudo.

Here is the script i used:


#!/usr/bin/python
#
# HD44780 LCD Test Script for
# Raspberry Pi
#
# Author : Matt Hawkins
# Site   : http://www.raspberrypi-spy.co.uk
#
# Date   : 26/07/2012
#

# The wiring for the LCD is as follows:
# 1 : GND
# 2 : 5V
# 3 : Contrast (0-5V)*
# 4 : RS (Register Select)
# 5 : R/W (Read Write)       - GROUND THIS PIN
# 6 : Enable or Strobe
# 7 : Data Bit 0             - NOT USED
# 8 : Data Bit 1             - NOT USED
# 9 : Data Bit 2             - NOT USED
# 10: Data Bit 3             - NOT USED
# 11: Data Bit 4
# 12: Data Bit 5
# 13: Data Bit 6
# 14: Data Bit 7
# 15: LCD Backlight +5V**
# 16: LCD Backlight GND

#import
import RPi.GPIO as GPIO
import time
import socket
import fcntl
import struct
GPIO.setwarnings(False)

# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18

# Define some device constants
LCD_WIDTH = 16    # Maximum characters per line
LCD_CHR = True
LCD_CMD = False

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

# Timing constants
E_PULSE = 0.00005
E_DELAY = 0.00005

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

def main():
  # Main program block

  GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7

  # Initialise display
  lcd_init()

  # Send some test
  lcd_byte(LCD_LINE_1, LCD_CMD)
  lcd_string("Rasbperry Pi")
  lcd_byte(LCD_LINE_2, LCD_CMD)
  lcd_string("Model B")

  time.sleep(3) # 3 second delay

  # Send some text
  lcd_byte(LCD_LINE_1, LCD_CMD)
  lcd_string(get_ip_address('eth0'))
  lcd_byte(LCD_LINE_2, LCD_CMD)
  lcd_string("IP Address")

  time.sleep(20)

def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD)
  lcd_byte(0x32,LCD_CMD)
  lcd_byte(0x28,LCD_CMD)
  lcd_byte(0x0C,LCD_CMD)
  lcd_byte(0x06,LCD_CMD)
  lcd_byte(0x01,LCD_CMD)

def lcd_string(message):
  # Send string to display

  message = message.ljust(LCD_WIDTH," ")

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = data
  # mode = True  for character
  #        False for command

  GPIO.output(LCD_RS, mode) # RS

  # High bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x10==0x10:
    GPIO.output(LCD_D4, True)
  if bits&0x20==0x20:
    GPIO.output(LCD_D5, True)
  if bits&0x40==0x40:
    GPIO.output(LCD_D6, True)
  if bits&0x80==0x80:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  time.sleep(E_DELAY)  
  GPIO.output(LCD_E, True)
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False)
  time.sleep(E_DELAY)    

  # Low bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x01==0x01:
    GPIO.output(LCD_D4, True)
  if bits&0x02==0x02:
    GPIO.output(LCD_D5, True)
  if bits&0x04==0x04:
    GPIO.output(LCD_D6, True)
  if bits&0x08==0x08:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  time.sleep(E_DELAY)  
  GPIO.output(LCD_E, True)
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False)
  time.sleep(E_DELAY)  

if __name__ == '__main__':
  main()


This should display the ip addressof you PI:
And that should be it.

I will start working on the OBD soon. and hopefully post something about it.



3 comments: